svga: Performance fixes
authorNeha Bhende <bhenden@vmware.com>
Tue, 26 May 2020 15:59:50 +0000 (21:29 +0530)
committerMarge Bot <eric+marge@anholt.net>
Fri, 5 Jun 2020 06:36:54 +0000 (06:36 +0000)
This is a squash commit of in house performance fixes and misc bug fixes
for GL4.1 support.

Performance fixes:
* started using system memory for constant buffer to gain 3X performance boost with metro redux

Misc bug fixes:
* fixed usage of vertexid in shader
* added empty control point phase in hull shader for zero ouput control point
* misc shader signature fixes
* fixed clip_distance input declaration
* clearing the dirty bit for the surface while using direct map if surface is already flushed
  and there is no pending primitive

This patch also uses SVGA_RETRY macro for commands retries. Part of it is already
used in previous patch.

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Charmaine Lee <charmainel@vmware.com>
Signed-off-by: Neha Bhende <bhenden@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5317>

41 files changed:
src/gallium/drivers/svga/svga_cmd.h
src/gallium/drivers/svga/svga_cmd_vgpu10.c
src/gallium/drivers/svga/svga_context.c
src/gallium/drivers/svga/svga_context.h
src/gallium/drivers/svga/svga_draw.c
src/gallium/drivers/svga/svga_link.c
src/gallium/drivers/svga/svga_link.h
src/gallium/drivers/svga/svga_pipe_constants.c
src/gallium/drivers/svga/svga_pipe_depthstencil.c
src/gallium/drivers/svga/svga_pipe_draw.c
src/gallium/drivers/svga/svga_pipe_fs.c
src/gallium/drivers/svga/svga_pipe_gs.c
src/gallium/drivers/svga/svga_pipe_query.c
src/gallium/drivers/svga/svga_pipe_rasterizer.c
src/gallium/drivers/svga/svga_pipe_sampler.c
src/gallium/drivers/svga/svga_pipe_streamout.c
src/gallium/drivers/svga/svga_pipe_vertex.c
src/gallium/drivers/svga/svga_pipe_vs.c
src/gallium/drivers/svga/svga_resource_buffer.c
src/gallium/drivers/svga/svga_resource_buffer.h
src/gallium/drivers/svga/svga_resource_buffer_upload.c
src/gallium/drivers/svga/svga_resource_texture.c
src/gallium/drivers/svga/svga_screen.c
src/gallium/drivers/svga/svga_screen_cache.c
src/gallium/drivers/svga/svga_screen_cache.h
src/gallium/drivers/svga/svga_shader.h
src/gallium/drivers/svga/svga_state.c
src/gallium/drivers/svga/svga_state.h
src/gallium/drivers/svga/svga_state_constants.c
src/gallium/drivers/svga/svga_state_fs.c
src/gallium/drivers/svga/svga_state_ts.c
src/gallium/drivers/svga/svga_state_vs.c
src/gallium/drivers/svga/svga_surface.c
src/gallium/drivers/svga/svga_swtnl_backend.c
src/gallium/drivers/svga/svga_swtnl_draw.c
src/gallium/drivers/svga/svga_tgsi_vgpu10.c
src/gallium/drivers/svga/svga_winsys.h
src/gallium/winsys/svga/drm/vmw_screen.c
src/gallium/winsys/svga/drm/vmw_screen_svga.c
src/gallium/winsys/svga/drm/vmw_surface.c
src/gallium/winsys/svga/drm/vmw_surface.h

index 22a40cf05cb30e76fc89eda7f99d2b4eaa2d7203..9247298733a488cb225cdf56485efe5d9b9fcb54 100644 (file)
@@ -656,6 +656,12 @@ SVGA3D_vgpu10_SetSingleConstantBuffer(struct svga_winsys_context *swc,
                                       uint32 offsetInBytes,
                                       uint32 sizeInBytes);
 
+enum pipe_error
+SVGA3D_vgpu10_SetConstantBufferOffset(struct svga_winsys_context *swc,
+                                      unsigned command,
+                                      unsigned slot,
+                                      uint32 offsetInBytes);
+
 enum pipe_error
 SVGA3D_vgpu10_UpdateSubResource(struct svga_winsys_context *swc,
                                 struct svga_winsys_surface *surface,
index eb5a482d9ba0360ed0e304138785d6b6c2e365e7..30e174a754affe14ad7b51e1d8271de670ee7695 100644 (file)
@@ -1264,6 +1264,31 @@ SVGA3D_vgpu10_SetSingleConstantBuffer(struct svga_winsys_context *swc,
 }
 
 
+enum pipe_error
+SVGA3D_vgpu10_SetConstantBufferOffset(struct svga_winsys_context *swc,
+                                      unsigned command,
+                                      unsigned slot,
+                                      uint32 offsetInBytes)
+{
+   SVGA3dCmdDXSetConstantBufferOffset *cmd;
+
+   assert(offsetInBytes % 256 == 0);
+
+   cmd = SVGA3D_FIFOReserve(swc, command,
+                            sizeof(SVGA3dCmdDXSetConstantBufferOffset),
+                            0);  /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->slot = slot;
+   cmd->offsetInBytes = offsetInBytes;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
 enum pipe_error
 SVGA3D_vgpu10_ReadbackSubResource(struct svga_winsys_context *swc,
                                   struct svga_winsys_surface *surface,
index 4ef99efe9897d43f8c63231fbb07b7853a466f78..d80336cf785938c28f70445c5be541d1e072ccf0 100644 (file)
@@ -75,7 +75,9 @@ svga_destroy(struct pipe_context *pipe)
 
    /* free HW constant buffers */
    for (shader = 0; shader < ARRAY_SIZE(svga->state.hw_draw.constbuf); shader++) {
-      pipe_resource_reference(&svga->state.hw_draw.constbuf[shader], NULL);
+      for (i = 0; i < ARRAY_SIZE(svga->state.hw_draw.constbuf[0]); i++) {
+         pipe_resource_reference(&svga->state.hw_draw.constbuf[shader][i], NULL);
+      }
    }
 
    pipe->delete_blend_state(pipe, svga->noop_blend);
index c0c315119f64bb1263365fead7ae9bd69952f909..4d3a9f101dc1f42fff9aff12b0f61cb2521550aa 100644 (file)
@@ -258,6 +258,10 @@ struct svga_velems_state {
    SVGA3dElementLayoutId id; /**< VGPU10 */
 };
 
+struct svga_constant_buffer {
+   struct svga_winsys_surface *handle;
+   unsigned size;
+};
 
 /* Use to calculate differences between state emitted to hardware and
  * current driver-calculated state.
@@ -308,6 +312,8 @@ struct svga_state
    unsigned num_vertex_buffers;
    enum pipe_prim_type reduced_prim;
 
+   unsigned vertex_id_bias;
+
    struct {
       unsigned flag_1d;
       unsigned flag_srgb;
@@ -391,7 +397,8 @@ struct svga_hw_draw_state
    struct svga_shader_variant *cs;
 
    /** Currently bound constant buffer, per shader stage */
-   struct pipe_resource *constbuf[PIPE_SHADER_TYPES];
+   struct pipe_resource *constbuf[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
+   struct svga_constant_buffer constbufoffsets[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
 
    /** Bitmask of enabled constant buffers */
    unsigned enabled_constbufs[PIPE_SHADER_TYPES];
@@ -699,8 +706,18 @@ struct svga_context
 #define SVGA_NEW_TCS_CONST_BUFFER    ((uint64_t) 0x1000000000)
 #define SVGA_NEW_TES_CONST_BUFFER    ((uint64_t) 0x2000000000)
 #define SVGA_NEW_TCS_PARAM           ((uint64_t) 0x4000000000)
+#define SVGA_NEW_FS_CONSTS           ((uint64_t) 0x8000000000)
+#define SVGA_NEW_VS_CONSTS           ((uint64_t) 0x10000000000)
+#define SVGA_NEW_GS_CONSTS           ((uint64_t) 0x20000000000)
+#define SVGA_NEW_TCS_CONSTS          ((uint64_t) 0x40000000000)
+#define SVGA_NEW_TES_CONSTS          ((uint64_t) 0x800000000000)
 #define SVGA_NEW_ALL                 ((uint64_t) 0xFFFFFFFFFFFFFFFF)
 
+#define SVGA_NEW_CONST_BUFFER \
+   (SVGA_NEW_FS_CONST_BUFFER | SVGA_NEW_VS_CONST_BUFFER | \
+    SVGA_NEW_GS_CONST_BUFFER | \
+    SVGA_NEW_TCS_CONST_BUFFER | SVGA_NEW_TES_CONST_BUFFER)
+
 
 void svga_init_state_functions( struct svga_context *svga );
 void svga_init_flush_functions( struct svga_context *svga );
@@ -739,6 +756,7 @@ void svga_context_finish(struct svga_context *svga);
 void svga_hwtnl_flush_retry( struct svga_context *svga );
 void svga_hwtnl_flush_buffer( struct svga_context *svga,
                               struct pipe_resource *buffer );
+boolean svga_hwtnl_has_pending_prim(struct svga_hwtnl *);
 
 void svga_surfaces_flush(struct svga_context *svga);
 
index f8db818b3d0b5f2ed20f6ddbb797833fbd4a9e7c..d17653723c44669a16f7dfe1b0fc76cfbff04e69 100644 (file)
@@ -419,12 +419,10 @@ validate_constant_buffers(struct svga_context *svga)
    for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_COMPUTE; shader++) {
       enum pipe_error ret;
       struct svga_buffer *buffer;
-      struct svga_winsys_surface *handle;
-      unsigned enabled_constbufs;
 
       /* Rebind the default constant buffer if needed */
       if (svga->rebind.flags.constbufs) {
-         buffer = svga_buffer(svga->state.hw_draw.constbuf[shader]);
+         buffer = svga_buffer(svga->state.hw_draw.constbuf[shader][0]);
          if (buffer) {
             ret = svga->swc->resource_rebind(svga->swc,
                                              buffer->handle,
@@ -435,6 +433,9 @@ validate_constant_buffers(struct svga_context *svga)
          }
       }
 
+      struct svga_winsys_surface *handle;
+      unsigned enabled_constbufs;
+
       /*
        * Reference other bound constant buffers to ensure pending updates are
        * noticed by the device.
@@ -443,18 +444,23 @@ validate_constant_buffers(struct svga_context *svga)
       while (enabled_constbufs) {
          unsigned i = u_bit_scan(&enabled_constbufs);
          buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
-         if (buffer) {
+
+         /* If the constant buffer has hw storage, get the buffer winsys handle.
+          * Rebind the resource if needed.
+          */
+         if (buffer && !buffer->use_swbuf)
             handle = svga_buffer_handle(svga, &buffer->b.b,
                                         PIPE_BIND_CONSTANT_BUFFER);
+         else
+            handle = svga->state.hw_draw.constbufoffsets[shader][i].handle;
 
-            if (svga->rebind.flags.constbufs) {
-               ret = svga->swc->resource_rebind(svga->swc,
-                                                handle,
-                                                NULL,
-                                                SVGA_RELOC_READ);
-               if (ret != PIPE_OK)
-                  return ret;
-            }
+         if (svga->rebind.flags.constbufs && handle) {
+            ret = svga->swc->resource_rebind(svga->swc,
+                                             handle,
+                                             NULL,
+                                             SVGA_RELOC_READ);
+            if (ret != PIPE_OK)
+               return ret;
          }
       }
    }
@@ -1189,3 +1195,13 @@ done:
    SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
    return ret;
 }
+
+
+/**
+ * Return TRUE if there are pending primitives.
+ */
+boolean
+svga_hwtnl_has_pending_prim(struct svga_hwtnl *hwtnl)
+{
+   return hwtnl->cmd.prim_count > 0;
+}
index c9861a7e481b9fd145db5851dc9df9cba082c6f2..394040d93036e7d9947245f6a91961fab95e6673 100644 (file)
@@ -50,6 +50,10 @@ svga_link_shaders(const struct tgsi_shader_info *outshader_info,
       linkage->input_map[i] = INVALID_INDEX;
    }
 
+   for (i = 0; i < ARRAY_SIZE(linkage->prevShader.output_map); i++) {
+      linkage->prevShader.output_map[i] = INVALID_INDEX;
+   }
+
    /* Assign input slots for input shader inputs.
     * Basically, we want to use the same index for the output shader's outputs
     * and the input shader's inputs that should be linked together.
@@ -65,26 +69,31 @@ svga_link_shaders(const struct tgsi_shader_info *outshader_info,
       enum tgsi_semantic sem_name = inshader_info->input_semantic_name[i];
       unsigned sem_index = inshader_info->input_semantic_index[i];
       unsigned j;
+      unsigned out_index;
+
+      /* search output shader outputs for same item */
+      for (j = 0; j < outshader_info->num_outputs; j++) {
+         assert(j < ARRAY_SIZE(outshader_info->output_semantic_name));
+         if (outshader_info->output_semantic_name[j] == sem_name &&
+             outshader_info->output_semantic_index[j] == sem_index) {
+            linkage->input_map[i] = j;
+            linkage->prevShader.output_map[j] = i;
+            break;
+         }
+      }
+
       /**
-       * Get the clip distance inputs from the output shader's
-       * clip distance shadow copy.
+       * The clip distance inputs come from the output shader's
+       * clip distance shadow copy, so mark the input index to match
+       * the index of the shadow copy.
        */
       if (sem_name == TGSI_SEMANTIC_CLIPDIST) {
-         linkage->input_map[i] = outshader_info->num_outputs + 1 + sem_index;
+         out_index = outshader_info->num_outputs + 1 + sem_index;
+         linkage->input_map[i] = out_index;
+         linkage->prevShader.output_map[out_index] = i;
          /* make sure free_slot includes this extra output */
          free_slot = MAX2(free_slot, linkage->input_map[i] + 1);
       }
-      else {
-         /* search output shader outputs for same item */
-         for (j = 0; j < outshader_info->num_outputs; j++) {
-            assert(j < ARRAY_SIZE(outshader_info->output_semantic_name));
-            if (outshader_info->output_semantic_name[j] == sem_name &&
-                outshader_info->output_semantic_index[j] == sem_index) {
-               linkage->input_map[i] = j;
-               break;
-            }
-         }
-      }
    }
 
    /* Find the index for position */
@@ -97,12 +106,14 @@ svga_link_shaders(const struct tgsi_shader_info *outshader_info,
    }
 
    linkage->num_inputs = inshader_info->num_inputs;
+   linkage->prevShader.num_outputs = outshader_info->num_outputs;
 
    /* Things like the front-face register are handled here */
    for (i = 0; i < inshader_info->num_inputs; i++) {
       if (linkage->input_map[i] == INVALID_INDEX) {
          unsigned j = free_slot++;
          linkage->input_map[i] = j;
+         linkage->prevShader.output_map[j] = i;
       }
    }
    linkage->input_map_max = free_slot - 1;
@@ -111,8 +122,11 @@ svga_link_shaders(const struct tgsi_shader_info *outshader_info,
    if (SVGA_DEBUG & DEBUG_TGSI) {
       uint64_t reg = 0;
       uint64_t one = 1;
-      debug_printf("### linkage info: num_inputs=%d input_map_max=%d\n",
-                   linkage->num_inputs, linkage->input_map_max);
+
+      debug_printf(
+      "### linkage info: num_inputs=%d input_map_max=%d prevShader.num_outputs=%d\n",
+                   linkage->num_inputs, linkage->input_map_max,
+                   linkage->prevShader.num_outputs);
 
       for (i = 0; i < linkage->num_inputs; i++) {
 
index 8d3517ea28a53eff6561a3f9cd14ccd15bf7b49c..c48be279651eb576528930e1a3d6a01be577a22f 100644 (file)
@@ -8,10 +8,15 @@ struct svga_context;
 
 struct shader_linkage
 {
-   unsigned num_inputs;
+   unsigned num_inputs;     /* number of inputs in the current shader */
    unsigned position_index; /* position register index */
    unsigned input_map_max;  /* highest index of mapped inputs */
    ubyte input_map[PIPE_MAX_SHADER_INPUTS];
+
+   struct {
+      unsigned num_outputs;
+      ubyte output_map[PIPE_MAX_SHADER_OUTPUTS];
+   } prevShader;
 };
 
 void
index 4ef8fb7379638c373442f343cf47ddf002392510..388fc959e3ae0e3a85d47c013f975fe2a3a74014 100644 (file)
@@ -77,15 +77,32 @@ svga_set_constant_buffer(struct pipe_context *pipe,
    svga->curr.constbufs[shader][index].buffer_offset = cb ? cb->buffer_offset : 0;
    svga->curr.constbufs[shader][index].user_buffer = NULL; /* not used */
 
-   if (shader == PIPE_SHADER_FRAGMENT)
-      svga->dirty |= SVGA_NEW_FS_CONST_BUFFER;
-   else if (shader == PIPE_SHADER_VERTEX)
-      svga->dirty |= SVGA_NEW_VS_CONST_BUFFER;
-   else
-      svga->dirty |= SVGA_NEW_GS_CONST_BUFFER;
-
-   /* update bitmask of dirty const buffers */
-   svga->state.dirty_constbufs[shader] |= (1 << index);
+   if (index == 0) {
+      if (shader == PIPE_SHADER_FRAGMENT)
+         svga->dirty |= SVGA_NEW_FS_CONSTS;
+      else if (shader == PIPE_SHADER_VERTEX)
+         svga->dirty |= SVGA_NEW_VS_CONSTS;
+      else if (shader == PIPE_SHADER_GEOMETRY)
+         svga->dirty |= SVGA_NEW_GS_CONSTS;
+      else if (shader == PIPE_SHADER_TESS_CTRL)
+         svga->dirty |= SVGA_NEW_TCS_CONSTS;
+      else if (shader == PIPE_SHADER_TESS_EVAL)
+         svga->dirty |= SVGA_NEW_TES_CONSTS;
+   } else {
+      if (shader == PIPE_SHADER_FRAGMENT)
+         svga->dirty |= SVGA_NEW_FS_CONST_BUFFER;
+      else if (shader == PIPE_SHADER_VERTEX)
+         svga->dirty |= SVGA_NEW_VS_CONST_BUFFER;
+      else if (shader == PIPE_SHADER_GEOMETRY)
+         svga->dirty |= SVGA_NEW_GS_CONST_BUFFER;
+      else if (shader == PIPE_SHADER_TESS_CTRL)
+         svga->dirty |= SVGA_NEW_TCS_CONST_BUFFER;
+      else if (shader == PIPE_SHADER_TESS_EVAL)
+         svga->dirty |= SVGA_NEW_TES_CONST_BUFFER;
+
+      /* update bitmask of dirty const buffers */
+      svga->state.dirty_constbufs[shader] |= (1 << index);
+   }
 
    if (cb && cb->user_buffer) {
       pipe_resource_reference(&buf, NULL);
index 9f06a4b2692fe8698884bfcc2b93fce727aff045..55878c89532f8b2a93a9718714cd9d88038abbc7 100644 (file)
@@ -79,8 +79,6 @@ static void
 define_depth_stencil_state_object(struct svga_context *svga,
                                   struct svga_depth_stencil_state *ds)
 {
-   unsigned try;
-
    assert(svga_have_vgpu10(svga));
 
    ds->id = util_bitmask_add(svga->ds_object_id_bm);
@@ -90,40 +88,33 @@ define_depth_stencil_state_object(struct svga_context *svga,
    STATIC_ASSERT(SVGA3D_COMPARISON_LESS == SVGA3D_CMP_LESS);
    STATIC_ASSERT(SVGA3D_COMPARISON_NOT_EQUAL == SVGA3D_CMP_NOTEQUAL);
 
-   /* Loop in case command buffer is full and we need to flush and retry */
-   for (try = 0; try < 2; try++) {
-      enum pipe_error ret;
-
-      /* Note: we use the ds->stencil[0].enabled value for both the front
-       * and back-face enables.  If single-side stencil is used, we'll have
-       * set the back state the same as the front state.
-       */
-      ret = SVGA3D_vgpu10_DefineDepthStencilState(svga->swc,
-                                                  ds->id,
-                                                  /* depth/Z */
-                                                  ds->zenable,
-                                                  ds->zwriteenable,
-                                                  ds->zfunc,
-                                                  /* Stencil */
-                                                  ds->stencil[0].enabled, /*f|b*/
-                                                  ds->stencil[0].enabled, /*f*/
-                                                  ds->stencil[0].enabled, /*b*/
-                                                  ds->stencil_mask,
-                                                  ds->stencil_writemask,
-                                                  /* front stencil */
-                                                  ds->stencil[0].fail,
-                                                  ds->stencil[0].zfail,
-                                                  ds->stencil[0].pass,
-                                                  ds->stencil[0].func,
-                                                  /* back stencil */
-                                                  ds->stencil[1].fail,
-                                                  ds->stencil[1].zfail,
-                                                  ds->stencil[1].pass,
-                                                  ds->stencil[1].func);
-      if (ret == PIPE_OK)
-         return;
-      svga_context_flush(svga, NULL);
-   }
+   /* Note: we use the ds->stencil[0].enabled value for both the front
+    * and back-face enables.  If single-side stencil is used, we'll have
+    * set the back state the same as the front state.
+    */
+   SVGA_RETRY(svga, SVGA3D_vgpu10_DefineDepthStencilState
+              (svga->swc,
+               ds->id,
+               /* depth/Z */
+               ds->zenable,
+               ds->zwriteenable,
+               ds->zfunc,
+               /* Stencil */
+               ds->stencil[0].enabled, /*f|b*/
+               ds->stencil[0].enabled, /*f*/
+               ds->stencil[0].enabled, /*b*/
+               ds->stencil_mask,
+               ds->stencil_writemask,
+               /* front stencil */
+               ds->stencil[0].fail,
+               ds->stencil[0].zfail,
+               ds->stencil[0].pass,
+               ds->stencil[0].func,
+               /* back stencil */
+               ds->stencil[1].fail,
+               ds->stencil[1].zfail,
+               ds->stencil[1].pass,
+               ds->stencil[1].func));
 }
 
 
@@ -251,18 +242,12 @@ svga_delete_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil)
       (struct svga_depth_stencil_state *) depth_stencil;
 
    if (svga_have_vgpu10(svga)) {
-      enum pipe_error ret;
-
       svga_hwtnl_flush_retry(svga);
 
       assert(ds->id != SVGA3D_INVALID_ID);
 
-      ret = SVGA3D_vgpu10_DestroyDepthStencilState(svga->swc, ds->id);
-      if (ret != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_vgpu10_DestroyDepthStencilState(svga->swc, ds->id);
-         assert(ret == PIPE_OK);
-      }
+      SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyDepthStencilState(svga->swc,
+                                                              ds->id));
 
       if (ds->id == svga->state.hw_draw.depth_stencil_id)
          svga->state.hw_draw.depth_stencil_id = SVGA3D_INVALID_ID;
index e6fabfc995e136332cf34f94f40048d522684f8e..06540e46dcfd401f3f7bb6857bb302ea033ae905 100644 (file)
@@ -244,6 +244,15 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
       svga->dirty |= SVGA_NEW_REDUCED_PRIMITIVE;
    }
 
+   /* We need to adjust the vertexID in the vertex shader since SV_VertexID
+    * always start from 0 for DrawArrays and does not include baseVertex for
+    * DrawIndexed.
+    */
+   if (svga->curr.vertex_id_bias != (info->start + info->index_bias)) {
+      svga->curr.vertex_id_bias = info->start + info->index_bias;
+      svga->dirty |= SVGA_NEW_VS_CONSTS;
+   }
+
    if (svga->curr.vertices_per_patch != info->vertices_per_patch) {
       svga->curr.vertices_per_patch = info->vertices_per_patch;
 
index 7795afbfe1fb617d3eb90a50b061855a54c54ac8..4562174910643aef22a08d0cf8e9cb25dab4716c 100644 (file)
@@ -87,7 +87,6 @@ svga_delete_fs_state(struct pipe_context *pipe, void *shader)
    struct svga_fragment_shader *fs = (struct svga_fragment_shader *) shader;
    struct svga_fragment_shader *next_fs;
    struct svga_shader_variant *variant, *tmp;
-   enum pipe_error ret;
 
    svga_hwtnl_flush_retry(svga);
 
@@ -103,12 +102,7 @@ svga_delete_fs_state(struct pipe_context *pipe, void *shader)
 
          /* Check if deleting currently bound shader */
          if (variant == svga->state.hw_draw.fs) {
-            ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_PS, NULL);
-            if (ret != PIPE_OK) {
-               svga_context_flush(svga, NULL);
-               ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_PS, NULL);
-               assert(ret == PIPE_OK);
-            }
+            SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_PS, NULL));
             svga->state.hw_draw.fs = NULL;
          }
 
index edc03f6b6e113b90571c511ab36f1ea86f57b50f..333ca3d6bbac3c1135c1f5db5b9d9cea36c28eb6 100644 (file)
@@ -89,7 +89,6 @@ svga_delete_gs_state(struct pipe_context *pipe, void *shader)
    struct svga_geometry_shader *gs = (struct svga_geometry_shader *)shader;
    struct svga_geometry_shader *next_gs;
    struct svga_shader_variant *variant, *tmp;
-   enum pipe_error ret;
 
    svga_hwtnl_flush_retry(svga);
 
@@ -111,12 +110,7 @@ svga_delete_gs_state(struct pipe_context *pipe, void *shader)
 
          /* Check if deleting currently bound shader */
          if (variant == svga->state.hw_draw.gs) {
-            ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL);
-            if (ret != PIPE_OK) {
-               svga_context_flush(svga, NULL);
-               ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL);
-               assert(ret == PIPE_OK);
-            }
+            SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL));
             svga->state.hw_draw.gs = NULL;
          }
 
