svga: use srv raw buffer for accessing readonly shader buffer
authorCharmaine Lee <charmainel@vmware.com>
Tue, 13 Sep 2022 05:33:01 +0000 (08:33 +0300)
committerMarge Bot <emma+marge@anholt.net>
Mon, 25 Sep 2023 23:36:58 +0000 (23:36 +0000)
When a surface is to be created for a buffer that is to be persistently mapped,
set the UAV bind flag as well, otherwise, an extra copy of the surface will have
to be created when the buffer is later bound as shader storage buffer, and
it will then incur extra buffer copies to keep the shadow copies of the surface
in sync. But when a buffer is simultanously bound to uniform buffer and shader
storage buffer, having both srv and uav on the same resource can also be costly.
This patch also provides optimization for readonly shader buffer. In this case,
instead of creating uav for accessing a readonly shader buffer, srv
raw buffer is used instead.

Tested with yuzu tracefile included in VMware bug 3029385.

Reviewed-by: Martin Krastev <krastevm@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25381>

14 files changed:
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_resource_buffer.h
src/gallium/drivers/svga/svga_resource_buffer_upload.c
src/gallium/drivers/svga/svga_shader.c
src/gallium/drivers/svga/svga_shader.h
src/gallium/drivers/svga/svga_shader_buffer.c
src/gallium/drivers/svga/svga_shader_buffer.h
src/gallium/drivers/svga/svga_state.c
src/gallium/drivers/svga/svga_state_constants.c
src/gallium/drivers/svga/svga_state_uav.c
src/gallium/drivers/svga/svga_tgsi.c
src/gallium/drivers/svga/svga_tgsi_vgpu10.c

index 2bf5987..aa8e88d 100644 (file)
@@ -1,5 +1,5 @@
 /**********************************************************
- * Copyright 2008-2009 VMware, Inc.  All rights reserved.
+ * Copyright 2008-2022 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -314,6 +314,8 @@ svga_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
           sizeof(svga->state.hw_draw.enabled_constbufs));
    memset(svga->state.hw_draw.enabled_rawbufs, 0,
           sizeof(svga->state.hw_draw.enabled_rawbufs));
+   memset(svga->state.hw_draw.enabled_raw_shaderbufs, 0,
+          sizeof(svga->state.hw_draw.enabled_raw_shaderbufs));
    memset(svga->state.hw_draw.rawbufs, 0,
           sizeof(svga->state.hw_draw.rawbufs));
    svga->state.hw_draw.ib = NULL;
index 93e4155..a079241 100644 (file)
@@ -1,5 +1,5 @@
 /**********************************************************
- * Copyright 2008-2009 VMware, Inc.  All rights reserved.
+ * Copyright 2008-2023 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -89,6 +89,7 @@ enum svga_hud {
  * including the zero slot for the default constant buffer.
  */
 #define SVGA_MAX_CONST_BUFS 15
