• 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_shader.h"
42 #include "svga_surface.h"
43 #include "svga_winsys.h"
44 #include "svga_cmd.h"
45 
46 
47 struct svga_hwtnl *
svga_hwtnl_create(struct svga_context * svga)48 svga_hwtnl_create(struct svga_context *svga)
49 {
50    struct svga_hwtnl *hwtnl = CALLOC_STRUCT(svga_hwtnl);
51    if (!hwtnl)
52       goto fail;
53 
54    hwtnl->svga = svga;
55 
56    hwtnl->cmd.swc = svga->swc;
57 
58    return hwtnl;
59 
60 fail:
61    return NULL;
62 }
63 
64 
65 void
svga_hwtnl_destroy(struct svga_hwtnl * hwtnl)66 svga_hwtnl_destroy(struct svga_hwtnl *hwtnl)
67 {
68    unsigned i, j;
69 
70    for (i = 0; i < PIPE_PRIM_MAX; i++) {
71       for (j = 0; j < IDX_CACHE_MAX; j++) {
72          pipe_resource_reference(&hwtnl->index_cache[i][j].buffer, NULL);
73       }
74    }
75 
76    for (i = 0; i < hwtnl->cmd.vbuf_count; i++)
77       pipe_resource_reference(&hwtnl->cmd.vbufs[i].buffer, NULL);
78 
79    for (i = 0; i < hwtnl->cmd.prim_count; i++)
80       pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
81 
82    FREE(hwtnl);
83 }
84 
85 
86 void
svga_hwtnl_set_flatshade(struct svga_hwtnl * hwtnl,boolean flatshade,boolean flatshade_first)87 svga_hwtnl_set_flatshade(struct svga_hwtnl *hwtnl,
88                          boolean flatshade, boolean flatshade_first)
89 {
90    struct svga_screen *svgascreen = svga_screen(hwtnl->svga->pipe.screen);
91 
92    /* User-specified PV */
93    hwtnl->api_pv = (flatshade && !flatshade_first) ? PV_LAST : PV_FIRST;
94 
95    /* Device supported PV */
96    if (svgascreen->haveProvokingVertex) {
97       /* use the mode specified by the user */
98       hwtnl->hw_pv = hwtnl->api_pv;
99    }
100    else {
101       /* the device only support first provoking vertex */
102       hwtnl->hw_pv = PV_FIRST;
103    }
104 }
105 
106 
107 void
svga_hwtnl_set_fillmode(struct svga_hwtnl * hwtnl,unsigned mode)108 svga_hwtnl_set_fillmode(struct svga_hwtnl *hwtnl, unsigned mode)
109 {
110    hwtnl->api_fillmode = mode;
111 }
112 
113 
114 void
svga_hwtnl_vertex_decls(struct svga_hwtnl * hwtnl,unsigned count,const SVGA3dVertexDecl * decls,const unsigned * buffer_indexes,SVGA3dElementLayoutId layout_id)115 svga_hwtnl_vertex_decls(struct svga_hwtnl *hwtnl,
116                         unsigned count,
117                         const SVGA3dVertexDecl * decls,
118                         const unsigned *buffer_indexes,
119                         SVGA3dElementLayoutId layout_id)
120 {
121    assert(hwtnl->cmd.prim_count == 0);
122    hwtnl->cmd.vdecl_count = count;
123    hwtnl->cmd.vdecl_layout_id = layout_id;
124    memcpy(hwtnl->cmd.vdecl, decls, count * sizeof(*decls));
125    memcpy(hwtnl->cmd.vdecl_buffer_index, buffer_indexes,
126           count * sizeof(unsigned));
127 }
128 
129 
130 /**
131  * Specify vertex buffers for hardware drawing.
132  */
133 void
svga_hwtnl_vertex_buffers(struct svga_hwtnl * hwtnl,unsigned count,struct pipe_vertex_buffer * buffers)134 svga_hwtnl_vertex_buffers(struct svga_hwtnl *hwtnl,
135                           unsigned count, struct pipe_vertex_buffer *buffers)
136 {
137    util_set_vertex_buffers_count(hwtnl->cmd.vbufs,
138                                  &hwtnl->cmd.vbuf_count, buffers, 0, count);
139 }
140 
141 
142 /**
143  * Determine whether the specified buffer is referred in the primitive queue,
144  * for which no commands have been written yet.
145  */
146 boolean
svga_hwtnl_is_buffer_referred(struct svga_hwtnl * hwtnl,struct pipe_resource * buffer)147 svga_hwtnl_is_buffer_referred(struct svga_hwtnl *hwtnl,
148                               struct pipe_resource *buffer)
149 {
150    unsigned i;
151 
152    if (svga_buffer_is_user_buffer(buffer)) {
153       return FALSE;
154    }
155 
156    if (!hwtnl->cmd.prim_count) {
157       return FALSE;
158    }
159 
160    for (i = 0; i < hwtnl->cmd.vbuf_count; ++i) {
161       if (hwtnl->cmd.vbufs[i].buffer == buffer) {
162          return TRUE;
163       }
164    }
165 
166    for (i = 0; i < hwtnl->cmd.prim_count; ++i) {
167       if (hwtnl->cmd.prim_ib[i] == buffer) {
168          return TRUE;
169       }
170    }
171 
172    return FALSE;
173 }
174 
175 
176 static enum pipe_error
draw_vgpu9(struct svga_hwtnl * hwtnl)177 draw_vgpu9(struct svga_hwtnl *hwtnl)
178 {
179    struct svga_winsys_context *swc = hwtnl->cmd.swc;
180    struct svga_context *svga = hwtnl->svga;
181    enum pipe_error ret;
182    struct svga_winsys_surface *vb_handle[SVGA3D_INPUTREG_MAX];
183    struct svga_winsys_surface *ib_handle[QSZ];
184    struct svga_winsys_surface *handle;
185    SVGA3dVertexDecl *vdecl;
186    SVGA3dPrimitiveRange *prim;
187    unsigned i;
188 
189    for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
190       unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
191       handle = svga_buffer_handle(svga, hwtnl->cmd.vbufs[j].buffer);
192       if (!handle)
193          return PIPE_ERROR_OUT_OF_MEMORY;
194 
195       vb_handle[i] = handle;
196    }
197 
198    for (i = 0; i < hwtnl->cmd.prim_count; i++) {
199       if (hwtnl->cmd.prim_ib[i]) {
200          handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i]);
201          if (!handle)
202             return PIPE_ERROR_OUT_OF_MEMORY;
203       }
204       else
205          handle = NULL;
206 
207       ib_handle[i] = handle;
208    }
209 
210    if (svga->rebind.flags.rendertargets) {
211       ret = svga_reemit_framebuffer_bindings(svga);
212       if (ret != PIPE_OK) {
213          return ret;
214       }
215    }
216 
217    if (svga->rebind.flags.texture_samplers) {
218       ret = svga_reemit_tss_bindings(svga);
219       if (ret != PIPE_OK) {
220          return ret;
221       }
222    }
223 
224    if (svga->rebind.flags.vs) {
225       ret = svga_reemit_vs_bindings(svga);
226       if (ret != PIPE_OK) {
227          return ret;
228       }
229    }
230 
231    if (svga->rebind.flags.fs) {
232       ret = svga_reemit_fs_bindings(svga);
233       if (ret != PIPE_OK) {
234          return ret;
235       }
236    }
237 
238    SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n",
239             svga->curr.framebuffer.cbufs[0] ?
240             svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL,
241             hwtnl->cmd.prim_count);
242 
243    ret = SVGA3D_BeginDrawPrimitives(swc,
244                                     &vdecl,
245                                     hwtnl->cmd.vdecl_count,
246                                     &prim, hwtnl->cmd.prim_count);
247    if (ret != PIPE_OK)
248       return ret;
249 
250    memcpy(vdecl,
251           hwtnl->cmd.vdecl,
252           hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]);
253 
254    for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
255       /* check for 4-byte alignment */
256       assert(vdecl[i].array.offset % 4 == 0);
257       assert(vdecl[i].array.stride % 4 == 0);
258 
259       /* Given rangeHint is considered to be relative to indexBias, and
260        * indexBias varies per primitive, we cannot accurately supply an
261        * rangeHint when emitting more than one primitive per draw command.
262        */
263       if (hwtnl->cmd.prim_count == 1) {
264          vdecl[i].rangeHint.first = hwtnl->cmd.min_index[0];
265          vdecl[i].rangeHint.last = hwtnl->cmd.max_index[0] + 1;
266       }
267       else {
268          vdecl[i].rangeHint.first = 0;
269          vdecl[i].rangeHint.last = 0;
270       }
271 
272       swc->surface_relocation(swc,
273                               &vdecl[i].array.surfaceId,
274                               NULL, vb_handle[i], SVGA_RELOC_READ);
275    }
276 
277    memcpy(prim,
278           hwtnl->cmd.prim, hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]);
279 
280    for (i = 0; i < hwtnl->cmd.prim_count; i++) {
281       swc->surface_relocation(swc,
282                               &prim[i].indexArray.surfaceId,
283                               NULL, ib_handle[i], SVGA_RELOC_READ);
284       pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
285    }
286 
287    SVGA_FIFOCommitAll(swc);
288 
289    hwtnl->cmd.prim_count = 0;
290 
291    return PIPE_OK;
292 }
293 
294 
295 static SVGA3dSurfaceFormat
xlate_index_format(unsigned indexWidth)296 xlate_index_format(unsigned indexWidth)
297 {
298    if (indexWidth == 2) {
299       return SVGA3D_R16_UINT;
300    }
301    else if (indexWidth == 4) {
302       return SVGA3D_R32_UINT;
303    }
304    else {
305       assert(!"Bad indexWidth");
306       return SVGA3D_R32_UINT;
307    }
308 }
309 
310 
311 static enum pipe_error
validate_sampler_resources(struct svga_context * svga)312 validate_sampler_resources(struct svga_context *svga)
313 {
314    enum pipe_shader_type shader;
315 
316    assert(svga_have_vgpu10(svga));
317 
318    for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
319       unsigned count = svga->curr.num_sampler_views[shader];
320       unsigned i;
321       struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS];
322       enum pipe_error ret;
323 
324       /*
325        * Reference bound sampler resources to ensure pending updates are
326        * noticed by the device.
327        */
328       for (i = 0; i < count; i++) {
329          struct svga_pipe_sampler_view *sv =
330             svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
331 
332          if (sv) {
333             if (sv->base.texture->target == PIPE_BUFFER) {
334                surfaces[i] = svga_buffer_handle(svga, sv->base.texture);
335             }
336             else {
337                surfaces[i] = svga_texture(sv->base.texture)->handle;
338             }
339          }
340          else {
341             surfaces[i] = NULL;
342          }
343       }
344 
345       if (shader == PIPE_SHADER_FRAGMENT &&
346           svga->curr.rast->templ.poly_stipple_enable) {
347          const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
348          struct svga_pipe_sampler_view *sv =
349             svga->polygon_stipple.sampler_view;
350 
351          assert(sv);
352          surfaces[unit] = svga_texture(sv->base.texture)->handle;
353          count = MAX2(count, unit+1);
354       }
355 
356       /* rebind the shader resources if needed */
357       if (svga->rebind.flags.texture_samplers) {
358          for (i = 0; i < count; i++) {
359             if (surfaces[i]) {
360                ret = svga->swc->resource_rebind(svga->swc,
361                                                 surfaces[i],
362                                                 NULL,
363                                                 SVGA_RELOC_READ);
364                if (ret != PIPE_OK)
365                   return ret;
366             }
367          }
368       }
369    }
370    svga->rebind.flags.texture_samplers = FALSE;
371 
372    return PIPE_OK;
373 }
374 
375 
376 static enum pipe_error
validate_constant_buffers(struct svga_context * svga)377 validate_constant_buffers(struct svga_context *svga)
378 {
379    enum pipe_shader_type shader;
380 
381    assert(svga_have_vgpu10(svga));
382 
383    for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
384       enum pipe_error ret;
385       struct svga_buffer *buffer;
386       struct svga_winsys_surface *handle;
387       unsigned enabled_constbufs;
388 
389       /* Rebind the default constant buffer if needed */
390       if (svga->rebind.flags.constbufs) {
391          buffer = svga_buffer(svga->state.hw_draw.constbuf[shader]);
392          if (buffer) {
393             ret = svga->swc->resource_rebind(svga->swc,
394                                              buffer->handle,
395                                              NULL,
396                                              SVGA_RELOC_READ);
397             if (ret != PIPE_OK)
398                return ret;
399          }
400       }
401 
402       /*
403        * Reference other bound constant buffers to ensure pending updates are
404        * noticed by the device.
405        */
406       enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] & ~1u;
407       while (enabled_constbufs) {
408          unsigned i = u_bit_scan(&enabled_constbufs);
409          buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
410          if (buffer) {
411             handle = svga_buffer_handle(svga, &buffer->b.b);
412 
413             if (svga->rebind.flags.constbufs) {
414                ret = svga->swc->resource_rebind(svga->swc,
415                                                 handle,
416                                                 NULL,
417                                                 SVGA_RELOC_READ);
418                if (ret != PIPE_OK)
419                   return ret;
420             }
421          }
422       }
423    }
424    svga->rebind.flags.constbufs = FALSE;
425 
426    return PIPE_OK;
427 }
428 
429 
430 /**
431  * Was the last command put into the command buffer a drawing command?
432  * We use this to determine if we can skip emitting buffer re-bind
433  * commands when we have a sequence of drawing commands that use the
434  * same vertex/index buffers with no intervening commands.
435  *
436  * The first drawing command will bind the vertex/index buffers.  If
437  * the immediately following command is also a drawing command using the
438  * same buffers, we shouldn't have to rebind them.
439  */
440 static bool
last_command_was_draw(const struct svga_context * svga)441 last_command_was_draw(const struct svga_context *svga)
442 {
443    switch (SVGA3D_GetLastCommand(svga->swc)) {
444    case SVGA_3D_CMD_DX_DRAW:
445    case SVGA_3D_CMD_DX_DRAW_INDEXED:
446    case SVGA_3D_CMD_DX_DRAW_INSTANCED:
447    case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED:
448    case SVGA_3D_CMD_DX_DRAW_AUTO:
449       return true;
450    default:
451       return false;
452    }
453 }
454 
455 
456 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)457 draw_vgpu10(struct svga_hwtnl *hwtnl,
458             const SVGA3dPrimitiveRange *range,
459             unsigned vcount,
460             unsigned min_index,
461             unsigned max_index, struct pipe_resource *ib,
462             unsigned start_instance, unsigned instance_count)
463 {
464    struct svga_context *svga = hwtnl->svga;
465    struct pipe_resource *vbuffers[SVGA3D_INPUTREG_MAX];
466    struct svga_winsys_surface *vbuffer_handles[SVGA3D_INPUTREG_MAX];
467    struct svga_winsys_surface *ib_handle;
468    const unsigned vbuf_count = hwtnl->cmd.vbuf_count;
469    int last_vbuf = -1;
470    enum pipe_error ret;
471    unsigned i;
472 
473    assert(svga_have_vgpu10(svga));
474    assert(hwtnl->cmd.prim_count == 0);
475 
476    /* We need to reemit all the current resource bindings along with the Draw
477     * command to be sure that the referenced resources are available for the
478     * Draw command, just in case the surfaces associated with the resources
479     * are paged out.
480     */
481    if (svga->rebind.val) {
482       ret = svga_rebind_framebuffer_bindings(svga);
483       if (ret != PIPE_OK)
484          return ret;
485 
486       ret = svga_rebind_shaders(svga);
487       if (ret != PIPE_OK)
488          return ret;
489 
490       /* Rebind stream output targets */
491       ret = svga_rebind_stream_output_targets(svga);
492       if (ret != PIPE_OK)
493          return ret;
494 
495       /* No need to explicitly rebind index buffer and vertex buffers here.
496        * Even if the same index buffer or vertex buffers are referenced for this
497        * draw and we skip emitting the redundant set command, we will still
498        * reference the associated resources.
499        */
500    }
501 
502    ret = validate_sampler_resources(svga);
503    if (ret != PIPE_OK)
504       return ret;
505 
506    ret = validate_constant_buffers(svga);
507    if (ret != PIPE_OK)
508       return ret;
509 
510    /* Get handle for each referenced vertex buffer */
511    for (i = 0; i < vbuf_count; i++) {
512       struct svga_buffer *sbuf = svga_buffer(hwtnl->cmd.vbufs[i].buffer);
513 
514       if (sbuf) {
515          assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER);
516          vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b.b);
517          if (vbuffer_handles[i] == NULL)
518             return PIPE_ERROR_OUT_OF_MEMORY;
519          vbuffers[i] = &sbuf->b.b;
520          last_vbuf = i;
521       }
522       else {
523          vbuffers[i] = NULL;
524          vbuffer_handles[i] = NULL;
525       }
526    }
527 
528    for (; i < svga->state.hw_draw.num_vbuffers; i++) {
529       vbuffers[i] = NULL;
530       vbuffer_handles[i] = NULL;
531    }
532 
533    /* Get handle for the index buffer */
534    if (ib) {
535       struct svga_buffer *sbuf = svga_buffer(ib);
536 
537       assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_INDEX_BUFFER);
538       (void) sbuf; /* silence unused var warning */
539 
540       ib_handle = svga_buffer_handle(svga, ib);
541       if (!ib_handle)
542          return PIPE_ERROR_OUT_OF_MEMORY;
543    }
544    else {
545       ib_handle = NULL;
546    }
547 
548    /* setup vertex attribute input layout */
549    if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) {
550       ret = SVGA3D_vgpu10_SetInputLayout(svga->swc,
551                                          hwtnl->cmd.vdecl_layout_id);
552       if (ret != PIPE_OK)
553          return ret;
554 
555       svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id;
556    }
557 
558    /* setup vertex buffers */
559    {
560       SVGA3dVertexBuffer vbuffer_attrs[PIPE_MAX_ATTRIBS];
561 
562       for (i = 0; i < vbuf_count; i++) {
563          vbuffer_attrs[i].stride = hwtnl->cmd.vbufs[i].stride;
564          vbuffer_attrs[i].offset = hwtnl->cmd.vbufs[i].buffer_offset;
565          vbuffer_attrs[i].sid = 0;
566       }
567 
568       /* If we haven't yet emitted a drawing command or if any
569        * vertex buffer state is changing, issue that state now.
570        */
571       if (((hwtnl->cmd.swc->hints & SVGA_HINT_FLAG_CAN_PRE_FLUSH) == 0) ||
572           vbuf_count != svga->state.hw_draw.num_vbuffers ||
573           memcmp(vbuffer_attrs, svga->state.hw_draw.vbuffer_attrs,
574                  vbuf_count * sizeof(vbuffer_attrs[0])) ||
575           memcmp(vbuffers, svga->state.hw_draw.vbuffers,
576                  vbuf_count * sizeof(vbuffers[0]))) {
577 
578          unsigned num_vbuffers;
579 
580          /* get the max of the current bound vertex buffers count and
581           * the to-be-bound vertex buffers count, so as to unbind
582           * the unused vertex buffers.
583           */
584          num_vbuffers = MAX2(vbuf_count, svga->state.hw_draw.num_vbuffers);
585 
586          if (num_vbuffers > 0) {
587 
588             ret = SVGA3D_vgpu10_SetVertexBuffers(svga->swc, num_vbuffers,
589                                                  0,    /* startBuffer */
590                                                  vbuffer_attrs,
591                                                  vbuffer_handles);
592             if (ret != PIPE_OK)
593                return ret;
594 
595             /* save the number of vertex buffers sent to the device, not
596              * including trailing unbound vertex buffers.
597              */
598             svga->state.hw_draw.num_vbuffers = last_vbuf + 1;
599             memcpy(svga->state.hw_draw.vbuffer_attrs, vbuffer_attrs,
600                    num_vbuffers * sizeof(vbuffer_attrs[0]));
601             for (i = 0; i < num_vbuffers; i++) {
602                pipe_resource_reference(&svga->state.hw_draw.vbuffers[i],
603                                        vbuffers[i]);
604             }
605          }
606       }
607       else {
608          /* Even though we can avoid emitting the redundant SetVertexBuffers
609           * command, we still need to reference the vertex buffers surfaces.
610           */
611          for (i = 0; i < vbuf_count; i++) {
612             if (vbuffer_handles[i] && !last_command_was_draw(svga)) {
613                ret = svga->swc->resource_rebind(svga->swc, vbuffer_handles[i],
614                                                 NULL, SVGA_RELOC_READ);
615                if (ret != PIPE_OK)
616                   return ret;
617             }
618          }
619       }
620    }
621 
622    /* Set primitive type (line, tri, etc) */
623    if (svga->state.hw_draw.topology != range->primType) {
624       ret = SVGA3D_vgpu10_SetTopology(svga->swc, range->primType);
625       if (ret != PIPE_OK)
626          return ret;
627 
628       svga->state.hw_draw.topology = range->primType;
629    }
630 
631    if (ib_handle) {
632       /* indexed drawing */
633       SVGA3dSurfaceFormat indexFormat = xlate_index_format(range->indexWidth);
634 
635       /* setup index buffer */
636       if (ib != svga->state.hw_draw.ib ||
637           indexFormat != svga->state.hw_draw.ib_format ||
638           range->indexArray.offset != svga->state.hw_draw.ib_offset) {
639 
640          assert(indexFormat != SVGA3D_FORMAT_INVALID);
641          ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, ib_handle,
642                                             indexFormat,
643                                             range->indexArray.offset);
644          if (ret != PIPE_OK)
645             return ret;
646 
647          pipe_resource_reference(&svga->state.hw_draw.ib, ib);
648          svga->state.hw_draw.ib_format = indexFormat;
649          svga->state.hw_draw.ib_offset = range->indexArray.offset;
650       }
651       else {
652          /* Even though we can avoid emitting the redundant SetIndexBuffer
653           * command, we still need to reference the index buffer surface.
654           */
655          if (!last_command_was_draw(svga)) {
656             ret = svga->swc->resource_rebind(svga->swc, ib_handle,
657                                              NULL, SVGA_RELOC_READ);
658             if (ret != PIPE_OK)
659                return ret;
660          }
661       }
662 
663       if (instance_count > 1) {
664          ret = SVGA3D_vgpu10_DrawIndexedInstanced(svga->swc,
665                                                   vcount,
666                                                   instance_count,
667                                                   0, /* startIndexLocation */
668                                                   range->indexBias,
669                                                   start_instance);
670          if (ret != PIPE_OK)
671             return ret;
672       }
673       else {
674          /* non-instanced drawing */
675          ret = SVGA3D_vgpu10_DrawIndexed(svga->swc,
676                                          vcount,
677                                          0,      /* startIndexLocation */
678                                          range->indexBias);
679          if (ret != PIPE_OK)
680             return ret;
681       }
682    }
683    else {
684       /* non-indexed drawing */
685       if (svga->state.hw_draw.ib_format != SVGA3D_FORMAT_INVALID ||
686           svga->state.hw_draw.ib != NULL) {
687          /* Unbind previously bound index buffer */
688          ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, NULL,
689                                             SVGA3D_FORMAT_INVALID, 0);
690          if (ret != PIPE_OK)
691             return ret;
692          pipe_resource_reference(&svga->state.hw_draw.ib, NULL);
693          svga->state.hw_draw.ib_format = SVGA3D_FORMAT_INVALID;
694       }
695 
696       assert(svga->state.hw_draw.ib == NULL);
697 
698       if (instance_count > 1) {
699          ret = SVGA3D_vgpu10_DrawInstanced(svga->swc,
700                                            vcount,
701                                            instance_count,
702                                            range->indexBias,
703                                            start_instance);
704          if (ret != PIPE_OK)
705             return ret;
706       }
707       else {
708          /* non-instanced */
709          ret = SVGA3D_vgpu10_Draw(svga->swc,
710                                   vcount,
711                                   range->indexBias);
712          if (ret != PIPE_OK)
713             return ret;
714       }
715    }
716 
717    hwtnl->cmd.prim_count = 0;
718 
719    return PIPE_OK;
720 }
721 
722 
723 
724 /**
725  * Emit any pending drawing commands to the command buffer.
726  * When we receive VGPU9 drawing commands we accumulate them and don't
727  * immediately emit them into the command buffer.
728  * This function needs to be called before we change state that could
729  * effect those pending draws.
730  */
731 enum pipe_error
svga_hwtnl_flush(struct svga_hwtnl * hwtnl)732 svga_hwtnl_flush(struct svga_hwtnl *hwtnl)
733 {
734    enum pipe_error ret = PIPE_OK;
735 
736    SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLFLUSH);
737 
738    if (!svga_have_vgpu10(hwtnl->svga) && hwtnl->cmd.prim_count) {
739       /* we only queue up primitive for VGPU9 */
740       ret = draw_vgpu9(hwtnl);
741    }
742 
743    SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
744    return ret;
745 }
746 
747 
748 void
svga_hwtnl_set_index_bias(struct svga_hwtnl * hwtnl,int index_bias)749 svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias)
750 {
751    hwtnl->index_bias = index_bias;
752 }
753 
754 
755 
756 /***********************************************************************
757  * Internal functions:
758  */
759 
760 /**
761  * For debugging only.
762  */
763 static void
check_draw_params(struct svga_hwtnl * hwtnl,const SVGA3dPrimitiveRange * range,unsigned min_index,unsigned max_index,struct pipe_resource * ib)764 check_draw_params(struct svga_hwtnl *hwtnl,
765                   const SVGA3dPrimitiveRange *range,
766                   unsigned min_index, unsigned max_index,
767                   struct pipe_resource *ib)
768 {
769    unsigned i;
770 
771    assert(!svga_have_vgpu10(hwtnl->svga));
772 
773    for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
774       unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
775       const struct pipe_vertex_buffer *vb = &hwtnl->cmd.vbufs[j];
776       unsigned size = vb->buffer ? vb->buffer->width0 : 0;
777       unsigned offset = hwtnl->cmd.vdecl[i].array.offset;
778       unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
779       int index_bias = (int) range->indexBias + hwtnl->index_bias;
780       unsigned width;
781 
782       if (size == 0)
783          continue;
784 
785       assert(vb);
786       assert(size);
787       assert(offset < size);
788       assert(min_index <= max_index);
789       (void) width;
790       (void) stride;
791       (void) offset;
792       (void) size;
793 
794       switch (hwtnl->cmd.vdecl[i].identity.type) {
795       case SVGA3D_DECLTYPE_FLOAT1:
796          width = 4;
797          break;
798       case SVGA3D_DECLTYPE_FLOAT2:
799          width = 4 * 2;
800          break;
801       case SVGA3D_DECLTYPE_FLOAT3:
802          width = 4 * 3;
803          break;
804       case SVGA3D_DECLTYPE_FLOAT4:
805          width = 4 * 4;
806          break;
807       case SVGA3D_DECLTYPE_D3DCOLOR:
808          width = 4;
809          break;
810       case SVGA3D_DECLTYPE_UBYTE4:
811          width = 1 * 4;
812          break;
813       case SVGA3D_DECLTYPE_SHORT2:
814          width = 2 * 2;
815          break;
816       case SVGA3D_DECLTYPE_SHORT4:
817          width = 2 * 4;
818          break;
819       case SVGA3D_DECLTYPE_UBYTE4N:
820          width = 1 * 4;
821          break;
822       case SVGA3D_DECLTYPE_SHORT2N:
823          width = 2 * 2;
824          break;
825       case SVGA3D_DECLTYPE_SHORT4N:
826          width = 2 * 4;
827          break;
828       case SVGA3D_DECLTYPE_USHORT2N:
829          width = 2 * 2;
830          break;
831       case SVGA3D_DECLTYPE_USHORT4N:
832          width = 2 * 4;
833          break;
834       case SVGA3D_DECLTYPE_UDEC3:
835          width = 4;
836          break;
837       case SVGA3D_DECLTYPE_DEC3N:
838          width = 4;
839          break;
840       case SVGA3D_DECLTYPE_FLOAT16_2:
841          width = 2 * 2;
842          break;
843       case SVGA3D_DECLTYPE_FLOAT16_4:
844          width = 2 * 4;
845          break;
846       default:
847          assert(0);
848          width = 0;
849          break;
850       }
851 
852       if (index_bias >= 0) {
853          assert(offset + index_bias * stride + width <= size);
854       }
855 
856       /*
857        * min_index/max_index are merely conservative guesses, so we can't
858        * make buffer overflow detection based on their values.
859        */
860    }
861 
862    assert(range->indexWidth == range->indexArray.stride);
863 
864    if (ib) {
865       MAYBE_UNUSED unsigned size = ib->width0;
866       MAYBE_UNUSED unsigned offset = range->indexArray.offset;
867       MAYBE_UNUSED unsigned stride = range->indexArray.stride;
868       MAYBE_UNUSED unsigned count;
869 
870       assert(size);
871       assert(offset < size);
872       assert(stride);
873 
874       switch (range->primType) {
875       case SVGA3D_PRIMITIVE_POINTLIST:
876          count = range->primitiveCount;
877          break;
878       case SVGA3D_PRIMITIVE_LINELIST:
879          count = range->primitiveCount * 2;
880          break;
881       case SVGA3D_PRIMITIVE_LINESTRIP:
882          count = range->primitiveCount + 1;
883          break;
884       case SVGA3D_PRIMITIVE_TRIANGLELIST:
885          count = range->primitiveCount * 3;
886          break;
887       case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
888          count = range->primitiveCount + 2;
889          break;
890       case SVGA3D_PRIMITIVE_TRIANGLEFAN:
891          count = range->primitiveCount + 2;
892          break;
893       default:
894          assert(0);
895          count = 0;
896          break;
897       }
898 
899       assert(offset + count * stride <= size);
900    }
901 }
902 
903 
904 /**
905  * All drawing filters down into this function, either directly
906  * on the hardware path or after doing software vertex processing.
907  */
908 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)909 svga_hwtnl_prim(struct svga_hwtnl *hwtnl,
910                 const SVGA3dPrimitiveRange * range,
911                 unsigned vcount,
912                 unsigned min_index,
913                 unsigned max_index, struct pipe_resource *ib,
914                 unsigned start_instance, unsigned instance_count)
915 {
916    enum pipe_error ret = PIPE_OK;
917 
918    SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLPRIM);
919 
920    if (svga_have_vgpu10(hwtnl->svga)) {
921       /* draw immediately */
922       ret = draw_vgpu10(hwtnl, range, vcount, min_index, max_index, ib,
923                         start_instance, instance_count);
924       if (ret != PIPE_OK) {
925          svga_context_flush(hwtnl->svga, NULL);
926          ret = draw_vgpu10(hwtnl, range, vcount, min_index, max_index, ib,
927                            start_instance, instance_count);
928          assert(ret == PIPE_OK);
929       }
930    }
931    else {
932       /* batch up drawing commands */
933 #ifdef DEBUG
934       check_draw_params(hwtnl, range, min_index, max_index, ib);
935       assert(start_instance == 0);
936       assert(instance_count <= 1);
937 #else
938       (void) check_draw_params;
939 #endif
940 
941       if (hwtnl->cmd.prim_count + 1 >= QSZ) {
942          ret = svga_hwtnl_flush(hwtnl);
943          if (ret != PIPE_OK)
944             goto done;
945       }
946 
947       /* min/max indices are relative to bias */
948       hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index;
949       hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index;
950 
951       hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range;
952       hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias;
953 
954       pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
955       hwtnl->cmd.prim_count++;
956    }
957 
958 done:
959    SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
960    return ret;
961 }
962