index 38874deb414890ad54c756b2fb66281df89df700..77be3692ba06c6176cc36905205bd554ba488256 100644 (file)
@@ -119,11 +119,10 @@ define_query_vgpu9(struct svga_context *svga,
    return PIPE_OK;
 }
 
-static enum pipe_error
+static void
 begin_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
 {
    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
-   enum pipe_error ret = PIPE_OK;
 
    if (sq->queryResult->state == SVGA3D_QUERYSTATE_PENDING) {
       /* The application doesn't care for the pending query result.
@@ -141,28 +140,16 @@ begin_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
    sq->queryResult->state = SVGA3D_QUERYSTATE_NEW;
    sws->fence_reference(sws, &sq->fence, NULL);
 
-   ret = SVGA3D_BeginQuery(svga->swc, sq->svga_type);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_BeginQuery(svga->swc, sq->svga_type);
-   }
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_BeginQuery(svga->swc, sq->svga_type));
 }
 
-static enum pipe_error
+static void
 end_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
 {
-   enum pipe_error ret = PIPE_OK;
-
    /* Set to PENDING before sending EndQuery. */
    sq->queryResult->state = SVGA3D_QUERYSTATE_PENDING;
 
-   ret = SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf);
-   }
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf));
 }
 
 static bool
@@ -170,7 +157,6 @@ get_query_result_vgpu9(struct svga_context *svga, struct svga_query *sq,
                        bool wait, uint64_t *result)
 {
    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
-   enum pipe_error ret;
    SVGA3dQueryState state;
 
    if (!sq->fence) {
@@ -178,12 +164,8 @@ get_query_result_vgpu9(struct svga_context *svga, struct svga_query *sq,
        * SVGA_3D_CMD_WAIT_FOR_QUERY is emitted. Unfortunately this will cause
        * a synchronous wait on the host.
        */
-      ret = SVGA3D_WaitForQuery(svga->swc, sq->svga_type, sq->hwbuf);
-      if (ret != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_WaitForQuery(svga->swc, sq->svga_type, sq->hwbuf);
-      }
-      assert (ret == PIPE_OK);
+      SVGA_RETRY(svga, SVGA3D_WaitForQuery(svga->swc, sq->svga_type,
+                                           sq->hwbuf));
       svga_context_flush(svga, &sq->fence);
       assert(sq->fence);
    }
@@ -510,12 +492,8 @@ define_query_vgpu10(struct svga_context *svga,
       svga->gb_query_alloc_mask = util_bitmask_create();
 
       /* Bind the query object to the context */
-      if (svga->swc->query_bind(svga->swc, svga->gb_query,
-                                SVGA_QUERY_FLAG_SET) != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         svga->swc->query_bind(svga->swc, svga->gb_query,
-                               SVGA_QUERY_FLAG_SET);
-      }
+      SVGA_RETRY(svga, svga->swc->query_bind(svga->swc, svga->gb_query,
+                                             SVGA_QUERY_FLAG_SET));
    }
 
    sq->gb_query = svga->gb_query;
@@ -536,42 +514,26 @@ define_query_vgpu10(struct svga_context *svga,
    /**
     * Send SVGA3D commands to define the query
     */
-   ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags);
-   }
+   SVGA_RETRY_OOM(svga, ret, SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id,
+                                                       sq->svga_type,
+                                                       sq->flags));
    if (ret != PIPE_OK)
       return PIPE_ERROR_OUT_OF_MEMORY;
 
-   ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id);
-   }
-   assert(ret == PIPE_OK);
-
-   ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
-   }
-   assert(ret == PIPE_OK);
+   SVGA_RETRY(svga, SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id));
+   SVGA_RETRY(svga, SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id,
+                                                 sq->offset));
 
    return PIPE_OK;
 }
 
-static enum pipe_error
+static void
 destroy_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
 {
-   enum pipe_error ret;
-
-   ret = SVGA3D_vgpu10_DestroyQuery(svga->swc, sq->id);
+   SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyQuery(svga->swc, sq->id));
 
    /* Deallocate the memory slot allocated for this query */
    deallocate_query(svga, sq);
-
-   return ret;
 }
 
 
@@ -581,13 +543,8 @@ destroy_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
 static void
 rebind_vgpu10_query(struct svga_context *svga)
 {
-   if (svga->swc->query_bind(svga->swc, svga->gb_query,
-                             SVGA_QUERY_FLAG_REF) != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      svga->swc->query_bind(svga->swc, svga->gb_query,
-                            SVGA_QUERY_FLAG_REF);
-   }
-
+   SVGA_RETRY(svga, svga->swc->query_bind(svga->swc, svga->gb_query,
+                                          SVGA_QUERY_FLAG_REF));
    svga->rebind.flags.query = FALSE;
 }
 
@@ -596,7 +553,6 @@ static enum pipe_error
 begin_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
 {
    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
-   enum pipe_error ret = PIPE_OK;
    int status = 0;
 
    sws->fence_reference(sws, &sq->fence, NULL);
@@ -611,30 +567,18 @@ begin_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
    }
 
    /* Send the BeginQuery command to the device */
-   ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id);
-   }
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id));
+   return PIPE_OK;
 }
 
-static enum pipe_error
+static void
 end_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
 {
-   enum pipe_error ret = PIPE_OK;
-
    if (svga->rebind.flags.query) {
       rebind_vgpu10_query(svga);
    }
 
-   ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
-   }
-
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_vgpu10_EndQuery(svga->swc, sq->id));
 }
 
 static bool
@@ -775,6 +719,7 @@ svga_create_query(struct pipe_context *pipe,
    case SVGA_QUERY_NUM_BUFFERS_MAPPED:
    case SVGA_QUERY_NUM_TEXTURES_MAPPED:
    case SVGA_QUERY_NUM_BYTES_UPLOADED:
+   case SVGA_QUERY_NUM_COMMAND_BUFFERS:
    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
    case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
    case SVGA_QUERY_MEMORY_USED:
@@ -790,12 +735,16 @@ svga_create_query(struct pipe_context *pipe,
    case SVGA_QUERY_NUM_CONST_UPDATES:
    case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
    case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
+   case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
+   case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
+   case SVGA_QUERY_SHADER_MEM_USED:
       break;
    case SVGA_QUERY_FLUSH_TIME:
    case SVGA_QUERY_MAP_BUFFER_TIME:
       /* These queries need os_time_get() */
       svga->hud.uses_time = TRUE;
       break;
+
    default:
       assert(!"unexpected query type in svga_create_query()");
    }
@@ -856,6 +805,7 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_BUFFERS_MAPPED:
    case SVGA_QUERY_NUM_TEXTURES_MAPPED:
    case SVGA_QUERY_NUM_BYTES_UPLOADED:
+   case SVGA_QUERY_NUM_COMMAND_BUFFERS:
    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
    case SVGA_QUERY_FLUSH_TIME:
    case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
@@ -872,6 +822,9 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_CONST_UPDATES:
    case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
    case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
+   case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
+   case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
+   case SVGA_QUERY_SHADER_MEM_USED:
       /* nothing */
       break;
    default:
@@ -890,14 +843,11 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
 {
    struct svga_context *svga = svga_context(pipe);
    struct svga_query *sq = svga_query(q);
-   enum pipe_error ret;
+   enum pipe_error ret = PIPE_OK;
 
    assert(sq);
    assert(sq->type < SVGA_QUERY_MAX);
 
-   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
-            sq, sq->id);
-
    /* Need to flush out buffered drawing commands so that they don't
     * get counted in the query results.
     */
@@ -917,7 +867,7 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
             (void) status;
          }
       } else {
-         ret = begin_query_vgpu9(svga, sq);
+         begin_query_vgpu9(svga, sq);
       }
       assert(ret == PIPE_OK);
       (void) ret;
@@ -954,6 +904,9 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_BYTES_UPLOADED:
       sq->begin_count = svga->hud.num_bytes_uploaded;
       break;
+   case SVGA_QUERY_NUM_COMMAND_BUFFERS:
+      sq->begin_count = svga->swc->num_command_buffers;
+      break;
    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
       sq->begin_count = svga->hud.command_buffer_size;
       break;
@@ -978,6 +931,12 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_CONST_UPDATES:
       sq->begin_count = svga->hud.num_const_updates;
       break;
+   case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
+      sq->begin_count = svga->swc->num_shader_reloc;
+      break;
+   case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
+      sq->begin_count = svga->swc->num_surf_reloc;
+      break;
    case SVGA_QUERY_MEMORY_USED:
    case SVGA_QUERY_NUM_SHADERS:
    case SVGA_QUERY_NUM_RESOURCES:
@@ -986,6 +945,7 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_GENERATE_MIPMAP:
    case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
    case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
+   case SVGA_QUERY_SHADER_MEM_USED:
       /* nothing */
       break;
    default:
@@ -1006,17 +966,19 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
 {
    struct svga_context *svga = svga_context(pipe);
    struct svga_query *sq = svga_query(q);
-   enum pipe_error ret;
 
    assert(sq);
    assert(sq->type < SVGA_QUERY_MAX);
 
-   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
-            sq, sq->id);
+   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x type=%d\n",
+            __FUNCTION__, sq, sq->type);
 
    if (sq->type == PIPE_QUERY_TIMESTAMP && !sq->active)
       svga_begin_query(pipe, q);
 
+   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d type=%d svga_type=%d\n",
+            __FUNCTION__, sq, sq->id, sq->type, sq->svga_type);
+
    svga_hwtnl_flush_retry(svga);
 
    assert(sq->active);
@@ -1026,27 +988,21 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
    case PIPE_QUERY_OCCLUSION_PREDICATE:
    case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
       if (svga_have_vgpu10(svga)) {
-         ret = end_query_vgpu10(svga, sq);
+         end_query_vgpu10(svga, sq);
          /* also need to end the associated occlusion predicate query */
          if (sq->predicate) {
-            enum pipe_error status;
-            status = end_query_vgpu10(svga, svga_query(sq->predicate));
-            assert(status == PIPE_OK);
-            (void) status;
+            end_query_vgpu10(svga, svga_query(sq->predicate));
          }
       } else {
-         ret = end_query_vgpu9(svga, sq);
+         end_query_vgpu9(svga, sq);
       }