+#define SVGA_MAX_RAW_BUFS   64
 
 /**
  * Maximum constant buffer size that can be set in the
@@ -98,10 +99,10 @@ enum svga_hud {
 #define SVGA_MAX_CONST_BUF_SIZE (4096 * 4 * sizeof(int))
 
 #define CONST0_UPLOAD_ALIGNMENT 256
+#define SVGA_MAX_UAVIEWS        SVGA3D_DX11_1_MAX_UAVIEWS
 #define SVGA_MAX_IMAGES         SVGA3D_MAX_UAVIEWS
 #define SVGA_MAX_SHADER_BUFFERS        SVGA3D_MAX_UAVIEWS
 #define SVGA_MAX_ATOMIC_BUFFERS        SVGA3D_MAX_UAVIEWS
-#define SVGA_MAX_UAVIEWS        SVGA3D_DX11_1_MAX_UAVIEWS
 
 enum svga_surface_state
 {
@@ -321,7 +322,7 @@ struct svga_state
     * svga_shader_emitter_v10.num_shader_consts.
     */
    struct pipe_constant_buffer constbufs[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
-   struct svga_raw_buffer rawbufs[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
+   struct svga_raw_buffer rawbufs[PIPE_SHADER_TYPES][SVGA_MAX_RAW_BUFS];
 
    struct pipe_framebuffer_state framebuffer;
    float depthscale;
@@ -444,8 +445,8 @@ struct svga_hw_draw_state
    /** Currently bound constant buffer, per shader stage */
    struct pipe_resource *constbuf[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
    struct svga_constant_buffer constbufoffsets[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
-   struct svga_raw_buffer rawbufs[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
-   unsigned enabled_rawbufs[PIPE_SHADER_TYPES];
+   struct svga_raw_buffer rawbufs[PIPE_SHADER_TYPES][SVGA_MAX_RAW_BUFS];
+   uint64_t enabled_rawbufs[PIPE_SHADER_TYPES];
 
    /** Bitmask of enabled constant buffers */
    unsigned enabled_constbufs[PIPE_SHADER_TYPES];
@@ -497,6 +498,7 @@ struct svga_hw_draw_state
    /* Shader Buffers */
    unsigned num_shader_buffers[PIPE_SHADER_TYPES];
    struct svga_shader_buffer shader_buffers[PIPE_SHADER_TYPES][SVGA_MAX_SHADER_BUFFERS];
+   uint64_t enabled_raw_shaderbufs[PIPE_SHADER_TYPES];
 
    /* HW Atomic Buffers */
    unsigned num_atomic_buffers;
@@ -646,9 +648,12 @@ struct svga_context
       /** bitmasks of which const buffers are changed */
       unsigned dirty_constbufs[PIPE_SHADER_TYPES];
 
-      /** bitmasks of which const buffers to be bound as raw buffers */
+      /** bitmasks of which const buffers to be bound as srv raw buffers */
       unsigned raw_constbufs[PIPE_SHADER_TYPES];
 
+      /** bitmasks of which shader buffers to be bound as srv raw buffers */
+      uint64_t raw_shaderbufs[PIPE_SHADER_TYPES];
+
       unsigned texture_timestamp;
       unsigned uav_timestamp[2];
 
index 2e11601..16865ba 100644 (file)
@@ -1,5 +1,5 @@
 /**********************************************************
- * Copyright 2008-2009 VMware, Inc.  All rights reserved.
+ * Copyright 2008-2022 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -503,7 +503,7 @@ svga_validate_constant_buffers(struct svga_context *svga,
       unsigned enabled_rawbufs = svga->state.hw_draw.enabled_rawbufs[shader] & ~1u;
       while (enabled_rawbufs) {
          unsigned i = u_bit_scan(&enabled_rawbufs);
-         buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
+         buffer = svga_buffer(svga->state.hw_draw.rawbufs[shader][i].buffer);
 
          assert(buffer != NULL);
          handle = svga_buffer_handle(svga, &buffer->b,
index ddde586..f9f1644 100644 (file)
@@ -1,5 +1,5 @@
 /**********************************************************
- * Copyright 2008-2009 VMware, Inc.  All rights reserved.
+ * Copyright 2008-2022 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -358,6 +358,15 @@ svga_was_buffer_rendered_to(const struct svga_buffer_surface *bufsurf)
 }
 
 
+static inline bool
+svga_has_raw_buffer_view(struct svga_buffer *sbuf)
+{
+   return (sbuf->uav ||
+           (sbuf->key.persistent &&
+            (sbuf->key.flags & SVGA3D_SURFACE_BIND_RAW_VIEWS) != 0));
+}
+
+
 struct pipe_resource *
 svga_user_buffer_create(struct pipe_screen *screen,
                         void *ptr,
index 29cae84..fd4ec4e 100644 (file)
@@ -222,7 +222,10 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
              * surface cannot have other bind flags.
              */
             if ((bind_flags & PIPE_BIND_CONSTANT_BUFFER) == 0) {
-               sbuf->key.flags |= SVGA3D_SURFACE_BIND_RAW_VIEWS;
+              sbuf->key.flags |= SVGA3D_SURFACE_BIND_UAVIEW |
+                                  SVGA3D_SURFACE_BIND_RAW_VIEWS;
+               bind_flags = bind_flags | PIPE_BIND_SHADER_BUFFER;
+               //sbuf->key.flags |= SVGA3D_SURFACE_BIND_RAW_VIEWS;
             }
          }
       }
index 4eeabf3..b410f97 100644 (file)
@@ -470,6 +470,19 @@ svga_init_shader_key_common(const struct svga_context *svga,
    }
 
    if (svga_have_gl43(svga)) {
+
+      /* Save info about which constant buffers are to be viewed
+       * as srv raw buffers in the shader key.
+       */
+      if (shader->info.const_buffers_declared &
+          svga->state.raw_constbufs[shader_type]) {
+         key->raw_constbufs = svga->state.raw_constbufs[shader_type] &
+                              shader->info.const_buffers_declared;
+      }
+
+      /* beginning index for srv for raw constant buffers */
+      key->srv_raw_constbuf_index = PIPE_MAX_SAMPLERS;
+
       if (shader->info.uses_images || shader->info.uses_hw_atomic ||
           shader->info.uses_shader_buffers) {
 
@@ -520,10 +533,21 @@ svga_init_shader_key_common(const struct svga_context *svga,
          const struct svga_shader_buffer *cur_sbuf =
             &svga->curr.shader_buffers[shader_type][0];
 
+         /* Save info about which shader buffers are to be viewed
+          * as srv raw buffers in the shader key.
+          */
+         if (shader->info.shader_buffers_declared &
+             svga->state.raw_shaderbufs[shader_type]) {
+            key->raw_shaderbufs = svga->state.raw_shaderbufs[shader_type] &
+                                  shader->info.shader_buffers_declared;
+            key->srv_raw_shaderbuf_index = key->srv_raw_constbuf_index +
+                                          SVGA_MAX_CONST_BUFS;
+         }
+
          for (unsigned i = 0; i < ARRAY_SIZE(svga->curr.shader_buffers[shader_type]);
               i++, cur_sbuf++) {
 
-            if (cur_sbuf->resource)
+            if (cur_sbuf->resource && (!(key->raw_shaderbufs & (1 << i))))
                key->shader_buf_uav_index[i] = cur_sbuf->uav_index + uav_splice_index;
             else
                key->shader_buf_uav_index[i] = SVGA3D_INVALID_ID;
@@ -543,16 +567,6 @@ svga_init_shader_key_common(const struct svga_context *svga,
          key->image_size_used = shader->info.uses_image_size;
       }
 
-      /* Save info about which constant buffers are to be viewed
-       * as raw buffers in the shader key.
-       */
-      if (shader->info.const_buffers_declared &
-          svga->state.raw_constbufs[shader_type]) {
-         key->raw_buffers = svga->state.raw_constbufs[shader_type];
-
-         /* beginning index for srv for raw buffers */
-         key->srv_raw_buf_index = PIPE_MAX_SAMPLERS;
-      }
    }
 
    key->clamp_vertex_color = svga->curr.rast ?
index 9604017..e59b025 100644 (file)
@@ -1,5 +1,5 @@
 /**********************************************************
- * Copyright 2008-2022 VMware, Inc.  All rights reserved.
+ * Copyright 2008-2023 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -151,10 +151,12 @@ struct svga_compile_key
    } tex[PIPE_MAX_SAMPLERS];
 
    unsigned uav_splice_index:4;      /* starting uav index */
-   unsigned srv_raw_buf_index:8;     /* start index for srv raw buffers */
+   unsigned srv_raw_constbuf_index:8;   /* start index for srv raw buffers */
+   unsigned srv_raw_shaderbuf_index:8;  /* start index for srv raw shader bufs */
    unsigned image_size_used:1;
 
-   uint16_t raw_buffers;             /* bitmask of raw buffers */
+   uint16_t raw_constbufs;           /* bitmask of raw constant buffers */
+   uint64_t raw_shaderbufs;          /* bitmask of raw shader buffers */
 
    struct {
       enum tgsi_return_type return_type;
@@ -329,6 +331,8 @@ struct svga_shader_info
    unsigned const_buffers_declared;  /* bitmask of declared const buffers */
    unsigned constbuf0_num_uniforms;  /* number of uniforms in constbuf0 */
 
+   unsigned shader_buffers_declared;  /* bitmask of declared shader buffers */
+
    struct {
       bool color0_writes_all_cbufs;
    } fs;
index a39cbd6..61d87b2 100644 (file)
@@ -110,7 +110,7 @@ svga_set_shader_buffers(struct pipe_context *pipe,
    buf = buffers;
    if (buffers) {
       int last_buffer = -1;
-      for (unsigned i = start; i < start + num; i++, buf++) {
+      for (unsigned i = start, j=0; i < start + num; i++, buf++, j++) {
          struct svga_shader_buffer *cbuf = &svga->curr.shader_buffers[shader][i];
 
          if (buf && buf->buffer) {
@@ -125,6 +125,7 @@ svga_set_shader_buffers(struct pipe_context *pipe,
             pipe_resource_reference(&cbuf->resource, NULL);
          }
          cbuf->uav_index = -1;
+        cbuf->writeAccess = (writeable_bitmask & (1 << j)) != 0;
       }
       svga->curr.num_shader_buffers[shader] =
          MAX2(svga->curr.num_shader_buffers[shader], last_buffer + 1);
@@ -342,3 +343,71 @@ svga_validate_shader_buffer_resources(struct svga_context *svga,
 
    return PIPE_OK;
 }
+
+
+/**
+ * Returns TRUE if the shader buffer can be bound to SRV as raw buffer.
+ * It is TRUE if the shader buffer is readonly and the surface already
+ * has the RAW_BUFFER_VIEW bind flag set.
+ */
+bool
+svga_shader_buffer_can_use_srv(struct svga_context *svga,
+                              enum pipe_shader_type shader,
+                               unsigned index,
+                               struct svga_shader_buffer *buf)
+{
+   if (buf->resource) {
+      struct svga_buffer *sbuf = svga_buffer(buf->resource);
+      if (sbuf && !buf->writeAccess && svga_has_raw_buffer_view(sbuf)) {
+         return true;
+      }
+   }
+   return false;
+}
+
+
+#define SVGA_SSBO_SRV_START  SVGA_MAX_CONST_BUFS
+
+/**
+ * Bind the shader buffer as SRV raw buffer.
+ */
+enum pipe_error
+svga_shader_buffer_bind_srv(struct svga_context *svga,
+                            enum pipe_shader_type shader,
+                            unsigned index,
+                            struct svga_shader_buffer *buf)
+{
+   enum pipe_error ret;
+   unsigned slot = index + SVGA_SSBO_SRV_START;
+
+   svga->state.raw_shaderbufs[shader] |= (1 << index);
+   ret = svga_emit_rawbuf(svga, slot, shader, buf->desc.buffer_offset,
+                          buf->desc.buffer_size, buf->resource);
+   if (ret == PIPE_OK)
+      svga->state.hw_draw.enabled_raw_shaderbufs[shader] |= (1 << index);
+
+   return ret;
+}
+
+
+/**
+ * Unbind the shader buffer SRV.
+ */
+enum pipe_error
+svga_shader_buffer_unbind_srv(struct svga_context *svga,
+                              enum pipe_shader_type shader,
+                              unsigned index,
+                              struct svga_shader_buffer *buf)
+{
+   enum pipe_error ret = PIPE_OK;
+   unsigned slot = index + SVGA_SSBO_SRV_START;
+
+   if ((svga->state.hw_draw.enabled_raw_shaderbufs[shader] & (1 << index))
+          != 0) {
+      ret = svga_emit_rawbuf(svga, slot, shader, 0, 0, NULL);
+      if (ret == PIPE_OK)
+         svga->state.hw_draw.enabled_raw_shaderbufs[shader] &= ~(1 << index);
+   }
+   svga->state.raw_shaderbufs[shader] &= ~(1 << index);
+   return ret;
+}
index 7b63b9e..92bfb39 100644 (file)
@@ -31,6 +31,7 @@ struct svga_shader_buffer {
    struct pipe_resource *resource;
    unsigned uav_index;
    struct svga_winsys_surface *handle;
+   bool writeAccess;
 };
 
 void
@@ -54,5 +55,30 @@ svga_create_uav_buffer(struct svga_context *svga,
 void
 svga_uav_cache_purge_buffers(struct svga_context *svga);
 
+bool
+svga_shader_buffer_can_use_srv(struct svga_context *svga,
+                               enum pipe_shader_type shader,
+                               unsigned index,
+                               struct svga_shader_buffer *buffer);
+
+enum pipe_error
+svga_shader_buffer_bind_srv(struct svga_context *svga,
+                            enum pipe_shader_type shader,
+                            unsigned index,
+                            struct svga_shader_buffer *buffer);
+
+enum pipe_error
+svga_shader_buffer_unbind_srv(struct svga_context *svga,
+                              enum pipe_shader_type shader,
+                              unsigned index,
+                              struct svga_shader_buffer *buffer);
+
+enum pipe_error
+svga_emit_rawbuf(struct svga_context *svga,
+                 unsigned slot,
+                 enum pipe_shader_type shader,
+                 unsigned buffer_offset,
+                 unsigned buffer_size,
+                 void *buffer);
 
 #endif /* SVGA_SHADER_BUFFER_H */
index 652eb12..869d0ae 100644 (file)
@@ -1,5 +1,5 @@
 /**********************************************************
- * Copyright 2008-2009 VMware, Inc.  All rights reserved.
+ * Copyright 2008-2022 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -145,8 +145,8 @@ static const struct svga_tracked_state *hw_draw_state_sm5[] =
 static const struct svga_tracked_state *hw_draw_state_gl43[] =
 {
    &svga_need_tgsi_transform,
-   &svga_hw_uav,
    &svga_need_rawbuf_srv,
+   &svga_hw_uav,
    &svga_hw_fs,
    &svga_hw_gs,
    &svga_hw_tes,
index 0e710ff..6e3fdfa 100644 (file)
@@ -639,15 +639,18 @@ svga_destroy_rawbuf_srv(struct svga_context *svga)
 /**
  * A helper function to emit constant buffer as srv raw buffer.
  */
-static enum pipe_error
-emit_rawbuf(struct svga_context *svga,
-            unsigned slot,
-            enum pipe_shader_type shader,
-            unsigned buffer_offset,
-            unsigned buffer_size,
-            void *buffer)
+enum pipe_error
+svga_emit_rawbuf(struct svga_context *svga,
+                 unsigned slot,
+                 enum pipe_shader_type shader,
+                 unsigned buffer_offset,
+                 unsigned buffer_size,
+                 void *buffer)
 {
    enum pipe_error ret = PIPE_OK;
+
+   assert(slot < SVGA_MAX_RAW_BUFS);
+
    struct svga_raw_buffer *rawbuf = &svga->state.hw_draw.rawbufs[shader][slot];
    struct svga_winsys_surface *buf_handle = NULL;
    unsigned srvid = SVGA3D_INVALID_ID;
@@ -1020,7 +1023,7 @@ emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
        * need to be bound as a shader resource raw buffer.
        */
       if (svga->state.raw_constbufs[shader] & (1 << index)) {
-         ret = emit_rawbuf(svga, index, shader, offset, size, buffer);
+         ret = svga_emit_rawbuf(svga, index, shader, offset, size, buffer);
          if (ret != PIPE_OK) {
             return ret;
          }
@@ -1039,7 +1042,7 @@ emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
       }
       else {
          if (svga->state.hw_draw.enabled_rawbufs[shader] & (1 << index)) {
-            ret = emit_rawbuf(svga, index, shader, offset, size, NULL);
+            ret = svga_emit_rawbuf(svga, index, shader, offset, size, NULL);
             if (ret != PIPE_OK) {
                return ret;
             }
@@ -1437,14 +1440,6 @@ struct svga_tracked_state svga_hw_cs_constbufs =
 };
 
 
-static inline boolean
-has_raw_buffer_view(struct svga_buffer *sbuf)
-{
-   return (sbuf->uav ||
-           (sbuf->key.persistent &&
-            (sbuf->key.flags & SVGA3D_SURFACE_BIND_RAW_VIEWS) != 0));
-}
-
 /**
  * A helper function to update the rawbuf for constbuf mask
  */
@@ -1462,7 +1457,7 @@ update_rawbuf_mask(struct svga_context *svga, enum pipe_shader_type shader)
       struct svga_buffer *sbuf =
          svga_buffer(svga->curr.constbufs[shader][index].buffer);
 
-      if (sbuf && has_raw_buffer_view(sbuf)) {
+      if (sbuf && svga_has_raw_buffer_view(sbuf)) {
          svga->state.raw_constbufs[shader] |= (1 << index);
       } else {
          svga->state.raw_constbufs[shader] &= ~(1 << index);
@@ -1491,6 +1486,7 @@ update_rawbuf(struct svga_context *svga, uint64 dirty)
    for (enum pipe_shader_type shader = PIPE_SHADER_VERTEX;
         shader < PIPE_SHADER_COMPUTE; shader++) {
       unsigned rawbuf_mask = svga->state.raw_constbufs[shader];
+      unsigned rawbuf_sbuf_mask = svga->state.raw_shaderbufs[shader];
 
       update_rawbuf_mask(svga, shader);
 
@@ -1498,7 +1494,8 @@ update_rawbuf(struct svga_context *svga, uint64 dirty)
        * send SVGA_NEW_XX_RAW_BUFFER to trigger a new shader
        * variant that will use srv for ubo access.
        */
-      if (svga->state.raw_constbufs[shader] != rawbuf_mask)
+      if ((svga->state.raw_constbufs[shader] != rawbuf_mask) ||
+          (svga->state.raw_shaderbufs[shader] != rawbuf_sbuf_mask))
          svga->dirty |= rawbuf_dirtybit[shader];
    }
 
index 62cd0f4..b7cda4e 100644 (file)
@@ -447,6 +447,19 @@ svga_create_uav_list(struct svga_context *svga,
                 &svga->curr.shader_buffers[shader][i];
             struct pipe_resource *res = cur_sbuf->resource;
             SVGA3dUAViewId uaViewId;
+           enum pipe_error ret;
+
+            /* Use srv rawbuffer to access readonly shader buffer */
+           if (svga_shader_buffer_can_use_srv(svga, shader, i, cur_sbuf)) {
+               ret = svga_shader_buffer_bind_srv(svga, shader, i, cur_sbuf);
+               if (ret != PIPE_OK)
+                  return ret;
+               continue;
+           } else {
+               ret = svga_shader_buffer_unbind_srv(svga, shader, i, cur_sbuf);
+               if (ret != PIPE_OK)
+                  return ret;
+            }
 
             if (res) {
                /* Get the buffer handle that can be bound as uav. */
index 76bc930..038ab40 100644 (file)
@@ -420,6 +420,7 @@ svga_tgsi_scan_shader(struct svga_shader *shader)
    info->uses_image_size = tgsi_info->opcode_count[TGSI_OPCODE_RESQ] ? 1 : 0;
    info->uses_shader_buffers = tgsi_info->shader_buffers_declared != 0;
    info->const_buffers_declared = tgsi_info->const_buffers_declared;
+   info->shader_buffers_declared = tgsi_info->shader_buffers_declared;
 
    info->generic_inputs_mask = svga_get_generic_inputs_mask(tgsi_info);
    info->generic_outputs_mask = svga_get_generic_outputs_mask(tgsi_info);
index caaf265..20e316c 100644 (file)
@@ -272,6 +272,8 @@ struct svga_shader_emitter_v10
 
    /* Shader buffers */
    unsigned num_shader_bufs;
+   unsigned raw_shaderbuf_srv_start_index;  /* starting srv index for raw shaderbuf */
+   uint64_t raw_shaderbufs;                 /* raw shader buffers bitmask */
 
    /* HW atomic buffers */
    unsigned num_atomic_bufs;
@@ -2924,7 +2926,7 @@ emit_vgpu10_immediates_block(struct svga_shader_emitter_v10 *emit)
  * immediates that are allocated after the block is declared. Those
  * immediates are used as constant indices to constant buffers.
  */
-static boolean
+static bool
 reemit_immediates_block(struct svga_shader_emitter_v10 *emit)
 {
    unsigned num_tokens = emit_get_num_tokens(emit);
@@ -2932,7 +2934,7 @@ reemit_immediates_block(struct svga_shader_emitter_v10 *emit)
 
    /* Reserve room for the new immediates */
    if (!reserve(emit, 4 * num_new_immediates))
-      return FALSE;
+      return false;
 
    /* Move the tokens after the immediates block to make room for the
     * new immediates.
@@ -2956,7 +2958,7 @@ reemit_immediates_block(struct svga_shader_emitter_v10 *emit)
 
    emit->ptr = (char *) (tokens + num_tokens + 4 * num_new_immediates);
 
-   return TRUE;
+   return true;
 }
 
 
@@ -5270,7 +5272,6 @@ emit_tcs_input_declarations(struct svga_shader_emitter_v10 *emit)
 {
    unsigned i;
    unsigned size = emit->key.tcs.vertices_per_patch;
-   UNUSED unsigned indicesMask = 0;
    bool addSignature = true;
 
    if (!emit->tcs.control_point_phase)
@@ -5285,9 +5286,6 @@ emit_tcs_input_declarations(struct svga_shader_emitter_v10 *emit)
       SVGA3dDXSignatureSemanticName sgn_name =
          map_tgsi_semantic_to_sgn_name(semantic_name);
 
-      /* indices that are declared */
-      indicesMask |= 1 << index;
-
       if (semantic_name == TGSI_SEMANTIC_POSITION ||
           index == emit->linkage.position_index) {
          /* save the input control point index for later use */
@@ -5932,6 +5930,33 @@ emit_temporaries_declaration(struct svga_shader_emitter_v10 *emit)
 
 
 static bool
+emit_rawbuf_declaration(struct svga_shader_emitter_v10 *emit,
+                        unsigned index)
+{
+   VGPU10OpcodeToken0 opcode1;
+   VGPU10OperandToken0 operand1;
+
+   opcode1.value = 0;
+   opcode1.opcodeType = VGPU10_OPCODE_DCL_RESOURCE_RAW;
+   opcode1.resourceDimension = VGPU10_RESOURCE_DIMENSION_UNKNOWN;
+
+   operand1.value = 0;
+   operand1.numComponents = VGPU10_OPERAND_0_COMPONENT;
+   operand1.operandType = VGPU10_OPERAND_TYPE_RESOURCE;
+   operand1.indexDimension = VGPU10_OPERAND_INDEX_1D;
+   operand1.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
+
+   begin_emit_instruction(emit);
+   emit_dword(emit, opcode1.value);
+   emit_dword(emit, operand1.value);
+   emit_dword(emit, index);
+   end_emit_instruction(emit);
+
+   return true;
+}
+
+
+static bool
 emit_constant_declaration(struct svga_shader_emitter_v10 *emit)
 {
    VGPU10OpcodeToken0 opcode0;
@@ -6034,25 +6059,7 @@ emit_constant_declaration(struct svga_shader_emitter_v10 *emit)
       if (emit->num_shader_consts[i] > 0) {
          if (emit->raw_bufs & (1 << i)) {
             /* UBO declared as srv raw buffer */
-
-            VGPU10OpcodeToken0 opcode1;
-            VGPU10OperandToken0 operand1;
-
-            opcode1.value = 0;
-            opcode1.opcodeType = VGPU10_OPCODE_DCL_RESOURCE_RAW;
-            opcode1.resourceDimension = VGPU10_RESOURCE_DIMENSION_UNKNOWN;
-
-            operand1.value = 0;
-            operand1.numComponents = VGPU10_OPERAND_0_COMPONENT;
-            operand1.operandType = VGPU10_OPERAND_TYPE_RESOURCE;
-            operand1.indexDimension = VGPU10_OPERAND_INDEX_1D;
-            operand1.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
-
-            begin_emit_instruction(emit);
-            emit_dword(emit, opcode1.value);
-            emit_dword(emit, operand1.value);
-            emit_dword(emit, i + emit->raw_buf_srv_start_index);
-            end_emit_instruction(emit);
+            emit_rawbuf_declaration(emit, i + emit->raw_buf_srv_start_index);
          }
          else {
 
@@ -6412,6 +6419,11 @@ emit_shader_buf_declarations(struct svga_shader_emitter_v10 *emit)
       VGPU10OpcodeToken0 opcode0;
       VGPU10OperandToken0 operand0;
 
+      if (emit->raw_shaderbufs & (1 << i)) {
+         emit_rawbuf_declaration(emit, i + emit->raw_shaderbuf_srv_start_index);
+         continue;
+      }
+
       /* If the corresponding uav for the shader buf is already declared,
        * skip this shader buffer declaration.
        */
@@ -10416,6 +10428,13 @@ emit_load_instruction(struct svga_shader_emitter_v10 *emit,
    } else if (resourceType == TGSI_FILE_HW_ATOMIC) {
       emit_uav_register(emit, inst->Src[0].Dimension.Index,
                         UAV_LOAD, inst->Src[0].Register.File, 0);
+   } else if (resourceType == TGSI_FILE_BUFFER) {
+      if (emit->raw_shaderbufs & (1 << resourceIndex))
+         emit_resource_register(emit, resourceIndex +
+                                      emit->raw_shaderbuf_srv_start_index);
+      else
+         emit_uav_register(emit, resourceIndex,
+                           UAV_LOAD, inst->Src[0].Register.File, 0);
    } else {
       emit_uav_register(emit, resourceIndex,
                         UAV_LOAD, inst->Src[0].Register.File, 0);
@@ -12495,7 +12514,8 @@ emit_rawbuf_instruction(struct svga_shader_emitter_v10 *emit,
          imm.Int = element_index;
          int immpos = find_immediate(emit, imm, 0);
          if (immpos < 0) {
-            unsigned element_index_imm = add_immediate_int(emit, element_index);
+            UNUSED unsigned element_index_imm =
+                               add_immediate_int(emit, element_index);
          }
          element_src = make_immediate_reg_int(emit, element_index);
       }
@@ -13112,10 +13132,13 @@ svga_tgsi_vgpu10_translate(struct svga_context *svga,
    }
 
    /* Determine if constbuf to rawbuf translation is needed */
-   if (emit->info.const_buffers_declared) {
-      emit->raw_bufs = emit->key.raw_buffers;
-      emit->raw_buf_srv_start_index = emit->key.srv_raw_buf_index;
-   }
+   emit->raw_buf_srv_start_index = emit->key.srv_raw_constbuf_index;
+   if (emit->info.const_buffers_declared)
+      emit->raw_bufs = emit->key.raw_constbufs;
+
+   emit->raw_shaderbuf_srv_start_index = emit->key.srv_raw_shaderbuf_index;
+   if (emit->info.shader_buffers_declared)
+      emit->raw_shaderbufs = emit->key.raw_shaderbufs;
 
    /*
     * Do actual shader translation.