1/**********************************************************
2 * Copyright 2008-2009 VMware, Inc.  All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 **********************************************************/
25
26#include "pipe/p_compiler.h"
27#include "util/u_inlines.h"
28#include "pipe/p_defines.h"
29#include "util/u_helpers.h"
30#include "util/u_memory.h"
31#include "util/u_math.h"
32
33#include "svga_context.h"
34#include "svga_draw.h"
35#include "svga_draw_private.h"
36#include "svga_debug.h"
37#include "svga_screen.h"
38#include "svga_resource.h"
39#include "svga_resource_buffer.h"
40#include "svga_resource_texture.h"
41#include "svga_sampler_view.h"
42#include "svga_shader.h"
43#include "svga_surface.h"
44#include "svga_winsys.h"
45#include "svga_cmd.h"
46
47
48struct svga_hwtnl *
49svga_hwtnl_create(struct svga_context *svga)
50{
51   struct svga_hwtnl *hwtnl = CALLOC_STRUCT(svga_hwtnl);
52   if (!hwtnl)
53      goto fail;
54
55   hwtnl->svga = svga;
56
57   hwtnl->cmd.swc = svga->swc;
58
59   return hwtnl;
60
61fail:
62   return NULL;
63}
64
65
66void
67svga_hwtnl_destroy(struct svga_hwtnl *hwtnl)
68{
69   unsigned i, j;
70
71   for (i = 0; i < PIPE_PRIM_MAX; i++) {
72      for (j = 0; j < IDX_CACHE_MAX; j++) {
73         pipe_resource_reference(&hwtnl->index_cache[i][j].buffer, NULL);
74      }
75   }
76
77   for (i = 0; i < hwtnl->cmd.vbuf_count; i++)
78      pipe_vertex_buffer_unreference(&hwtnl->cmd.vbufs[i]);
79
80   for (i = 0; i < hwtnl->cmd.prim_count; i++)
81      pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
82
83   FREE(hwtnl);
84}
85
86
87void
88svga_hwtnl_set_flatshade(struct svga_hwtnl *hwtnl,
89                         boolean flatshade, boolean flatshade_first)
90{
91   struct svga_screen *svgascreen = svga_screen(hwtnl->svga->pipe.screen);
92
93   /* User-specified PV */
94   hwtnl->api_pv = (flatshade && !flatshade_first) ? PV_LAST : PV_FIRST;
95
96   /* Device supported PV */
97   if (svgascreen->haveProvokingVertex) {
98      /* use the mode specified by the user */
99      hwtnl->hw_pv = hwtnl->api_pv;
100   }
101   else {
102      /* the device only support first provoking vertex */
103      hwtnl->hw_pv = PV_FIRST;
104   }
105}
106
107
108void
109svga_hwtnl_set_fillmode(struct svga_hwtnl *hwtnl, unsigned mode)
110{
111   hwtnl->api_fillmode = mode;
112}
113
114
115void
116svga_hwtnl_vertex_decls(struct svga_hwtnl *hwtnl,
117                        unsigned count,
118                        const SVGA3dVertexDecl * decls,
119                        const unsigned *buffer_indexes,
120                        SVGA3dElementLayoutId layout_id)
121{
122   assert(hwtnl->cmd.prim_count == 0);
123   hwtnl->cmd.vdecl_count = count;
124   hwtnl->cmd.vdecl_layout_id = layout_id;
125   memcpy(hwtnl->cmd.vdecl, decls, count * sizeof(*decls));
126   memcpy(hwtnl->cmd.vdecl_buffer_index, buffer_indexes,
127          count * sizeof(unsigned));
128}
129
130
131/**
132 * Specify vertex buffers for hardware drawing.
133 */
134void
135svga_hwtnl_vertex_buffers(struct svga_hwtnl *hwtnl,
136                          unsigned count, struct pipe_vertex_buffer *buffers)
137{
138   struct pipe_vertex_buffer *dst = hwtnl->cmd.vbufs;
139   const struct pipe_vertex_buffer *src = buffers;
140   unsigned i;
141
142   for (i = 0; i < count; i++) {
143      pipe_vertex_buffer_reference(&dst[i], &src[i]);
144   }
145
146   /* release old buffer references */
147   for ( ; i < hwtnl->cmd.vbuf_count; i++) {
148      pipe_vertex_buffer_unreference(&dst[i]);
149      /* don't bother zeroing stride/offset fields */
150   }
151
152   hwtnl->cmd.vbuf_count = count;
153}
154
155
156/**
157 * Determine whether the specified buffer is referred in the primitive queue,
158 * for which no commands have been written yet.
159 */
160boolean
161svga_hwtnl_is_buffer_referred(struct svga_hwtnl *hwtnl,
162                              struct pipe_resource *buffer)
163{
164   unsigned i;
165
166   if (svga_buffer_is_user_buffer(buffer)) {
167      return FALSE;
168   }
169
170   if (!hwtnl->cmd.prim_count) {
171      return FALSE;
172   }
173
174   for (i = 0; i < hwtnl->cmd.vbuf_count; ++i) {
175      if (hwtnl->cmd.vbufs[i].buffer.resource == buffer) {
176         return TRUE;
177      }
178   }
179
180   for (i = 0; i < hwtnl->cmd.prim_count; ++i) {
181      if (hwtnl->cmd.prim_ib[i] == buffer) {
182         return TRUE;
183      }
184   }
185
186   return FALSE;
187}
188
189
190static enum pipe_error
191draw_vgpu9(struct svga_hwtnl *hwtnl)
192{
193   struct svga_winsys_context *swc = hwtnl->cmd.swc;
194   struct svga_context *svga = hwtnl->svga;
195   enum pipe_error ret;
196   struct svga_winsys_surface *vb_handle[SVGA3D_INPUTREG_MAX];
197   struct svga_winsys_surface *ib_handle[QSZ];
198   struct svga_winsys_surface *handle;
199   SVGA3dVertexDecl *vdecl;
200   SVGA3dPrimitiveRange *prim;
201   unsigned i;
202
203   /* Re-validate those sampler views with backing copy
204    * of texture whose original copy has been updated.
205    * This is done here at draw time because the texture binding might not
206    * have modified, hence validation is not triggered at state update time,
207    * and yet the texture might have been updated in another context, so
208    * we need to re-validate the sampler view in order to update the backing
209    * copy of the updated texture.
210    */
211   if (svga->state.hw_draw.num_backed_views) {
212      for (i = 0; i < svga->state.hw_draw.num_views; i++) {
213         struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
214         struct svga_texture *tex = svga_texture(view->texture);
215         struct svga_sampler_view *sv = view->v;
216         if (sv && tex && sv->handle != tex->handle && sv->age < tex->age)
217            svga_validate_sampler_view(svga, view->v);
218      }
219   }
220
221   for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
222      unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
223      handle = svga_buffer_handle(svga, hwtnl->cmd.vbufs[j].buffer.resource,
224                                  PIPE_BIND_VERTEX_BUFFER);
225      if (!handle)
226         return PIPE_ERROR_OUT_OF_MEMORY;
227
228      vb_handle[i] = handle;
229   }
230
231   for (i = 0; i < hwtnl->cmd.prim_count; i++) {
232      if (hwtnl->cmd.prim_ib[i]) {
233         handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i],
234                                     PIPE_BIND_INDEX_BUFFER);
235         if (!handle)
236            return PIPE_ERROR_OUT_OF_MEMORY;
237      }
238      else
239         handle = NULL;
240
241      ib_handle[i] = handle;
242   }
243
244   if (svga->rebind.flags.rendertargets) {
245      ret = svga_reemit_framebuffer_bindings(svga);
246      if (ret != PIPE_OK) {
247         return ret;
248      }
249   }
250
251   if (svga->rebind.flags.texture_samplers) {
252      ret = svga_reemit_tss_bindings(svga);
253      if (ret != PIPE_OK) {
254         return ret;
255      }
256   }
257
258   if (svga->rebind.flags.vs) {
259      ret = svga_reemit_vs_bindings(svga);
260      if (ret != PIPE_OK) {
261         return ret;
262      }
263   }
264
265   if (svga->rebind.flags.fs) {
266      ret = svga_reemit_fs_bindings(svga);
267      if (ret != PIPE_OK) {
268         return ret;
269      }
270   }
271
272   SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n",
273            svga->curr.framebuffer.cbufs[0] ?
274            svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL,
275            hwtnl->cmd.prim_count);
276
277   ret = SVGA3D_BeginDrawPrimitives(swc,
278                                    &vdecl,
279                                    hwtnl->cmd.vdecl_count,
280                                    &prim, hwtnl->cmd.prim_count);
281   if (ret != PIPE_OK)
282      return ret;
283
284   memcpy(vdecl,
285          hwtnl->cmd.vdecl,
286          hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]);
287
288   for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
289      /* check for 4-byte alignment */
290      assert(vdecl[i].array.offset % 4 == 0);
291      assert(vdecl[i].array.stride % 4 == 0);
292
293      /* Given rangeHint is considered to be relative to indexBias, and
294       * indexBias varies per primitive, we cannot accurately supply an
295       * rangeHint when emitting more than one primitive per draw command.
296       */
297      if (hwtnl->cmd.prim_count == 1) {
298         vdecl[i].rangeHint.first = hwtnl->cmd.min_index[0];
299         vdecl[i].rangeHint.last = hwtnl->cmd.max_index[0] + 1;
300      }
301      else {
302         vdecl[i].rangeHint.first = 0;
303         vdecl[i].rangeHint.last = 0;
304      }
305
306      swc->surface_relocation(swc,
307                              &vdecl[i].array.surfaceId,
308                              NULL, vb_handle[i], SVGA_RELOC_READ);
309   }
310
311   memcpy(prim,
312          hwtnl->cmd.prim, hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]);
313
314   for (i = 0; i < hwtnl->cmd.prim_count; i++) {
315      swc->surface_relocation(swc,
316                              &prim[i].indexArray.surfaceId,
317                              NULL, ib_handle[i], SVGA_RELOC_READ);
318      pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
319   }
320
321   SVGA_FIFOCommitAll(swc);
322
323   hwtnl->cmd.prim_count = 0;
324
325   return PIPE_OK;
326}
327
328
329static SVGA3dSurfaceFormat
330xlate_index_format(unsigned indexWidth)
331{
332   if (indexWidth == 2) {
333      return SVGA3D_R16_UINT;
334   }
335   else if (indexWidth == 4) {
336      return SVGA3D_R32_UINT;
337   }
338   else {
339      assert(!"Bad indexWidth");
340      return SVGA3D_R32_UINT;
341   }
342}
343
344
345static enum pipe_error
346validate_sampler_resources(struct svga_context *svga)
347{
348   enum pipe_shader_type shader;
349
350   assert(svga_have_vgpu10(svga));
351
352   for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
353      unsigned count = svga->curr.num_sampler_views[shader];
354      unsigned i;
355      struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS];
356      enum pipe_error ret;
357
358      /*
359       * Reference bound sampler resources to ensure pending updates are
360       * noticed by the device.
361       */
362      for (i = 0; i < count; i++) {
363         struct svga_pipe_sampler_view *sv =
364            svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
365
366         if (sv) {
367            if (sv->base.texture->target == PIPE_BUFFER) {
368               surfaces[i] = svga_buffer_handle(svga, sv->base.texture,
369                                                PIPE_BIND_SAMPLER_VIEW);
370            }
371            else {
372               surfaces[i] = svga_texture(sv->base.texture)->handle;
373            }
374         }
375         else {
376            surfaces[i] = NULL;
377         }
378      }
379
380      if (shader == PIPE_SHADER_FRAGMENT &&
381          svga->curr.rast->templ.poly_stipple_enable) {
382         const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
383         struct svga_pipe_sampler_view *sv =
384            svga->polygon_stipple.sampler_view;
385
386         assert(sv);
387         surfaces[unit] = svga_texture(sv->base.texture)->handle;
388         count = MAX2(count, unit+1);
389      }
390
391      /* rebind the shader resources if needed */
392      if (svga->rebind.flags.texture_samplers) {
393         for (i = 0; i < count; i++) {
394            if (surfaces[i]) {
395               ret = svga->swc->resource_rebind(svga->swc,
396                                                surfaces[i],
397                                                NULL,
398                                                SVGA_RELOC_READ);
399               if (ret != PIPE_OK)
400                  return ret;
401            }
402         }
403      }
404   }
405   svga->rebind.flags.texture_samplers = FALSE;
406
407   return PIPE_OK;
408}
409
410
411static enum pipe_error
412validate_constant_buffers(struct svga_context *svga)
413{
414   enum pipe_shader_type shader;
415
416   assert(svga_have_vgpu10(svga));
417
418   for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
419      enum pipe_error ret;
420      struct svga_buffer *buffer;
421      struct svga_winsys_surface *handle;
422      unsigned enabled_constbufs;
423
424      /* Rebind the default constant buffer if needed */
425      if (svga->rebind.flags.constbufs) {
426         buffer = svga_buffer(svga->state.hw_draw.constbuf[shader]);
427         if (buffer) {
428            ret = svga->swc->resource_rebind(svga->swc,
429                                             buffer->handle,
430                                             NULL,
431                                             SVGA_RELOC_READ);
432            if (ret != PIPE_OK)
433               return ret;
434         }
435      }
436
437      /*
438       * Reference other bound constant buffers to ensure pending updates are
439       * noticed by the device.
440       */
441      enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] & ~1u;
442      while (enabled_constbufs) {
443         unsigned i = u_bit_scan(&enabled_constbufs);
444         buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
445         if (buffer) {
446            handle = svga_buffer_handle(svga, &buffer->b.b,
447                                        PIPE_BIND_CONSTANT_BUFFER);
448
449            if (svga->rebind.flags.constbufs) {
450               ret = svga->swc->resource_rebind(svga->swc,
451                                                handle,
452                                                NULL,
453                                                SVGA_RELOC_READ);
454               if (ret != PIPE_OK)
455                  return ret;
456            }
457         }
458      }
459   }
460   svga->rebind.flags.constbufs = FALSE;
461
462   return PIPE_OK;
463}
464
465
466/**
467 * Was the last command put into the command buffer a drawing command?
468 * We use this to determine if we can skip emitting buffer re-bind
469 * commands when we have a sequence of drawing commands that use the
470 * same vertex/index buffers with no intervening commands.
471 *
472 * The first drawing command will bind the vertex/index buffers.  If
473 * the immediately following command is also a drawing command using the
474 * same buffers, we shouldn't have to rebind them.
475 */
476static bool
477last_command_was_draw(const struct svga_context *svga)
478{
479   switch (SVGA3D_GetLastCommand(svga->swc)) {
480   case SVGA_3D_CMD_DX_DRAW:
481   case SVGA_3D_CMD_DX_DRAW_INDEXED:
482   case SVGA_3D_CMD_DX_DRAW_INSTANCED:
483   case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED:
484   case SVGA_3D_CMD_DX_DRAW_AUTO:
485      return true;
486   default:
487      return false;
488   }
489}
490
491
492/**
493 * A helper function to compare vertex buffers.
494 * They are equal if the vertex buffer attributes and the vertex buffer
495 * resources are identical.
496 */
497static boolean
498vertex_buffers_equal(unsigned count,
499                     SVGA3dVertexBuffer *pVBufAttr1,
500                     struct pipe_resource **pVBuf1,
501                     SVGA3dVertexBuffer *pVBufAttr2,
502                     struct pipe_resource **pVBuf2)
503{
504   return (memcmp(pVBufAttr1, pVBufAttr2,
505                  count * sizeof(*pVBufAttr1)) == 0) &&
506          (memcmp(pVBuf1, pVBuf2, count * sizeof(*pVBuf1)) == 0);
507}
508
509
510/*
511 * Prepare the vertex buffers for a drawing command.
512 */
513static enum pipe_error
514validate_vertex_buffers(struct svga_hwtnl *hwtnl)
515{
516   struct svga_context *svga = hwtnl->svga;
517   struct pipe_resource *vbuffers[SVGA3D_INPUTREG_MAX];
518   struct svga_winsys_surface *vbuffer_handles[SVGA3D_INPUTREG_MAX];
519   const unsigned vbuf_count = hwtnl->cmd.vbuf_count;
520   int last_vbuf = -1;
521   unsigned i;
522
523   assert(svga_have_vgpu10(svga));
524
525   /* Get handle for each referenced vertex buffer */
526   for (i = 0; i < vbuf_count; i++) {
527      struct svga_buffer *sbuf =
528         svga_buffer(hwtnl->cmd.vbufs[i].buffer.resource);
529
530      if (sbuf) {
531         vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b.b,
532                                                 PIPE_BIND_VERTEX_BUFFER);
533         assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER);
534         if (vbuffer_handles[i] == NULL)
535            return PIPE_ERROR_OUT_OF_MEMORY;
536         vbuffers[i] = &sbuf->b.b;
537         last_vbuf = i;
538      }
539      else {
540         vbuffers[i] = NULL;
541         vbuffer_handles[i] = NULL;
542      }
543   }
544
545   for (; i < svga->state.hw_draw.num_vbuffers; i++) {
546      vbuffers[i] = NULL;
547      vbuffer_handles[i] = NULL;
548   }
549
550   /* setup vertex attribute input layout */
551   if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) {
552      enum pipe_error ret =
553         SVGA3D_vgpu10_SetInputLayout(svga->swc,
554                                      hwtnl->cmd.vdecl_layout_id);
555      if (ret != PIPE_OK)
556         return ret;
557
558      svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id;
559   }
560
561   /* setup vertex buffers */
562   {
563      SVGA3dVertexBuffer vbuffer_attrs[PIPE_MAX_ATTRIBS];
564
565      for (i = 0; i < vbuf_count; i++) {
566         vbuffer_attrs[i].stride = hwtnl->cmd.vbufs[i].stride;
567         vbuffer_attrs[i].offset = hwtnl->cmd.vbufs[i].buffer_offset;
568         vbuffer_attrs[i].sid = 0;
569      }
570
571      /* If any of the vertex buffer state has changed, issue
572       * the SetVertexBuffers command. Otherwise, we will just
573       * need to rebind the resources.
574       */
575      if (vbuf_count != svga->state.hw_draw.num_vbuffers ||
576          !vertex_buffers_equal(vbuf_count,
577                                vbuffer_attrs,
578                                vbuffers,
579                                svga->state.hw_draw.vbuffer_attrs,
580                                svga->state.hw_draw.vbuffers)) {
581
582         unsigned num_vbuffers;
583
584         /* get the max of the current bound vertex buffers count and
585          * the to-be-bound vertex buffers count, so as to unbind
586          * the unused vertex buffers.
587          */
588         num_vbuffers = MAX2(vbuf_count, svga->state.hw_draw.num_vbuffers);
589
590         /* Zero-out the old buffers we want to unbind (the number of loop
591          * iterations here is typically very small, and often zero.)
592          */
593         for (i = vbuf_count; i < num_vbuffers; i++) {
594            vbuffer_attrs[i].sid = 0;
595            vbuffer_attrs[i].stride = 0;
596            vbuffer_attrs[i].offset = 0;
597            vbuffer_handles[i] = NULL;
598         }
599
600         if (num_vbuffers > 0) {
601            SVGA3dVertexBuffer *pbufAttrs = vbuffer_attrs;
602            struct svga_winsys_surface **pbufHandles = vbuffer_handles;
603            unsigned numVBuf = 0;
604
605            /* Loop through the vertex buffer lists to only emit
606             * those vertex buffers that are not already in the
607             * corresponding entries in the device's vertex buffer list.
608             */
609            for (i = 0; i < num_vbuffers; i++) {
610               boolean emit =
611                  vertex_buffers_equal(1,
612                                       &vbuffer_attrs[i],
613                                       &vbuffers[i],
614                                       &svga->state.hw_draw.vbuffer_attrs[i],
615                                       &svga->state.hw_draw.vbuffers[i]);
616
617               if (!emit && i == num_vbuffers-1) {
618                  /* Include the last vertex buffer in the next emit
619                   * if it is different.
620                   */
621                  emit = TRUE;
622                  numVBuf++;
623                  i++;
624               }
625
626               if (emit) {
627                  /* numVBuf can only be 0 if the first vertex buffer
628                   * is the same as the one in the device's list.
629                   * In this case, there is nothing to send yet.
630                   */
631                  if (numVBuf) {
632                     enum pipe_error ret =
633                        SVGA3D_vgpu10_SetVertexBuffers(svga->swc,
634                                                       numVBuf,
635                                                       i - numVBuf,
636                                                       pbufAttrs, pbufHandles);
637                     if (ret != PIPE_OK)
638                        return ret;
639                  }
640                  pbufAttrs += (numVBuf + 1);
641                  pbufHandles += (numVBuf + 1);
642                  numVBuf = 0;
643               }
644               else
645                  numVBuf++;
646            }
647
648            /* save the number of vertex buffers sent to the device, not
649             * including trailing unbound vertex buffers.
650             */
651            svga->state.hw_draw.num_vbuffers = last_vbuf + 1;
652            memcpy(svga->state.hw_draw.vbuffer_attrs, vbuffer_attrs,
653                   num_vbuffers * sizeof(vbuffer_attrs[0]));
654            for (i = 0; i < num_vbuffers; i++) {
655               pipe_resource_reference(&svga->state.hw_draw.vbuffers[i],
656                                       vbuffers[i]);
657            }
658         }
659      }
660      else {
661         /* Even though we can avoid emitting the redundant SetVertexBuffers
662          * command, we still need to reference the vertex buffers surfaces.
663          */
664         for (i = 0; i < vbuf_count; i++) {
665            if (vbuffer_handles[i] && !last_command_was_draw(svga)) {
666               enum pipe_error ret =
667                  svga->swc->resource_rebind(svga->swc, vbuffer_handles[i],
668                                             NULL, SVGA_RELOC_READ);
669               if (ret != PIPE_OK)
670                  return ret;
671            }
672         }
673      }
674   }
675
676   return PIPE_OK;
677}
678
679
680/*
681 * Prepare the index buffer for a drawing command.
682 */
683static enum pipe_error
684validate_index_buffer(struct svga_hwtnl *hwtnl,
685                      const SVGA3dPrimitiveRange *range,
686                      struct pipe_resource *ib)
687{
688   struct svga_context *svga = hwtnl->svga;
689   struct svga_winsys_surface *ib_handle =
690      svga_buffer_handle(svga, ib, PIPE_BIND_INDEX_BUFFER);
691
692   if (!ib_handle)
693      return PIPE_ERROR_OUT_OF_MEMORY;
694
695   struct svga_buffer *sbuf = svga_buffer(ib);
696   assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_INDEX_BUFFER);
697   (void) sbuf; /* silence unused var warning */
698
699   SVGA3dSurfaceFormat indexFormat = xlate_index_format(range->indexWidth);
700
701   if (ib != svga->state.hw_draw.ib ||
702       indexFormat != svga->state.hw_draw.ib_format ||
703       range->indexArray.offset != svga->state.hw_draw.ib_offset) {
704
705      assert(indexFormat != SVGA3D_FORMAT_INVALID);
706      enum pipe_error ret =
707         SVGA3D_vgpu10_SetIndexBuffer(svga->swc, ib_handle,
708                                      indexFormat,
709                                      range->indexArray.offset);
710      if (ret != PIPE_OK)
711         return ret;
712
713      pipe_resource_reference(&svga->state.hw_draw.ib, ib);
714      svga->state.hw_draw.ib_format = indexFormat;
715      svga->state.hw_draw.ib_offset = range->indexArray.offset;
716   }
717   else {
718      /* Even though we can avoid emitting the redundant SetIndexBuffer
719       * command, we still need to reference the index buffer surface.
720       */
721      if (!last_command_was_draw(svga)) {
722         enum pipe_error ret = svga->swc->resource_rebind(svga->swc,
723                                                          ib_handle,
724                                                          NULL,
725                                                          SVGA_RELOC_READ);
726         if (ret != PIPE_OK)
727            return ret;
728      }
729   }
730
731   return PIPE_OK;
732}
733
734
735static enum pipe_error
736draw_vgpu10(struct svga_hwtnl *hwtnl,
737            const SVGA3dPrimitiveRange *range,
738            unsigned vcount,
739            struct pipe_resource *ib,
740            unsigned start_instance, unsigned instance_count)
741{
742   struct svga_context *svga = hwtnl->svga;
743   enum pipe_error ret;
744
745   assert(svga_have_vgpu10(svga));
746   assert(hwtnl->cmd.prim_count == 0);
747
748   /* We need to reemit all the current resource bindings along with the Draw
749    * command to be sure that the referenced resources are available for the
750    * Draw command, just in case the surfaces associated with the resources
751    * are paged out.
752    */
753   if (svga->rebind.val) {
754      ret = svga_rebind_framebuffer_bindings(svga);
755      if (ret != PIPE_OK)
756         return ret;
757
758      ret = svga_rebind_shaders(svga);
759      if (ret != PIPE_OK)
760         return ret;
761
762      /* Rebind stream output targets */
763      ret = svga_rebind_stream_output_targets(svga);
764      if (ret != PIPE_OK)
765         return ret;
766
767      /* No need to explicitly rebind index buffer and vertex buffers here.
768       * Even if the same index buffer or vertex buffers are referenced for this
769       * draw and we skip emitting the redundant set command, we will still
770       * reference the associated resources.
771       */
772   }
773
774   ret = validate_sampler_resources(svga);
775   if (ret != PIPE_OK)
776      return ret;
777
778   ret = validate_constant_buffers(svga);
779   if (ret != PIPE_OK)
780      return ret;
781
782   ret = validate_vertex_buffers(hwtnl);
783   if (ret != PIPE_OK)
784      return ret;
785
786   if (ib) {
787      ret = validate_index_buffer(hwtnl, range, ib);
788      if (ret != PIPE_OK)
789         return ret;
790   }
791
792   /* Set primitive type (line, tri, etc) */
793   if (svga->state.hw_draw.topology != range->primType) {
794      ret = SVGA3D_vgpu10_SetTopology(svga->swc, range->primType);
795      if (ret != PIPE_OK)
796         return ret;
797
798      svga->state.hw_draw.topology = range->primType;
799   }
800
801   if (ib) {
802      /* indexed drawing */
803      if (instance_count > 1) {
804         ret = SVGA3D_vgpu10_DrawIndexedInstanced(svga->swc,
805                                                  vcount,
806                                                  instance_count,
807                                                  0, /* startIndexLocation */
808                                                  range->indexBias,
809                                                  start_instance);
810         if (ret != PIPE_OK)
811            return ret;
812      }
813      else {
814         /* non-instanced drawing */
815         ret = SVGA3D_vgpu10_DrawIndexed(svga->swc,
816                                         vcount,
817                                         0,      /* startIndexLocation */
818                                         range->indexBias);
819         if (ret != PIPE_OK)
820            return ret;
821      }
822   }
823   else {
824      /* non-indexed drawing */
825      if (svga->state.hw_draw.ib_format != SVGA3D_FORMAT_INVALID ||
826          svga->state.hw_draw.ib != NULL) {
827         /* Unbind previously bound index buffer */
828         ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, NULL,
829                                            SVGA3D_FORMAT_INVALID, 0);
830         if (ret != PIPE_OK)
831            return ret;
832         pipe_resource_reference(&svga->state.hw_draw.ib, NULL);
833         svga->state.hw_draw.ib_format = SVGA3D_FORMAT_INVALID;
834      }
835
836      assert(svga->state.hw_draw.ib == NULL);
837
838      if (instance_count > 1) {
839         ret = SVGA3D_vgpu10_DrawInstanced(svga->swc,
840                                           vcount,
841                                           instance_count,
842                                           range->indexBias,
843                                           start_instance);
844         if (ret != PIPE_OK)
845            return ret;
846      }
847      else {
848         /* non-instanced */
849         ret = SVGA3D_vgpu10_Draw(svga->swc,
850                                  vcount,
851                                  range->indexBias);
852         if (ret != PIPE_OK)
853            return ret;
854      }
855   }
856
857   hwtnl->cmd.prim_count = 0;
858
859   return PIPE_OK;
860}
861
862
863
864/**
865 * Emit any pending drawing commands to the command buffer.
866 * When we receive VGPU9 drawing commands we accumulate them and don't
867 * immediately emit them into the command buffer.
868 * This function needs to be called before we change state that could
869 * effect those pending draws.
870 */
871enum pipe_error
872svga_hwtnl_flush(struct svga_hwtnl *hwtnl)
873{
874   enum pipe_error ret = PIPE_OK;
875
876   SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLFLUSH);
877
878   if (!svga_have_vgpu10(hwtnl->svga) && hwtnl->cmd.prim_count) {
879      /* we only queue up primitive for VGPU9 */
880      ret = draw_vgpu9(hwtnl);
881   }
882
883   SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
884   return ret;
885}
886
887
888void
889svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias)
890{
891   hwtnl->index_bias = index_bias;
892}
893
894
895
896/***********************************************************************
897 * Internal functions:
898 */
899
900/**
901 * For debugging only.
902 */
903static void
904check_draw_params(struct svga_hwtnl *hwtnl,
905                  const SVGA3dPrimitiveRange *range,
906                  unsigned min_index, unsigned max_index,
907                  struct pipe_resource *ib)
908{
909   unsigned i;
910
911   assert(!svga_have_vgpu10(hwtnl->svga));
912
913   for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
914      unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
915      const struct pipe_vertex_buffer *vb = &hwtnl->cmd.vbufs[j];
916      unsigned size = vb->buffer.resource ? vb->buffer.resource->width0 : 0;
917      unsigned offset = hwtnl->cmd.vdecl[i].array.offset;
918      unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
919      int index_bias = (int) range->indexBias + hwtnl->index_bias;
920      unsigned width;
921
922      if (size == 0)
923         continue;
924
925      assert(vb);
926      assert(size);
927      assert(offset < size);
928      assert(min_index <= max_index);
929      (void) width;
930      (void) stride;
931      (void) offset;
932      (void) size;
933
934      switch (hwtnl->cmd.vdecl[i].identity.type) {
935      case SVGA3D_DECLTYPE_FLOAT1:
936         width = 4;
937         break;
938      case SVGA3D_DECLTYPE_FLOAT2:
939         width = 4 * 2;
940         break;
941      case SVGA3D_DECLTYPE_FLOAT3:
942         width = 4 * 3;
943         break;
944      case SVGA3D_DECLTYPE_FLOAT4:
945         width = 4 * 4;
946         break;
947      case SVGA3D_DECLTYPE_D3DCOLOR:
948         width = 4;
949         break;
950      case SVGA3D_DECLTYPE_UBYTE4:
951         width = 1 * 4;
952         break;
953      case SVGA3D_DECLTYPE_SHORT2:
954         width = 2 * 2;
955         break;
956      case SVGA3D_DECLTYPE_SHORT4:
957         width = 2 * 4;
958         break;
959      case SVGA3D_DECLTYPE_UBYTE4N:
960         width = 1 * 4;
961         break;
962      case SVGA3D_DECLTYPE_SHORT2N:
963         width = 2 * 2;
964         break;
965      case SVGA3D_DECLTYPE_SHORT4N:
966         width = 2 * 4;
967         break;
968      case SVGA3D_DECLTYPE_USHORT2N:
969         width = 2 * 2;
970         break;
971      case SVGA3D_DECLTYPE_USHORT4N:
972         width = 2 * 4;
973         break;
974      case SVGA3D_DECLTYPE_UDEC3:
975         width = 4;
976         break;
977      case SVGA3D_DECLTYPE_DEC3N:
978         width = 4;
979         break;
980      case SVGA3D_DECLTYPE_FLOAT16_2:
981         width = 2 * 2;
982         break;
983      case SVGA3D_DECLTYPE_FLOAT16_4:
984         width = 2 * 4;
985         break;
986      default:
987         assert(0);
988         width = 0;
989         break;
990      }
991
992      if (index_bias >= 0) {
993         assert(offset + index_bias * stride + width <= size);
994      }
995
996      /*
997       * min_index/max_index are merely conservative guesses, so we can't
998       * make buffer overflow detection based on their values.
999       */
1000   }
1001
1002   assert(range->indexWidth == range->indexArray.stride);
1003
1004   if (ib) {
1005      MAYBE_UNUSED unsigned size = ib->width0;
1006      MAYBE_UNUSED unsigned offset = range->indexArray.offset;
1007      MAYBE_UNUSED unsigned stride = range->indexArray.stride;
1008      MAYBE_UNUSED unsigned count;
1009
1010      assert(size);
1011      assert(offset < size);
1012      assert(stride);
1013
1014      switch (range->primType) {
1015      case SVGA3D_PRIMITIVE_POINTLIST:
1016         count = range->primitiveCount;
1017         break;
1018      case SVGA3D_PRIMITIVE_LINELIST:
1019         count = range->primitiveCount * 2;
1020         break;
1021      case SVGA3D_PRIMITIVE_LINESTRIP:
1022         count = range->primitiveCount + 1;
1023         break;
1024      case SVGA3D_PRIMITIVE_TRIANGLELIST:
1025         count = range->primitiveCount * 3;
1026         break;
1027      case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
1028         count = range->primitiveCount + 2;
1029         break;
1030      case SVGA3D_PRIMITIVE_TRIANGLEFAN:
1031         count = range->primitiveCount + 2;
1032         break;
1033      default:
1034         assert(0);
1035         count = 0;
1036         break;
1037      }
1038
1039      assert(offset + count * stride <= size);
1040   }
1041}
1042
1043
1044/**
1045 * All drawing filters down into this function, either directly
1046 * on the hardware path or after doing software vertex processing.
1047 */
1048enum pipe_error
1049svga_hwtnl_prim(struct svga_hwtnl *hwtnl,
1050                const SVGA3dPrimitiveRange * range,
1051                unsigned vcount,
1052                unsigned min_index,
1053                unsigned max_index, struct pipe_resource *ib,
1054                unsigned start_instance, unsigned instance_count)
1055{
1056   enum pipe_error ret = PIPE_OK;
1057
1058   SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLPRIM);
1059
1060   if (svga_have_vgpu10(hwtnl->svga)) {
1061      /* draw immediately */
1062      ret = draw_vgpu10(hwtnl, range, vcount, ib,
1063                        start_instance, instance_count);
1064      if (ret != PIPE_OK) {
1065         svga_context_flush(hwtnl->svga, NULL);
1066         ret = draw_vgpu10(hwtnl, range, vcount, ib,
1067                           start_instance, instance_count);
1068         assert(ret == PIPE_OK);
1069      }
1070   }
1071   else {
1072      /* batch up drawing commands */
1073#ifdef DEBUG
1074      check_draw_params(hwtnl, range, min_index, max_index, ib);
1075      assert(start_instance == 0);
1076      assert(instance_count <= 1);
1077#else
1078      (void) check_draw_params;
1079#endif
1080
1081      if (hwtnl->cmd.prim_count + 1 >= QSZ) {
1082         ret = svga_hwtnl_flush(hwtnl);
1083         if (ret != PIPE_OK)
1084            goto done;
1085      }
1086
1087      /* min/max indices are relative to bias */
1088      hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index;
1089      hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index;
1090
1091      hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range;
1092      hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias;
1093
1094      pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
1095      hwtnl->cmd.prim_count++;
1096   }
1097
1098done:
1099   SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
1100   return ret;
1101}
1102