-      assert(ret == PIPE_OK);
-      (void) ret;
       break;
    case PIPE_QUERY_PRIMITIVES_GENERATED:
    case PIPE_QUERY_PRIMITIVES_EMITTED:
    case PIPE_QUERY_SO_STATISTICS:
    case PIPE_QUERY_TIMESTAMP:
       assert(svga_have_vgpu10(svga));
-      ret = end_query_vgpu10(svga, sq);
-      assert(ret == PIPE_OK);
+      end_query_vgpu10(svga, sq);
       break;
    case SVGA_QUERY_NUM_DRAW_CALLS:
       sq->end_count = svga->hud.num_draw_calls;
@@ -1072,6 +1028,9 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_BYTES_UPLOADED:
       sq->end_count = svga->hud.num_bytes_uploaded;
       break;
+   case SVGA_QUERY_NUM_COMMAND_BUFFERS:
+      sq->end_count = svga->swc->num_command_buffers;
+      break;
    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
       sq->end_count = svga->hud.command_buffer_size;
       break;
@@ -1096,6 +1055,12 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_CONST_UPDATES:
       sq->end_count = svga->hud.num_const_updates;
       break;
+   case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
+      sq->end_count = svga->swc->num_shader_reloc;
+      break;
+   case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
+      sq->end_count = svga->swc->num_surf_reloc;
+      break;
    case SVGA_QUERY_MEMORY_USED:
    case SVGA_QUERY_NUM_SHADERS:
    case SVGA_QUERY_NUM_RESOURCES:
@@ -1104,6 +1069,7 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
    case SVGA_QUERY_NUM_GENERATE_MIPMAP:
    case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
    case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
+   case SVGA_QUERY_SHADER_MEM_USED:
       /* nothing */
       break;
    default:
@@ -1204,6 +1170,7 @@ svga_get_query_result(struct pipe_context *pipe,
    case SVGA_QUERY_NUM_BUFFERS_MAPPED:
    case SVGA_QUERY_NUM_TEXTURES_MAPPED:
    case SVGA_QUERY_NUM_BYTES_UPLOADED:
+   case SVGA_QUERY_NUM_COMMAND_BUFFERS:
    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
    case SVGA_QUERY_FLUSH_TIME:
    case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
@@ -1212,6 +1179,8 @@ svga_get_query_result(struct pipe_context *pipe,
    case SVGA_QUERY_NUM_BUFFER_UPLOADS:
    case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
    case SVGA_QUERY_NUM_CONST_UPDATES:
+   case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
+   case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
       vresult->u64 = sq->end_count - sq->begin_count;
       break;
    /* These are running total counters */
@@ -1245,6 +1214,9 @@ svga_get_query_result(struct pipe_context *pipe,
       vresult->f = (float) svga->swc->num_commands
          / (float) svga->swc->num_draw_commands;
       break;
+   case SVGA_QUERY_SHADER_MEM_USED:
+      vresult->u64 = svga->hud.shader_mem_used;
+      break;
    default:
       assert(!"unexpected query type in svga_get_query_result");
    }
@@ -1262,7 +1234,6 @@ svga_render_condition(struct pipe_context *pipe, struct pipe_query *q,
    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    struct svga_query *sq = svga_query(q);
    SVGA3dQueryId queryId;
-   enum pipe_error ret;
 
    SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
 
@@ -1296,13 +1267,8 @@ svga_render_condition(struct pipe_context *pipe, struct pipe_query *q,
     * This is probably acceptable for the typical case of occlusion culling.
     */
    if (sws->have_set_predication_cmd) {
-      ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
-                                         (uint32) condition);
-      if (ret != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
-                                            (uint32) condition);
-      }
+      SVGA_RETRY(svga, SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
+                                                    (uint32) condition));
       svga->pred.query_id = queryId;
       svga->pred.cond = condition;
    }
@@ -1350,7 +1316,6 @@ svga_toggle_render_condition(struct svga_context *svga,
                              boolean on)
 {
    SVGA3dQueryId query_id;
-   enum pipe_error ret;
 
    if (render_condition_enabled ||
        svga->pred.query_id == SVGA3D_INVALID_ID) {
@@ -1365,14 +1330,8 @@ svga_toggle_render_condition(struct svga_context *svga,
     */
    query_id = on ? svga->pred.query_id : SVGA3D_INVALID_ID;
 
-   ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
-                                      (uint32) svga->pred.cond);
-   if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
-                                         (uint32) svga->pred.cond);
-      assert(ret == PIPE_OK);
-   }
+   SVGA_RETRY(svga, SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
+                                                 (uint32) svga->pred.cond));
 }
 
 
index 7764a855391e16749446bdd62ec7d0cee9e389fd..1b823d64ec040013f7c6e96bd49c458c54204f2e 100644 (file)
@@ -121,8 +121,6 @@ define_rasterizer_object(struct svga_context *svga,
    const uint8 pv_last = !rast->templ.flatshade_first &&
       svgascreen->haveProvokingVertex;
 
-   unsigned try;
-
    rast->id = util_bitmask_add(svga->rast_object_id_bm);
 
    if (rast->templ.fill_front != rast->templ.fill_back) {
@@ -133,31 +131,24 @@ define_rasterizer_object(struct svga_context *svga,
       fill_mode = SVGA3D_FILLMODE_FILL;
    }
 
-   for (try = 0; try < 2; try++) {
-      const uint8 pv_last = !rast->templ.flatshade_first &&
-         svgascreen->haveProvokingVertex;
-      enum pipe_error ret =
-         SVGA3D_vgpu10_DefineRasterizerState(svga->swc,
-                                             rast->id,
-                                             fill_mode,
-                                             cull_mode,
-                                             rast->templ.front_ccw,
-                                             depth_bias,
-                                             depth_bias_clamp,
-                                             slope_scaled_depth_bias,
-                                             rast->templ.depth_clip_near,
-                                             rast->templ.scissor,
-                                             rast->templ.multisample,
-                                             rast->templ.line_smooth,
-                                             line_width,
-                                             rast->templ.line_stipple_enable,
-                                             line_factor,
-                                             line_pattern,
-                                             pv_last);
-      if (ret == PIPE_OK)
-         return;
-      svga_context_flush(svga, NULL);
-   }
+   SVGA_RETRY(svga, SVGA3D_vgpu10_DefineRasterizerState
+              (svga->swc,
+               rast->id,
+               fill_mode,
+               cull_mode,
+               rast->templ.front_ccw,
+               depth_bias,
+               depth_bias_clamp,
+               slope_scaled_depth_bias,
+               rast->templ.depth_clip_near,
+               rast->templ.scissor,
+               rast->templ.multisample,
+               rast->templ.line_smooth,
+               line_width,
+               rast->templ.line_stipple_enable,
+               line_factor,
+               line_pattern,
+               pv_last));
 }
 
 
@@ -418,12 +409,8 @@ svga_delete_rasterizer_state(struct pipe_context *pipe, void *state)
       (struct svga_rasterizer_state *) state;
 
    if (svga_have_vgpu10(svga)) {
-      enum pipe_error ret =
-         SVGA3D_vgpu10_DestroyRasterizerState(svga->swc, raster->id);
-      if (ret != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_vgpu10_DestroyRasterizerState(svga->swc, raster->id);
-      }
+      SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyRasterizerState(svga->swc,
+                                                            raster->id));
 
       if (raster->id == svga->state.hw_draw.rasterizer_id)
          svga->state.hw_draw.rasterizer_id = SVGA3D_INVALID_ID;
index 2f8fedb7aa0380113f2de93da743260e04783c9b..d73a5816be15c2d0a27f4ad918db5248aeccedbd 100644 (file)
@@ -166,7 +166,6 @@ define_sampler_state_object(struct svga_context *svga,
    uint8 compare_func;
    SVGA3dFilter filter;
    SVGA3dRGBAFloat bcolor;
-   unsigned try;
    float min_lod, max_lod;
 
    assert(svga_have_vgpu10(svga));
@@ -207,25 +206,19 @@ define_sampler_state_object(struct svga_context *svga,
    for (i = 0; i <= ss->compare_mode; i++) {
       ss->id[i] = util_bitmask_add(svga->sampler_object_id_bm);
 
-      /* Loop in case command buffer is full and we need to flush and retry */
-      for (try = 0; try < 2; try++) {
-         enum pipe_error ret =
-            SVGA3D_vgpu10_DefineSamplerState(svga->swc,
-                                             ss->id[i],
-                                             filter,
-                                             ss->addressu,
-                                             ss->addressv,
-                                             ss->addressw,
-                                             ss->lod_bias, /* float */
-                                             max_aniso,
-                                             compare_func,
-                                             bcolor,
-                                             min_lod,       /* float */
-                                             max_lod);      /* float */
-         if (ret == PIPE_OK)
-            break;
-         svga_context_flush(svga, NULL);
-      }
+      SVGA_RETRY(svga, SVGA3D_vgpu10_DefineSamplerState
+                 (svga->swc,
+                  ss->id[i],
+                  filter,
+                  ss->addressu,
+                  ss->addressv,
+                  ss->addressw,
+                  ss->lod_bias, /* float */
+                  max_aniso,
+                  compare_func,
+                  bcolor,
+                  min_lod,       /* float */
+                  max_lod));      /* float */
 
       /* turn off the shadow compare option for second iteration */
       filter &= ~SVGA3D_FILTER_COMPARE;
@@ -349,16 +342,11 @@ svga_delete_sampler_state(struct pipe_context *pipe, void *sampler)
    if (svga_have_vgpu10(svga)) {
       unsigned i;
       for (i = 0; i < 2; i++) {
-         enum pipe_error ret;
-
          if (ss->id[i] != SVGA3D_INVALID_ID) {
             svga_hwtnl_flush_retry(svga);
 
-            ret = SVGA3D_vgpu10_DestroySamplerState(svga->swc, ss->id[i]);
-            if (ret != PIPE_OK) {
-               svga_context_flush(svga, NULL);
-               ret = SVGA3D_vgpu10_DestroySamplerState(svga->swc, ss->id[i]);
-            }
+            SVGA_RETRY(svga, SVGA3D_vgpu10_DestroySamplerState(svga->swc,
+                                                               ss->id[i]));
             util_bitmask_clear(svga->sampler_object_id_bm, ss->id[i]);
          }
       }
@@ -405,17 +393,12 @@ svga_sampler_view_destroy(struct pipe_context *pipe,
    struct svga_pipe_sampler_view *sv = svga_pipe_sampler_view(view);
 
    if (svga_have_vgpu10(svga) && sv->id != SVGA3D_INVALID_ID) {
-      enum pipe_error ret;
-
       assert(view->context == pipe);
 
       svga_hwtnl_flush_retry(svga);
 
-      ret = SVGA3D_vgpu10_DestroyShaderResourceView(svga->swc, sv->id);
-      if (ret != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_vgpu10_DestroyShaderResourceView(svga->swc, sv->id);
-      }
+      SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyShaderResourceView(svga->swc,
+                                                               sv->id));
       util_bitmask_clear(svga->sampler_view_id_bm, sv->id);
    }
 
@@ -534,7 +517,7 @@ svga_cleanup_sampler_state(struct svga_context *svga)
 {
    enum pipe_shader_type shader;
 
-   for (shader = 0; shader <= PIPE_SHADER_GEOMETRY; shader++) {
+   for (shader = 0; shader <= PIPE_SHADER_TESS_EVAL; shader++) {
       unsigned i;
 
       for (i = 0; i < svga->state.hw_draw.num_sampler_views[shader]; i++) {
index 380ceaa3aa7548218b7bf0db51c8eae167538545..f20f58d49d129c309eec4d9f445d5ed95695843b 100644 (file)
@@ -354,6 +354,15 @@ svga_delete_stream_output(struct svga_context *svga,
       sws->buffer_destroy(sws, streamout->declBuf);
    }
 
+   /* Before deleting the current streamout, make sure to stop any pending
+    * SO queries.
+    */
+   if (svga->current_so == streamout) {
+      if (svga->in_streamout)
+         svga_end_stream_output_queries(svga, svga->current_so->streammask);
+      svga->current_so = NULL;
+   }
+
    /* Release the ID */
    util_bitmask_clear(svga->stream_output_id_bm, streamout->id);
 
index 346a13105b72b325528161d5c58204582cc694a4..cd38dab6ca5b37432d1bf5e69d35f1fda68977bd 100644 (file)
@@ -120,7 +120,6 @@ define_input_element_object(struct svga_context *svga,
                             struct svga_velems_state *velems)
 {
    SVGA3dInputElementDesc elements[PIPE_MAX_ATTRIBS];
-   enum pipe_error ret;
    unsigned i;
 
    assert(velems->count <= PIPE_MAX_ATTRIBS);
@@ -186,14 +185,8 @@ define_input_element_object(struct svga_context *svga,
 
    velems->id = util_bitmask_add(svga->input_element_object_id_bm);
 
-   ret = SVGA3D_vgpu10_DefineElementLayout(svga->swc, velems->count,
-                                           velems->id, elements);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_DefineElementLayout(svga->swc, velems->count,
-                                              velems->id, elements);
-      assert(ret == PIPE_OK);
-   }
+   SVGA_RETRY(svga, SVGA3D_vgpu10_DefineElementLayout(svga->swc, velems->count,
+                                                      velems->id, elements));
 }
 
 
@@ -293,16 +286,10 @@ svga_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
    struct svga_velems_state *velems = (struct svga_velems_state *) state;
 
    if (svga_have_vgpu10(svga)) {
-      enum pipe_error ret;
-
       svga_hwtnl_flush_retry(svga);
 
-      ret = SVGA3D_vgpu10_DestroyElementLayout(svga->swc, velems->id);
-      if (ret != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_vgpu10_DestroyElementLayout(svga->swc, velems->id);
-         assert(ret == PIPE_OK);
-      }
+      SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyElementLayout(svga->swc,
+                                                          velems->id));
 
       if (velems->id == svga->state.hw_draw.layout_id)
          svga->state.hw_draw.layout_id = SVGA3D_INVALID_ID;
index aa7396c2c6b00987f89f5c1880beebe2f0d85b69..b94576f78d63796b79b59b3d495f5371a7ea4ee6 100644 (file)
@@ -168,7 +168,6 @@ svga_delete_vs_state(struct pipe_context *pipe, void *shader)
    struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader;
    struct svga_vertex_shader *next_vs;
    struct svga_shader_variant *variant, *tmp;
-   enum pipe_error ret;
 
    svga_hwtnl_flush_retry(svga);
 
@@ -194,12 +193,7 @@ svga_delete_vs_state(struct pipe_context *pipe, void *shader)
 
          /* Check if deleting currently bound shader */
          if (variant == svga->state.hw_draw.vs) {
-            ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_VS, NULL);
-            if (ret != PIPE_OK) {
-               svga_context_flush(svga, NULL);
-               ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_VS, NULL);
-               assert(ret == PIPE_OK);
-            }
+            SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_VS, NULL));
             svga->state.hw_draw.vs = NULL;
          }
 
index 4f19b8ca035fde15bc9edb896637fea60918368d..80f91a9ef65aa3d9bf59df93082eddec83e20d19 100644 (file)
@@ -62,14 +62,13 @@ svga_buffer_needs_hw_storage(const struct svga_screen *ss,
        * tagged with PIPE_BIND_CUSTOM
        */
       bind_mask |= PIPE_BIND_CUSTOM;
-      /* Uniform buffer objects.
-       * Make sure we don't create hardware storage for gallium frontend
-       * const0 buffers, because we frequently map them for reading.
-       * They are distinguished by having PIPE_USAGE_STREAM, but not
-       * PIPE_BIND_CUSTOM.
+      /**
+       * Uniform buffer objects.
+       * Don't create hardware storage for state-tracker constant buffers,
+       * because we frequently map them for reading and writing, and
+       * the length of those buffers are always small, so it is better
+       * to just use system memory.
        */
-      if (template->usage != PIPE_USAGE_STREAM)
-         bind_mask |= PIPE_BIND_CONSTANT_BUFFER;
    }
 
    if (template->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
@@ -132,7 +131,6 @@ svga_buffer_transfer_map(struct pipe_context *pipe,
 
    if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty &&
        !sbuf->key.coherent && !svga->swc->force_coherent) {
-      enum pipe_error ret;
 
       /* Host-side buffers can only be dirtied with vgpu10 features
        * (streamout and buffer copy).
@@ -150,13 +148,8 @@ svga_buffer_transfer_map(struct pipe_context *pipe,
 
       assert(sbuf->handle);
 
-      ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, sbuf->handle, 0);
-      if (ret != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, sbuf->handle, 0);
-         assert(ret == PIPE_OK);
-      }
-
+      SVGA_RETRY(svga, SVGA3D_vgpu10_ReadbackSubResource(svga->swc,
+                                                         sbuf->handle, 0));
       svga->hud.num_readbacks++;
 
       svga_context_finish(svga);
@@ -278,15 +271,18 @@ svga_buffer_transfer_map(struct pipe_context *pipe,
    else if (svga_buffer_has_hw_storage(sbuf)) {
       boolean retry;
 
-      map = svga_buffer_hw_storage_map(svga, sbuf, transfer->usage, &retry);
+      map = SVGA_TRY_MAP(svga_buffer_hw_storage_map
+                         (svga, sbuf, transfer->usage, &retry), retry);
       if (map == NULL && retry) {
          /*
           * At this point, svga_buffer_get_transfer() has already
           * hit the DISCARD_WHOLE_RESOURCE path and flushed HWTNL
           * for this buffer.
           */
+         svga_retry_enter(svga);
          svga_context_flush(svga, NULL);
          map = svga_buffer_hw_storage_map(svga, sbuf, transfer->usage, &retry);
+         svga_retry_exit(svga);
       }
    }
    else {
@@ -349,6 +345,7 @@ svga_buffer_transfer_unmap(struct pipe_context *pipe,
    }
 
    if (svga_buffer_has_hw_storage(sbuf)) {
+
       /* Note: we may wind up flushing here and unmapping other buffers
        * which leads to recursively locking ss->swc_mutex.
        */
@@ -370,6 +367,19 @@ svga_buffer_transfer_unmap(struct pipe_context *pipe,
          if (!(svga->swc->force_coherent || sbuf->key.coherent) || sbuf->swbuf)
             svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
       }
+
+      if (sbuf->swbuf &&
+          (!sbuf->bind_flags || (sbuf->bind_flags & PIPE_BIND_CONSTANT_BUFFER))) {
+         /*
+          * Since the constant buffer is in system buffer, we need
+          * to set the constant buffer dirty bits, so that the context
+          * can update the changes in the device.
+          * According to the GL spec, buffer bound to other contexts will
+          * have to be explicitly rebound by the user to have the changes take
+          * into effect.
+          */
+         svga->dirty |= SVGA_NEW_CONST_BUFFER;
+      }
    }
 
    mtx_unlock(&ss->swc_mutex);
@@ -491,6 +501,13 @@ svga_buffer_create(struct pipe_screen *screen,
       sbuf->swbuf = align_malloc(sbuf->b.b.width0, 64);
       if (!sbuf->swbuf)
          goto error2;
+
+      /* Since constant buffer is usually small, it is much cheaper to
+       * use system memory for the data just as it is being done for
+       * the default constant buffer.
+       */
+      if ((bind_flags & PIPE_BIND_CONSTANT_BUFFER) || !bind_flags)
+         sbuf->use_swbuf = TRUE;
    }
 
    debug_reference(&sbuf->b.b.reference,
index bd219742e6864f70d306b99acacda60bd429af68..09648d2ec0976dd258c83eaad4c891a68cd2125c 100644 (file)
@@ -93,6 +93,11 @@ struct svga_buffer
     */
    boolean user;
 
+   /**
+    * Whether swbuf is used for this buffer.
+    */
+   boolean use_swbuf;
+
    /**
     * Creation key for the host surface handle.
     *
@@ -323,16 +328,10 @@ svga_buffer_hw_storage_unmap(struct svga_context *svga,
    if (sws->have_gb_objects) {
       struct svga_winsys_context *swc = svga->swc;
       boolean rebind;
+
       swc->surface_unmap(swc, sbuf->handle, &rebind);
       if (rebind) {
-         enum pipe_error ret;
-         ret = SVGA3D_BindGBSurface(swc, sbuf->handle);
-         if (ret != PIPE_OK) {
-            /* flush and retry */
-            svga_context_flush(svga, NULL);
-            ret = SVGA3D_BindGBSurface(swc, sbuf->handle);
-            assert(ret == PIPE_OK);
-         }
+         SVGA_RETRY(svga, SVGA3D_BindGBSurface(swc, sbuf->handle));
       }
    } else
       sws->buffer_unmap(sws, sbuf->hwbuf);
index 5d2b934e7c16d0f9f0242aa6e5b9b5f6726ce063..78535643563e300e2945c62be427d3b3fa4b9db5 100644 (file)
@@ -72,14 +72,16 @@ svga_winsys_buffer_create( struct svga_context *svga,
    struct svga_winsys_buffer *buf;
 
    /* Just try */
-   buf = sws->buffer_create(sws, alignment, usage, size);
+   buf = SVGA_TRY_PTR(sws->buffer_create(sws, alignment, usage, size));
    if (!buf) {
       SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "flushing context to find %d bytes GMR\n",
                size);
 
       /* Try flushing all pending DMAs */
+      svga_retry_enter(svga);
       svga_context_flush(svga, NULL);
       buf = sws->buffer_create(sws, alignment, usage, size);
+      svga_retry_exit(svga);
    }
 
    return buf;
@@ -229,6 +231,12 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
                                          bind_flags);
    }
 
+   if (ss->sws->have_gb_objects) {
+      /* Initialize the surface with zero */
+      ss->sws->surface_init(ss->sws, sbuf->handle, svga_surface_size(&sbuf->key),
+                            sbuf->key.flags);
+   }
+
    return ret;
 }
 
@@ -255,14 +263,9 @@ svga_buffer_recreate_host_surface(struct svga_context *svga,
    if (ret == PIPE_OK) {
       /* Copy the surface data */
       assert(sbuf->handle);
-      ret = SVGA3D_vgpu10_BufferCopy(svga->swc, old_handle, sbuf->handle,
-                                     0, 0, sbuf->b.b.width0);
-      if (ret != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_vgpu10_BufferCopy(svga->swc, old_handle, sbuf->handle,
-                                        0, 0, sbuf->b.b.width0);
-         assert(ret == PIPE_OK);
-      }
+      SVGA_RETRY(svga, SVGA3D_vgpu10_BufferCopy(svga->swc, old_handle,
+                                                sbuf->handle,
+                                                0, 0, sbuf->b.b.width0));
    }
 
    /* Set the new bind flags for this buffer resource */
@@ -344,8 +347,6 @@ svga_buffer_bind_host_surface(struct svga_context *svga,
                               struct svga_buffer *sbuf,
                               struct svga_buffer_surface *bufsurf)
 {
-   enum pipe_error ret;
-
    /* Update the to-bind surface */
    assert(bufsurf->handle);
    assert(sbuf->handle);
@@ -354,14 +355,9 @@ svga_buffer_bind_host_surface(struct svga_context *svga,
     * make sure to copy the buffer content.
     */
    if (sbuf->bind_flags & PIPE_BIND_STREAM_OUTPUT) {
-      ret = SVGA3D_vgpu10_BufferCopy(svga->swc, sbuf->handle, bufsurf->handle,
-                                     0, 0, sbuf->b.b.width0);
-      if (ret != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_vgpu10_BufferCopy(svga->swc, sbuf->handle, bufsurf->handle,
-                                        0, 0, sbuf->b.b.width0);
-         assert(ret == PIPE_OK);
-      }
+      SVGA_RETRY(svga, SVGA3D_vgpu10_BufferCopy(svga->swc, sbuf->handle,
+                                                bufsurf->handle,
+                                                0, 0, sbuf->b.b.width0));
    }
 
    /* Set this surface as the current one */
@@ -943,7 +939,6 @@ svga_buffer_upload_piecewise(struct svga_screen *ss,
       while (offset < range->end) {
          struct svga_winsys_buffer *hwbuf;
          uint8_t *map;
-         enum pipe_error ret;
 
          if (offset + size > range->end)
             size = range->end - offset;
@@ -968,19 +963,10 @@ svga_buffer_upload_piecewise(struct svga_screen *ss,
             sws->buffer_unmap(sws, hwbuf);
          }
 
-         ret = SVGA3D_BufferDMA(svga->swc,
-                                hwbuf, sbuf->handle,
-                                SVGA3D_WRITE_HOST_VRAM,
-                                size, 0, offset, sbuf->dma.flags);
-         if (ret != PIPE_OK) {
-            svga_context_flush(svga, NULL);
-            ret =  SVGA3D_BufferDMA(svga->swc,
-                                    hwbuf, sbuf->handle,
-                                    SVGA3D_WRITE_HOST_VRAM,
-                                    size, 0, offset, sbuf->dma.flags);
-            assert(ret == PIPE_OK);
-         }
-
+         SVGA_RETRY(svga, SVGA3D_BufferDMA(svga->swc,
+                                           hwbuf, sbuf->handle,
+                                           SVGA3D_WRITE_HOST_VRAM,
+                                           size, 0, offset, sbuf->dma.flags));
          sbuf->dma.flags.discard = FALSE;
 
          sws->buffer_destroy(sws, hwbuf);
@@ -1061,12 +1047,7 @@ svga_buffer_handle(struct svga_context *svga, struct pipe_resource *buf,
          ret = svga_buffer_update_hw(svga, sbuf, sbuf->bind_flags);
          if (ret == PIPE_OK) {
             /* Emit DMA or UpdateGBImage commands */
-            ret = svga_buffer_upload_command(svga, sbuf);
-            if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
-               svga_context_flush(svga, NULL);
-               ret = svga_buffer_upload_command(svga, sbuf);
-               assert(ret == PIPE_OK);
-            }
+            SVGA_RETRY_OOM(svga, ret, svga_buffer_upload_command(svga, sbuf));
             if (ret == PIPE_OK) {
                sbuf->dma.pending = TRUE;
                assert(!sbuf->head.prev && !sbuf->head.next);
index 1bae8c395958653f84e0a2e8e7eed81a1e97fd97..137d15bcb4fd928f37b017fd858b8ff34203cf2c 100644 (file)
@@ -58,7 +58,6 @@ svga_transfer_dma_band(struct svga_context *svga,
 {
    struct svga_texture *texture = svga_texture(st->base.resource);
    SVGA3dCopyBox box;
-   enum pipe_error ret;
 
    assert(!st->use_direct_map);
 
@@ -87,12 +86,7 @@ svga_transfer_dma_band(struct svga_context *svga,
             (util_format_get_blockwidth(texture->b.b.format)
              * util_format_get_blockheight(texture->b.b.format)));
 
-   ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
-      assert(ret == PIPE_OK);
-   }
+   SVGA_RETRY(svga, SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags));
 }
 
 
@@ -274,40 +268,28 @@ need_tex_readback(struct svga_transfer *st)
 }
 
 
-static enum pipe_error
+static void
 readback_image_vgpu9(struct svga_context *svga,
                    struct svga_winsys_surface *surf,
                    unsigned slice,
                    unsigned level)
 {
-   enum pipe_error ret;
-
-   ret = SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level);
-   }
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level));
 }
 
 
-static enum pipe_error
+static void
 readback_image_vgpu10(struct svga_context *svga,
                     struct svga_winsys_surface *surf,
                     unsigned slice,
                     unsigned level,
                     unsigned numMipLevels)
 {
-   enum pipe_error ret;
    unsigned subResource;
 
    subResource = slice * numMipLevels + level;
-   ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf, subResource);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf, subResource);
-   }
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf,
+                                                      subResource));
 }
 
 
