"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/svga/svga_state_constants.c" (16 Sep 2020, 25157 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "svga_state_constants.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 20.1.5_vs_20.2.0-rc1.

    1 
    2 /**********************************************************
    3  * Copyright 2008-2009 VMware, Inc.  All rights reserved.
    4  *
    5  * Permission is hereby granted, free of charge, to any person
    6  * obtaining a copy of this software and associated documentation
    7  * files (the "Software"), to deal in the Software without
    8  * restriction, including without limitation the rights to use, copy,
    9  * modify, merge, publish, distribute, sublicense, and/or sell copies
   10  * of the Software, and to permit persons to whom the Software is
   11  * furnished to do so, subject to the following conditions:
   12  *
   13  * The above copyright notice and this permission notice shall be
   14  * included in all copies or substantial portions of the Software.
   15  *
   16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   23  * SOFTWARE.
   24  *
   25  **********************************************************/
   26 
   27 #include "util/format/u_format.h"
   28 #include "util/u_inlines.h"
   29 #include "util/u_memory.h"
   30 #include "pipe/p_defines.h"
   31 #include "util/u_upload_mgr.h"
   32 
   33 #include "svga_screen.h"
   34 #include "svga_context.h"
   35 #include "svga_state.h"
   36 #include "svga_cmd.h"
   37 #include "svga_tgsi.h"
   38 #include "svga_debug.h"
   39 #include "svga_resource_buffer.h"
   40 #include "svga_shader.h"
   41 
   42 #include "svga_hw_reg.h"
   43 
   44 
   45 /*
   46  * Don't try to send more than 4kb of successive constants.
   47  */
   48 #define MAX_CONST_REG_COUNT 256  /**< number of float[4] constants */
   49 
   50 /**
   51  * Extra space for svga-specific VS/PS constants (such as texcoord
   52  * scale factors, vertex transformation scale/translation).
   53  */
   54 #define MAX_EXTRA_CONSTS 32
   55 
   56 /** Guest-backed surface constant buffers must be this size */
   57 #define GB_CONSTBUF_SIZE (SVGA3D_CONSTREG_MAX)
   58 
   59 
   60 /**
   61  * Emit any extra shader-type-independent shader constants into the buffer
   62  * pointed to by 'dest'.
   63  * \return number of float[4] constants put into the 'dest' buffer
   64  */
   65 static unsigned
   66 svga_get_extra_constants_common(const struct svga_context *svga,
   67                                 const struct svga_shader_variant *variant,
   68                                 enum pipe_shader_type shader, float *dest)
   69 {
   70    uint32_t *dest_u = (uint32_t *) dest;  // uint version of dest
   71    unsigned i;
   72    unsigned count = 0;
   73 
   74    for (i = 0; i < variant->key.num_textures; i++) {
   75       const struct pipe_sampler_view *sv = svga->curr.sampler_views[shader][i];
   76       if (sv) {
   77          const struct pipe_resource *tex = sv->texture;
   78          /* Scaling factors needed for handling unnormalized texture coordinates
   79           * for texture rectangles.
   80           */
   81          if (variant->key.tex[i].unnormalized) {
   82             /* debug/sanity check */
   83             assert(variant->key.tex[i].width_height_idx == count);
   84 
   85             *dest++ = 1.0f / (float) tex->width0;
   86             *dest++ = 1.0f / (float) tex->height0;
   87             *dest++ = 1.0f;
   88             *dest++ = 1.0f;
   89 
   90             count++;
   91          }
   92 
   93          /* Store the sizes for texture buffers.
   94          */
   95          if (tex->target == PIPE_BUFFER) {
   96             unsigned bytes_per_element = util_format_get_blocksize(sv->format);
   97             *dest_u++ = tex->width0 / bytes_per_element;
   98             *dest_u++ = 1;
   99             *dest_u++ = 1;
  100             *dest_u++ = 1;
  101 
  102             count++;
  103          }
  104       }
  105    }
  106 
  107    return count;
  108 }
  109 
  110 
  111 /**
  112  * Emit any extra fragment shader constants into the buffer pointed
  113  * to by 'dest'.
  114  * \return number of float[4] constants put into the dest buffer
  115  */
  116 static unsigned
  117 svga_get_extra_fs_constants(const struct svga_context *svga, float *dest)
  118 {
  119    const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
  120    unsigned count = 0;
  121 
  122    count += svga_get_extra_constants_common(svga, variant,
  123                                             PIPE_SHADER_FRAGMENT, dest);
  124 
  125    assert(count <= MAX_EXTRA_CONSTS);
  126 
  127    return count;
  128 }
  129 
  130 /**
  131  * Emit extra constants needed for prescale computation into the
  132  * the buffer pointed to by '*dest'. The updated buffer pointer
  133  * will be returned in 'dest'.
  134  */
  135 static unsigned
  136 svga_get_prescale_constants(const struct svga_context *svga, float **dest)
  137 {
  138    memcpy(*dest, svga->state.hw_clear.prescale.scale, 4 * sizeof(float));
  139    *dest += 4;
  140 
  141    memcpy(*dest, svga->state.hw_clear.prescale.translate, 4 * sizeof(float));
  142    *dest += 4;
  143 
  144    return 2;
  145 }
  146 
  147 /**
  148  * Emit extra constants needed for point sprite emulation.
  149  */
  150 static unsigned
  151 svga_get_pt_sprite_constants(const struct svga_context *svga, float **dest)
  152 {
  153    const struct svga_screen *screen = svga_screen(svga->pipe.screen);
  154    float *dst = *dest;
  155 
  156    dst[0] = 1.0 / (svga->curr.viewport.scale[0] * 2);
  157    dst[1] = 1.0 / (svga->curr.viewport.scale[1] * 2);
  158    dst[2] = svga->curr.rast->pointsize;
  159    dst[3] = screen->maxPointSize;
  160    *dest = *dest + 4;
  161    return 1;
  162 }
  163 
  164 /**
  165  * Emit user-defined clip plane coefficients into the buffer pointed to
  166  * by '*dest'. The updated buffer pointer will be returned in 'dest'.
  167  */
  168 static unsigned
  169 svga_get_clip_plane_constants(const struct svga_context *svga,
  170                               const struct svga_shader_variant *variant,
  171                               float **dest)
  172 {
  173    unsigned count = 0;
  174 
  175    /* SVGA_NEW_CLIP */
  176    if (svga_have_vgpu10(svga)) {
  177       /* append user-defined clip plane coefficients onto constant buffer */
  178       unsigned clip_planes = variant->key.clip_plane_enable;
  179       while (clip_planes) {
  180          int i = u_bit_scan(&clip_planes);
  181          COPY_4V(*dest, svga->curr.clip.ucp[i]);
  182          *dest += 4;
  183          count += 1;
  184       }
  185    }
  186    return count;
  187 }
  188 
  189 /**
  190  * Emit any extra vertex shader constants into the buffer pointed
  191  * to by 'dest'.
  192  * In particular, these would be the scale and bias factors computed
  193  * from the framebuffer size which are used to copy with differences in
  194  * GL vs D3D coordinate spaces.  See svga_tgsi_insn.c for more info.
  195  * \return number of float[4] constants put into the dest buffer
  196  */
  197 static unsigned
  198 svga_get_extra_vs_constants(const struct svga_context *svga, float *dest)
  199 {
  200    const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
  201    unsigned count = 0;
  202 
  203    /* SVGA_NEW_VS_VARIANT
  204     */
  205    if (variant->key.vs.need_prescale) {
  206       count += svga_get_prescale_constants(svga, &dest);
  207    }
  208 
  209    if (variant->key.vs.undo_viewport) {
  210       /* Used to convert window coords back to NDC coords */
  211       dest[0] = 1.0f / svga->curr.viewport.scale[0];
  212       dest[1] = 1.0f / svga->curr.viewport.scale[1];
  213       dest[2] = -svga->curr.viewport.translate[0];
  214       dest[3] = -svga->curr.viewport.translate[1];
  215       dest += 4;
  216       count += 1;
  217    }
  218 
  219    /* SVGA_NEW_CLIP */
  220    count += svga_get_clip_plane_constants(svga, variant, &dest);
  221 
  222    /* common constants */
  223    count += svga_get_extra_constants_common(svga, variant,
  224                                             PIPE_SHADER_VERTEX, dest);
  225 
  226    assert(count <= MAX_EXTRA_CONSTS);
  227 
  228    return count;
  229 }
  230 
  231 /**
  232  * Emit any extra geometry shader constants into the buffer pointed
  233  * to by 'dest'.
  234  */
  235 static unsigned
  236 svga_get_extra_gs_constants(const struct svga_context *svga, float *dest)
  237 {
  238    const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
  239    unsigned count = 0;
  240 
  241    /* SVGA_NEW_GS_VARIANT
  242     */
  243 
  244    /* Constants for point sprite
  245     * These are used in the transformed gs that supports point sprite.
  246     * They need to be added before the prescale constants.
  247     */
  248    if (variant->key.gs.wide_point) {
  249       count += svga_get_pt_sprite_constants(svga, &dest);
  250    }
  251 
  252    if (variant->key.gs.need_prescale) {
  253       count += svga_get_prescale_constants(svga, &dest);
  254    }
  255 
  256    /* SVGA_NEW_CLIP */
  257    count += svga_get_clip_plane_constants(svga, variant, &dest);
  258 
  259    /* common constants */
  260    count += svga_get_extra_constants_common(svga, variant,
  261                                             PIPE_SHADER_GEOMETRY, dest);
  262 
  263    assert(count <= MAX_EXTRA_CONSTS);
  264    return count;
  265 }
  266 
  267 
  268 /*
  269  * Check and emit a range of shader constant registers, trying to coalesce
  270  * successive shader constant updates in a single command in order to save
  271  * space on the command buffer.  This is a HWv8 feature.
  272  */
  273 static enum pipe_error
  274 emit_const_range(struct svga_context *svga,
  275                  enum pipe_shader_type shader,
  276                  unsigned offset,
  277                  unsigned count,
  278                  const float (*values)[4])
  279 {
  280    unsigned i, j;
  281    enum pipe_error ret;
  282 
  283    assert(shader == PIPE_SHADER_VERTEX ||
  284           shader == PIPE_SHADER_FRAGMENT);
  285    assert(!svga_have_vgpu10(svga));
  286 
  287 #ifdef DEBUG
  288    if (offset + count > SVGA3D_CONSTREG_MAX) {
  289       debug_printf("svga: too many constants (offset %u + count %u = %u (max = %u))\n",
  290                    offset, count, offset + count, SVGA3D_CONSTREG_MAX);
  291    }
  292 #endif
  293 
  294    if (offset > SVGA3D_CONSTREG_MAX) {
  295       /* This isn't OK, but if we propagate an error all the way up we'll
  296        * just get into more trouble.
  297        * XXX note that offset is always zero at this time so this is moot.
  298        */
  299       return PIPE_OK;
  300    }
  301 
  302    if (offset + count > SVGA3D_CONSTREG_MAX) {
  303       /* Just drop the extra constants for now.
  304        * Ideally we should not have allowed the app to create a shader
  305        * that exceeds our constant buffer size but there's no way to
  306        * express that in gallium at this time.
  307        */
  308       count = SVGA3D_CONSTREG_MAX - offset;
  309    }
  310 
  311    i = 0;
  312    while (i < count) {
  313       if (memcmp(svga->state.hw_draw.cb[shader][offset + i],
  314                  values[i],
  315                  4 * sizeof(float)) != 0) {
  316          /* Found one dirty constant
  317           */
  318          if (SVGA_DEBUG & DEBUG_CONSTS)
  319             debug_printf("%s %s %d: %f %f %f %f\n",
  320                          __FUNCTION__,
  321                          shader == PIPE_SHADER_VERTEX ? "VERT" : "FRAG",
  322                          offset + i,
  323                          values[i][0],
  324                          values[i][1],
  325                          values[i][2],
  326                          values[i][3]);
  327 
  328          /* Look for more consecutive dirty constants.
  329           */
  330          j = i + 1;
  331          while (j < count &&
  332                 j < i + MAX_CONST_REG_COUNT &&
  333                 memcmp(svga->state.hw_draw.cb[shader][offset + j],
  334                        values[j],
  335                        4 * sizeof(float)) != 0) {
  336 
  337             if (SVGA_DEBUG & DEBUG_CONSTS)
  338                debug_printf("%s %s %d: %f %f %f %f\n",
  339                             __FUNCTION__,
  340                             shader == PIPE_SHADER_VERTEX ? "VERT" : "FRAG",
  341                             offset + j,
  342                             values[j][0],
  343                             values[j][1],
  344                             values[j][2],
  345                             values[j][3]);
  346 
  347             ++j;
  348          }
  349 
  350          assert(j >= i + 1);
  351 
  352          /* Send them all together.
  353           */
  354          if (svga_have_gb_objects(svga)) {
  355             ret = SVGA3D_SetGBShaderConstsInline(svga->swc,
  356                                                  offset + i, /* start */
  357                                                  j - i,  /* count */
  358                                                  svga_shader_type(shader),
  359                                                  SVGA3D_CONST_TYPE_FLOAT,
  360                                                  values + i);
  361          }
  362          else {
  363             ret = SVGA3D_SetShaderConsts(svga->swc,
  364                                          offset + i, j - i,
  365                                          svga_shader_type(shader),
  366                                          SVGA3D_CONST_TYPE_FLOAT,
  367                                          values + i);
  368          }
  369          if (ret != PIPE_OK) {
  370             return ret;
  371          }
  372 
  373          /*
  374           * Local copy of the hardware state.
  375           */
  376          memcpy(svga->state.hw_draw.cb[shader][offset + i],
  377                 values[i],
  378                 (j - i) * 4 * sizeof(float));
  379 
  380          i = j + 1;
  381 
  382          svga->hud.num_const_updates++;
  383 
  384       } else {
  385          ++i;
  386       }
  387    }
  388 
  389    return PIPE_OK;
  390 }
  391 
  392 
  393 /**
  394  * Emit all the constants in a constant buffer for a shader stage.
  395  * On VGPU10, emit_consts_vgpu10 is used instead.
  396  */
  397 static enum pipe_error
  398 emit_consts_vgpu9(struct svga_context *svga, enum pipe_shader_type shader)
  399 {
  400    const struct pipe_constant_buffer *cbuf;
  401    struct pipe_transfer *transfer = NULL;
  402    unsigned count;
  403    const float (*data)[4] = NULL;
  404    enum pipe_error ret = PIPE_OK;
  405    const unsigned offset = 0;
  406 
  407    assert(shader < PIPE_SHADER_TYPES);
  408    assert(!svga_have_vgpu10(svga));
  409    /* Only one constant buffer per shader is supported before VGPU10.
  410     * This is only an approximate check against that.
  411     */
  412    assert(svga->curr.constbufs[shader][1].buffer == NULL);
  413 
  414    cbuf = &svga->curr.constbufs[shader][0];
  415 
  416    if (svga->curr.constbufs[shader][0].buffer) {
  417       /* emit user-provided constants */
  418       data = (const float (*)[4])
  419          pipe_buffer_map(&svga->pipe, svga->curr.constbufs[shader][0].buffer,
  420                          PIPE_TRANSFER_READ, &transfer);
  421       if (!data) {
  422          return PIPE_ERROR_OUT_OF_MEMORY;
  423       }
  424 
  425       /* sanity check */
  426       assert(cbuf->buffer->width0 >= cbuf->buffer_size);
  427 
  428       /* Use/apply the constant buffer size and offsets here */
  429       count = cbuf->buffer_size / (4 * sizeof(float));
  430       data += cbuf->buffer_offset / (4 * sizeof(float));
  431 
  432       ret = emit_const_range( svga, shader, offset, count, data );
  433 
  434       pipe_buffer_unmap(&svga->pipe, transfer);
  435 
  436       if (ret != PIPE_OK) {
  437          return ret;
  438       }
  439    }
  440 
  441    /* emit extra shader constants */
  442    {
  443       const struct svga_shader_variant *variant = NULL;
  444       unsigned offset;
  445       float extras[MAX_EXTRA_CONSTS][4];
  446       unsigned count;
  447 
  448       switch (shader) {
  449       case PIPE_SHADER_VERTEX:
  450          variant = svga->state.hw_draw.vs;
  451          count = svga_get_extra_vs_constants(svga, (float *) extras);
  452          break;
  453       case PIPE_SHADER_FRAGMENT:
  454          variant = svga->state.hw_draw.fs;
  455          count = svga_get_extra_fs_constants(svga, (float *) extras);
  456          break;
  457       default:
  458          assert(!"Unexpected shader type");
  459          count = 0;
  460       }
  461 
  462       assert(variant);
  463       offset = variant->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
  464       assert(count <= ARRAY_SIZE(extras));
  465 
  466       if (count > 0) {
  467          ret = emit_const_range(svga, shader, offset, count,
  468                                 (const float (*) [4])extras);
  469       }
  470    }
  471 
  472    return ret;
  473 }
  474 
  475 
  476 
  477 static enum pipe_error
  478 emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
  479 {
  480    const struct pipe_constant_buffer *cbuf;
  481    struct pipe_resource *dst_buffer = NULL;
  482    enum pipe_error ret = PIPE_OK;
  483    struct pipe_transfer *src_transfer;
  484    struct svga_winsys_surface *dst_handle;
  485    float extras[MAX_EXTRA_CONSTS][4];
  486    unsigned extra_count, extra_size, extra_offset;
  487    unsigned new_buf_size;
  488    void *src_map = NULL, *dst_map;
  489    unsigned offset;
  490    const struct svga_shader_variant *variant;
  491    unsigned alloc_buf_size;
  492 
  493    switch (shader) {
  494    case PIPE_SHADER_VERTEX:
  495       variant = svga->state.hw_draw.vs;
  496       extra_count = svga_get_extra_vs_constants(svga, (float *) extras);
  497       break;
  498    case PIPE_SHADER_FRAGMENT:
  499       variant = svga->state.hw_draw.fs;
  500       extra_count = svga_get_extra_fs_constants(svga, (float *) extras);
  501       break;
  502    case PIPE_SHADER_GEOMETRY:
  503       variant = svga->state.hw_draw.gs;
  504       extra_count = svga_get_extra_gs_constants(svga, (float *) extras);
  505       break;
  506    default:
  507       assert(!"Unexpected shader type");
  508       /* Don't return an error code since we don't want to keep re-trying
  509        * this function and getting stuck in an infinite loop.
  510        */
  511       return PIPE_OK;
  512    }
  513 
  514    assert(variant);
  515 
  516    cbuf = &svga->curr.constbufs[shader][0];
  517 
  518    /* Compute extra constants size and offset in bytes */
  519    extra_size = extra_count * 4 * sizeof(float);
  520    extra_offset = 4 * sizeof(float) * variant->extra_const_start;
  521 
  522    if (cbuf->buffer_size + extra_size == 0)
  523       return PIPE_OK;  /* nothing to do */
  524 
  525    /* Typically, the cbuf->buffer here is a user-space buffer so mapping
  526     * it is really cheap.  If we ever get real HW buffers for constants
  527     * we should void mapping and instead use a ResourceCopy command.
  528     */
  529    if (cbuf->buffer_size > 0) {
  530       src_map = pipe_buffer_map_range(&svga->pipe, cbuf->buffer,
  531                                       cbuf->buffer_offset, cbuf->buffer_size,
  532                                       PIPE_TRANSFER_READ, &src_transfer);
  533       assert(src_map);
  534       if (!src_map) {
  535          return PIPE_ERROR_OUT_OF_MEMORY;
  536       }
  537    }
  538 
  539    /* The new/dest buffer's size must be large enough to hold the original,
  540     * user-specified constants, plus the extra constants.
  541     * The size of the original constant buffer _should_ agree with what the
  542     * shader is expecting, but it might not (it's not enforced anywhere by
  543     * gallium).
  544     */
  545    new_buf_size = MAX2(cbuf->buffer_size, extra_offset) + extra_size;
  546 
  547    /* According to the DX10 spec, the constant buffer size must be
  548     * in multiples of 16.
  549     */
  550    new_buf_size = align(new_buf_size, 16);
  551 
  552    /* Constant buffer size in the upload buffer must be in multiples of 256.
  553     * In order to maximize the chance of merging the upload buffer chunks
  554     * when svga_buffer_add_range() is called,
  555     * the allocate buffer size needs to be in multiples of 256 as well.
  556     * Otherwise, since there is gap between each dirty range of the upload buffer,
  557     * each dirty range will end up in its own UPDATE_GB_IMAGE command.
  558     */
  559    alloc_buf_size = align(new_buf_size, CONST0_UPLOAD_ALIGNMENT);
  560 
  561    u_upload_alloc(svga->const0_upload, 0, alloc_buf_size,
  562                   CONST0_UPLOAD_ALIGNMENT, &offset,
  563                   &dst_buffer, &dst_map);
  564    if (!dst_map) {
  565       if (src_map)
  566          pipe_buffer_unmap(&svga->pipe, src_transfer);
  567       return PIPE_ERROR_OUT_OF_MEMORY;
  568    }
  569 
  570    if (src_map) {
  571       memcpy(dst_map, src_map, cbuf->buffer_size);
  572       pipe_buffer_unmap(&svga->pipe, src_transfer);
  573    }
  574 
  575    if (extra_size) {
  576       assert(extra_offset + extra_size <= new_buf_size);
  577       memcpy((char *) dst_map + extra_offset, extras, extra_size);
  578    }
  579 
  580    /* Get winsys handle for the constant buffer */
  581    if (svga->state.hw_draw.const0_buffer == dst_buffer &&
  582        svga->state.hw_draw.const0_handle) {
  583       /* re-reference already mapped buffer */
  584       dst_handle = svga->state.hw_draw.const0_handle;
  585    }
  586    else {
  587       /* we must unmap the buffer before getting the winsys handle */
  588       u_upload_unmap(svga->const0_upload);
  589 
  590       dst_handle = svga_buffer_handle(svga, dst_buffer,
  591                                       PIPE_BIND_CONSTANT_BUFFER);
  592       if (!dst_handle) {
  593          pipe_resource_reference(&dst_buffer, NULL);
  594          return PIPE_ERROR_OUT_OF_MEMORY;
  595       }
  596 
  597       /* save the buffer / handle for next time */
  598       pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer);
  599       svga->state.hw_draw.const0_handle = dst_handle;
  600    }
  601 
  602    /* Issue the SetSingleConstantBuffer command */
  603    assert(new_buf_size % 16 == 0);
  604    ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
  605                                                0, /* index */
  606                                                svga_shader_type(shader),
  607                                                dst_handle,
  608                                                offset,
  609                                                new_buf_size);
  610 
  611    if (ret != PIPE_OK) {
  612       pipe_resource_reference(&dst_buffer, NULL);
  613       return ret;
  614    }
  615 
  616    /* Save this const buffer until it's replaced in the future.
  617     * Otherwise, all references to the buffer will go away after the
  618     * command buffer is submitted, it'll get recycled and we will have
  619     * incorrect constant buffer bindings.
  620     */
  621    pipe_resource_reference(&svga->state.hw_draw.constbuf[shader], dst_buffer);
  622 
  623    svga->state.hw_draw.default_constbuf_size[shader] = new_buf_size;
  624 
  625    pipe_resource_reference(&dst_buffer, NULL);
  626 
  627    svga->hud.num_const_buf_updates++;
  628 
  629    return ret;
  630 }
  631 
  632 
  633 static enum pipe_error
  634 emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
  635 {
  636    enum pipe_error ret;
  637    unsigned dirty_constbufs;
  638    unsigned enabled_constbufs;
  639 
  640    /* Emit 0th constant buffer (with extra constants) */
  641    ret = emit_constbuf_vgpu10(svga, shader);
  642    if (ret != PIPE_OK) {
  643       return ret;
  644    }
  645 
  646    enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] | 1u;
  647 
  648    /* Emit other constant buffers (UBOs) */
  649    dirty_constbufs = svga->state.dirty_constbufs[shader] & ~1u;
  650 
  651    while (dirty_constbufs) {
  652       unsigned index = u_bit_scan(&dirty_constbufs);
  653       unsigned offset = svga->curr.constbufs[shader][index].buffer_offset;
  654       unsigned size = svga->curr.constbufs[shader][index].buffer_size;
  655       struct svga_buffer *buffer =
  656          svga_buffer(svga->curr.constbufs[shader][index].buffer);
  657       struct svga_winsys_surface *handle;
  658 
  659       if (buffer) {
  660          handle = svga_buffer_handle(svga, &buffer->b.b,
  661                                      PIPE_BIND_CONSTANT_BUFFER);
  662          enabled_constbufs |= 1 << index;
  663       }
  664       else {
  665          handle = NULL;
  666          enabled_constbufs &= ~(1 << index);
  667          assert(offset == 0);
  668          assert(size == 0);
  669       }
  670 
  671       if (size % 16 != 0) {
  672          /* GL's buffer range sizes can be any number of bytes but the
  673           * SVGA3D device requires a multiple of 16 bytes.
  674           */
  675          const unsigned total_size = buffer->b.b.width0;
  676 
  677          if (offset + align(size, 16) <= total_size) {
  678             /* round up size to multiple of 16 */
  679             size = align(size, 16);
  680          }
  681          else {
  682             /* round down to mulitple of 16 (this may cause rendering problems
  683              * but should avoid a device error).
  684              */
  685             size &= ~15;
  686          }
  687       }
  688 
  689       assert(size % 16 == 0);
  690       ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
  691                                                   index,
  692                                                   svga_shader_type(shader),
  693                                                   handle,
  694                                                   offset,
  695                                                   size);
  696       if (ret != PIPE_OK)
  697          return ret;
  698 
  699       svga->hud.num_const_buf_updates++;
  700    }
  701 
  702    svga->state.hw_draw.enabled_constbufs[shader] = enabled_constbufs;
  703    svga->state.dirty_constbufs[shader] = 0;
  704 
  705    return ret;
  706 }
  707 
  708 static enum pipe_error
  709 emit_fs_consts(struct svga_context *svga, unsigned dirty)
  710 {
  711    const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
  712    enum pipe_error ret = PIPE_OK;
  713 
  714    /* SVGA_NEW_FS_VARIANT
  715     */
  716    if (!variant)
  717       return PIPE_OK;
  718 
  719    /* SVGA_NEW_FS_CONST_BUFFER
  720     */
  721    if (svga_have_vgpu10(svga)) {
  722       ret = emit_consts_vgpu10(svga, PIPE_SHADER_FRAGMENT);
  723    }
  724    else {
  725       ret = emit_consts_vgpu9(svga, PIPE_SHADER_FRAGMENT);
  726    }
  727 
  728    return ret;
  729 }
  730 
  731 
  732 struct svga_tracked_state svga_hw_fs_constants =
  733 {
  734    "hw fs params",
  735    (SVGA_NEW_FS_CONST_BUFFER |
  736     SVGA_NEW_FS_VARIANT |
  737     SVGA_NEW_TEXTURE_CONSTS),
  738    emit_fs_consts
  739 };
  740 
  741 
  742 
  743 static enum pipe_error
  744 emit_vs_consts(struct svga_context *svga, unsigned dirty)
  745 {
  746    const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
  747    enum pipe_error ret = PIPE_OK;
  748 
  749    /* SVGA_NEW_VS_VARIANT
  750     */
  751    if (!variant)
  752       return PIPE_OK;
  753 
  754    /* SVGA_NEW_VS_CONST_BUFFER
  755     */
  756    if (svga_have_vgpu10(svga)) {
  757       ret = emit_consts_vgpu10(svga, PIPE_SHADER_VERTEX);
  758    }
  759    else {
  760       ret = emit_consts_vgpu9(svga, PIPE_SHADER_VERTEX);
  761    }
  762 
  763    return ret;
  764 }
  765 
  766 
  767 struct svga_tracked_state svga_hw_vs_constants =
  768 {
  769    "hw vs params",
  770    (SVGA_NEW_PRESCALE |
  771     SVGA_NEW_VS_CONST_BUFFER |
  772     SVGA_NEW_VS_VARIANT |
  773     SVGA_NEW_TEXTURE_CONSTS),
  774    emit_vs_consts
  775 };
  776 
  777 
  778 static enum pipe_error
  779 emit_gs_consts(struct svga_context *svga, unsigned dirty)
  780 {
  781    const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
  782    enum pipe_error ret = PIPE_OK;
  783 
  784    /* SVGA_NEW_GS_VARIANT
  785     */
  786    if (!variant)
  787       return PIPE_OK;
  788 
  789    /* SVGA_NEW_GS_CONST_BUFFER
  790     */
  791    if (svga_have_vgpu10(svga)) {
  792       /**
  793        * If only the rasterizer state has changed and the current geometry
  794        * shader does not emit wide points, then there is no reason to
  795        * re-emit the GS constants, so skip it.
  796        */
  797       if (dirty == SVGA_NEW_RAST && !variant->key.gs.wide_point)
  798          return PIPE_OK;
  799 
  800       ret = emit_consts_vgpu10(svga, PIPE_SHADER_GEOMETRY);
  801    }
  802 
  803    return ret;
  804 }
  805 
  806 
  807 struct svga_tracked_state svga_hw_gs_constants =
  808 {
  809    "hw gs params",
  810    (SVGA_NEW_PRESCALE |
  811     SVGA_NEW_GS_CONST_BUFFER |
  812     SVGA_NEW_RAST |
  813     SVGA_NEW_GS_VARIANT |
  814     SVGA_NEW_TEXTURE_CONSTS),
  815    emit_gs_consts
  816 };