• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
48 struct svga_hwtnl *
svga_hwtnl_create(struct svga_context * svga)49 svga_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 
61 fail:
62    return NULL;
63 }
64 
65 
66 void
svga_hwtnl_destroy(struct svga_hwtnl * hwtnl)67 svga_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 
87 void
svga_hwtnl_set_flatshade(struct svga_hwtnl * hwtnl,boolean flatshade,boolean flatshade_first)88 svga_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 
108 void
svga_hwtnl_set_fillmode(struct svga_hwtnl * hwtnl,unsigned mode)109 svga_hwtnl_set_fillmode(struct svga_hwtnl *hwtnl, unsigned mode)
110 {
111    hwtnl->api_fillmode = mode;
112 }
113 
114 
115 void
svga_hwtnl_vertex_decls(struct svga_hwtnl * hwtnl,unsigned count,const SVGA3dVertexDecl * decls,const unsigned * buffer_indexes,SVGA3dElementLayoutId layout_id)116 svga_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  */
134 void
svga_hwtnl_vertex_buffers(struct svga_hwtnl * hwtnl,unsigned count,struct pipe_vertex_buffer * buffers)135 svga_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  */
160 boolean
svga_hwtnl_is_buffer_referred(struct svga_hwtnl * hwtnl,struct pipe_resource * buffer)161 svga_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 
190 static enum pipe_error
draw_vgpu9(struct svga_hwtnl * hwtnl)191 draw_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 
329 static SVGA3dSurfaceFormat
xlate_index_format(unsigned indexWidth)330 xlate_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 
345 /**
346  * A helper function to validate sampler view resources to ensure any
347  * pending updates to buffers will be emitted before they are referenced
348  * at draw or dispatch time. It also rebinds the resources if needed.
349  */
350 enum pipe_error
svga_validate_sampler_resources(struct svga_context * svga,enum svga_pipe_type pipe_type)351 svga_validate_sampler_resources(struct svga_context *svga,
352                                 enum svga_pipe_type pipe_type)
353 {
354    enum pipe_shader_type shader, first_shader, last_shader;
355 
356    assert(svga_have_vgpu10(svga));
357 
358    if (pipe_type == SVGA_PIPE_GRAPHICS) {
359       first_shader = PIPE_SHADER_VERTEX;
360       last_shader = PIPE_SHADER_TESS_EVAL;
361    }
362    else {
363       assert(svga_have_gl43(svga));
364       first_shader = PIPE_SHADER_COMPUTE;
365       last_shader = PIPE_SHADER_COMPUTE;
366    }
367 
368    for (shader = first_shader; shader <= last_shader; shader++) {
369       unsigned count = svga->curr.num_sampler_views[shader];
370       unsigned i;
371       struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS];
372       enum pipe_error ret;
373 
374       /*
375        * Reference bound sampler resources to ensure pending updates are
376        * noticed by the device.
377        */
378       for (i = 0; i < count; i++) {
379          struct svga_pipe_sampler_view *sv =
380             svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
381 
382          if (sv) {
383             if (sv->base.texture->target == PIPE_BUFFER) {
384                surfaces[i] = svga_buffer_handle(svga, sv->base.texture,
385                                                 PIPE_BIND_SAMPLER_VIEW);
386             }
387             else {
388                surfaces[i] = svga_texture(sv->base.texture)->handle;
389             }
390          }
391          else {
392             surfaces[i] = NULL;
393          }
394       }
395 
396       if (shader == PIPE_SHADER_FRAGMENT &&
397           svga->curr.rast->templ.poly_stipple_enable) {
398          const unsigned unit =
399             svga_fs_variant(svga->state.hw_draw.fs)->pstipple_sampler_unit;
400          struct svga_pipe_sampler_view *sv =
401             svga->polygon_stipple.sampler_view;
402 
403          assert(sv);
404          surfaces[unit] = svga_texture(sv->base.texture)->handle;
405          count = MAX2(count, unit+1);
406       }
407 
408       /* rebind the shader resources if needed */
409       if (svga->rebind.flags.texture_samplers) {
410          for (i = 0; i < count; i++) {
411             if (surfaces[i]) {
412                ret = svga->swc->resource_rebind(svga->swc,
413                                                 surfaces[i],
414                                                 NULL,
415                                                 SVGA_RELOC_READ);
416                if (ret != PIPE_OK)
417                   return ret;
418             }
419          }
420       }
421    }
422    svga->rebind.flags.texture_samplers = FALSE;
423 
424    return PIPE_OK;
425 }
426 
427 
428 /**
429  * A helper function to validate constant buffers to ensure any
430  * pending updates to the buffers will be emitted before they are referenced
431  * at draw or dispatch time. It also rebinds the resources if needed.
432  */
433 enum pipe_error
svga_validate_constant_buffers(struct svga_context * svga,enum svga_pipe_type pipe_type)434 svga_validate_constant_buffers(struct svga_context *svga,
435                                enum svga_pipe_type pipe_type)
436 {
437    enum pipe_shader_type shader, first_shader, last_shader;
438 
439    assert(svga_have_vgpu10(svga));
440 
441    if (pipe_type == SVGA_PIPE_GRAPHICS) {
442       first_shader = PIPE_SHADER_VERTEX;
443       last_shader = PIPE_SHADER_TESS_EVAL;
444    }
445    else {
446       assert(svga_have_gl43(svga));
447       first_shader = PIPE_SHADER_COMPUTE;
448       last_shader = PIPE_SHADER_COMPUTE;
449    }
450 
451    for (shader = first_shader; shader <= last_shader; shader++) {
452 
453       enum pipe_error ret;
454       struct svga_buffer *buffer;
455 
456       /* Rebind the default constant buffer if needed */
457       if (svga->rebind.flags.constbufs) {
458          buffer = svga_buffer(svga->state.hw_draw.constbuf[shader][0]);
459          if (buffer) {
460             ret = svga->swc->resource_rebind(svga->swc,
461                                              buffer->handle,
462                                              NULL,
463                                              SVGA_RELOC_READ);
464             if (ret != PIPE_OK)
465                return ret;
466          }
467       }
468 
469       struct svga_winsys_surface *handle;
470       unsigned enabled_constbufs;
471 
472       /*
473        * Reference other bound constant buffers to ensure pending updates are
474        * noticed by the device.
475        */
476       enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] & ~1u;
477       while (enabled_constbufs) {
478          unsigned i = u_bit_scan(&enabled_constbufs);
479          buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
480 
481          /* If the constant buffer has hw storage, get the buffer winsys handle.
482           * Rebind the resource if needed.
483           */
484          if (buffer && !buffer->use_swbuf)
485             handle = svga_buffer_handle(svga, &buffer->b,
486                                         PIPE_BIND_CONSTANT_BUFFER);
487          else
488             handle = svga->state.hw_draw.constbufoffsets[shader][i].handle;
489 
490          if (svga->rebind.flags.constbufs && handle) {
491             ret = svga->swc->resource_rebind(svga->swc,
492                                              handle,
493                                              NULL,
494                                              SVGA_RELOC_READ);
495             if (ret != PIPE_OK)
496                return ret;
497          }
498       }
499 
500       /* Reference raw constant buffers as they are not included in the
501        * hw constant buffers list.
502        */
503       unsigned enabled_rawbufs = svga->state.hw_draw.enabled_rawbufs[shader] & ~1u;
504       while (enabled_rawbufs) {
505          unsigned i = u_bit_scan(&enabled_rawbufs);
506          buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
507 
508          assert(buffer != NULL);
509          handle = svga_buffer_handle(svga, &buffer->b,
510                                      PIPE_BIND_SAMPLER_VIEW);
511 
512          if (svga->rebind.flags.constbufs && handle) {
513             ret = svga->swc->resource_rebind(svga->swc,
514                                              handle,
515                                              NULL,
516                                              SVGA_RELOC_READ);
517             if (ret != PIPE_OK)
518                return ret;
519          }
520       }
521    }
522    svga->rebind.flags.constbufs = FALSE;
523 
524    return PIPE_OK;
525 }
526 
527 
528 /**
529  * A helper function to validate image view resources to ensure any
530  * pending updates to buffers will be emitted before they are referenced
531  * at draw or dispatch time. It also rebinds the resources if needed.
532  */
533 enum pipe_error
svga_validate_image_views(struct svga_context * svga,enum svga_pipe_type pipe_type)534 svga_validate_image_views(struct svga_context *svga,
535                           enum svga_pipe_type pipe_type)
536 {
537    enum pipe_shader_type shader, first_shader, last_shader;
538    bool rebind = svga->rebind.flags.images;
539    enum pipe_error ret;
540 
541    assert(svga_have_gl43(svga));
542 
543    if (pipe_type == SVGA_PIPE_GRAPHICS) {
544       first_shader = PIPE_SHADER_VERTEX;
545       last_shader = PIPE_SHADER_TESS_EVAL;
546    }
547    else {
548       first_shader = PIPE_SHADER_COMPUTE;
549       last_shader = PIPE_SHADER_COMPUTE;
550    }
551 
552    for (shader = first_shader; shader <= last_shader; shader++) {
553       ret = svga_validate_image_view_resources(svga,
554                svga->state.hw_draw.num_image_views[shader],
555                &svga->state.hw_draw.image_views[shader][0], rebind);
556 
557       if (ret != PIPE_OK)
558          return ret;
559    }
560 
561    svga->rebind.flags.images = FALSE;
562 
563    return PIPE_OK;
564 }
565 
566 
567 /**
568  * A helper function to validate shader buffer and atomic buffer resources to
569  * ensure any pending updates to buffers will be emitted before they are
570  * referenced at draw or dispatch time. It also rebinds the resources if needed.
571  */
572 enum pipe_error
svga_validate_shader_buffers(struct svga_context * svga,enum svga_pipe_type pipe_type)573 svga_validate_shader_buffers(struct svga_context *svga,
574                              enum svga_pipe_type pipe_type)
575 {
576    enum pipe_shader_type shader, first_shader, last_shader;
577    bool rebind = svga->rebind.flags.shaderbufs;
578    enum pipe_error ret;
579 
580    assert(svga_have_gl43(svga));
581 
582    if (pipe_type == SVGA_PIPE_GRAPHICS) {
583       first_shader = PIPE_SHADER_VERTEX;
584       last_shader = PIPE_SHADER_TESS_EVAL;
585    }
586    else {
587       first_shader = PIPE_SHADER_COMPUTE;
588       last_shader = PIPE_SHADER_COMPUTE;
589    }
590 
591    for (shader = first_shader; shader <= last_shader; shader++) {
592       ret = svga_validate_shader_buffer_resources(svga,
593                svga->state.hw_draw.num_shader_buffers[shader],
594                &svga->state.hw_draw.shader_buffers[shader][0], rebind);
595 
596       if (ret != PIPE_OK)
597          return ret;
598    }
599 
600    svga->rebind.flags.shaderbufs = FALSE;
601 
602    ret = svga_validate_shader_buffer_resources(svga,
603                svga->state.hw_draw.num_atomic_buffers,
604                svga->state.hw_draw.atomic_buffers,
605                svga->rebind.flags.atomicbufs);
606 
607    if (ret != PIPE_OK)
608       return ret;
609 
610    svga->rebind.flags.atomicbufs = FALSE;
611 
612    return PIPE_OK;
613 }
614 
615 
616 /**
617  * Was the last command put into the command buffer a drawing command?
618  * We use this to determine if we can skip emitting buffer re-bind
619  * commands when we have a sequence of drawing commands that use the
620  * same vertex/index buffers with no intervening commands.
621  *
622  * The first drawing command will bind the vertex/index buffers.  If
623  * the immediately following command is also a drawing command using the
624  * same buffers, we shouldn't have to rebind them.
625  */
626 static bool
last_command_was_draw(const struct svga_context * svga)627 last_command_was_draw(const struct svga_context *svga)
628 {
629    switch (SVGA3D_GetLastCommand(svga->swc)) {
630    case SVGA_3D_CMD_DX_DRAW:
631    case SVGA_3D_CMD_DX_DRAW_INDEXED:
632    case SVGA_3D_CMD_DX_DRAW_INSTANCED:
633    case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED:
634    case SVGA_3D_CMD_DX_DRAW_AUTO:
635    case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT:
636    case SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT:
637       return true;
638    default:
639       return false;
640    }
641 }
642 
643 
644 /**
645  * A helper function to compare vertex buffers.
646  * They are equal if the vertex buffer attributes and the vertex buffer
647  * resources are identical.
648  */
649 static boolean
vertex_buffers_equal(unsigned count,SVGA3dVertexBuffer_v2 * pVBufAttr1,struct pipe_resource ** pVBuf1,SVGA3dVertexBuffer_v2 * pVBufAttr2,struct pipe_resource ** pVBuf2)650 vertex_buffers_equal(unsigned count,
651                      SVGA3dVertexBuffer_v2 *pVBufAttr1,
652                      struct pipe_resource **pVBuf1,
653                      SVGA3dVertexBuffer_v2 *pVBufAttr2,
654                      struct pipe_resource **pVBuf2)
655 {
656    return (memcmp(pVBufAttr1, pVBufAttr2,
657                   count * sizeof(*pVBufAttr1)) == 0) &&
658           (memcmp(pVBuf1, pVBuf2, count * sizeof(*pVBuf1)) == 0);
659 }
660 
661 
662 /*
663  * Prepare the vertex buffers for a drawing command.
664  */
665 static enum pipe_error
validate_vertex_buffers(struct svga_hwtnl * hwtnl,const struct pipe_stream_output_target * so_vertex_count)666 validate_vertex_buffers(struct svga_hwtnl *hwtnl,
667                    const struct pipe_stream_output_target *so_vertex_count)
668 {
669    struct svga_context *svga = hwtnl->svga;
670    struct pipe_resource *vbuffers[SVGA3D_INPUTREG_MAX];
671    struct svga_winsys_surface *vbuffer_handles[SVGA3D_INPUTREG_MAX];
672    struct svga_winsys_surface *so_vertex_count_handle = NULL;
673    const unsigned vbuf_count = so_vertex_count ? 1 : hwtnl->cmd.vbuf_count;
674    SVGA3dVertexBuffer_v2 vbuffer_attrs[PIPE_MAX_ATTRIBS];
675    int last_vbuf = -1;
676    unsigned i;
677 
678    assert(svga_have_vgpu10(svga));
679 
680    /* setup vertex attribute input layout */
681    if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) {
682       enum pipe_error ret =
683          SVGA3D_vgpu10_SetInputLayout(svga->swc,
684                                       hwtnl->cmd.vdecl_layout_id);
685       if (ret != PIPE_OK)
686          return ret;
687 
688       svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id;
689    }
690 
691    /* Get handle for each referenced vertex buffer, unless we're using a
692     * stream-out buffer to specify the drawing information (DrawAuto).
693     * Also set up the buffer attributes.
694     */
695    if (so_vertex_count) {
696       so_vertex_count_handle = svga_buffer_handle(svga,
697                                                   so_vertex_count->buffer,
698                                                   (PIPE_BIND_VERTEX_BUFFER |
699                                                    PIPE_BIND_STREAM_OUTPUT));
700       if (!so_vertex_count_handle)
701          return PIPE_ERROR_OUT_OF_MEMORY;
702 
703       /* Set IA slot0 input buffer to the SO buffer */
704       assert(vbuf_count == 1);
705       vbuffer_attrs[0].stride = hwtnl->cmd.vbufs[0].stride;
706       vbuffer_attrs[0].offset = hwtnl->cmd.vbufs[0].buffer_offset;
707       vbuffer_attrs[0].sid = 0;
708       assert(so_vertex_count->buffer != NULL);
709       vbuffer_attrs[0].sizeInBytes = svga_buffer(so_vertex_count->buffer)->size;
710       vbuffers[0] = so_vertex_count->buffer;
711       vbuffer_handles[0] = so_vertex_count_handle;
712 
713       i = 1;
714    }
715    else {
716       for (i = 0; i < vbuf_count; i++) {
717          struct svga_buffer *sbuf =
718             svga_buffer(hwtnl->cmd.vbufs[i].buffer.resource);
719 
720          vbuffer_attrs[i].stride = hwtnl->cmd.vbufs[i].stride;
721          vbuffer_attrs[i].offset = hwtnl->cmd.vbufs[i].buffer_offset;
722          vbuffer_attrs[i].sid = 0;
723 
724          if (sbuf) {
725             vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b,
726                                                     PIPE_BIND_VERTEX_BUFFER);
727             assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER);
728             if (vbuffer_handles[i] == NULL)
729                return PIPE_ERROR_OUT_OF_MEMORY;
730             vbuffers[i] = &sbuf->b;
731             last_vbuf = i;
732 
733             vbuffer_attrs[i].sizeInBytes = sbuf->size;
734          }
735          else {
736             vbuffers[i] = NULL;
737             vbuffer_handles[i] = NULL;
738             vbuffer_attrs[i].sizeInBytes = 0;
739          }
740       }
741    }
742 
743    /* Unbind the unreferenced the vertex buffer handles */
744    for (; i < svga->state.hw_draw.num_vbuffers; i++) {
745       vbuffers[i] = NULL;
746       vbuffer_handles[i] = NULL;
747       vbuffer_attrs[i].sid = 0;
748       vbuffer_attrs[i].stride = 0;
749       vbuffer_attrs[i].offset = 0;
750       vbuffer_attrs[i].sizeInBytes = 0;
751    }
752 
753    /* Get handle for each referenced vertex buffer */
754    for (i = 0; i < vbuf_count; i++) {
755       struct svga_buffer *sbuf =
756          svga_buffer(hwtnl->cmd.vbufs[i].buffer.resource);
757 
758       if (sbuf) {
759          vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b,
760                                                  PIPE_BIND_VERTEX_BUFFER);
761          assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER);
762          if (vbuffer_handles[i] == NULL)
763             return PIPE_ERROR_OUT_OF_MEMORY;
764          vbuffers[i] = &sbuf->b;
765          last_vbuf = i;
766       }
767       else {
768          vbuffers[i] = NULL;
769          vbuffer_handles[i] = NULL;
770       }
771    }
772 
773    for (; i < svga->state.hw_draw.num_vbuffers; i++) {
774       vbuffers[i] = NULL;
775       vbuffer_handles[i] = NULL;
776    }
777 
778    /* setup vertex attribute input layout */
779    if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) {
780       enum pipe_error ret =
781          SVGA3D_vgpu10_SetInputLayout(svga->swc,
782                                       hwtnl->cmd.vdecl_layout_id);
783       if (ret != PIPE_OK)
784          return ret;
785 
786       svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id;
787    }
788 
789    /* Get handle for the stream out buffer */
790    if (so_vertex_count) {
791       so_vertex_count_handle = svga_buffer_handle(svga,
792                                                   so_vertex_count->buffer,
793                                                   (PIPE_BIND_VERTEX_BUFFER |
794                                                    PIPE_BIND_STREAM_OUTPUT));
795       if (!so_vertex_count_handle)
796          return PIPE_ERROR_OUT_OF_MEMORY;
797    }
798    else {
799       so_vertex_count_handle = NULL;
800    }
801 
802    /* setup vertex buffers */
803    {
804       /* If any of the vertex buffer state has changed, issue
805        * the SetVertexBuffers command. Otherwise, we will just
806        * need to rebind the resources.
807        */
808       if (vbuf_count != svga->state.hw_draw.num_vbuffers ||
809           !vertex_buffers_equal(vbuf_count,
810                                 vbuffer_attrs,
811                                 vbuffers,
812                                 svga->state.hw_draw.vbuffer_attrs,
813                                 svga->state.hw_draw.vbuffers)) {
814 
815          unsigned num_vbuffers;
816 
817          /* get the max of the current bound vertex buffers count and
818           * the to-be-bound vertex buffers count, so as to unbind
819           * the unused vertex buffers.
820           */
821          num_vbuffers = MAX2(vbuf_count, svga->state.hw_draw.num_vbuffers);
822 
823          if (num_vbuffers > 0) {
824             SVGA3dVertexBuffer_v2 *pbufAttrs = vbuffer_attrs;
825             struct svga_winsys_surface **pbufHandles = vbuffer_handles;
826             unsigned numVBuf = 0;
827             boolean emitVBufs =
828                !svga_sws(svga)->have_index_vertex_buffer_offset_cmd ||
829                svga->rebind.flags.vertexbufs;
830 
831             /* Loop through the vertex buffer lists to only emit
832              * those vertex buffers that are not already in the
833              * corresponding entries in the device's vertex buffer list.
834              */
835             for (i = 0; i < num_vbuffers; i++) {
836                boolean emit =
837                   vertex_buffers_equal(1,
838                                        &vbuffer_attrs[i],
839                                        &vbuffers[i],
840                                        &svga->state.hw_draw.vbuffer_attrs[i],
841                                        &svga->state.hw_draw.vbuffers[i]);
842 
843                /* Check if we can use the SetVertexBuffersOffsetAndSize command */
844                emitVBufs = emitVBufs ||
845                               (vbuffers[i] != svga->state.hw_draw.vbuffers[i]);
846 
847                if (!emit && i == num_vbuffers-1) {
848                   /* Include the last vertex buffer in the next emit
849                    * if it is different.
850                    */
851                   emit = TRUE;
852                   numVBuf++;
853                   i++;
854                }
855 
856                if (emit) {
857                   /* numVBuf can only be 0 if the first vertex buffer
858                    * is the same as the one in the device's list.
859                    * In this case, there is nothing to send yet.
860                    */
861                   if (numVBuf) {
862                      enum pipe_error ret;
863 
864                      /* If all vertex buffers handle are the same as the one
865                       * in the device, just use the
866                       * SetVertexBuffersOffsetAndSize comand.
867                       */
868                      if (emitVBufs) {
869                         ret = SVGA3D_vgpu10_SetVertexBuffers(svga->swc,
870                                                              numVBuf,
871                                                              i - numVBuf,
872                                                              pbufAttrs, pbufHandles);
873                      } else {
874                         ret = SVGA3D_vgpu10_SetVertexBuffersOffsetAndSize(svga->swc,
875                                                              numVBuf,
876                                                              i - numVBuf,
877                                                              pbufAttrs);
878                      }
879                      if (ret != PIPE_OK)
880                         return ret;
881                   }
882                   pbufAttrs += (numVBuf + 1);
883                   pbufHandles += (numVBuf + 1);
884                   numVBuf = 0;
885                }
886                else
887                   numVBuf++;
888             }
889 
890             /* save the number of vertex buffers sent to the device, not
891              * including trailing unbound vertex buffers.
892              */
893             svga->state.hw_draw.num_vbuffers = last_vbuf + 1;
894             memcpy(svga->state.hw_draw.vbuffer_attrs, vbuffer_attrs,
895                    num_vbuffers * sizeof(vbuffer_attrs[0]));
896             for (i = 0; i < num_vbuffers; i++) {
897                pipe_resource_reference(&svga->state.hw_draw.vbuffers[i],
898                                        vbuffers[i]);
899             }
900          }
901       }
902       else {
903          /* Even though we can avoid emitting the redundant SetVertexBuffers
904           * command, we still need to reference the vertex buffers surfaces.
905           */
906          for (i = 0; i < vbuf_count; i++) {
907             if (vbuffer_handles[i] && !last_command_was_draw(svga)) {
908                enum pipe_error ret =
909                   svga->swc->resource_rebind(svga->swc, vbuffer_handles[i],
910                                              NULL, SVGA_RELOC_READ);
911                if (ret != PIPE_OK)
912                   return ret;
913             }
914          }
915       }
916    }
917 
918    svga->rebind.flags.vertexbufs = FALSE;
919 
920    return PIPE_OK;
921 }
922 
923 
924 /*
925  * Prepare the index buffer for a drawing command.
926  */
927 static enum pipe_error
validate_index_buffer(struct svga_hwtnl * hwtnl,const SVGA3dPrimitiveRange * range,struct pipe_resource * ib)928 validate_index_buffer(struct svga_hwtnl *hwtnl,
929                       const SVGA3dPrimitiveRange *range,
930                       struct pipe_resource *ib)
931 {
932    struct svga_context *svga = hwtnl->svga;
933    struct svga_winsys_surface *ib_handle =
934       svga_buffer_handle(svga, ib, PIPE_BIND_INDEX_BUFFER);
935    enum pipe_error ret;
936 
937    if (!ib_handle)
938       return PIPE_ERROR_OUT_OF_MEMORY;
939 
940    struct svga_buffer *sbuf = svga_buffer(ib);
941    assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_INDEX_BUFFER);
942    (void) sbuf; /* silence unused var warning */
943 
944    SVGA3dSurfaceFormat indexFormat = xlate_index_format(range->indexWidth);
945 
946    if (ib != svga->state.hw_draw.ib ||
947        indexFormat != svga->state.hw_draw.ib_format ||
948        range->indexArray.offset != svga->state.hw_draw.ib_offset) {
949 
950       assert(indexFormat != SVGA3D_FORMAT_INVALID);
951 
952       if ((ib == svga->state.hw_draw.ib) &&
953           svga_sws(hwtnl->svga)->have_index_vertex_buffer_offset_cmd &&
954           !svga->rebind.flags.indexbuf) {
955 
956          ret = SVGA3D_vgpu10_SetIndexBufferOffsetAndSize(svga->swc,
957                                                          indexFormat,
958                                                          range->indexArray.offset,
959                                                          sbuf->size);
960          if (ret != PIPE_OK)
961             return ret;
962       }
963       else {
964 
965          ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, ib_handle,
966                                             indexFormat,
967                                             range->indexArray.offset);
968          if (ret != PIPE_OK)
969             return ret;
970       }
971 
972       pipe_resource_reference(&svga->state.hw_draw.ib, ib);
973       svga->state.hw_draw.ib_format = indexFormat;
974       svga->state.hw_draw.ib_offset = range->indexArray.offset;
975    }
976    else {
977       /* Even though we can avoid emitting the redundant SetIndexBuffer
978        * command, we still need to reference the index buffer surface.
979        */
980       if (!last_command_was_draw(svga)) {
981          enum pipe_error ret = svga->swc->resource_rebind(svga->swc,
982                                                           ib_handle,
983                                                           NULL,
984                                                           SVGA_RELOC_READ);
985          if (ret != PIPE_OK)
986             return ret;
987       }
988    }
989 
990    svga->rebind.flags.indexbuf = FALSE;
991 
992    return PIPE_OK;
993 }
994 
995 
996 static enum pipe_error
draw_vgpu10(struct svga_hwtnl * hwtnl,const SVGA3dPrimitiveRange * range,unsigned vcount,unsigned min_index,unsigned max_index,struct pipe_resource * ib,unsigned start_instance,unsigned instance_count,const struct pipe_draw_indirect_info * indirect,const struct pipe_stream_output_target * so_vertex_count)997 draw_vgpu10(struct svga_hwtnl *hwtnl,
998             const SVGA3dPrimitiveRange *range,
999             unsigned vcount,
1000             unsigned min_index, unsigned max_index,
1001             struct pipe_resource *ib,
1002             unsigned start_instance, unsigned instance_count,
1003             const struct pipe_draw_indirect_info *indirect,
1004             const struct pipe_stream_output_target *so_vertex_count)
1005 {
1006    struct svga_context *svga = hwtnl->svga;
1007    struct svga_winsys_surface *indirect_handle;
1008    enum pipe_error ret;
1009 
1010    assert(svga_have_vgpu10(svga));
1011    assert(hwtnl->cmd.prim_count == 0);
1012 
1013    /* We need to reemit all the current resource bindings along with the Draw
1014     * command to be sure that the referenced resources are available for the
1015     * Draw command, just in case the surfaces associated with the resources
1016     * are paged out.
1017     */
1018    if (svga->rebind.val) {
1019       ret = svga_rebind_framebuffer_bindings(svga);
1020       if (ret != PIPE_OK)
1021          return ret;
1022 
1023       ret = svga_rebind_shaders(svga);
1024       if (ret != PIPE_OK)
1025          return ret;
1026 
1027       /* Rebind stream output targets */
1028       ret = svga_rebind_stream_output_targets(svga);
1029       if (ret != PIPE_OK)
1030          return ret;
1031 
1032       /* No need to explicitly rebind index buffer and vertex buffers here.
1033        * Even if the same index buffer or vertex buffers are referenced for this
1034        * draw and we skip emitting the redundant set command, we will still
1035        * reference the associated resources.
1036        */
1037    }
1038 
1039    ret = svga_validate_sampler_resources(svga, SVGA_PIPE_GRAPHICS);
1040    if (ret != PIPE_OK)
1041       return ret;
1042 
1043    ret = svga_validate_constant_buffers(svga, SVGA_PIPE_GRAPHICS);
1044    if (ret != PIPE_OK)
1045       return ret;
1046 
1047    if (svga_have_gl43(svga)) {
1048       ret = svga_validate_image_views(svga, SVGA_PIPE_GRAPHICS);
1049       if (ret != PIPE_OK)
1050          return ret;
1051 
1052       ret = svga_validate_shader_buffers(svga, SVGA_PIPE_GRAPHICS);
1053       if (ret != PIPE_OK)
1054          return ret;
1055 
1056       if (svga->rebind.flags.uav) {
1057          ret= svga_rebind_uav(svga);
1058          if (ret != PIPE_OK)
1059             return ret;
1060       }
1061    }
1062 
1063    ret = validate_vertex_buffers(hwtnl, so_vertex_count);
1064    if (ret != PIPE_OK)
1065       return ret;
1066 
1067    if (ib) {
1068       ret = validate_index_buffer(hwtnl, range, ib);
1069       if (ret != PIPE_OK)
1070          return ret;
1071    }
1072 
1073    if (indirect) {
1074       indirect_handle = svga_buffer_handle(svga, indirect->buffer,
1075                                            PIPE_BIND_COMMAND_ARGS_BUFFER);
1076       if (!indirect_handle)
1077          return PIPE_ERROR_OUT_OF_MEMORY;
1078    }
1079    else {
1080       indirect_handle = NULL;
1081    }
1082 
1083    /* Set primitive type (line, tri, etc) */
1084    if (svga->state.hw_draw.topology != range->primType) {
1085       ret = SVGA3D_vgpu10_SetTopology(svga->swc, range->primType);
1086       if (ret != PIPE_OK)
1087          return ret;
1088 
1089       svga->state.hw_draw.topology = range->primType;
1090    }
1091 
1092    if (ib) {
1093       /* indexed drawing */
1094       if (indirect) {
1095          ret = SVGA3D_sm5_DrawIndexedInstancedIndirect(svga->swc,
1096                                                        indirect_handle,
1097                                                        indirect->offset);
1098       }
1099       else if (instance_count > 1) {
1100          ret = SVGA3D_vgpu10_DrawIndexedInstanced(svga->swc,
1101                                                   vcount,
1102                                                   instance_count,
1103                                                   0, /* startIndexLocation */
1104                                                   range->indexBias,
1105                                                   start_instance);
1106       }
1107       else {
1108          /* non-instanced drawing */
1109          ret = SVGA3D_vgpu10_DrawIndexed(svga->swc,
1110                                          vcount,
1111                                          0,      /* startIndexLocation */
1112                                          range->indexBias);
1113       }
1114       if (ret != PIPE_OK) {
1115          return ret;
1116       }
1117    }
1118    else {
1119       /* non-indexed drawing */
1120       if (svga->state.hw_draw.ib_format != SVGA3D_FORMAT_INVALID ||
1121           svga->state.hw_draw.ib != NULL) {
1122          /* Unbind previously bound index buffer */
1123          ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, NULL,
1124                                             SVGA3D_FORMAT_INVALID, 0);
1125          if (ret != PIPE_OK)
1126             return ret;
1127          pipe_resource_reference(&svga->state.hw_draw.ib, NULL);
1128          svga->state.hw_draw.ib_format = SVGA3D_FORMAT_INVALID;
1129       }
1130 
1131       assert(svga->state.hw_draw.ib == NULL);
1132 
1133       if (so_vertex_count) {
1134          /* Stream-output drawing */
1135          ret = SVGA3D_vgpu10_DrawAuto(svga->swc);
1136       }
1137       else if (indirect) {
1138          ret = SVGA3D_sm5_DrawInstancedIndirect(svga->swc,
1139                                                 indirect_handle,
1140                                                 indirect->offset);
1141       }
1142       else if (instance_count > 1) {
1143          ret = SVGA3D_vgpu10_DrawInstanced(svga->swc,
1144                                            vcount,
1145                                            instance_count,
1146                                            range->indexBias,
1147                                            start_instance);
1148       }
1149       else {
1150          /* non-instanced */
1151          ret = SVGA3D_vgpu10_Draw(svga->swc,
1152                                   vcount,
1153                                   range->indexBias);
1154       }
1155       if (ret != PIPE_OK) {
1156          return ret;
1157       }
1158    }
1159 
1160    hwtnl->cmd.prim_count = 0;
1161 
1162    return PIPE_OK;
1163 }
1164 
1165 
1166 
1167 /**
1168  * Emit any pending drawing commands to the command buffer.
1169  * When we receive VGPU9 drawing commands we accumulate them and don't
1170  * immediately emit them into the command buffer.
1171  * This function needs to be called before we change state that could
1172  * effect those pending draws.
1173  */
1174 enum pipe_error
svga_hwtnl_flush(struct svga_hwtnl * hwtnl)1175 svga_hwtnl_flush(struct svga_hwtnl *hwtnl)
1176 {
1177    enum pipe_error ret = PIPE_OK;
1178 
1179    SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLFLUSH);
1180 
1181    if (!svga_have_vgpu10(hwtnl->svga) && hwtnl->cmd.prim_count) {
1182       /* we only queue up primitive for VGPU9 */
1183       ret = draw_vgpu9(hwtnl);
1184    }
1185 
1186    SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
1187    return ret;
1188 }
1189 
1190 
1191 void
svga_hwtnl_set_index_bias(struct svga_hwtnl * hwtnl,int index_bias)1192 svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias)
1193 {
1194    hwtnl->index_bias = index_bias;
1195 }
1196 
1197 
1198 
1199 /***********************************************************************
1200  * Internal functions:
1201  */
1202 
1203 /**
1204  * For debugging only.
1205  */
1206 static void
check_draw_params(struct svga_hwtnl * hwtnl,const SVGA3dPrimitiveRange * range,unsigned min_index,unsigned max_index,struct pipe_resource * ib)1207 check_draw_params(struct svga_hwtnl *hwtnl,
1208                   const SVGA3dPrimitiveRange *range,
1209                   unsigned min_index, unsigned max_index,
1210                   struct pipe_resource *ib)
1211 {
1212    unsigned i;
1213 
1214    assert(!svga_have_vgpu10(hwtnl->svga));
1215 
1216    for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
1217       unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
1218       const struct pipe_vertex_buffer *vb = &hwtnl->cmd.vbufs[j];
1219       unsigned size = vb->buffer.resource ? vb->buffer.resource->width0 : 0;
1220       unsigned offset = hwtnl->cmd.vdecl[i].array.offset;
1221       unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
1222       int index_bias = (int) range->indexBias + hwtnl->index_bias;
1223       unsigned width;
1224 
1225       if (size == 0)
1226          continue;
1227 
1228       assert(vb);
1229       assert(size);
1230       assert(offset < size);
1231       assert(min_index <= max_index);
1232       (void) width;
1233       (void) stride;
1234       (void) offset;
1235       (void) size;
1236 
1237       switch (hwtnl->cmd.vdecl[i].identity.type) {
1238       case SVGA3D_DECLTYPE_FLOAT1:
1239          width = 4;
1240          break;
1241       case SVGA3D_DECLTYPE_FLOAT2:
1242          width = 4 * 2;
1243          break;
1244       case SVGA3D_DECLTYPE_FLOAT3:
1245          width = 4 * 3;
1246          break;
1247       case SVGA3D_DECLTYPE_FLOAT4:
1248          width = 4 * 4;
1249          break;
1250       case SVGA3D_DECLTYPE_D3DCOLOR:
1251          width = 4;
1252          break;
1253       case SVGA3D_DECLTYPE_UBYTE4:
1254          width = 1 * 4;
1255          break;
1256       case SVGA3D_DECLTYPE_SHORT2:
1257          width = 2 * 2;
1258          break;
1259       case SVGA3D_DECLTYPE_SHORT4:
1260          width = 2 * 4;
1261          break;
1262       case SVGA3D_DECLTYPE_UBYTE4N:
1263          width = 1 * 4;
1264          break;
1265       case SVGA3D_DECLTYPE_SHORT2N:
1266          width = 2 * 2;
1267          break;
1268       case SVGA3D_DECLTYPE_SHORT4N:
1269          width = 2 * 4;
1270          break;
1271       case SVGA3D_DECLTYPE_USHORT2N:
1272          width = 2 * 2;
1273          break;
1274       case SVGA3D_DECLTYPE_USHORT4N:
1275          width = 2 * 4;
1276          break;
1277       case SVGA3D_DECLTYPE_UDEC3:
1278          width = 4;
1279          break;
1280       case SVGA3D_DECLTYPE_DEC3N:
1281          width = 4;
1282          break;
1283       case SVGA3D_DECLTYPE_FLOAT16_2:
1284          width = 2 * 2;
1285          break;
1286       case SVGA3D_DECLTYPE_FLOAT16_4:
1287          width = 2 * 4;
1288          break;
1289       default:
1290          assert(0);
1291          width = 0;
1292          break;
1293       }
1294 
1295       if (index_bias >= 0) {
1296          assert(offset + index_bias * stride + width <= size);
1297       }
1298 
1299       /*
1300        * min_index/max_index are merely conservative guesses, so we can't
1301        * make buffer overflow detection based on their values.
1302        */
1303    }
1304 
1305    assert(range->indexWidth == range->indexArray.stride);
1306 
1307    if (ib) {
1308       ASSERTED unsigned size = ib->width0;
1309       ASSERTED unsigned offset = range->indexArray.offset;
1310       ASSERTED unsigned stride = range->indexArray.stride;
1311       ASSERTED unsigned count;
1312 
1313       assert(size);
1314       assert(offset < size);
1315       assert(stride);
1316 
1317       switch (range->primType) {
1318       case SVGA3D_PRIMITIVE_POINTLIST:
1319          count = range->primitiveCount;
1320          break;
1321       case SVGA3D_PRIMITIVE_LINELIST:
1322          count = range->primitiveCount * 2;
1323          break;
1324       case SVGA3D_PRIMITIVE_LINESTRIP:
1325          count = range->primitiveCount + 1;
1326          break;
1327       case SVGA3D_PRIMITIVE_TRIANGLELIST:
1328          count = range->primitiveCount * 3;
1329          break;
1330       case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
1331          count = range->primitiveCount + 2;
1332          break;
1333       case SVGA3D_PRIMITIVE_TRIANGLEFAN:
1334          count = range->primitiveCount + 2;
1335          break;
1336       default:
1337          assert(0);
1338          count = 0;
1339          break;
1340       }
1341 
1342       assert(offset + count * stride <= size);
1343    }
1344 }
1345 
1346 
1347 /**
1348  * All drawing filters down into this function, either directly
1349  * on the hardware path or after doing software vertex processing.
1350  * \param indirect  if non-null, get the vertex count, first vertex, etc.
1351  *                  from a buffer.
1352  * \param so_vertex_count  if non-null, get the vertex count from a
1353  *                         stream-output target.
1354  */
1355 enum pipe_error
svga_hwtnl_prim(struct svga_hwtnl * hwtnl,const SVGA3dPrimitiveRange * range,unsigned vcount,unsigned min_index,unsigned max_index,struct pipe_resource * ib,unsigned start_instance,unsigned instance_count,const struct pipe_draw_indirect_info * indirect,const struct pipe_stream_output_target * so_vertex_count)1356 svga_hwtnl_prim(struct svga_hwtnl *hwtnl,
1357                 const SVGA3dPrimitiveRange *range,
1358                 unsigned vcount,
1359                 unsigned min_index, unsigned max_index,
1360                 struct pipe_resource *ib,
1361                 unsigned start_instance, unsigned instance_count,
1362                 const struct pipe_draw_indirect_info *indirect,
1363                 const struct pipe_stream_output_target *so_vertex_count)
1364 {
1365    enum pipe_error ret = PIPE_OK;
1366 
1367    SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLPRIM);
1368 
1369    if (svga_have_vgpu10(hwtnl->svga)) {
1370       /* draw immediately */
1371       SVGA_RETRY(hwtnl->svga, draw_vgpu10(hwtnl, range, vcount, min_index,
1372                                           max_index, ib, start_instance,
1373                                           instance_count, indirect,
1374                                           so_vertex_count));
1375    }
1376    else {
1377       /* batch up drawing commands */
1378       assert(indirect == NULL);
1379 #ifdef DEBUG
1380       check_draw_params(hwtnl, range, min_index, max_index, ib);
1381       assert(start_instance == 0);
1382       assert(instance_count <= 1);
1383 #else
1384       (void) check_draw_params;
1385 #endif
1386 
1387       if (hwtnl->cmd.prim_count + 1 >= QSZ) {
1388          ret = svga_hwtnl_flush(hwtnl);
1389          if (ret != PIPE_OK)
1390             goto done;
1391       }
1392 
1393       /* min/max indices are relative to bias */
1394       hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index;
1395       hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index;
1396 
1397       hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range;
1398       hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias;
1399 
1400       pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
1401       hwtnl->cmd.prim_count++;
1402    }
1403 
1404 done:
1405    SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
1406    return ret;
1407 }
1408 
1409 
1410 /**
1411  * Return TRUE if there are pending primitives.
1412  */
1413 boolean
svga_hwtnl_has_pending_prim(struct svga_hwtnl * hwtnl)1414 svga_hwtnl_has_pending_prim(struct svga_hwtnl *hwtnl)
1415 {
1416    return hwtnl->cmd.prim_count > 0;
1417 }
1418