@@ -397,25 +379,20 @@ svga_texture_transfer_map_direct(struct svga_context *svga,
    unsigned usage = st->base.usage;
 
    if (need_tex_readback(st)) {
-      enum pipe_error ret;
-
       svga_surfaces_flush(svga);
 
       if (!svga->swc->force_coherent || tex->imported) {
          for (i = 0; i < st->box.d; i++) {
             if (svga_have_vgpu10(svga)) {
-               ret = readback_image_vgpu10(svga, surf, st->slice + i, level,
-                                           tex->b.b.last_level + 1);
+               readback_image_vgpu10(svga, surf, st->slice + i, level,
+                                     tex->b.b.last_level + 1);
             } else {
-               ret = readback_image_vgpu9(svga, surf, st->slice + i, level);
+               readback_image_vgpu9(svga, surf, st->slice + i, level);
             }
          }
          svga->hud.num_readbacks++;
          SVGA_STATS_COUNT_INC(sws, SVGA_STATS_COUNT_TEXREADBACK);
 
-         assert(ret == PIPE_OK);
-         (void) ret;
-
          svga_context_flush(svga, NULL);
       }
       /*
@@ -465,26 +442,19 @@ svga_texture_transfer_map_direct(struct svga_context *svga,
          usage |= PIPE_TRANSFER_PERSISTENT | PIPE_TRANSFER_COHERENT;
       }
 
-      map = swc->surface_map(swc, surf, usage, &retry, &rebind);
+      map = SVGA_TRY_MAP(svga->swc->surface_map
+                         (svga->swc, surf, usage, &retry, &rebind), retry);
+
       if (map == NULL && retry) {
          /*
           * At this point, the svga_surfaces_flush() should already have
           * called in svga_texture_get_transfer().
           */
          svga->hud.surface_write_flushes++;
+         svga_retry_enter(svga);
          svga_context_flush(svga, NULL);
-         map = swc->surface_map(swc, surf, usage, &retry, &rebind);
-      }
-      if (map && rebind) {
-         enum pipe_error ret;
-
-         ret = SVGA3D_BindGBSurface(swc, surf);
-         if (ret != PIPE_OK) {
-            svga_context_flush(svga, NULL);
-            ret = SVGA3D_BindGBSurface(swc, surf);
-            assert(ret == PIPE_OK);
-         }
-         svga_context_flush(svga, NULL);
+         map = svga->swc->surface_map(svga->swc, surf, usage, &retry, &rebind);
+         svga_retry_exit(svga);
       }
 
       if (map && rebind) {
@@ -626,9 +596,12 @@ svga_texture_transfer_map(struct pipe_context *pipe,
    pipe_resource_reference(&st->base.resource, texture);
 
    /* If this is the first time mapping to the surface in this
-    * command buffer, clear the dirty masks of this surface.
+    * command buffer and there is no pending primitives, clear
+    * the dirty masks of this surface.
     */
-   if (sws->surface_is_flushed(sws, surf)) {
+   if (sws->surface_is_flushed(sws, surf) &&
+       (svga_have_vgpu10(svga) ||
+        !svga_hwtnl_has_pending_prim(svga->hwtnl))) {
       svga_clear_texture_dirty(tex);
    }
 
@@ -716,37 +689,23 @@ svga_texture_surface_unmap(struct svga_context *svga,
 
    swc->surface_unmap(swc, surf, &rebind);
    if (rebind) {
-      enum pipe_error ret;
-      ret = SVGA3D_BindGBSurface(swc, surf);
-      if (ret != PIPE_OK) {
-         /* flush and retry */
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_BindGBSurface(swc, surf);
-         assert(ret == PIPE_OK);
-      }
+      SVGA_RETRY(svga, SVGA3D_BindGBSurface(swc, surf));
    }
 }
 
 
-static enum pipe_error
+static void
 update_image_vgpu9(struct svga_context *svga,
                    struct svga_winsys_surface *surf,
                    const SVGA3dBox *box,
                    unsigned slice,
                    unsigned level)
 {
-   enum pipe_error ret;
-
-   ret = SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level);
-   }
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level));
 }
 
 
-static enum pipe_error
+static void
 update_image_vgpu10(struct svga_context *svga,
                     struct svga_winsys_surface *surf,
                     const SVGA3dBox *box,
@@ -754,17 +713,12 @@ update_image_vgpu10(struct svga_context *svga,
                     unsigned level,
                     unsigned numMipLevels)
 {
-   enum pipe_error ret;
    unsigned subResource;
 
    subResource = slice * numMipLevels + level;
 
-   ret = SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box, subResource);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box, subResource);
-   }
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box,
+                                                    subResource));
 }
 
 
@@ -819,7 +773,6 @@ svga_texture_transfer_unmap_direct(struct svga_context *svga,
    /* Now send an update command to update the content in the backend. */
    if (st->base.usage & PIPE_TRANSFER_WRITE) {
       struct svga_winsys_surface *surf = tex->handle;
-      enum pipe_error ret;
 
       assert(svga_have_gb_objects(svga));
 
@@ -851,19 +804,16 @@ svga_texture_transfer_unmap_direct(struct svga_context *svga,
             unsigned i;
 
             for (i = 0; i < nlayers; i++) {
-               ret = update_image_vgpu10(svga, surf, &box,
-                                         st->slice + i, transfer->level,
-                                         tex->b.b.last_level + 1);
-               assert(ret == PIPE_OK);
+               update_image_vgpu10(svga, surf, &box,
+                                   st->slice + i, transfer->level,
+                                   tex->b.b.last_level + 1);
             }
          } else {
             assert(nlayers == 1);
-            ret = update_image_vgpu9(svga, surf, &box, st->slice,
-                                     transfer->level);
-            assert(ret == PIPE_OK);
+            update_image_vgpu9(svga, surf, &box, st->slice,
+                               transfer->level);
          }
       }
-      (void) ret;
    }
 }
 
@@ -1311,7 +1261,6 @@ svga_texture_generate_mipmap(struct pipe_context *pipe,
    struct svga_pipe_sampler_view *sv;
    struct svga_context *svga = svga_context(pipe);
    struct svga_texture *tex = svga_texture(pt);
-   enum pipe_error ret;
 
    assert(svga_have_vgpu10(svga));
 
@@ -1342,18 +1291,9 @@ svga_texture_generate_mipmap(struct pipe_context *pipe,
       return false;
 
    sv = svga_pipe_sampler_view(psv);
-   ret = svga_validate_pipe_sampler_view(svga, sv);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = svga_validate_pipe_sampler_view(svga, sv);
-      assert(ret == PIPE_OK);
-   }
+   SVGA_RETRY(svga, svga_validate_pipe_sampler_view(svga, sv));
 
-   ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle);
-   }
+   SVGA_RETRY(svga, SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle));
    pipe_sampler_view_reference(&psv, NULL);
 
    svga->hud.num_generate_mipmap++;
@@ -1521,7 +1461,6 @@ svga_texture_transfer_unmap_upload(struct svga_context *svga,
    struct svga_winsys_surface *dstsurf;
    struct pipe_resource *texture = st->base.resource;
    struct svga_texture *tex = svga_texture(texture);
-   enum pipe_error ret;
    unsigned subResource;
    unsigned numMipLevels;
    unsigned i, layer;
@@ -1545,22 +1484,12 @@ svga_texture_transfer_unmap_upload(struct svga_context *svga,
       /* send a transferFromBuffer command to update the host texture surface */
       assert((offset & 15) == 0);
 
-      ret = SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
-                                             offset,
-                                             st->base.stride,
-                                             st->base.layer_stride,
-                                             dstsurf, subResource,
-                                             &st->upload.box);
-      if (ret != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
-                                                offset,
-                                                st->base.stride,
-                                                st->base.layer_stride,
-                                                dstsurf, subResource,
-                                                &st->upload.box);
-         assert(ret == PIPE_OK);
-      }
+      SVGA_RETRY(svga, SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
+                                                        offset,
+                                                        st->base.stride,
+                                                        st->base.layer_stride,
+                                                        dstsurf, subResource,
+                                                        &st->upload.box));
       offset += st->base.layer_stride;
 
       /* Set rendered-to flag */
