Home | History | Annotate | Download | only in svga
      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 *
     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
     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
     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
    108 svga_hwtnl_set_fillmode(struct svga_hwtnl *hwtnl, unsigned mode)
    109 {
    110    hwtnl->api_fillmode = mode;
    111 }
    112 
    113 
    114 void
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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