xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/svga/svga_draw.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (c) 2008-2024 Broadcom. All Rights Reserved.
3  * The term “Broadcom” refers to Broadcom Inc.
4  * and/or its subsidiaries.
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #include "util/compiler.h"
9 #include "util/u_inlines.h"
10 #include "pipe/p_defines.h"
11 #include "util/u_helpers.h"
12 #include "util/u_memory.h"
13 #include "util/u_math.h"
14 
15 #include "svga_context.h"
16 #include "svga_draw.h"
17 #include "svga_draw_private.h"
18 #include "svga_debug.h"
19 #include "svga_screen.h"
20 #include "svga_resource.h"
21 #include "svga_resource_buffer.h"
22 #include "svga_resource_texture.h"
23 #include "svga_sampler_view.h"
24 #include "svga_shader.h"
25 #include "svga_surface.h"
26 #include "svga_winsys.h"
27 #include "svga_cmd.h"
28 
29 
30 struct svga_hwtnl *
svga_hwtnl_create(struct svga_context * svga)31 svga_hwtnl_create(struct svga_context *svga)
32 {
33    struct svga_hwtnl *hwtnl = CALLOC_STRUCT(svga_hwtnl);
34    if (!hwtnl)
35       goto fail;
36 
37    hwtnl->svga = svga;
38 
39    hwtnl->cmd.swc = svga->swc;
40 
41    return hwtnl;
42 
43 fail:
44    return NULL;
45 }
46 
47 
48 void
svga_hwtnl_destroy(struct svga_hwtnl * hwtnl)49 svga_hwtnl_destroy(struct svga_hwtnl *hwtnl)
50 {
51    unsigned i, j;
52 
53    for (i = 0; i < MESA_PRIM_COUNT; i++) {
54       for (j = 0; j < IDX_CACHE_MAX; j++) {
55          pipe_resource_reference(&hwtnl->index_cache[i][j].buffer, NULL);
56       }
57    }
58 
59    for (i = 0; i < hwtnl->cmd.vbuf_count; i++)
60       pipe_vertex_buffer_unreference(&hwtnl->cmd.vbufs[i]);
61 
62    for (i = 0; i < hwtnl->cmd.prim_count; i++)
63       pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
64 
65    FREE(hwtnl);
66 }
67 
68 
69 void
svga_hwtnl_set_flatshade(struct svga_hwtnl * hwtnl,bool flatshade,bool flatshade_first)70 svga_hwtnl_set_flatshade(struct svga_hwtnl *hwtnl,
71                          bool flatshade, bool flatshade_first)
72 {
73    struct svga_screen *svgascreen = svga_screen(hwtnl->svga->pipe.screen);
74 
75    /* User-specified PV */
76    hwtnl->api_pv = (flatshade && !flatshade_first) ? PV_LAST : PV_FIRST;
77 
78    /* Device supported PV */
79    if (svgascreen->haveProvokingVertex) {
80       /* use the mode specified by the user */
81       hwtnl->hw_pv = hwtnl->api_pv;
82    }
83    else {
84       /* the device only support first provoking vertex */
85       hwtnl->hw_pv = PV_FIRST;
86    }
87 }
88 
89 
90 void
svga_hwtnl_set_fillmode(struct svga_hwtnl * hwtnl,unsigned mode)91 svga_hwtnl_set_fillmode(struct svga_hwtnl *hwtnl, unsigned mode)
92 {
93    hwtnl->api_fillmode = mode;
94 }
95 
96 
97 void
svga_hwtnl_vertex_decls(struct svga_hwtnl * hwtnl,unsigned count,const SVGA3dVertexDecl * decls,const unsigned * buffer_indexes,SVGA3dElementLayoutId layout_id)98 svga_hwtnl_vertex_decls(struct svga_hwtnl *hwtnl,
99                         unsigned count,
100                         const SVGA3dVertexDecl * decls,
101                         const unsigned *buffer_indexes,
102                         SVGA3dElementLayoutId layout_id)
103 {
104    assert(hwtnl->cmd.prim_count == 0);
105    hwtnl->cmd.vdecl_count = count;
106    hwtnl->cmd.vdecl_layout_id = layout_id;
107    memcpy(hwtnl->cmd.vdecl, decls, count * sizeof(*decls));
108    memcpy(hwtnl->cmd.vdecl_buffer_index, buffer_indexes,
109           count * sizeof(unsigned));
110 }
111 
112 
113 /**
114  * Specify vertex buffers for hardware drawing.
115  */
116 void
svga_hwtnl_vertex_buffers(struct svga_hwtnl * hwtnl,unsigned count,struct pipe_vertex_buffer * buffers)117 svga_hwtnl_vertex_buffers(struct svga_hwtnl *hwtnl,
118                           unsigned count, struct pipe_vertex_buffer *buffers)
119 {
120    struct pipe_vertex_buffer *dst = hwtnl->cmd.vbufs;
121    const struct pipe_vertex_buffer *src = buffers;
122    unsigned i;
123 
124    for (i = 0; i < count; i++) {
125       pipe_vertex_buffer_reference(&dst[i], &src[i]);
126    }
127 
128    /* release old buffer references */
129    for ( ; i < hwtnl->cmd.vbuf_count; i++) {
130       pipe_vertex_buffer_unreference(&dst[i]);
131       /* don't bother zeroing stride/offset fields */
132    }
133 
134    hwtnl->cmd.vbuf_count = count;
135 }
136 
137 
138 /**
139  * Determine whether the specified buffer is referred in the primitive queue,
140  * for which no commands have been written yet.
141  */
142 bool
svga_hwtnl_is_buffer_referred(struct svga_hwtnl * hwtnl,struct pipe_resource * buffer)143 svga_hwtnl_is_buffer_referred(struct svga_hwtnl *hwtnl,
144                               struct pipe_resource *buffer)
145 {
146    unsigned i;
147 
148    if (svga_buffer_is_user_buffer(buffer)) {
149       return false;
150    }
151 
152    if (!hwtnl->cmd.prim_count) {
153       return false;
154    }
155 
156    for (i = 0; i < hwtnl->cmd.vbuf_count; ++i) {
157       if (hwtnl->cmd.vbufs[i].buffer.resource == buffer) {
158          return true;
159       }
160    }
161 
162    for (i = 0; i < hwtnl->cmd.prim_count; ++i) {
163       if (hwtnl->cmd.prim_ib[i] == buffer) {
164          return true;
165       }
166    }
167 
168    return false;
169 }
170 
171 
172 static enum pipe_error
draw_vgpu9(struct svga_hwtnl * hwtnl)173 draw_vgpu9(struct svga_hwtnl *hwtnl)
174 {
175    struct svga_winsys_context *swc = hwtnl->cmd.swc;
176    struct svga_context *svga = hwtnl->svga;
177    enum pipe_error ret;
178    struct svga_winsys_surface *vb_handle[SVGA3D_INPUTREG_MAX];
179    struct svga_winsys_surface *ib_handle[QSZ];
180    struct svga_winsys_surface *handle;
181    SVGA3dVertexDecl *vdecl;
182    SVGA3dPrimitiveRange *prim;
183    unsigned i;
184 
185    /* Re-validate those sampler views with backing copy
186     * of texture whose original copy has been updated.
187     * This is done here at draw time because the texture binding might not
188     * have modified, hence validation is not triggered at state update time,
189     * and yet the texture might have been updated in another context, so
190     * we need to re-validate the sampler view in order to update the backing
191     * copy of the updated texture.
192     */
193    if (svga->state.hw_draw.num_backed_views) {
194       for (i = 0; i < svga->state.hw_draw.num_views; i++) {
195          struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
196          struct svga_texture *tex = svga_texture(view->texture);
197          struct svga_sampler_view *sv = view->v;
198          if (sv && tex && sv->handle != tex->handle && sv->age < tex->age)
199             svga_validate_sampler_view(svga, view->v);
200       }
201    }
202 
203    for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
204       unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
205       handle = svga_buffer_handle(svga, hwtnl->cmd.vbufs[j].buffer.resource,
206                                   PIPE_BIND_VERTEX_BUFFER);
207       if (!handle)
208          return PIPE_ERROR_OUT_OF_MEMORY;
209 
210       vb_handle[i] = handle;
211    }
212 
213    for (i = 0; i < hwtnl->cmd.prim_count; i++) {
214       if (hwtnl->cmd.prim_ib[i]) {
215          handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i],
216                                      PIPE_BIND_INDEX_BUFFER);
217          if (!handle)
218             return PIPE_ERROR_OUT_OF_MEMORY;
219       }
220       else
221          handle = NULL;
222 
223       ib_handle[i] = handle;
224    }
225 
226    if (svga->rebind.flags.rendertargets) {
227       ret = svga_reemit_framebuffer_bindings(svga);
228       if (ret != PIPE_OK) {
229          return ret;
230       }
231    }
232 
233    if (svga->rebind.flags.texture_samplers) {
234       ret = svga_reemit_tss_bindings(svga);
235       if (ret != PIPE_OK) {
236          return ret;
237       }
238    }
239 
240    if (svga->rebind.flags.vs) {
241       ret = svga_reemit_vs_bindings(svga);
242       if (ret != PIPE_OK) {
243          return ret;
244       }
245    }
246 
247    if (svga->rebind.flags.fs) {
248       ret = svga_reemit_fs_bindings(svga);
249       if (ret != PIPE_OK) {
250          return ret;
251       }
252    }
253 
254    SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n",
255             svga->curr.framebuffer.cbufs[0] ?
256             svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL,
257             hwtnl->cmd.prim_count);
258 
259    ret = SVGA3D_BeginDrawPrimitives(swc,
260                                     &vdecl,
261                                     hwtnl->cmd.vdecl_count,
262                                     &prim, hwtnl->cmd.prim_count);
263    if (ret != PIPE_OK)
264       return ret;
265 
266    memcpy(vdecl,
267           hwtnl->cmd.vdecl,
268           hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]);
269 
270    for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
271       /* check for 4-byte alignment */
272       assert(vdecl[i].array.offset % 4 == 0);
273       assert(vdecl[i].array.stride % 4 == 0);
274 
275       /* Given rangeHint is considered to be relative to indexBias, and
276        * indexBias varies per primitive, we cannot accurately supply an
277        * rangeHint when emitting more than one primitive per draw command.
278        */
279       if (hwtnl->cmd.prim_count == 1) {
280          vdecl[i].rangeHint.first = hwtnl->cmd.min_index[0];
281          vdecl[i].rangeHint.last = hwtnl->cmd.max_index[0] + 1;
282       }
283       else {
284          vdecl[i].rangeHint.first = 0;
285          vdecl[i].rangeHint.last = 0;
286       }
287 
288       swc->surface_relocation(swc,
289                               &vdecl[i].array.surfaceId,
290                               NULL, vb_handle[i], SVGA_RELOC_READ);
291    }
292 
293    memcpy(prim,
294           hwtnl->cmd.prim, hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]);
295 
296    for (i = 0; i < hwtnl->cmd.prim_count; i++) {
297       swc->surface_relocation(swc,
298                               &prim[i].indexArray.surfaceId,
299                               NULL, ib_handle[i], SVGA_RELOC_READ);
300       pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
301    }
302 
303    SVGA_FIFOCommitAll(swc);
304 
305    hwtnl->cmd.prim_count = 0;
306 
307    return PIPE_OK;
308 }
309 
310 
311 static SVGA3dSurfaceFormat
xlate_index_format(unsigned indexWidth)312 xlate_index_format(unsigned indexWidth)
313 {
314    if (indexWidth == 2) {
315       return SVGA3D_R16_UINT;
316    }
317    else if (indexWidth == 4) {
318       return SVGA3D_R32_UINT;
319    }
320    else {
321       assert(!"Bad indexWidth");
322       return SVGA3D_R32_UINT;
323    }
324 }
325 
326 
327 /**
328  * A helper function to validate sampler view resources to ensure any
329  * pending updates to buffers will be emitted before they are referenced
330  * at draw or dispatch time. It also rebinds the resources if needed.
331  */
332 enum pipe_error
svga_validate_sampler_resources(struct svga_context * svga,enum svga_pipe_type pipe_type)333 svga_validate_sampler_resources(struct svga_context *svga,
334                                 enum svga_pipe_type pipe_type)
335 {
336    enum pipe_shader_type shader, first_shader, last_shader;
337 
338    assert(svga_have_vgpu10(svga));
339 
340    if (pipe_type == SVGA_PIPE_GRAPHICS) {
341       first_shader = PIPE_SHADER_VERTEX;
342       last_shader = PIPE_SHADER_COMPUTE;
343    }
344    else {
345       assert(svga_have_gl43(svga));
346       first_shader = PIPE_SHADER_COMPUTE;
347       last_shader = first_shader+1;
348    }
349 
350    for (shader = first_shader; shader < last_shader; shader++) {
351       unsigned count = svga->curr.num_sampler_views[shader];
352       unsigned i;
353       struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS];
354       enum pipe_error ret;
355 
356       /*
357        * Reference bound sampler resources to ensure pending updates are
358        * noticed by the device.
359        */
360       for (i = 0; i < count; i++) {
361          struct svga_pipe_sampler_view *sv =
362             svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
363 
364          if (sv) {
365             if (sv->base.texture->target == PIPE_BUFFER) {
366                surfaces[i] = svga_buffer_handle(svga, sv->base.texture,
367                                                 PIPE_BIND_SAMPLER_VIEW);
368             }
369             else {
370                surfaces[i] = svga_texture(sv->base.texture)->handle;
371             }
372          }
373          else {
374             surfaces[i] = NULL;
375          }
376       }
377 
378       if (shader == PIPE_SHADER_FRAGMENT &&
379           svga->curr.rast->templ.poly_stipple_enable) {
380          const unsigned unit =
381             svga_fs_variant(svga->state.hw_draw.fs)->pstipple_sampler_unit;
382          struct svga_pipe_sampler_view *sv =
383             svga->polygon_stipple.sampler_view;
384 
385          assert(sv);
386          surfaces[unit] = svga_texture(sv->base.texture)->handle;
387          count = MAX2(count, unit+1);
388       }
389 
390       /* rebind the shader resources if needed */
391       if (svga->rebind.flags.texture_samplers) {
392          for (i = 0; i < count; i++) {
393             if (surfaces[i]) {
394                ret = svga->swc->resource_rebind(svga->swc,
395                                                 surfaces[i],
396                                                 NULL,
397                                                 SVGA_RELOC_READ);
398                if (ret != PIPE_OK)
399                   return ret;
400             }
401          }
402       }
403    }
404    svga->rebind.flags.texture_samplers = false;
405 
406    return PIPE_OK;
407 }
408 
409 
410 /**
411  * A helper function to validate constant buffers to ensure any
412  * pending updates to the buffers will be emitted before they are referenced
413  * at draw or dispatch time. It also rebinds the resources if needed.
414  */
415 enum pipe_error
svga_validate_constant_buffers(struct svga_context * svga,enum svga_pipe_type pipe_type)416 svga_validate_constant_buffers(struct svga_context *svga,
417                                enum svga_pipe_type pipe_type)
418 {
419    enum pipe_shader_type shader, first_shader, last_shader;
420 
421    assert(svga_have_vgpu10(svga));
422 
423    if (pipe_type == SVGA_PIPE_GRAPHICS) {
424       first_shader = PIPE_SHADER_VERTEX;
425       last_shader = PIPE_SHADER_COMPUTE;
426    }
427    else {
428       assert(svga_have_gl43(svga));
429       first_shader = PIPE_SHADER_COMPUTE;
430       last_shader = first_shader + 1;
431    }
432 
433    for (shader = first_shader; shader < last_shader; shader++) {
434 
435       enum pipe_error ret;
436       struct svga_buffer *buffer;
437 
438       /* Rebind the default constant buffer if needed */
439       if (svga->rebind.flags.constbufs) {
440          buffer = svga_buffer(svga->state.hw_draw.constbuf[shader][0]);
441          if (buffer) {
442             ret = svga->swc->resource_rebind(svga->swc,
443                                              buffer->handle,
444                                              NULL,
445                                              SVGA_RELOC_READ);
446             if (ret != PIPE_OK)
447                return ret;
448          }
449       }
450 
451       struct svga_winsys_surface *handle;
452       unsigned enabled_constbufs;
453 
454       /*
455        * Reference other bound constant buffers to ensure pending updates are
456        * noticed by the device.
457        */
458       enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] & ~1u;
459       while (enabled_constbufs) {
460          unsigned i = u_bit_scan(&enabled_constbufs);
461          buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
462 
463          /* If the constant buffer has hw storage, get the buffer winsys handle.
464           * Rebind the resource if needed.
465           */
466          if (buffer && !buffer->use_swbuf)
467             handle = svga_buffer_handle(svga, &buffer->b,
468                                         PIPE_BIND_CONSTANT_BUFFER);
469          else
470             handle = svga->state.hw_draw.constbufoffsets[shader][i].handle;
471 
472          if (svga->rebind.flags.constbufs && handle) {
473             ret = svga->swc->resource_rebind(svga->swc,
474                                              handle,
475                                              NULL,
476                                              SVGA_RELOC_READ);
477             if (ret != PIPE_OK)
478                return ret;
479          }
480       }
481 
482       /* Reference raw constant buffers as they are not included in the
483        * hw constant buffers list.
484        */
485       unsigned enabled_rawbufs = svga->state.hw_draw.enabled_rawbufs[shader] & ~1u;
486       while (enabled_rawbufs) {
487          unsigned i = u_bit_scan(&enabled_rawbufs);
488          buffer = svga_buffer(svga->state.hw_draw.rawbufs[shader][i].buffer);
489 
490          assert(buffer != NULL);
491          handle = svga_buffer_handle(svga, &buffer->b,
492                                      PIPE_BIND_SAMPLER_VIEW);
493 
494          if (svga->rebind.flags.constbufs && handle) {
495             ret = svga->swc->resource_rebind(svga->swc,
496                                              handle,
497                                              NULL,
498                                              SVGA_RELOC_READ);
499             if (ret != PIPE_OK)
500                return ret;
501          }
502       }
503    }
504    svga->rebind.flags.constbufs = false;
505 
506    return PIPE_OK;
507 }
508 
509 
510 /**
511  * A helper function to validate image view resources to ensure any
512  * pending updates to buffers will be emitted before they are referenced
513  * at draw or dispatch time. It also rebinds the resources if needed.
514  */
515 enum pipe_error
svga_validate_image_views(struct svga_context * svga,enum svga_pipe_type pipe_type)516 svga_validate_image_views(struct svga_context *svga,
517                           enum svga_pipe_type pipe_type)
518 {
519    enum pipe_shader_type shader, first_shader, last_shader;
520    bool rebind = svga->rebind.flags.images;
521    enum pipe_error ret;
522 
523    assert(svga_have_gl43(svga));
524 
525    if (pipe_type == SVGA_PIPE_GRAPHICS) {
526       first_shader = PIPE_SHADER_VERTEX;
527       last_shader = PIPE_SHADER_COMPUTE;
528    }
529    else {
530       first_shader = PIPE_SHADER_COMPUTE;
531       last_shader = first_shader + 1;
532    }
533 
534    for (shader = first_shader; shader < last_shader; shader++) {
535       ret = svga_validate_image_view_resources(svga,
536                svga->state.hw_draw.num_image_views[shader],
537                &svga->state.hw_draw.image_views[shader][0], rebind);
538 
539       if (ret != PIPE_OK)
540          return ret;
541    }
542 
543    svga->rebind.flags.images = false;
544 
545    return PIPE_OK;
546 }
547 
548 
549 /**
550  * A helper function to validate shader buffer and atomic buffer resources to
551  * ensure any pending updates to buffers will be emitted before they are
552  * referenced at draw or dispatch time. It also rebinds the resources if needed.
553  */
554 enum pipe_error
svga_validate_shader_buffers(struct svga_context * svga,enum svga_pipe_type pipe_type)555 svga_validate_shader_buffers(struct svga_context *svga,
556                              enum svga_pipe_type pipe_type)
557 {
558    enum pipe_shader_type shader, first_shader, last_shader;
559    bool rebind = svga->rebind.flags.shaderbufs;
560    enum pipe_error ret;
561 
562    assert(svga_have_gl43(svga));
563 
564    if (pipe_type == SVGA_PIPE_GRAPHICS) {
565       first_shader = PIPE_SHADER_VERTEX;
566       last_shader = PIPE_SHADER_COMPUTE;
567    }
568    else {
569       first_shader = PIPE_SHADER_COMPUTE;
570       last_shader = first_shader + 1;
571    }
572 
573    for (shader = first_shader; shader < last_shader; shader++) {
574       ret = svga_validate_shader_buffer_resources(svga,
575                svga->state.hw_draw.num_shader_buffers[shader],
576                &svga->state.hw_draw.shader_buffers[shader][0], rebind);
577 
578       if (ret != PIPE_OK)
579          return ret;
580    }
581 
582    svga->rebind.flags.shaderbufs = false;
583 
584    ret = svga_validate_shader_buffer_resources(svga,
585                svga->state.hw_draw.num_atomic_buffers,
586                svga->state.hw_draw.atomic_buffers,
587                svga->rebind.flags.atomicbufs);
588 
589    if (ret != PIPE_OK)
590       return ret;
591 
592    svga->rebind.flags.atomicbufs = false;
593 
594    return PIPE_OK;
595 }
596 
597 
598 /**
599  * Was the last command put into the command buffer a drawing command?
600  * We use this to determine if we can skip emitting buffer re-bind
601  * commands when we have a sequence of drawing commands that use the
602  * same vertex/index buffers with no intervening commands.
603  *
604  * The first drawing command will bind the vertex/index buffers.  If
605  * the immediately following command is also a drawing command using the
606  * same buffers, we shouldn't have to rebind them.
607  */
608 static bool
last_command_was_draw(const struct svga_context * svga)609 last_command_was_draw(const struct svga_context *svga)
610 {
611    switch (SVGA3D_GetLastCommand(svga->swc)) {
612    case SVGA_3D_CMD_DX_DRAW:
613    case SVGA_3D_CMD_DX_DRAW_INDEXED:
614    case SVGA_3D_CMD_DX_DRAW_INSTANCED:
615    case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED:
616    case SVGA_3D_CMD_DX_DRAW_AUTO:
617    case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT:
618    case SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT:
619       return true;
620    default:
621       return false;
622    }
623 }
624 
625 
626 /**
627  * A helper function to compare vertex buffers.
628  * They are equal if the vertex buffer attributes and the vertex buffer
629  * resources are identical.
630  */
631 static bool
vertex_buffers_equal(unsigned count,SVGA3dVertexBuffer_v2 * pVBufAttr1,struct pipe_resource ** pVBuf1,SVGA3dVertexBuffer_v2 * pVBufAttr2,struct pipe_resource ** pVBuf2)632 vertex_buffers_equal(unsigned count,
633                      SVGA3dVertexBuffer_v2 *pVBufAttr1,
634                      struct pipe_resource **pVBuf1,
635                      SVGA3dVertexBuffer_v2 *pVBufAttr2,
636                      struct pipe_resource **pVBuf2)
637 {
638    return (memcmp(pVBufAttr1, pVBufAttr2,
639                   count * sizeof(*pVBufAttr1)) == 0) &&
640           (memcmp(pVBuf1, pVBuf2, count * sizeof(*pVBuf1)) == 0);
641 }
642 
643 
644 /*
645  * Prepare the vertex buffers for a drawing command.
646  */
647 static enum pipe_error
validate_vertex_buffers(struct svga_hwtnl * hwtnl,const struct pipe_stream_output_target * so_vertex_count)648 validate_vertex_buffers(struct svga_hwtnl *hwtnl,
649                    const struct pipe_stream_output_target *so_vertex_count)
650 {
651    struct svga_context *svga = hwtnl->svga;
652    struct pipe_resource *vbuffers[SVGA3D_INPUTREG_MAX];
653    struct svga_winsys_surface *vbuffer_handles[SVGA3D_INPUTREG_MAX];
654    struct svga_winsys_surface *so_vertex_count_handle = NULL;
655    const unsigned vbuf_count = so_vertex_count ? 1 : hwtnl->cmd.vbuf_count;
656    SVGA3dVertexBuffer_v2 vbuffer_attrs[PIPE_MAX_ATTRIBS];
657    int last_vbuf = -1;
658    unsigned i;
659 
660    assert(svga_have_vgpu10(svga));
661 
662    /* setup vertex attribute input layout */
663    if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) {
664       enum pipe_error ret =
665          SVGA3D_vgpu10_SetInputLayout(svga->swc,
666                                       hwtnl->cmd.vdecl_layout_id);
667       if (ret != PIPE_OK)
668          return ret;
669 
670       svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id;
671    }
672 
673    /* Get handle for each referenced vertex buffer, unless we're using a
674     * stream-out buffer to specify the drawing information (DrawAuto).
675     * Also set up the buffer attributes.
676     */
677    if (so_vertex_count) {
678       so_vertex_count_handle = svga_buffer_handle(svga,
679                                                   so_vertex_count->buffer,
680                                                   (PIPE_BIND_VERTEX_BUFFER |
681                                                    PIPE_BIND_STREAM_OUTPUT));
682       if (!so_vertex_count_handle)
683          return PIPE_ERROR_OUT_OF_MEMORY;
684 
685       /* Set IA slot0 input buffer to the SO buffer */
686       assert(vbuf_count == 1);
687       vbuffer_attrs[0].stride = svga->state.sw.need_swtnl ? hwtnl->cmd.vdecl[0].array.stride : svga->curr.velems->strides[0];
688       vbuffer_attrs[0].offset = hwtnl->cmd.vbufs[0].buffer_offset;
689       vbuffer_attrs[0].sid = 0;
690       assert(so_vertex_count->buffer != NULL);
691       vbuffer_attrs[0].sizeInBytes = svga_buffer(so_vertex_count->buffer)->size;
692       vbuffers[0] = so_vertex_count->buffer;
693       vbuffer_handles[0] = so_vertex_count_handle;
694 
695       i = 1;
696    }
697    else {
698       for (i = 0; i < vbuf_count; i++) {
699          struct svga_buffer *sbuf =
700             svga_buffer(hwtnl->cmd.vbufs[i].buffer.resource);
701 
702          vbuffer_attrs[i].stride = svga->state.sw.need_swtnl ? hwtnl->cmd.vdecl[i].array.stride : svga->curr.velems->strides[i];
703          vbuffer_attrs[i].offset = hwtnl->cmd.vbufs[i].buffer_offset;
704          vbuffer_attrs[i].sid = 0;
705 
706          if (sbuf) {
707             vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b,
708                                                     PIPE_BIND_VERTEX_BUFFER);
709             assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER);
710             if (vbuffer_handles[i] == NULL)
711                return PIPE_ERROR_OUT_OF_MEMORY;
712             vbuffers[i] = &sbuf->b;
713             last_vbuf = i;
714 
715             vbuffer_attrs[i].sizeInBytes = sbuf->size;
716          }
717          else {
718             vbuffers[i] = NULL;
719             vbuffer_handles[i] = NULL;
720             vbuffer_attrs[i].sizeInBytes = 0;
721          }
722       }
723    }
724 
725    /* Unbind the unreferenced the vertex buffer handles */
726    for (; i < svga->state.hw_draw.num_vbuffers; i++) {
727       vbuffers[i] = NULL;
728       vbuffer_handles[i] = NULL;
729       vbuffer_attrs[i].sid = 0;
730       vbuffer_attrs[i].stride = 0;
731       vbuffer_attrs[i].offset = 0;
732       vbuffer_attrs[i].sizeInBytes = 0;
733    }
734 
735    /* Get handle for each referenced vertex buffer */
736    for (i = 0; i < vbuf_count; i++) {
737       struct svga_buffer *sbuf =
738          svga_buffer(hwtnl->cmd.vbufs[i].buffer.resource);
739 
740       if (sbuf) {
741          vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b,
742                                                  PIPE_BIND_VERTEX_BUFFER);
743          assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER);
744          if (vbuffer_handles[i] == NULL)
745             return PIPE_ERROR_OUT_OF_MEMORY;
746          vbuffers[i] = &sbuf->b;
747          last_vbuf = i;
748       }
749       else {
750          vbuffers[i] = NULL;
751          vbuffer_handles[i] = NULL;
752       }
753    }
754 
755    for (; i < svga->state.hw_draw.num_vbuffers; i++) {
756       vbuffers[i] = NULL;
757       vbuffer_handles[i] = NULL;
758    }
759 
760    /* setup vertex attribute input layout */
761    if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) {
762       enum pipe_error ret =
763          SVGA3D_vgpu10_SetInputLayout(svga->swc,
764                                       hwtnl->cmd.vdecl_layout_id);
765       if (ret != PIPE_OK)
766          return ret;
767 
768       svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id;
769    }
770 
771    /* Get handle for the stream out buffer */
772    if (so_vertex_count) {
773       so_vertex_count_handle = svga_buffer_handle(svga,
774                                                   so_vertex_count->buffer,
775                                                   (PIPE_BIND_VERTEX_BUFFER |
776                                                    PIPE_BIND_STREAM_OUTPUT));
777       if (!so_vertex_count_handle)
778          return PIPE_ERROR_OUT_OF_MEMORY;
779    }
780    else {
781       so_vertex_count_handle = NULL;
782    }
783 
784    /* setup vertex buffers */
785    {
786       /* If any of the vertex buffer state has changed, issue
787        * the SetVertexBuffers command. Otherwise, we will just
788        * need to rebind the resources.
789        */
790       if (vbuf_count != svga->state.hw_draw.num_vbuffers ||
791           !vertex_buffers_equal(vbuf_count,
792                                 vbuffer_attrs,
793                                 vbuffers,
794                                 svga->state.hw_draw.vbuffer_attrs,
795                                 svga->state.hw_draw.vbuffers)) {
796 
797          unsigned num_vbuffers;
798 
799          /* get the max of the current bound vertex buffers count and
800           * the to-be-bound vertex buffers count, so as to unbind
801           * the unused vertex buffers.
802           */
803          num_vbuffers = MAX2(vbuf_count, svga->state.hw_draw.num_vbuffers);
804 
805          if (num_vbuffers > 0) {
806             SVGA3dVertexBuffer_v2 *pbufAttrs = vbuffer_attrs;
807             struct svga_winsys_surface **pbufHandles = vbuffer_handles;
808             unsigned numVBuf = 0;
809             bool emitVBufs =
810                !svga_sws(svga)->have_index_vertex_buffer_offset_cmd ||
811                svga->rebind.flags.vertexbufs;
812 
813             /* Loop through the vertex buffer lists to only emit
814              * those vertex buffers that are not already in the
815              * corresponding entries in the device's vertex buffer list.
816              */
817             for (i = 0; i < num_vbuffers; i++) {
818                bool emit =
819                   vertex_buffers_equal(1,
820                                        &vbuffer_attrs[i],
821                                        &vbuffers[i],
822                                        &svga->state.hw_draw.vbuffer_attrs[i],
823                                        &svga->state.hw_draw.vbuffers[i]);
824 
825                /* Check if we can use the SetVertexBuffersOffsetAndSize command */
826                emitVBufs = emitVBufs ||
827                               (vbuffers[i] != svga->state.hw_draw.vbuffers[i]);
828 
829                if (!emit && i == num_vbuffers-1) {
830                   /* Include the last vertex buffer in the next emit
831                    * if it is different.
832                    */
833                   emit = true;
834                   numVBuf++;
835                   i++;
836                }
837 
838                if (emit) {
839                   /* numVBuf can only be 0 if the first vertex buffer
840                    * is the same as the one in the device's list.
841                    * In this case, there is nothing to send yet.
842                    */
843                   if (numVBuf) {
844                      enum pipe_error ret;
845 
846                      /* If all vertex buffers handle are the same as the one
847                       * in the device, just use the
848                       * SetVertexBuffersOffsetAndSize comand.
849                       */
850                      if (emitVBufs) {
851                         ret = SVGA3D_vgpu10_SetVertexBuffers(svga->swc,
852                                                              numVBuf,
853                                                              i - numVBuf,
854                                                              pbufAttrs, pbufHandles);
855                      } else {
856                         ret = SVGA3D_vgpu10_SetVertexBuffersOffsetAndSize(svga->swc,
857                                                              numVBuf,
858                                                              i - numVBuf,
859                                                              pbufAttrs);
860                      }
861                      if (ret != PIPE_OK)
862                         return ret;
863                   }
864                   pbufAttrs += (numVBuf + 1);
865                   pbufHandles += (numVBuf + 1);
866                   numVBuf = 0;
867                }
868                else
869                   numVBuf++;
870             }
871 
872             /* save the number of vertex buffers sent to the device, not
873              * including trailing unbound vertex buffers.
874              */
875             svga->state.hw_draw.num_vbuffers = last_vbuf + 1;
876             memcpy(svga->state.hw_draw.vbuffer_attrs, vbuffer_attrs,
877                    num_vbuffers * sizeof(vbuffer_attrs[0]));
878             for (i = 0; i < num_vbuffers; i++) {
879                pipe_resource_reference(&svga->state.hw_draw.vbuffers[i],
880                                        vbuffers[i]);
881             }
882          }
883       }
884       else {
885          /* Even though we can avoid emitting the redundant SetVertexBuffers
886           * command, we still need to reference the vertex buffers surfaces.
887           */
888          for (i = 0; i < vbuf_count; i++) {
889             if (vbuffer_handles[i] && !last_command_was_draw(svga)) {
890                enum pipe_error ret =
891                   svga->swc->resource_rebind(svga->swc, vbuffer_handles[i],
892                                              NULL, SVGA_RELOC_READ);
893                if (ret != PIPE_OK)
894                   return ret;
895             }
896          }
897       }
898    }
899 
900    svga->rebind.flags.vertexbufs = false;
901 
902    return PIPE_OK;
903 }
904 
905 
906 /*
907  * Prepare the index buffer for a drawing command.
908  */
909 static enum pipe_error
validate_index_buffer(struct svga_hwtnl * hwtnl,const SVGA3dPrimitiveRange * range,struct pipe_resource * ib)910 validate_index_buffer(struct svga_hwtnl *hwtnl,
911                       const SVGA3dPrimitiveRange *range,
912                       struct pipe_resource *ib)
913 {
914    struct svga_context *svga = hwtnl->svga;
915    struct svga_winsys_surface *ib_handle =
916       svga_buffer_handle(svga, ib, PIPE_BIND_INDEX_BUFFER);
917    enum pipe_error ret;
918 
919    if (!ib_handle)
920       return PIPE_ERROR_OUT_OF_MEMORY;
921 
922    struct svga_buffer *sbuf = svga_buffer(ib);
923    assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_INDEX_BUFFER);
924    (void) sbuf; /* silence unused var warning */
925 
926    SVGA3dSurfaceFormat indexFormat = xlate_index_format(range->indexWidth);
927 
928    if (ib != svga->state.hw_draw.ib ||
929        indexFormat != svga->state.hw_draw.ib_format ||
930        range->indexArray.offset != svga->state.hw_draw.ib_offset) {
931 
932       assert(indexFormat != SVGA3D_FORMAT_INVALID);
933 
934       if ((ib == svga->state.hw_draw.ib) &&
935           svga_sws(hwtnl->svga)->have_index_vertex_buffer_offset_cmd &&
936           !svga->rebind.flags.indexbuf) {
937 
938          ret = SVGA3D_vgpu10_SetIndexBufferOffsetAndSize(svga->swc,
939                                                          indexFormat,
940                                                          range->indexArray.offset,
941                                                          sbuf->size);
942          if (ret != PIPE_OK)
943             return ret;
944       }
945       else {
946 
947          ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, ib_handle,
948                                             indexFormat,
949                                             range->indexArray.offset);
950          if (ret != PIPE_OK)
951             return ret;
952       }
953 
954       pipe_resource_reference(&svga->state.hw_draw.ib, ib);
955       svga->state.hw_draw.ib_format = indexFormat;
956       svga->state.hw_draw.ib_offset = range->indexArray.offset;
957    }
958    else {
959       /* Even though we can avoid emitting the redundant SetIndexBuffer
960        * command, we still need to reference the index buffer surface.
961        */
962       if (!last_command_was_draw(svga)) {
963          enum pipe_error ret = svga->swc->resource_rebind(svga->swc,
964                                                           ib_handle,
965                                                           NULL,
966                                                           SVGA_RELOC_READ);
967          if (ret != PIPE_OK)
968             return ret;
969       }
970    }
971 
972    svga->rebind.flags.indexbuf = false;
973 
974    return PIPE_OK;
975 }
976 
977 
978 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)979 draw_vgpu10(struct svga_hwtnl *hwtnl,
980             const SVGA3dPrimitiveRange *range,
981             unsigned vcount,
982             unsigned min_index, unsigned max_index,
983             struct pipe_resource *ib,
984             unsigned start_instance, unsigned instance_count,
985             const struct pipe_draw_indirect_info *indirect,
986             const struct pipe_stream_output_target *so_vertex_count)
987 {
988    struct svga_context *svga = hwtnl->svga;
989    struct svga_winsys_surface *indirect_handle;
990    enum pipe_error ret;
991    bool is_instanced_draw = instance_count > 1 || start_instance > 0;
992 
993    assert(svga_have_vgpu10(svga));
994    assert(hwtnl->cmd.prim_count == 0);
995 
996    /* We need to reemit all the current resource bindings along with the Draw
997     * command to be sure that the referenced resources are available for the
998     * Draw command, just in case the surfaces associated with the resources
999     * are paged out.
1000     */
1001    if (svga->rebind.val) {
1002       ret = svga_rebind_framebuffer_bindings(svga);
1003       if (ret != PIPE_OK)
1004          return ret;
1005 
1006       ret = svga_rebind_shaders(svga);
1007       if (ret != PIPE_OK)
1008          return ret;
1009 
1010       /* Rebind stream output targets */
1011       ret = svga_rebind_stream_output_targets(svga);
1012       if (ret != PIPE_OK)
1013          return ret;
1014 
1015       /* No need to explicitly rebind index buffer and vertex buffers here.
1016        * Even if the same index buffer or vertex buffers are referenced for this
1017        * draw and we skip emitting the redundant set command, we will still
1018        * reference the associated resources.
1019        */
1020    }
1021 
1022    ret = svga_validate_sampler_resources(svga, SVGA_PIPE_GRAPHICS);
1023    if (ret != PIPE_OK)
1024       return ret;
1025 
1026    ret = svga_validate_constant_buffers(svga, SVGA_PIPE_GRAPHICS);
1027    if (ret != PIPE_OK)
1028       return ret;
1029 
1030    if (svga_have_gl43(svga)) {
1031       ret = svga_validate_image_views(svga, SVGA_PIPE_GRAPHICS);
1032       if (ret != PIPE_OK)
1033          return ret;
1034 
1035       ret = svga_validate_shader_buffers(svga, SVGA_PIPE_GRAPHICS);
1036       if (ret != PIPE_OK)
1037          return ret;
1038 
1039       if (svga->rebind.flags.uav) {
1040          ret= svga_rebind_uav(svga);
1041          if (ret != PIPE_OK)
1042             return ret;
1043       }
1044    }
1045 
1046    ret = validate_vertex_buffers(hwtnl, so_vertex_count);
1047    if (ret != PIPE_OK)
1048       return ret;
1049 
1050    if (ib) {
1051       ret = validate_index_buffer(hwtnl, range, ib);
1052       if (ret != PIPE_OK)
1053          return ret;
1054    }
1055 
1056    if (indirect) {
1057       indirect_handle = svga_buffer_handle(svga, indirect->buffer,
1058                                            PIPE_BIND_COMMAND_ARGS_BUFFER);
1059       if (!indirect_handle)
1060          return PIPE_ERROR_OUT_OF_MEMORY;
1061    }
1062    else {
1063       indirect_handle = NULL;
1064    }
1065 
1066    /* Set primitive type (line, tri, etc) */
1067    if (svga->state.hw_draw.topology != range->primType) {
1068       ret = SVGA3D_vgpu10_SetTopology(svga->swc, range->primType);
1069       if (ret != PIPE_OK)
1070          return ret;
1071 
1072       svga->state.hw_draw.topology = range->primType;
1073    }
1074 
1075    if (ib) {
1076       /* indexed drawing */
1077       if (indirect) {
1078          ret = SVGA3D_sm5_DrawIndexedInstancedIndirect(svga->swc,
1079                                                        indirect_handle,
1080                                                        indirect->offset);
1081       }
1082       else if (is_instanced_draw) {
1083          ret = SVGA3D_vgpu10_DrawIndexedInstanced(svga->swc,
1084                                                   vcount,
1085                                                   instance_count,
1086                                                   0, /* startIndexLocation */
1087                                                   range->indexBias,
1088                                                   start_instance);
1089       }
1090       else {
1091          /* non-instanced drawing */
1092          ret = SVGA3D_vgpu10_DrawIndexed(svga->swc,
1093                                          vcount,
1094                                          0,      /* startIndexLocation */
1095                                          range->indexBias);
1096       }
1097       if (ret != PIPE_OK) {
1098          return ret;
1099       }
1100    }
1101    else {
1102       /* non-indexed drawing */
1103       if (svga->state.hw_draw.ib_format != SVGA3D_FORMAT_INVALID ||
1104           svga->state.hw_draw.ib != NULL) {
1105          /* Unbind previously bound index buffer */
1106          ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, NULL,
1107                                             SVGA3D_FORMAT_INVALID, 0);
1108          if (ret != PIPE_OK)
1109             return ret;
1110          pipe_resource_reference(&svga->state.hw_draw.ib, NULL);
1111          svga->state.hw_draw.ib_format = SVGA3D_FORMAT_INVALID;
1112       }
1113 
1114       assert(svga->state.hw_draw.ib == NULL);
1115 
1116       if (so_vertex_count) {
1117          /* Stream-output drawing */
1118          ret = SVGA3D_vgpu10_DrawAuto(svga->swc);
1119       }
1120       else if (indirect) {
1121          ret = SVGA3D_sm5_DrawInstancedIndirect(svga->swc,
1122                                                 indirect_handle,
1123                                                 indirect->offset);
1124       }
1125       else if (is_instanced_draw) {
1126          ret = SVGA3D_vgpu10_DrawInstanced(svga->swc,
1127                                            vcount,
1128                                            instance_count,
1129                                            range->indexBias,
1130                                            start_instance);
1131       }
1132       else {
1133          /* non-instanced */
1134          ret = SVGA3D_vgpu10_Draw(svga->swc,
1135                                   vcount,
1136                                   range->indexBias);
1137       }
1138       if (ret != PIPE_OK) {
1139          return ret;
1140       }
1141    }
1142 
1143    hwtnl->cmd.prim_count = 0;
1144 
1145    return PIPE_OK;
1146 }
1147 
1148 
1149 
1150 /**
1151  * Emit any pending drawing commands to the command buffer.
1152  * When we receive VGPU9 drawing commands we accumulate them and don't
1153  * immediately emit them into the command buffer.
1154  * This function needs to be called before we change state that could
1155  * effect those pending draws.
1156  */
1157 enum pipe_error
svga_hwtnl_flush(struct svga_hwtnl * hwtnl)1158 svga_hwtnl_flush(struct svga_hwtnl *hwtnl)
1159 {
1160    enum pipe_error ret = PIPE_OK;
1161 
1162    SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLFLUSH);
1163 
1164    if (!svga_have_vgpu10(hwtnl->svga) && hwtnl->cmd.prim_count) {
1165       /* we only queue up primitive for VGPU9 */
1166       ret = draw_vgpu9(hwtnl);
1167    }
1168 
1169    SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
1170    return ret;
1171 }
1172 
1173 
1174 void
svga_hwtnl_set_index_bias(struct svga_hwtnl * hwtnl,int index_bias)1175 svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias)
1176 {
1177    hwtnl->index_bias = index_bias;
1178 }
1179 
1180 
1181 
1182 /***********************************************************************
1183  * Internal functions:
1184  */
1185 
1186 /**
1187  * For debugging only.
1188  */
1189 static void
check_draw_params(struct svga_hwtnl * hwtnl,const SVGA3dPrimitiveRange * range,unsigned min_index,unsigned max_index,struct pipe_resource * ib)1190 check_draw_params(struct svga_hwtnl *hwtnl,
1191                   const SVGA3dPrimitiveRange *range,
1192                   unsigned min_index, unsigned max_index,
1193                   struct pipe_resource *ib)
1194 {
1195    unsigned i;
1196 
1197    assert(!svga_have_vgpu10(hwtnl->svga));
1198 
1199    for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
1200       unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
1201       const struct pipe_vertex_buffer *vb = &hwtnl->cmd.vbufs[j];
1202       unsigned size = vb->buffer.resource ? vb->buffer.resource->width0 : 0;
1203       unsigned offset = hwtnl->cmd.vdecl[i].array.offset;
1204       unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
1205       int index_bias = (int) range->indexBias + hwtnl->index_bias;
1206       unsigned width;
1207 
1208       if (size == 0)
1209          continue;
1210 
1211       assert(vb);
1212       assert(size);
1213       assert(offset < size);
1214       assert(min_index <= max_index);
1215       (void) width;
1216       (void) stride;
1217       (void) offset;
1218       (void) size;
1219 
1220       switch (hwtnl->cmd.vdecl[i].identity.type) {
1221       case SVGA3D_DECLTYPE_FLOAT1:
1222          width = 4;
1223          break;
1224       case SVGA3D_DECLTYPE_FLOAT2:
1225          width = 4 * 2;
1226          break;
1227       case SVGA3D_DECLTYPE_FLOAT3:
1228          width = 4 * 3;
1229          break;
1230       case SVGA3D_DECLTYPE_FLOAT4:
1231          width = 4 * 4;
1232          break;
1233       case SVGA3D_DECLTYPE_D3DCOLOR:
1234          width = 4;
1235          break;
1236       case SVGA3D_DECLTYPE_UBYTE4:
1237          width = 1 * 4;
1238          break;
1239       case SVGA3D_DECLTYPE_SHORT2:
1240          width = 2 * 2;
1241          break;
1242       case SVGA3D_DECLTYPE_SHORT4:
1243          width = 2 * 4;
1244          break;
1245       case SVGA3D_DECLTYPE_UBYTE4N:
1246          width = 1 * 4;
1247          break;
1248       case SVGA3D_DECLTYPE_SHORT2N:
1249          width = 2 * 2;
1250          break;
1251       case SVGA3D_DECLTYPE_SHORT4N:
1252          width = 2 * 4;
1253          break;
1254       case SVGA3D_DECLTYPE_USHORT2N:
1255          width = 2 * 2;
1256          break;
1257       case SVGA3D_DECLTYPE_USHORT4N:
1258          width = 2 * 4;
1259          break;
1260       case SVGA3D_DECLTYPE_UDEC3:
1261          width = 4;
1262          break;
1263       case SVGA3D_DECLTYPE_DEC3N:
1264          width = 4;
1265          break;
1266       case SVGA3D_DECLTYPE_FLOAT16_2:
1267          width = 2 * 2;
1268          break;
1269       case SVGA3D_DECLTYPE_FLOAT16_4:
1270          width = 2 * 4;
1271          break;
1272       default:
1273          assert(0);
1274          width = 0;
1275          break;
1276       }
1277 
1278       if (index_bias >= 0) {
1279          assert(offset + index_bias * stride + width <= size);
1280       }
1281 
1282       /*
1283        * min_index/max_index are merely conservative guesses, so we can't
1284        * make buffer overflow detection based on their values.
1285        */
1286    }
1287 
1288    assert(range->indexWidth == range->indexArray.stride);
1289 
1290    if (ib) {
1291       ASSERTED unsigned size = ib->width0;
1292       ASSERTED unsigned offset = range->indexArray.offset;
1293       ASSERTED unsigned stride = range->indexArray.stride;
1294       ASSERTED unsigned count;
1295 
1296       assert(size);
1297       assert(offset < size);
1298       assert(stride);
1299 
1300       switch (range->primType) {
1301       case SVGA3D_PRIMITIVE_POINTLIST:
1302          count = range->primitiveCount;
1303          break;
1304       case SVGA3D_PRIMITIVE_LINELIST:
1305          count = range->primitiveCount * 2;
1306          break;
1307       case SVGA3D_PRIMITIVE_LINESTRIP:
1308          count = range->primitiveCount + 1;
1309          break;
1310       case SVGA3D_PRIMITIVE_TRIANGLELIST:
1311          count = range->primitiveCount * 3;
1312          break;
1313       case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
1314          count = range->primitiveCount + 2;
1315          break;
1316       case SVGA3D_PRIMITIVE_TRIANGLEFAN:
1317          count = range->primitiveCount + 2;
1318          break;
1319       default:
1320          assert(0);
1321          count = 0;
1322          break;
1323       }
1324 
1325       assert(offset + count * stride <= size);
1326    }
1327 }
1328 
1329 
1330 /**
1331  * All drawing filters down into this function, either directly
1332  * on the hardware path or after doing software vertex processing.
1333  * \param indirect  if non-null, get the vertex count, first vertex, etc.
1334  *                  from a buffer.
1335  * \param so_vertex_count  if non-null, get the vertex count from a
1336  *                         stream-output target.
1337  */
1338 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)1339 svga_hwtnl_prim(struct svga_hwtnl *hwtnl,
1340                 const SVGA3dPrimitiveRange *range,
1341                 unsigned vcount,
1342                 unsigned min_index, unsigned max_index,
1343                 struct pipe_resource *ib,
1344                 unsigned start_instance, unsigned instance_count,
1345                 const struct pipe_draw_indirect_info *indirect,
1346                 const struct pipe_stream_output_target *so_vertex_count)
1347 {
1348    enum pipe_error ret = PIPE_OK;
1349 
1350    SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLPRIM);
1351 
1352    if (svga_have_vgpu10(hwtnl->svga)) {
1353       /* draw immediately */
1354       SVGA_RETRY(hwtnl->svga, draw_vgpu10(hwtnl, range, vcount, min_index,
1355                                           max_index, ib, start_instance,
1356                                           instance_count, indirect,
1357                                           so_vertex_count));
1358    }
1359    else {
1360       /* batch up drawing commands */
1361       assert(indirect == NULL);
1362 #if MESA_DEBUG
1363       check_draw_params(hwtnl, range, min_index, max_index, ib);
1364       assert(start_instance == 0);
1365       assert(instance_count <= 1);
1366 #else
1367       (void) check_draw_params;
1368 #endif
1369 
1370       if (hwtnl->cmd.prim_count + 1 >= QSZ) {
1371          ret = svga_hwtnl_flush(hwtnl);
1372          if (ret != PIPE_OK)
1373             goto done;
1374       }
1375 
1376       /* min/max indices are relative to bias */
1377       hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index;
1378       hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index;
1379 
1380       hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range;
1381       hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias;
1382 
1383       pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
1384       hwtnl->cmd.prim_count++;
1385    }
1386 
1387 done:
1388    SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
1389    return ret;
1390 }
1391 
1392 
1393 /**
1394  * Return TRUE if there are pending primitives.
1395  */
1396 bool
svga_hwtnl_has_pending_prim(struct svga_hwtnl * hwtnl)1397 svga_hwtnl_has_pending_prim(struct svga_hwtnl *hwtnl)
1398 {
1399    return hwtnl->cmd.prim_count > 0;
1400 }
1401