index f7e3a90029038819021d1d0abcdb5780b1f8837a..1dc5319f57213c9813a7cd101044e00848747731 100644 (file)
@@ -723,7 +723,7 @@ vgpu10_get_shader_param(struct pipe_screen *screen,
       else if (shader == PIPE_SHADER_GEOMETRY)
          return VGPU10_MAX_GS_INPUTS;
       else if (shader == PIPE_SHADER_TESS_CTRL)
-         return VGPU11_MAX_HS_INPUTS;
+         return VGPU11_MAX_HS_INPUT_CONTROL_POINTS;
       else if (shader == PIPE_SHADER_TESS_EVAL)
          return VGPU11_MAX_DS_INPUT_CONTROL_POINTS;
       else
index a0e5f5ff2b9834f753a533def39f59336ac46ee9..aba6e304fbdec86e679d22d099aeed40ef70d5cb 100644 (file)
@@ -41,8 +41,8 @@
 /**
  * Return the size of the surface described by the key (in bytes).
  */
-static unsigned
-surface_size(const struct svga_host_surface_cache_key *key)
+unsigned
+svga_surface_size(const struct svga_host_surface_cache_key *key)
 {
    unsigned bw, bh, bpb, total_size, i;
 
@@ -142,7 +142,7 @@ svga_screen_cache_lookup(struct svga_screen *svgascreen,
          list_add(&entry->head, &cache->empty);
 
          /* update the cache size */
-         surf_size = surface_size(&entry->key);
+         surf_size = svga_surface_size(&entry->key);
          assert(surf_size <= cache->total_size);
          if (surf_size > cache->total_size)
             cache->total_size = 0; /* should never happen, but be safe */
@@ -187,7 +187,7 @@ svga_screen_cache_shrink(struct svga_screen *svgascreen,
       if (entry->key.format != SVGA3D_BUFFER) {
          /* we don't want to discard vertex/index buffers */
 
-         cache->total_size -= surface_size(&entry->key);
+         cache->total_size -= svga_surface_size(&entry->key);
 
          assert(entry->handle);
          sws->surface_reference(sws, &entry->handle, NULL);
@@ -225,7 +225,7 @@ svga_screen_cache_add(struct svga_screen *svgascreen,
    if (!handle)
       return;
 
-   surf_size = surface_size(key);
+   surf_size = svga_surface_size(key);
 
    *p_handle = NULL;
    mtx_lock(&cache->mutex);
@@ -273,7 +273,7 @@ svga_screen_cache_add(struct svga_screen *svgascreen,
       SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
                "unref sid %p (make space)\n", entry->handle);
 
-      cache->total_size -= surface_size(&entry->key);
+      cache->total_size -= svga_surface_size(&entry->key);
 
       sws->surface_reference(sws, &entry->handle, NULL);
 
@@ -373,7 +373,8 @@ svga_screen_cache_flush(struct svga_screen *svgascreen,
          /* It is now safe to invalidate the surface content.
           * It will be done using the current context.
           */
-         if (SVGA3D_InvalidateGBSurface(svga->swc, entry->handle) != PIPE_OK) {
+         if (SVGA_TRY(SVGA3D_InvalidateGBSurface(svga->swc, entry->handle))
+             != PIPE_OK) {
             ASSERTED enum pipe_error ret;
 
             /* Even though surface invalidation here is done after the command
@@ -384,13 +385,16 @@ svga_screen_cache_flush(struct svga_screen *svgascreen,
              * Note, we don't want to call svga_context_flush() here because
              * this function itself is called inside svga_context_flush().
              */
+            svga_retry_enter(svga);
             svga->swc->flush(svga->swc, NULL);
             nsurf = 0;
             ret = SVGA3D_InvalidateGBSurface(svga->swc, entry->handle);
+            svga_retry_exit(svga);
             assert(ret == PIPE_OK);
          }
 
          /* add the entry to the invalidated list */
+
          list_add(&entry->head, &cache->invalidated);
          nsurf++;
       }
@@ -430,7 +434,7 @@ svga_screen_cache_cleanup(struct svga_screen *svgascreen)
                   "unref sid %p (shutdown)\n", cache->entries[i].handle);
         sws->surface_reference(sws, &cache->entries[i].handle, NULL);
 
-         cache->total_size -= surface_size(&cache->entries[i].key);
+         cache->total_size -= svga_surface_size(&cache->entries[i].key);
       }
 
       if (cache->entries[i].fence)
index 055a267c1897c2799df37b8c95cf5046ee425569..c2bfc076ffa053826cb6caa0b5ef7cff81f50ea5 100644 (file)
@@ -159,5 +159,8 @@ svga_screen_surface_destroy(struct svga_screen *svgascreen,
 void
 svga_screen_cache_dump(const struct svga_screen *svgascreen);
 
+unsigned
+svga_surface_size(const struct svga_host_surface_cache_key *key);
+
 
 #endif /* SVGA_SCREEN_CACHE_H_ */
index 31ccf97d39add31bd6cfbfb4e29ac69a6bc3427f..4fccde405355427f29eb93fa5eedff846feaba41 100644 (file)
@@ -50,6 +50,8 @@ struct svga_compile_key
       unsigned need_prescale:1;
       unsigned undo_viewport:1;
       unsigned allow_psiz:1;
+      unsigned need_vertex_id_bias:1;
+
       /** The following are all 32-bit bitmasks (per VS input) */
       unsigned adjust_attrib_range;
       unsigned attrib_is_pure_int;
@@ -93,6 +95,7 @@ struct svga_compile_key
    /* tessellation control shader */
    struct {
       unsigned vertices_per_patch:8;
+      unsigned vertices_out:8;
       enum pipe_prim_type prim_mode:8;
       enum pipe_tess_spacing spacing:3;
       unsigned vertices_order_cw:1;
index ad647d8784ca3b2c078a668b1401f31e199a0b1d..4f6af8052b6d9bdf60ea4a11d7b875cbf8cf249d 100644 (file)
@@ -97,8 +97,11 @@ static const struct svga_tracked_state *hw_draw_state_vgpu10[] =
    &svga_hw_clip_planes,
    &svga_hw_vdecl,
    &svga_hw_fs_constants,
+   &svga_hw_fs_constbufs,
    &svga_hw_gs_constants,
+   &svga_hw_gs_constbufs,
    &svga_hw_vs_constants,
+   &svga_hw_vs_constbufs,
    NULL
 };
 
@@ -122,10 +125,15 @@ static const struct svga_tracked_state *hw_draw_state_sm5[] =
    &svga_hw_clip_planes,
    &svga_hw_vdecl,
    &svga_hw_fs_constants,
+   &svga_hw_fs_constbufs,
    &svga_hw_gs_constants,
+   &svga_hw_gs_constbufs,
    &svga_hw_tes_constants,
+   &svga_hw_tes_constbufs,
    &svga_hw_tcs_constants,
+   &svga_hw_tcs_constbufs,
    &svga_hw_vs_constants,
+   &svga_hw_vs_constbufs,
    NULL
 };
 
index 76befebe4a3968a9052b6ea5a7fc9a51473b05db..853f867b70f4de79eca1b8906669668dc4b6e623 100644 (file)
@@ -76,6 +76,11 @@ extern struct svga_tracked_state svga_hw_gs_constants;
 extern struct svga_tracked_state svga_hw_vs_constants;
 extern struct svga_tracked_state svga_hw_tes_constants;
 extern struct svga_tracked_state svga_hw_tcs_constants;
+extern struct svga_tracked_state svga_hw_fs_constbufs;
+extern struct svga_tracked_state svga_hw_vs_constbufs;
+extern struct svga_tracked_state svga_hw_gs_constbufs;
+extern struct svga_tracked_state svga_hw_tcs_constbufs;
+extern struct svga_tracked_state svga_hw_tes_constbufs;
 
 /* SWTNL_DRAW
  */
index 9d9f8934ec4a88c3d5b8eae3f24abd1903de042b..7e245baf22c4e01559eac84e897c049e6b4f2976 100644 (file)
@@ -219,6 +219,17 @@ svga_get_extra_vs_constants(const struct svga_context *svga, float *dest)
       count += 1;
    }
 
+   /* Bias to be added to VertexID */
+   if (variant->key.vs.need_vertex_id_bias) {
+      uint32_t *dest_u = (uint32_t *) dest;  // uint version of dest
+      dest_u[0] = svga->curr.vertex_id_bias;
+      dest_u[1] = 1;
+      dest_u[2] = 1;
+      dest_u[3] = 1;
+      dest+=4;
+      count++;
+   }
+
    /* SVGA_NEW_CLIP */
    count += svga_get_clip_plane_constants(svga, variant, &dest);
 
@@ -560,22 +571,170 @@ emit_consts_vgpu9(struct svga_context *svga, enum pipe_shader_type shader)
 }
 
 
-
+/**
+ * A helper function to emit a constant buffer binding at the
+ * specified slot for the specified shader type
+ */
 static enum pipe_error
-emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
+emit_constbuf(struct svga_context *svga,
+              unsigned slot,
+              enum pipe_shader_type shader,
+              unsigned buffer_offset,
+              unsigned buffer_size,
+              const void *buffer,
+              unsigned extra_buffer_offset,
+              unsigned extra_buffer_size,
+              const void *extra_buffer)
 {
-   const struct pipe_constant_buffer *cbuf;
+   struct svga_buffer *sbuf = svga_buffer((struct pipe_resource *)buffer);
    struct pipe_resource *dst_buffer = NULL;
    enum pipe_error ret = PIPE_OK;
    struct pipe_transfer *src_transfer;
-   struct svga_winsys_surface *dst_handle;
+   struct svga_winsys_surface *dst_handle = NULL;
+   unsigned new_buf_size = 0;
+   unsigned alloc_buf_size;
+   unsigned offset = 0;;
+   void *src_map = NULL, *dst_map;
+
+   if ((sbuf && sbuf->swbuf) || extra_buffer) {
+
+      /* buffer here is a user-space buffer so mapping it is really cheap. */
+      if (buffer_size > 0) {
+         src_map = pipe_buffer_map_range(&svga->pipe,
+                                         (struct pipe_resource *)buffer,
+                                         buffer_offset, buffer_size,
+                                         PIPE_TRANSFER_READ, &src_transfer);
+         assert(src_map);
+         if (!src_map) {
+            return PIPE_ERROR_OUT_OF_MEMORY;
+         }
+      }
+
+      new_buf_size = MAX2(buffer_size, extra_buffer_offset) + extra_buffer_size;
+
+      /* According to the DX10 spec, the constant buffer size must be
+       * in multiples of 16.
+       */
+      new_buf_size = align(new_buf_size, 16);
+
+      /* Constant buffer size in the upload buffer must be in multiples of 256.
+       * In order to maximize the chance of merging the upload buffer chunks
+       * when svga_buffer_add_range() is called,
+       * the allocate buffer size needs to be in multiples of 256 as well.
+       * Otherwise, since there is gap between each dirty range of the upload buffer,
+       * each dirty range will end up in its own UPDATE_GB_IMAGE command.
+       */
+      alloc_buf_size = align(new_buf_size, CONST0_UPLOAD_ALIGNMENT);
+
+      u_upload_alloc(svga->const0_upload, 0, alloc_buf_size,
+                     CONST0_UPLOAD_ALIGNMENT, &offset,
+                     &dst_buffer, &dst_map);
+
+      if (!dst_map) {
+         if (src_map)
+            pipe_buffer_unmap(&svga->pipe, src_transfer);
+         return PIPE_ERROR_OUT_OF_MEMORY;
+      }
+
+      /* Initialize the allocated buffer slot to 0 to ensure the padding is
+       * filled with 0.
+       */
+      memset(dst_map, 0, alloc_buf_size);
+
+      if (src_map) {
+         memcpy(dst_map, src_map, buffer_size);
+         pipe_buffer_unmap(&svga->pipe, src_transfer);
+      }
+
+      if (extra_buffer_size) {
+         assert(extra_buffer_offset + extra_buffer_size <= new_buf_size);
+         memcpy((char *) dst_map + extra_buffer_offset, extra_buffer,
+                extra_buffer_size);
+      }
+
+      /* Get winsys handle for the constant buffer */
+      if (svga->state.hw_draw.const0_buffer == dst_buffer &&
+          svga->state.hw_draw.const0_handle) {
+         /* re-reference already mapped buffer */
+         dst_handle = svga->state.hw_draw.const0_handle;
+      }
+      else {
+         /* we must unmap the buffer before getting the winsys handle */
+         u_upload_unmap(svga->const0_upload);
+
+         dst_handle = svga_buffer_handle(svga, dst_buffer,
+                                         PIPE_BIND_CONSTANT_BUFFER);
+         if (!dst_handle) {
+            pipe_resource_reference(&dst_buffer, NULL);
+            return PIPE_ERROR_OUT_OF_MEMORY;
+         }
+      }
+   }
+   else if (sbuf) {
+      dst_handle = svga_buffer_handle(svga, &sbuf->b.b, PIPE_BIND_CONSTANT_BUFFER);
+      new_buf_size = align(buffer_size, 16);
+      offset = buffer_offset;
+   }
+
+   assert(new_buf_size % 16 == 0);
+
+   const struct svga_screen *screen = svga_screen(svga->pipe.screen);
+   const struct svga_winsys_screen *sws = screen->sws;
+
+   /* Issue the SetSingleConstantBuffer command */
+   if (!sws->have_constant_buffer_offset_cmd ||
+       svga->state.hw_draw.constbufoffsets[shader][slot].handle != dst_handle ||
+       svga->state.hw_draw.constbufoffsets[shader][slot].size != new_buf_size) {
+      ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
+                                                  slot, /* index */
+                                                  svga_shader_type(shader),
+                                                  dst_handle,
+                                                  offset,
+                                                  new_buf_size);
+   }
+   else if (dst_handle){
+      unsigned command = SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET + shader;
+      ret = SVGA3D_vgpu10_SetConstantBufferOffset(svga->swc,
+                                                  command,
+                                                  slot, /* index */
+                                                  offset);
+   }
+
+   if (ret != PIPE_OK) {
+      pipe_resource_reference(&dst_buffer, NULL);
+      return ret;
+   }
+
+   /* save the upload buffer / handle for next time */
+   if (dst_buffer != buffer && dst_buffer) {
+      pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer);
+      svga->state.hw_draw.const0_handle = dst_handle;
+   }
+
+   /* Save this const buffer until it's replaced in the future.
+    * Otherwise, all references to the buffer will go away after the
+    * command buffer is submitted, it'll get recycled and we will have
+    * incorrect constant buffer bindings.
+    */
+   pipe_resource_reference(&svga->state.hw_draw.constbuf[shader][slot], dst_buffer);
+   svga->state.hw_draw.constbufoffsets[shader][slot].handle = dst_handle;
+   svga->state.hw_draw.constbufoffsets[shader][slot].size = new_buf_size;
+
+   pipe_resource_reference(&dst_buffer, NULL);
+
+   return PIPE_OK;
+}
+
+
+/* For constbuf 0 */
+static enum pipe_error
+emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
+{
+   const struct pipe_constant_buffer *cbuf;
+   enum pipe_error ret = PIPE_OK;
    float extras[MAX_EXTRA_CONSTS][4];
    unsigned extra_count, extra_size, extra_offset;
-   unsigned new_buf_size;
-   void *src_map = NULL, *dst_map;
-   unsigned offset;
    const struct svga_shader_variant *variant;
-   unsigned alloc_buf_size;
 
    assert(shader == PIPE_SHADER_VERTEX ||
           shader == PIPE_SHADER_GEOMETRY ||
@@ -630,131 +789,30 @@ emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
    if (cbuf->buffer_size + extra_size == 0)
       return PIPE_OK;  /* nothing to do */
 
-   /* Typically, the cbuf->buffer here is a user-space buffer so mapping
-    * it is really cheap.  If we ever get real HW buffers for constants
-    * we should void mapping and instead use a ResourceCopy command.
-    */
-   if (cbuf->buffer_size > 0) {
-      src_map = pipe_buffer_map_range(&svga->pipe, cbuf->buffer,
-                                      cbuf->buffer_offset, cbuf->buffer_size,
-                                      PIPE_TRANSFER_READ, &src_transfer);
-      assert(src_map);
-      if (!src_map) {
-         return PIPE_ERROR_OUT_OF_MEMORY;
-      }
-   }
-
-   /* The new/dest buffer's size must be large enough to hold the original,
-    * user-specified constants, plus the extra constants.
-    * The size of the original constant buffer _should_ agree with what the
-    * shader is expecting, but it might not (it's not enforced anywhere by
-    * gallium).
-    */
-   new_buf_size = MAX2(cbuf->buffer_size, extra_offset) + extra_size;
-
-   /* According to the DX10 spec, the constant buffer size must be
-    * in multiples of 16.
-    */
-   new_buf_size = align(new_buf_size, 16);
-
-   /* Constant buffer size in the upload buffer must be in multiples of 256.
-    * In order to maximize the chance of merging the upload buffer chunks
-    * when svga_buffer_add_range() is called,
-    * the allocate buffer size needs to be in multiples of 256 as well.
-    * Otherwise, since there is gap between each dirty range of the upload buffer,
-    * each dirty range will end up in its own UPDATE_GB_IMAGE command.
-    */
-   alloc_buf_size = align(new_buf_size, CONST0_UPLOAD_ALIGNMENT);
-
-   u_upload_alloc(svga->const0_upload, 0, alloc_buf_size,
-                  CONST0_UPLOAD_ALIGNMENT, &offset,
-                  &dst_buffer, &dst_map);
-   if (!dst_map) {
-      if (src_map)
-         pipe_buffer_unmap(&svga->pipe, src_transfer);
-      return PIPE_ERROR_OUT_OF_MEMORY;
-   }
-
-   if (src_map) {
-      memcpy(dst_map, src_map, cbuf->buffer_size);
-      pipe_buffer_unmap(&svga->pipe, src_transfer);
-   }
-
-   if (extra_size) {
-      assert(extra_offset + extra_size <= new_buf_size);
-      memcpy((char *) dst_map + extra_offset, extras, extra_size);
-   }
-
-   /* Get winsys handle for the constant buffer */
-   if (svga->state.hw_draw.const0_buffer == dst_buffer &&
-       svga->state.hw_draw.const0_handle) {
-      /* re-reference already mapped buffer */
-      dst_handle = svga->state.hw_draw.const0_handle;
-   }
-   else {
-      /* we must unmap the buffer before getting the winsys handle */
-      u_upload_unmap(svga->const0_upload);
-
-      dst_handle = svga_buffer_handle(svga, dst_buffer,
-                                      PIPE_BIND_CONSTANT_BUFFER);
-      if (!dst_handle) {
-         pipe_resource_reference(&dst_buffer, NULL);
-         return PIPE_ERROR_OUT_OF_MEMORY;
-      }
-
-      /* save the buffer / handle for next time */
-      pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer);
-      svga->state.hw_draw.const0_handle = dst_handle;
-   }
-
-   /* Issue the SetSingleConstantBuffer command */
-   assert(new_buf_size % 16 == 0);
-   ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
-                                               0, /* index */
-                                               svga_shader_type(shader),
-                                               dst_handle,
-                                               offset,
-                                               new_buf_size);
-
-   if (ret != PIPE_OK) {
-      pipe_resource_reference(&dst_buffer, NULL);
+   ret = emit_constbuf(svga, 0, shader,
+                       cbuf->buffer_offset, cbuf->buffer_size, cbuf->buffer,
+                       extra_offset, extra_size, extras);
+   if (ret != PIPE_OK)
       return ret;
-   }
-
-   /* Save this const buffer until it's replaced in the future.
-    * Otherwise, all references to the buffer will go away after the
-    * command buffer is submitted, it'll get recycled and we will have
-    * incorrect constant buffer bindings.
-    */
-   pipe_resource_reference(&svga->state.hw_draw.constbuf[shader], dst_buffer);
 
-   svga->state.hw_draw.default_constbuf_size[shader] = new_buf_size;
+   svga->state.hw_draw.default_constbuf_size[shader] =
+      svga->state.hw_draw.constbufoffsets[shader][0].size;
 
-   pipe_resource_reference(&dst_buffer, NULL);
-
-   svga->hud.num_const_buf_updates++;
+   svga->hud.num_const_updates++;
 
    return ret;
 }
 
 
 static enum pipe_error
-emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
+emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
 {
-   enum pipe_error ret;
+   enum pipe_error ret = PIPE_OK;
    unsigned dirty_constbufs;
    unsigned enabled_constbufs;
 
-   /* Emit 0th constant buffer (with extra constants) */
-   ret = emit_constbuf_vgpu10(svga, shader);
-   if (ret != PIPE_OK) {
-      return ret;
-   }
-
    enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] | 1u;
-
-   /* Emit other constant buffers (UBOs) */
-   dirty_constbufs = svga->state.dirty_constbufs[shader] & ~1u;
+   dirty_constbufs = (svga->state.dirty_constbufs[shader]|enabled_constbufs) & ~1u;
 
    while (dirty_constbufs) {
       unsigned index = u_bit_scan(&dirty_constbufs);
@@ -762,15 +820,11 @@ emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
       unsigned size = svga->curr.constbufs[shader][index].buffer_size;
       struct svga_buffer *buffer =
          svga_buffer(svga->curr.constbufs[shader][index].buffer);
-      struct svga_winsys_surface *handle;
 
       if (buffer) {
-         handle = svga_buffer_handle(svga, &buffer->b.b,
-                                     PIPE_BIND_CONSTANT_BUFFER);
          enabled_constbufs |= 1 << index;
       }
       else {
-         handle = NULL;
          enabled_constbufs &= ~(1 << index);
          assert(offset == 0);
          assert(size == 0);
@@ -795,12 +849,9 @@ emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
       }
 
       assert(size % 16 == 0);
-      ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
-                                                  index,
-                                                  svga_shader_type(shader),
-                                                  handle,
-                                                  offset,
-                                                  size);
+
+      ret = emit_constbuf(svga, index, shader, offset, size, buffer,
+                          0, 0, NULL);
       if (ret != PIPE_OK)
          return ret;
 
@@ -824,7 +875,7 @@ emit_fs_consts(struct svga_context *svga, uint64_t dirty)
    if (!variant)
       return PIPE_OK;
 
-   /* SVGA_NEW_FS_CONST_BUFFER
+   /* SVGA_NEW_FS_CONSTS
     */
    if (svga_have_vgpu10(svga)) {
       ret = emit_consts_vgpu10(svga, PIPE_SHADER_FRAGMENT);
@@ -836,17 +887,42 @@ emit_fs_consts(struct svga_context *svga, uint64_t dirty)
    return ret;
 }
 
+static enum pipe_error
+emit_fs_constbuf(struct svga_context *svga, uint64_t dirty)
+{
+   const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
+   enum pipe_error ret = PIPE_OK;
+
+   /* SVGA_NEW_FS_VARIANT
+    */
+   if (!variant)
+      return PIPE_OK;
+
+   /* SVGA_NEW_FS_CONSTBUF
+    */
+   assert(svga_have_vgpu10(svga));
+   ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_FRAGMENT);
+
+   return ret;
+}
 
 struct svga_tracked_state svga_hw_fs_constants =
 {
    "hw fs params",
-   (SVGA_NEW_FS_CONST_BUFFER |
+   (SVGA_NEW_FS_CONSTS |
     SVGA_NEW_FS_VARIANT |
     SVGA_NEW_TEXTURE_CONSTS),
    emit_fs_consts
 };
 
 
+struct svga_tracked_state svga_hw_fs_constbufs =
+{
+   "hw fs params",
+   SVGA_NEW_FS_CONST_BUFFER,
+   emit_fs_constbuf
+};
+
 
 static enum pipe_error
 emit_vs_consts(struct svga_context *svga, uint64_t dirty)
@@ -872,17 +948,45 @@ emit_vs_consts(struct svga_context *svga, uint64_t dirty)
 }
 
 
+static enum pipe_error
+emit_vs_constbuf(struct svga_context *svga, uint64_t dirty)
+{
+   const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
+   enum pipe_error ret = PIPE_OK;
+
+   /* SVGA_NEW_FS_VARIANT
+    */
+   if (!variant)
+      return PIPE_OK;
+
+   /* SVGA_NEW_FS_CONSTBUF
+    */
+   assert(svga_have_vgpu10(svga));
+   ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_VERTEX);
+
+   return ret;
+}
+
+
 struct svga_tracked_state svga_hw_vs_constants =
 {
    "hw vs params",
    (SVGA_NEW_PRESCALE |
-    SVGA_NEW_VS_CONST_BUFFER |
+    SVGA_NEW_VS_CONSTS |
     SVGA_NEW_VS_VARIANT |
     SVGA_NEW_TEXTURE_CONSTS),
    emit_vs_consts
 };
 
 
+struct svga_tracked_state svga_hw_vs_constbufs =
+{
+   "hw vs params",
+   SVGA_NEW_VS_CONST_BUFFER,
+   emit_vs_constbuf
+};
+
+
 static enum pipe_error
 emit_gs_consts(struct svga_context *svga, uint64_t dirty)
 {
@@ -912,11 +1016,31 @@ emit_gs_consts(struct svga_context *svga, uint64_t dirty)
 }
 
 
+static enum pipe_error
+emit_gs_constbuf(struct svga_context *svga, uint64_t dirty)
+{
+   const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
+   enum pipe_error ret = PIPE_OK;
+
+   /* SVGA_NEW_GS_VARIANT
+    */
+   if (!variant)
+      return PIPE_OK;
+
+   /* SVGA_NEW_GS_CONSTBUF
+    */
+   assert(svga_have_vgpu10(svga));
+   ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_GEOMETRY);
+
+   return ret;
+}
+
+
 struct svga_tracked_state svga_hw_gs_constants =
 {
    "hw gs params",
    (SVGA_NEW_PRESCALE |
-    SVGA_NEW_GS_CONST_BUFFER |
+    SVGA_NEW_GS_CONSTS |
     SVGA_NEW_RAST |
     SVGA_NEW_GS_VARIANT |
     SVGA_NEW_TEXTURE_CONSTS),
@@ -924,6 +1048,14 @@ struct svga_tracked_state svga_hw_gs_constants =
 };
 
 
+struct svga_tracked_state svga_hw_gs_constbufs =
+{
+   "hw gs params",
+   SVGA_NEW_GS_CONST_BUFFER,
+   emit_gs_constbuf
+};
+
+
 /**
  * Emit constant buffer for tessellation control shader
  */
@@ -947,15 +1079,43 @@ emit_tcs_consts(struct svga_context *svga, uint64_t dirty)
 }
 
 
+static enum pipe_error
+emit_tcs_constbuf(struct svga_context *svga, uint64_t dirty)
+{
+   const struct svga_shader_variant *variant = svga->state.hw_draw.tcs;
+   enum pipe_error ret = PIPE_OK;
+
+   /* SVGA_NEW_TCS_VARIANT
+    */
+   if (!variant)
+      return PIPE_OK;
+
+   /* SVGA_NEW_TCS_CONSTBUF
+    */
+   assert(svga_have_vgpu10(svga));
+   ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_TESS_CTRL);
+
+   return ret;
+}
+
+
 struct svga_tracked_state svga_hw_tcs_constants =
 {
    "hw tcs params",
-   (SVGA_NEW_TCS_CONST_BUFFER |
+   (SVGA_NEW_TCS_CONSTS |
     SVGA_NEW_TCS_VARIANT),
    emit_tcs_consts
 };
 
 
+struct svga_tracked_state svga_hw_tcs_constbufs =
+{
+   "hw tcs params",
+   SVGA_NEW_TCS_CONST_BUFFER,
+   emit_tcs_constbuf
+};
+
+
 /**
  * Emit constant buffer for tessellation evaluation shader
  */
@@ -977,11 +1137,39 @@ emit_tes_consts(struct svga_context *svga, uint64_t dirty)
 }
 
 
+static enum pipe_error
+emit_tes_constbuf(struct svga_context *svga, uint64_t dirty)
+{
+   const struct svga_shader_variant *variant = svga->state.hw_draw.tes;
+   enum pipe_error ret = PIPE_OK;
+
+   /* SVGA_NEW_TES_VARIANT
+    */
+   if (!variant)
+      return PIPE_OK;
+
+   /* SVGA_NEW_TES_CONSTBUF
+    */
+   assert(svga_have_vgpu10(svga));
+   ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_TESS_EVAL);
+
+   return ret;
+}
+
+
 struct svga_tracked_state svga_hw_tes_constants =
 {
    "hw tes params",
    (SVGA_NEW_PRESCALE |
-    SVGA_NEW_TES_CONST_BUFFER |
+    SVGA_NEW_TES_CONSTS |
     SVGA_NEW_TES_VARIANT),
    emit_tes_consts
 };
+
+
+struct svga_tracked_state svga_hw_tes_constbufs =
+{
+   "hw gs params",
+   SVGA_NEW_TES_CONST_BUFFER,
+   emit_tes_constbuf
+};
index 675fec96cf86a1b0aece33ac6c2a30a4956134d0..5f3df6a2ba6ec39806a10dbde054cfa2b563ce6a 100644 (file)
@@ -210,16 +210,34 @@ make_fs_key(const struct svga_context *svga,
    if (!svga->state.sw.need_swtnl) {
       /* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
        */
+      enum pipe_prim_type prim_mode;
+      struct svga_shader *shader;
+
+      /* Find the last shader in the vertex pipeline and the output primitive mode
+       * from that shader.
+       */
+      if (svga->curr.tes) {
+         shader = &svga->curr.tes->base;
+         prim_mode = shader->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
+      } else if (svga->curr.gs) {
+         shader = &svga->curr.gs->base;
+         prim_mode = shader->info.properties[TGSI_PROPERTY_GS_OUTPUT_PRIM];
+      } else {
+         shader = &svga->curr.vs->base;
+         prim_mode = svga->curr.reduced_prim;
+      }
+
       key->fs.light_twoside = svga->curr.rast->templ.light_twoside;
       key->fs.front_ccw = svga->curr.rast->templ.front_ccw;
       key->fs.pstipple = (svga->curr.rast->templ.poly_stipple_enable &&
-                          svga->curr.reduced_prim == PIPE_PRIM_TRIANGLES);
+                          prim_mode == PIPE_PRIM_TRIANGLES);
+
       key->fs.aa_point = (svga->curr.rast->templ.point_smooth &&
-                          svga->curr.reduced_prim == PIPE_PRIM_POINTS &&
+                          prim_mode == PIPE_PRIM_POINTS &&
                           (svga->curr.rast->pointsize > 1.0 ||
-                           svga->curr.vs->base.info.writes_psize));
-      if (key->fs.aa_point) {
-         assert(svga->curr.gs != NULL);
+                           shader->info.writes_psize));
+
+      if (key->fs.aa_point && svga->curr.gs) {
          assert(svga->curr.gs->aa_point_coord_index != -1);
          key->fs.aa_point_coord_index = svga->curr.gs->aa_point_coord_index;
       }
index 890d153c7d676547ee8973a33d5b9f9370d74020..28f2ae403dd956d2492d01d765edcd1002456db8 100644 (file)
@@ -89,6 +89,14 @@ make_tcs_key(struct svga_context *svga, struct svga_compile_key *key)
    key->tcs.vertices_order_cw = tes->vertices_order_cw;
    key->tcs.point_mode = tes->point_mode;
 
+   /* The number of control point output from tcs is determined by the
+    * number of control point input expected in tes. If tes does not expect
+    * any control point input, then vertices_per_patch in the tes key will
+    * be 0, otherwise it will contain the number of vertices out as specified
+    * in the tcs property.
+    */
+   key->tcs.vertices_out = tes->base.key.tes.vertices_per_patch;
+
    if (svga->tcs.passthrough)
       key->tcs.passthrough = 1;
 
@@ -208,6 +216,7 @@ static void
 make_tes_key(struct svga_context *svga, struct svga_compile_key *key)
 {
    struct svga_tes_shader *tes = svga->curr.tes;
+   boolean has_control_point_inputs = FALSE;
 
    memset(key, 0, sizeof *key);
 
@@ -217,8 +226,23 @@ make_tes_key(struct svga_context *svga, struct svga_compile_key *key)
    svga_init_shader_key_common(svga, PIPE_SHADER_TESS_EVAL, &tes->base, key);
 
    assert(svga->curr.tcs);
-   key->tes.vertices_per_patch =
-      svga->curr.tcs->base.info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT];
+
+   /*
+    * Check if this tes expects any output control points from tcs.
+    */
+   for (unsigned i = 0; i < tes->base.info.num_inputs; i++) {
+      switch (tes->base.info.input_semantic_name[i]) {
+      case TGSI_SEMANTIC_PATCH:
+      case TGSI_SEMANTIC_TESSOUTER:
+      case TGSI_SEMANTIC_TESSINNER:
+         break;
+      default:
+         has_control_point_inputs = TRUE;
+      }
+   }
+
+   key->tes.vertices_per_patch = has_control_point_inputs ?
+      svga->curr.tcs->base.info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT] : 0;
 
    key->tes.need_prescale = svga->state.hw_clear.prescale[0].enabled &&
                             (svga->curr.gs == NULL);
@@ -239,7 +263,7 @@ make_tes_key(struct svga_context *svga, struct svga_compile_key *key)
    key->tes.need_tessinner = 0;
    key->tes.need_tessouter = 0;
 
-   for (int i = 0; i < svga->curr.tcs->base.info.num_outputs; i++) {
+   for (unsigned i = 0; i < svga->curr.tcs->base.info.num_outputs; i++) {
       switch (svga->curr.tcs->base.info.output_semantic_name[i]) {
       case TGSI_SEMANTIC_TESSOUTER:
          key->tes.need_tessouter = 1;
index 147b07aaeb18cab54760f3b534ca4b8ae25a3663..492a929bd8f1fab8a33ddb5d608a8f432fc19dc7 100644 (file)
@@ -175,6 +175,10 @@ make_vs_key(struct svga_context *svga, struct svga_compile_key *key)
       return;
    }
 
+   if (svga_have_vgpu10(svga)) {
+      key->vs.need_vertex_id_bias = 1;
+   }
+
    /* SVGA_NEW_PRESCALE */
    key->vs.need_prescale = svga->state.hw_clear.prescale[0].enabled &&
                            (svga->curr.tes == NULL) &&
index d3dd23d2d8163bcb7b985625f00199a79d492eee..68edf1c21db55af445f50dc2964f02da2b65fd25 100644 (file)
@@ -54,7 +54,6 @@ svga_texture_copy_region(struct svga_context *svga,
                          unsigned dst_x, unsigned dst_y, unsigned dst_z,
                          unsigned width, unsigned height, unsigned depth)
 {
-   enum pipe_error ret;
    SVGA3dCopyBox box;
 
    assert(svga_have_vgpu10(svga));
@@ -69,16 +68,9 @@ svga_texture_copy_region(struct svga_context *svga,
    box.srcy = src_y;
    box.srcz = src_z;
 
-   ret = SVGA3D_vgpu10_PredCopyRegion(svga->swc,
-                                      dst_handle, dstSubResource,
-                                      src_handle, srcSubResource, &box);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_PredCopyRegion(svga->swc,
-                                         dst_handle, dstSubResource,
-                                         src_handle, srcSubResource, &box);
-      assert(ret == PIPE_OK);
-   }
+   SVGA_RETRY(svga, SVGA3D_vgpu10_PredCopyRegion
+              (svga->swc, dst_handle, dstSubResource,
+               src_handle, srcSubResource, &box));
 }
 
 
@@ -93,7 +85,6 @@ svga_texture_copy_handle(struct svga_context *svga,
                          unsigned width, unsigned height, unsigned depth)
 {
    struct svga_surface dst, src;
-   enum pipe_error ret;
    SVGA3dCopyBox box, *boxes;
 
    assert(svga);
@@ -124,18 +115,11 @@ svga_texture_copy_handle(struct svga_context *svga,
             dst_handle, dst_level, dst_x, dst_y, dst_z);
 */
 
-   ret = SVGA3D_BeginSurfaceCopy(svga->swc,
-                                 &src.base,
-                                 &dst.base,
-                                 &boxes, 1);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_BeginSurfaceCopy(svga->swc,
-                                    &src.base,
-                                    &dst.base,
-                                    &boxes, 1);
-      assert(ret == PIPE_OK);
-   }
+   SVGA_RETRY(svga, SVGA3D_BeginSurfaceCopy(svga->swc,
+                                            &src.base,
+                                            &dst.base,
+                                            &boxes, 1));
+
    *boxes = box;
    SVGA_FIFOCommitAll(svga->swc);
 }
@@ -563,7 +547,7 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
     * associated resource. We will then use the cloned surface view for
     * render target.
     */
-   for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
+   for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_TESS_EVAL; shader++) {
       if (svga_check_sampler_view_resource_collision(svga, s->handle, shader)) {
          SVGA_DBG(DEBUG_VIEWS,
                   "same resource used in shaderResource and renderTarget 0x%x\n",
@@ -601,11 +585,7 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
           * need to update the host-side copy with the invalid
           * content when the associated mob is first bound to the surface.
           */
-         if (SVGA3D_InvalidateGBSurface(svga->swc, stex->handle) != PIPE_OK) {
-            svga_context_flush(svga, NULL);
-            ret = SVGA3D_InvalidateGBSurface(svga->swc, stex->handle);
-            assert(ret == PIPE_OK);
-         }
+         SVGA_RETRY(svga, SVGA3D_InvalidateGBSurface(svga->swc, stex->handle));
          stex->validated = TRUE;
       }
 
@@ -670,7 +650,6 @@ svga_surface_destroy(struct pipe_context *pipe,
    struct svga_surface *s = svga_surface(surf);
    struct svga_texture *t = svga_texture(surf->texture);
    struct svga_screen *ss = svga_screen(surf->texture->screen);
-   enum pipe_error ret = PIPE_OK;
 
    SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_DESTROYSURFACE);
 
@@ -689,8 +668,6 @@ svga_surface_destroy(struct pipe_context *pipe,
    }
 
    if (s->view_id != SVGA3D_INVALID_ID) {
-      unsigned try;
-
       /* The SVGA3D device will generate a device error if the
        * render target view or depth stencil view is destroyed from
        * a context other than the one it was created with.
@@ -702,18 +679,14 @@ svga_surface_destroy(struct pipe_context *pipe,
       }
       else {
          assert(svga_have_vgpu10(svga));
-         for (try = 0; try < 2; try++) {
-            if (util_format_is_depth_or_stencil(s->base.format)) {
-               ret = SVGA3D_vgpu10_DestroyDepthStencilView(svga->swc, s->view_id);
-            }
-            else {
-               ret = SVGA3D_vgpu10_DestroyRenderTargetView(svga->swc, s->view_id);
-            }
-            if (ret == PIPE_OK)
-               break;
-            svga_context_flush(svga, NULL);
+         if (util_format_is_depth_or_stencil(s->base.format)) {
+            SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyDepthStencilView(svga->swc,
+                                                                   s->view_id));
+         }
+         else {
+            SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyRenderTargetView(svga->swc,
+                                                                   s->view_id));
          }
-         assert(ret == PIPE_OK);
          util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
       }
    }
index 3e8c90d8e1e12f786a71a7e912b6d75859d58967..5887a9ad7d737b077356635da9d70af17e2ad9f5 100644 (file)
@@ -216,9 +216,9 @@ svga_vbuf_submit_state(struct svga_vbuf_render *svga_render)
 {
    struct svga_context *svga = svga_render->svga;
    SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS];
-   enum pipe_error ret;
    unsigned i;
    static const unsigned zero[PIPE_MAX_ATTRIBS] = {0};
+   boolean retried;
 
    /* if the vdecl or vbuf hasn't changed do nothing */
    if (!svga->swtnl.new_vdecl)
@@ -230,13 +230,10 @@ svga_vbuf_submit_state(struct svga_vbuf_render *svga_render)
    memcpy(vdecl, svga_render->vdecl, sizeof(vdecl));
 
    /* flush the hw state */
-   ret = svga_hwtnl_flush(svga->hwtnl);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = svga_hwtnl_flush(svga->hwtnl);
+   SVGA_RETRY_CHECK(svga, svga_hwtnl_flush(svga->hwtnl), retried);
+   if (retried) {
       /* if we hit this path we might become synced with hw */
       svga->swtnl.new_vbuf = TRUE;
-      assert(ret == PIPE_OK);
    }
 
    for (i = 0; i < svga_render->vdecl_count; i++) {
index 96d8a52eb6244608c0afff0726a39a94c219f68d..b719dd400c6f08329813cb0d01b64450904d535c 100644 (file)
@@ -47,7 +47,7 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
    ASSERTED unsigned old_num_vertex_buffers;
    unsigned i;
    const void *map;
-   enum pipe_error ret;
+   boolean retried;
 
    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SWTNLDRAWVBO);
 
@@ -58,12 +58,9 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
    /* Make sure that the need_swtnl flag does not go away */
    svga->state.sw.in_swtnl_draw = TRUE;
 
-   ret = svga_update_state(svga, SVGA_STATE_SWTNL_DRAW);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = svga_update_state(svga, SVGA_STATE_SWTNL_DRAW);
+   SVGA_RETRY_CHECK(svga, svga_update_state(svga, SVGA_STATE_SWTNL_DRAW), retried);
+   if (retried) {
       svga->swtnl.new_vbuf = TRUE;
-      assert(ret == PIPE_OK);
    }
 
    /*
@@ -148,7 +145,7 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
    svga->dirty |= SVGA_NEW_NEED_PIPELINE | SVGA_NEW_NEED_SWVFETCH;
 
    SVGA_STATS_TIME_POP(svga_sws(svga));
-   return ret;
+   return PIPE_OK;
 }
 
 
index 6e607cd0616813783b314c54259c6be64f4fe018..0c07985519cde8813cce38c1b56cd3f6d306a2e3 100644 (file)
@@ -279,6 +279,10 @@ struct svga_shader_emitter_v10
       /* viewport constant */
       unsigned viewport_index;
 
+      unsigned vertex_id_bias_index;
+      unsigned vertex_id_sys_index;
+      unsigned vertex_id_tmp_index;
+
       /* temp index of adjusted vertex attributes */
       unsigned adjusted_input[PIPE_MAX_SHADER_INPUTS];
    } vs;
@@ -333,7 +337,6 @@ struct svga_shader_emitter_v10
    struct {
       unsigned vertices_per_patch_index;     /**< vertices_per_patch system value index */
       unsigned imm_index;                    /**< immediate for tcs */
-      unsigned vertices_out;
       unsigned invocation_id_sys_index;      /**< invocation id */
       unsigned invocation_id_tmp_index;
       unsigned instruction_token_pos;        /* token pos for the first instruction */
@@ -343,6 +346,7 @@ struct svga_shader_emitter_v10
       unsigned control_point_tmp_index;      /* control point temporary register */
       unsigned control_point_out_count;      /* control point output count */
       boolean  control_point_phase;          /* true if in control point phase */
+      boolean  fork_phase_add_signature;     /* true if needs to add signature in fork phase */
       unsigned patch_generic_out_count;      /* per-patch generic output count */
       unsigned patch_generic_out_index;      /* per-patch generic output register index*/
       unsigned patch_generic_tmp_index;      /* per-patch generic temporary register index*/
@@ -408,6 +412,7 @@ struct svga_shader_emitter_v10
 
    /* VS/TCS/TES/GS/FS Linkage info */
    struct shader_linkage linkage;
+   struct tgsi_shader_info *prevShaderInfo;
 
    /* Shader signature */
    struct svga_shader_signature signature;
@@ -603,7 +608,7 @@ check_register_index(struct svga_shader_emitter_v10 *emit,
           (emit->unit == PIPE_SHADER_FRAGMENT &&
            index >= VGPU10_MAX_FS_INPUTS) ||
           (emit->unit == PIPE_SHADER_TESS_CTRL &&
-           index >= VGPU11_MAX_HS_INPUTS) ||
+           index >= VGPU11_MAX_HS_INPUT_CONTROL_POINTS) ||
           (emit->unit == PIPE_SHADER_TESS_EVAL &&
            index >= VGPU11_MAX_DS_INPUT_CONTROL_POINTS)) {
          emit->register_overflow = TRUE;
@@ -1445,7 +1450,7 @@ static boolean
 need_temp_reg_initialization(struct svga_shader_emitter_v10 *emit,
                              unsigned index)
 {
-   if (!(emit->info.indirect_files & (1u << TGSI_FILE_TEMPORARY))
+   if (!(emit->info.indirect_files && (1u << TGSI_FILE_TEMPORARY))
        && emit->current_loop_depth == 0) {
       if (!emit->temp_map[index].initialized &&
           emit->temp_map[index].index < emit->num_shader_temps) {
@@ -1575,10 +1580,18 @@ emit_src_register(struct svga_shader_emitter_v10 *emit,
          }
       }
       else if (file == TGSI_FILE_SYSTEM_VALUE) {
-         /* Map the TGSI system value to a VGPU10 input register */
-         assert(index < ARRAY_SIZE(emit->system_value_indexes));
-         file = TGSI_FILE_INPUT;
-         index = emit->system_value_indexes[index];
+         if (index == emit->vs.vertex_id_sys_index &&
+             emit->vs.vertex_id_tmp_index != INVALID_INDEX) {
+            file = TGSI_FILE_TEMPORARY;
+            index = emit->vs.vertex_id_tmp_index;
+            swizzleX = swizzleY = swizzleZ = swizzleW = TGSI_SWIZZLE_X;
+         }
+         else {
+            /* Map the TGSI system value to a VGPU10 input register */
+            assert(index < ARRAY_SIZE(emit->system_value_indexes));
+            file = TGSI_FILE_INPUT;
+            index = emit->system_value_indexes[index];
+         }
       }
    }
    else if (emit->unit == PIPE_SHADER_TESS_CTRL) {
@@ -1600,7 +1613,10 @@ emit_src_register(struct svga_shader_emitter_v10 *emit,
                 */
                operand0.numComponents = VGPU10_OPERAND_1_COMPONENT;
                operand0.operandType = VGPU10_OPERAND_TYPE_OUTPUT_CONTROL_POINT_ID;
-               index = 0;
+               operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_MASK_MODE;
+               operand0.mask = 0;
+               emit_dword(emit, operand0.value);
+               return;
             }
             else {
                /* There is no control point ID input declaration in
@@ -1718,6 +1734,8 @@ emit_src_register(struct svga_shader_emitter_v10 *emit,
              * to align with the tcs output index.
              */
             index = emit->linkage.input_map[index];
+
+            assert(index2 < emit->key.tes.vertices_per_patch);
          }
          else {
             if (index < emit->key.tes.tessfactor_index)
@@ -2824,7 +2842,7 @@ emit_vgpu10_property(struct svga_shader_emitter_v10 *emit,
       break;
 
    case TGSI_PROPERTY_TCS_VERTICES_OUT:
-      emit->tcs.vertices_out = prop->u[0].Data;
+      /* This info is already captured in the shader key */
       break;
 
    case TGSI_PROPERTY_TES_PRIM_MODE:
@@ -2935,7 +2953,7 @@ emit_domain_shader_declarations(struct svga_shader_emitter_v10 *emit)
    assert(emit->unit == PIPE_SHADER_TESS_EVAL);
 
    /* Emit the input control point count */
-   assert(emit->key.tes.vertices_per_patch > 0 &&
+   assert(emit->key.tes.vertices_per_patch >= 0 &&
           emit->key.tes.vertices_per_patch <= 32);
 
    opcode0.value = 0;
@@ -3066,11 +3084,11 @@ emit_hull_shader_declarations(struct svga_shader_emitter_v10 *emit)
    end_emit_instruction(emit);
 
    /* Emit the output control point count */
-   assert(emit->tcs.vertices_out >= 0 && emit->tcs.vertices_out <= 32);
+   assert(emit->key.tcs.vertices_out >= 0 && emit->key.tcs.vertices_out <= 32);
 
    opcode0.value = 0;
    opcode0.opcodeType = VGPU10_OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT;
-   opcode0.controlPointCount = emit->tcs.vertices_out;
+   opcode0.controlPointCount = emit->key.tcs.vertices_out;
    begin_emit_instruction(emit);
    emit_dword(emit, opcode0.value);
    end_emit_instruction(emit);
@@ -3157,7 +3175,8 @@ needs_control_point_phase(struct svga_shader_emitter_v10 *emit)
     * we need a control point phase to explicitly set the output control
     * points.
     */
-   if (emit->key.tcs.vertices_per_patch != emit->tcs.vertices_out)
+   if ((emit->key.tcs.vertices_per_patch != emit->key.tcs.vertices_out) &&
+       emit->key.tcs.vertices_out)
       return TRUE;
 
    for (i = 0; i < emit->info.num_outputs; i++) {
@@ -3175,23 +3194,93 @@ needs_control_point_phase(struct svga_shader_emitter_v10 *emit)
 
 
 /**
- * Start the hull shader control point phase
+ * A helper function to add shader signature for passthrough control point
+ * phase. This signature is also generated for passthrough control point
+ * phase from HLSL compiler and is needed by Metal Renderer.
  */
-static boolean
-emit_hull_shader_control_point_phase(struct svga_shader_emitter_v10 *emit)
+static void
+emit_passthrough_control_point_signature(struct svga_shader_emitter_v10 *emit)
 {
-   VGPU10OpcodeToken0 opcode0;
+   struct svga_shader_signature *sgn = &emit->signature;
+   SVGA3dDXShaderSignatureEntry *sgnEntry;
+   unsigned i;
 
-   /* If there is no control point output, skip the control point phase. */
-   if (!needs_control_point_phase(emit))
-      return FALSE;
+   for (i = 0; i < emit->info.num_inputs; i++) {
+      unsigned index = emit->linkage.input_map[i];
+      enum tgsi_semantic sem_name = emit->info.input_semantic_name[i];
+
+      sgnEntry = &sgn->inputs[sgn->header.numInputSignatures++];
+
+      set_shader_signature_entry(sgnEntry, index,
+                                 tgsi_semantic_to_sgn_name[sem_name],
+                                 VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
+                                 SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN,
+                                 SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT);
+
+      sgnEntry = &sgn->outputs[sgn->header.numOutputSignatures++];
+
+      set_shader_signature_entry(sgnEntry, i,
+                                 tgsi_semantic_to_sgn_name[sem_name],
+                                 VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
+                                 SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN,
+                                 SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT);
+   }
+}
+
+
+/**
+ * A helper function to emit an instruction to start the control point phase
+ * in the hull shader.
+ */
+static void
+emit_control_point_phase_instruction(struct svga_shader_emitter_v10 *emit)
+{
+   VGPU10OpcodeToken0 opcode0;
 
-   /* Start the control point phase in the hull shader */
    opcode0.value = 0;
    opcode0.opcodeType = VGPU10_OPCODE_HS_CONTROL_POINT_PHASE;
    begin_emit_instruction(emit);
    emit_dword(emit, opcode0.value);
    end_emit_instruction(emit);
+}
+
+
+/**
+ * Start the hull shader control point phase
+ */
+static boolean
+emit_hull_shader_control_point_phase(struct svga_shader_emitter_v10 *emit)
+{
+   /* If there is no control point output, skip the control point phase. */
+   if (!needs_control_point_phase(emit)) {
+      if (!emit->key.tcs.vertices_out) {
+         /**
+          * If the tcs does not explicitly generate any control point output
+          * and the tes does not use any input control point, then
+          * emit an empty control point phase with zero output control
+          * point count.
+          */
+         emit_control_point_phase_instruction(emit);
+
+         /**
+          * Since this is an empty control point phase, we will need to
+          * add input signatures when we parse the tcs again in the
+          * patch constant phase.
+          */
+         emit->tcs.fork_phase_add_signature = TRUE;
+      }
+      else {
+         /**
+          * Before skipping the control point phase, add the signature for
+          * the passthrough control point.
+          */
+         emit_passthrough_control_point_signature(emit);
+      }
+      return FALSE;
+   }
+
+   /* Start the control point phase in the hull shader */
+   emit_control_point_phase_instruction(emit);
 
    /* Declare the output control point ID */
    if (emit->tcs.invocation_id_sys_index == INVALID_INDEX) {
@@ -3799,9 +3888,6 @@ emit_fs_output_declarations(struct svga_shader_emitter_v10 *emit)
                      emit->key.fs.write_color0_to_n_cbufs;
             }
          }
-         else {
-            assert(!emit->key.fs.write_color0_to_n_cbufs);
-         }
       }
       else if (semantic_name == TGSI_SEMANTIC_POSITION) {
          /* Fragment depth output */
@@ -4064,7 +4150,7 @@ emit_tesslevel_declaration(struct svga_shader_emitter_v10 *emit,
    SVGA3dDXShaderSignatureEntry *sgnEntry =
       &sgn->patchConstants[sgn->header.numPatchConstantSignatures++];
    set_shader_signature_entry(sgnEntry, index,
-                              sgnName, SVGA3DWRITEMASK_0,
+                              sgnName, VGPU10_OPERAND_4_COMPONENT_MASK_X,
                               SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN,
                               SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT);
 }
@@ -4324,6 +4410,7 @@ emit_system_value_declaration(struct svga_shader_emitter_v10 *emit,
                              map_tgsi_semantic_to_sgn_name(semantic_name));
       break;
    case TGSI_SEMANTIC_VERTEXID:
+      emit->vs.vertex_id_sys_index = index;
       index = alloc_system_value_index(emit, index);
       emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT_SIV,
                              VGPU10_OPERAND_TYPE_INPUT,
@@ -4786,6 +4873,10 @@ emit_tcs_input_declarations(struct svga_shader_emitter_v10 *emit)
    unsigned i;
    unsigned size = emit->key.tcs.vertices_per_patch;
    unsigned indicesMask = 0;
+   boolean addSignature = TRUE;
+
+   if (!emit->tcs.control_point_phase)
+      addSignature = emit->tcs.fork_phase_add_signature;
 
    for (i = 0; i < emit->info.num_inputs; i++) {
       unsigned usage_mask = emit->info.input_usage_mask[i];
@@ -4793,7 +4884,8 @@ emit_tcs_input_declarations(struct svga_shader_emitter_v10 *emit)
       enum tgsi_semantic semantic_name = emit->info.input_semantic_name[i];
       VGPU10_SYSTEM_NAME name = VGPU10_NAME_UNDEFINED;
       VGPU10_OPERAND_TYPE operandType = VGPU10_OPERAND_TYPE_INPUT;
-      boolean addSignature = TRUE;
+      SVGA3dDXSignatureSemanticName sgn_name =
+         map_tgsi_semantic_to_sgn_name(semantic_name);
 
       /* indices that are declared */
       indicesMask |= 1 << index;
@@ -4806,13 +4898,18 @@ emit_tcs_input_declarations(struct svga_shader_emitter_v10 *emit)
       else if (usage_mask == 0) {
          continue;  /* register is not actually used */
       }
+      else if (semantic_name == TGSI_SEMANTIC_CLIPDIST) {
+         /* The shadow copy is being used here. So set the signature name
+          * to UNDEFINED.
+          */
+         sgn_name = SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED;
+      }
 
       /* input control points in the patch constant phase are emitted in the
        * vicp register rather than the v register.
        */
       if (!emit->tcs.control_point_phase) {
          operandType = VGPU10_OPERAND_TYPE_INPUT_CONTROL_POINT;
-         addSignature = emit->tcs.control_point_out_count == 0;
       }
 
       /* Tessellation control shader inputs are two dimensional.
@@ -4826,9 +4923,7 @@ emit_tcs_input_declarations(struct svga_shader_emitter_v10 *emit)
                              VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
                              VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
                              VGPU10_INTERPOLATION_UNDEFINED,
-                             addSignature,
-                             map_tgsi_semantic_to_sgn_name(semantic_name));
-
+                             addSignature, sgn_name);
    }
 
    if (emit->tcs.control_point_phase) {
@@ -4983,6 +5078,54 @@ emit_tes_input_declarations(struct svga_shader_emitter_v10 *emit)
    }
 
    emit_tessfactor_input_declarations(emit);
+
+   /* DX spec requires DS input controlpoint/patch-constant signatures to match
+    * the HS output controlpoint/patch-constant signatures exactly.
+    * Add missing input declarations even if they are not used in the shader.
+    */
+   if (emit->linkage.num_inputs < emit->linkage.prevShader.num_outputs) {
+      struct tgsi_shader_info *prevInfo = emit->prevShaderInfo;
+      for (i = 0; i < emit->linkage.prevShader.num_outputs; i++) {
+
+          /* If a tcs output does not have a corresponding input register in
+           * tes, add one.
+           */
+          if (emit->linkage.prevShader.output_map[i] >
+              emit->linkage.input_map_max) {
+             const enum tgsi_semantic sem_name = prevInfo->output_semantic_name[i];
+
+             if (sem_name == TGSI_SEMANTIC_PATCH) {
+                emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT,
+                                       VGPU10_OPERAND_TYPE_INPUT_PATCH_CONSTANT,
+                                       VGPU10_OPERAND_INDEX_1D,
+                                       i, 1, VGPU10_NAME_UNDEFINED,
+                                       VGPU10_OPERAND_4_COMPONENT,
+                                       VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
+                                       VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
+                                       VGPU10_INTERPOLATION_UNDEFINED,
+                                       TRUE,
+                                       map_tgsi_semantic_to_sgn_name(sem_name));
+
+             } else if (sem_name != TGSI_SEMANTIC_TESSINNER &&
+                        sem_name != TGSI_SEMANTIC_TESSOUTER) {
+                emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT,
+                                       VGPU10_OPERAND_TYPE_INPUT_CONTROL_POINT,
+                                       VGPU10_OPERAND_INDEX_2D,
+                                       i, emit->key.tes.vertices_per_patch,
+                                       VGPU10_NAME_UNDEFINED,
+                                       VGPU10_OPERAND_4_COMPONENT,
+                                       VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
+                                       VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
+                                       VGPU10_INTERPOLATION_UNDEFINED,
+                                       TRUE,
+                                       map_tgsi_semantic_to_sgn_name(sem_name));
+             }
+             /* tessellation factors are taken care of in
+              * emit_tessfactor_input_declarations().
+              */
+         }
+      }
+   }
 }
 
 
@@ -5088,7 +5231,7 @@ emit_output_declarations(struct svga_shader_emitter_v10 *emit)
                               VGPU10_NAME_UNDEFINED,
                               emit->output_usage_mask[emit->clip_dist_out_index],
                               TRUE,
-                              SVGADX_SIGNATURE_SEMANTIC_NAME_CLIP_DISTANCE);
+                              SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED);
 
       if (emit->info.num_written_clipdistance > 4) {
          /* for the second clip distance register, each handles 4 planes */
@@ -5097,7 +5240,7 @@ emit_output_declarations(struct svga_shader_emitter_v10 *emit)
                                  VGPU10_NAME_UNDEFINED,
                                  emit->output_usage_mask[emit->clip_dist_out_index+1],
                                  TRUE,
-                                 SVGADX_SIGNATURE_SEMANTIC_NAME_CLIP_DISTANCE);
+                                 SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED);
       }
    }
 
@@ -5184,6 +5327,11 @@ emit_temporaries_declaration(struct svga_shader_emitter_v10 *emit)
       total_temps++;
    }
 
+   if (emit->info.uses_vertexid) {
+      assert(emit->unit == PIPE_SHADER_VERTEX);
+      emit->vs.vertex_id_tmp_index = total_temps++;
+   }
+
    if (emit->unit == PIPE_SHADER_VERTEX || emit->unit == PIPE_SHADER_GEOMETRY) {
       if (emit->vposition.need_prescale || emit->key.vs.undo_viewport ||
           emit->key.clip_plane_enable ||
@@ -5440,6 +5588,9 @@ emit_constant_declaration(struct svga_shader_emitter_v10 *emit)
       if (emit->key.vs.undo_viewport) {
          emit->vs.viewport_index = total_consts++;
       }
+      if (emit->key.vs.need_vertex_id_bias) {
+         emit->vs.vertex_id_bias_index = total_consts++;
+      }
    }
 
    /* user-defined clip planes */
@@ -9985,6 +10136,33 @@ emit_temp_prescale_instructions(struct svga_shader_emitter_v10 *emit)
 }
 
 
+/**
+ * A helper function to emit an instruction in a vertex shader to add a bias
+ * to the VertexID system value. This patches the VertexID in the SVGA vertex
+ * shader to include the base vertex of an indexed primitive or the start index
+ * of a non-indexed primitive.
+ */
+static void
+emit_vertex_id_nobase_instruction(struct svga_shader_emitter_v10 *emit)
+{
+   struct tgsi_full_src_register vertex_id_bias_index =
+      make_src_const_reg(emit->vs.vertex_id_bias_index);
+   struct tgsi_full_src_register vertex_id_sys_src =
+      make_src_reg(TGSI_FILE_SYSTEM_VALUE, emit->vs.vertex_id_sys_index);
+   struct tgsi_full_src_register vertex_id_sys_src_x =
+      scalar_src(&vertex_id_sys_src, TGSI_SWIZZLE_X);
+   struct tgsi_full_dst_register vertex_id_tmp_dst =
+      make_dst_temp_reg(emit->vs.vertex_id_tmp_index);
+
+   /* IADD vertex_id_tmp, vertex_id_sys, vertex_id_bias */
+   unsigned vertex_id_tmp_index = emit->vs.vertex_id_tmp_index;
+   emit->vs.vertex_id_tmp_index = INVALID_INDEX;
+   emit_instruction_opn(emit, VGPU10_OPCODE_IADD, &vertex_id_tmp_dst,
+                        &vertex_id_sys_src_x, &vertex_id_bias_index, NULL, FALSE,
+                        FALSE);
+   emit->vs.vertex_id_tmp_index = vertex_id_tmp_index;
+}
+
 /**
  * Hull Shader must have control point outputs. But tessellation
  * control shader can return without writing to control point output.
@@ -10155,6 +10333,7 @@ emit_pre_helpers(struct svga_shader_emitter_v10 *emit)
        * do a second pass of the instructions for the patch constant phase.
        */
       emit->tcs.instruction_token_pos = emit->cur_tgsi_token;
+      emit->tcs.fork_phase_add_signature = FALSE;
 
       if (!emit_hull_shader_control_point_phase(emit)) {
          emit->skip_instruction = TRUE;
@@ -10230,6 +10409,9 @@ emit_pre_helpers(struct svga_shader_emitter_v10 *emit)
    }
    else if (emit->unit == PIPE_SHADER_VERTEX) {
       emit_vertex_attrib_instructions(emit);
+
+      if (emit->info.uses_vertexid)
+         emit_vertex_id_nobase_instruction(emit);
    }
    else if (emit->unit == PIPE_SHADER_TESS_EVAL) {
       emit_temp_tessfactor_instructions(emit);
@@ -10707,6 +10889,7 @@ compute_input_mapping(struct svga_context *svga,
 
    if (prevShader != NULL) {
       svga_link_shaders(&prevShader->info, &emit->info, &emit->linkage);
+      emit->prevShaderInfo = &prevShader->info;
    } 
    else {
       /**
@@ -10830,6 +11013,10 @@ svga_tgsi_vgpu10_translate(struct svga_context *svga,
    emit->vposition.so_index = INVALID_INDEX;
    emit->vposition.out_index = INVALID_INDEX;
 
+   emit->vs.vertex_id_sys_index = INVALID_INDEX;
+   emit->vs.vertex_id_tmp_index = INVALID_INDEX;
+   emit->vs.vertex_id_bias_index = INVALID_INDEX;
+
    emit->fs.color_tmp_index = INVALID_INDEX;
    emit->fs.face_input_index = INVALID_INDEX;
    emit->fs.fragcoord_input_index = INVALID_INDEX;
index 717e56caccf44159f35806b50aa723fc0e12d4a7..55534953d0cb422577a73fe0514947c927405dab 100644 (file)
@@ -132,6 +132,8 @@ enum svga_stats_time {
    SVGA_STATS_TIME_CREATEGS,
    SVGA_STATS_TIME_CREATESURFACE,
    SVGA_STATS_TIME_CREATESURFACEVIEW,
+   SVGA_STATS_TIME_CREATETCS,
+   SVGA_STATS_TIME_CREATETES,
    SVGA_STATS_TIME_CREATETEXTURE,
    SVGA_STATS_TIME_CREATEVS,
    SVGA_STATS_TIME_DEFINESHADER,
@@ -141,6 +143,8 @@ enum svga_stats_time {
    SVGA_STATS_TIME_DRAWELEMENTS,
    SVGA_STATS_TIME_EMITFS,
    SVGA_STATS_TIME_EMITGS,
+   SVGA_STATS_TIME_EMITTCS,
+   SVGA_STATS_TIME_EMITTES,
    SVGA_STATS_TIME_EMITVS,
    SVGA_STATS_TIME_EMULATESURFACEVIEW,
    SVGA_STATS_TIME_FENCEFINISH,
@@ -201,6 +205,8 @@ enum svga_stats_time {
    SVGA_STATS_PREFIX "CreateGS",                    \
    SVGA_STATS_PREFIX "CreateSurface",               \
    SVGA_STATS_PREFIX "CreateSurfaceView",           \
+   SVGA_STATS_PREFIX "CreateTCS",                   \
+   SVGA_STATS_PREFIX "CreateTES",                   \
    SVGA_STATS_PREFIX "CreateTexture",               \
    SVGA_STATS_PREFIX "CreateVS",                    \
    SVGA_STATS_PREFIX "DefineShader",                \
@@ -210,6 +216,8 @@ enum svga_stats_time {
    SVGA_STATS_PREFIX "DrawElements",                \
    SVGA_STATS_PREFIX "EmitFS",                      \
    SVGA_STATS_PREFIX "EmitGS",                      \
+   SVGA_STATS_PREFIX "EmitTCS",                     \
+   SVGA_STATS_PREFIX "EmitTES",                     \
    SVGA_STATS_PREFIX "EmitVS",                      \
    SVGA_STATS_PREFIX "EmulateSurfaceView",          \
    SVGA_STATS_PREFIX "FenceFinish",                 \
@@ -594,6 +602,11 @@ struct svga_winsys_screen
                          uint32 numMipLevels,
                          uint32 numSamples);
 
+   void
+   (*surface_init)(struct svga_winsys_screen *sws,
+                   struct svga_winsys_surface *surface,
+                   unsigned surf_size, SVGA3dSurfaceAllFlags flags);
+
    /**
     * Buffer management. Buffer attributes are mostly fixed over its lifetime.
     *
@@ -786,6 +799,7 @@ struct svga_winsys_screen
    boolean have_transfer_from_buffer_cmd;
    boolean have_fence_fd;
    boolean have_intra_surface_copy;
+   boolean have_constant_buffer_offset_cmd;
 };
 
 
index 2f70212de616c556b99e888e2d4fc58065b4ac89..917c7ef2f2510c78cd9ab792729341685782adc7 100644 (file)
@@ -98,6 +98,7 @@ vmw_winsys_create( int fd )
    vws->base.have_gb_dma = !vws->force_coherent;
    vws->base.need_to_rebind_resources = FALSE;
    vws->base.have_transfer_from_buffer_cmd = vws->base.have_vgpu10;
+   vws->base.have_constant_buffer_offset_cmd = FALSE;
    getenv_val = getenv("SVGA_FORCE_KERNEL_UNMAPS");
    vws->cache_maps = !getenv_val || strcmp(getenv_val, "0") == 0;
    vws->fence_ops = vmw_fence_ops_create(vws);
index fb0bee778224af96a86464d3251bf870e50821f3..38ef3bcb9feb38d4278775424333f67d971522d6 100644 (file)
@@ -495,6 +495,7 @@ vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws)
    vws->base.buffer_map = vmw_svga_winsys_buffer_map;
    vws->base.buffer_unmap = vmw_svga_winsys_buffer_unmap;
    vws->base.buffer_destroy = vmw_svga_winsys_buffer_destroy;
+   vws->base.surface_init = vmw_svga_winsys_surface_init;
    vws->base.fence_reference = vmw_svga_winsys_fence_reference;
    vws->base.fence_signalled = vmw_svga_winsys_fence_signalled;
    vws->base.shader_create = vmw_svga_winsys_shader_create;
index 698cd11a28e58a0a4a56b98cfc82d94a31146674..f6f40fcdf209abf108dc394c8f217e65445ef736 100644 (file)
 #include "vmw_context.h"
 #include "pipebuffer/pb_bufmgr.h"
 
+void
+vmw_svga_winsys_surface_init(struct svga_winsys_screen *sws,
+                             struct svga_winsys_surface *srf,
+                             unsigned surf_size, SVGA3dSurfaceAllFlags flags)
+{
+   struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf);
+   void *data = NULL;
+   struct pb_buffer *pb_buf;
+   uint32_t pb_flags;
+   struct vmw_winsys_screen *vws = vsrf->screen;
+   pb_flags = PIPE_TRANSFER_READ_WRITE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
+
+   struct pb_manager *provider;
+   struct pb_desc desc;
+
+   data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf,
+                                     PIPE_TRANSFER_DONTBLOCK | pb_flags);
+   if (data)
+      goto out_unlock;
+
+   provider = vws->pools.mob_fenced;
+   memset(&desc, 0, sizeof(desc));
+   desc.alignment = 4096;
+   pb_buf = provider->create_buffer(provider, vsrf->size, &desc);
+   if (pb_buf != NULL) {
+      struct svga_winsys_buffer *vbuf =
+         vmw_svga_winsys_buffer_wrap(pb_buf);
+
+      data = vmw_svga_winsys_buffer_map(&vws->base, vbuf, pb_flags);
+      if (data) {
+         if (vsrf->buf) {
+            vmw_svga_winsys_buffer_destroy(&vws->base, vsrf->buf);
+            vsrf->buf = vbuf;
+            goto out_unlock;
+         } else
+            vmw_svga_winsys_buffer_destroy(&vws->base, vbuf);
+      }
+   }
+
+   data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf, pb_flags);
+   if (data == NULL)
+      goto out_unlock;
+
+out_unlock:
+   mtx_unlock(&vsrf->mutex);
+
+   if (data)
+   {
+      if (flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) {
+         memset(data, 0, surf_size + sizeof(SVGA3dDXSOState));
+      }
+      else {
+         memset(data, 0, surf_size);
+      }
+   }
+   mtx_lock(&vsrf->mutex);
+   vmw_svga_winsys_buffer_unmap(&vsrf->screen->base, vsrf->buf);
+   mtx_unlock(&vsrf->mutex);
+}
 
 void *
 vmw_svga_winsys_surface_map(struct svga_winsys_context *swc,
                             struct svga_winsys_surface *srf,
index ab75fed5f97151a7a9b2b30668e7b430d5b8bdd5..4b1011aa3c76ebc561a955b085139f9adc4e8a19 100644 (file)
@@ -95,4 +95,10 @@ void
 vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc,
                               struct svga_winsys_surface *srf,
                               boolean *rebind);
+
+void
+vmw_svga_winsys_surface_init(struct svga_winsys_screen *sws,
+                             struct svga_winsys_surface *surface,
+                             unsigned surf_size, SVGA3dSurfaceAllFlags flags);
 #endif /* VMW_SURFACE_H_ */