llvmpipe: add ssbo support to compute shaders
authorDave Airlie <airlied@redhat.com>
Tue, 27 Aug 2019 05:21:48 +0000 (15:21 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 4 Sep 2019 05:22:20 +0000 (15:22 +1000)
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/gallium/drivers/llvmpipe/lp_state.h
src/gallium/drivers/llvmpipe/lp_state_cs.c
src/gallium/drivers/llvmpipe/lp_state_cs.h
src/gallium/drivers/llvmpipe/lp_state_fs.c

index 7138e6d74b708d3dd932db74482ae733a325582a..be7eeec811ea0ce0c85aa08c7ea4497a93648436 100644 (file)
@@ -63,6 +63,7 @@
 #define LP_CSNEW_CONSTANTS 0x2
 #define LP_CSNEW_SAMPLER 0x4
 #define LP_CSNEW_SAMPLER_VIEW 0x8
+#define LP_CSNEW_SSBOS 0x10
 
 struct vertex_info;
 struct pipe_context;
index 32bbdd2e6cf7ac56f906cbe45e9c88a9a29552c2..43760852826ac274de16a6b4139345e7769655a1 100644 (file)
@@ -905,6 +905,24 @@ lp_csctx_set_cs_constants(struct lp_cs_context *csctx,
    }
 }
 
+static void
+lp_csctx_set_cs_ssbos(struct lp_cs_context *csctx,
+                       unsigned num,
+                       struct pipe_shader_buffer *buffers)
+{
+   int i;
+   LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *)buffers);
+
+   assert (num <= ARRAY_SIZE(csctx->ssbos));
+
+   for (i = 0; i < num; ++i) {
+      util_copy_shader_buffer(&csctx->ssbos[i].current, &buffers[i]);
+   }
+   for (; i < ARRAY_SIZE(csctx->ssbos); i++) {
+      util_copy_shader_buffer(&csctx->ssbos[i].current, NULL);
+   }
+}
+
 static void
 update_csctx_consts(struct llvmpipe_context *llvmpipe)
 {
@@ -936,6 +954,31 @@ update_csctx_consts(struct llvmpipe_context *llvmpipe)
    }
 }
 
+static void
+update_csctx_ssbo(struct llvmpipe_context *llvmpipe)
+{
+   struct lp_cs_context *csctx = llvmpipe->csctx;
+   int i;
+   for (i = 0; i < ARRAY_SIZE(csctx->ssbos); ++i) {
+      struct pipe_resource *buffer = csctx->ssbos[i].current.buffer;
+      const ubyte *current_data = NULL;
+
+      if (!buffer)
+         continue;
+      /* resource buffer */
+      current_data = (ubyte *) llvmpipe_resource_data(buffer);
+      if (current_data) {
+         current_data += csctx->ssbos[i].current.buffer_offset;
+
+         csctx->cs.current.jit_context.ssbos[i] = (const uint32_t *)current_data;
+         csctx->cs.current.jit_context.num_ssbos[i] = csctx->ssbos[i].current.buffer_size;
+      } else {
+         csctx->cs.current.jit_context.ssbos[i] = NULL;
+         csctx->cs.current.jit_context.num_ssbos[i] = 0;
+      }
+   }
+}
+
 static void
 llvmpipe_cs_update_derived(struct llvmpipe_context *llvmpipe)
 {
@@ -949,6 +992,13 @@ llvmpipe_cs_update_derived(struct llvmpipe_context *llvmpipe)
       update_csctx_consts(llvmpipe);
    }
 
+   if (llvmpipe->cs_dirty & LP_CSNEW_SSBOS) {
+      lp_csctx_set_cs_ssbos(llvmpipe->csctx,
+                            ARRAY_SIZE(llvmpipe->ssbos[PIPE_SHADER_COMPUTE]),
+                            llvmpipe->ssbos[PIPE_SHADER_COMPUTE]);
+      update_csctx_ssbo(llvmpipe);
+   }
+
    if (llvmpipe->cs_dirty & LP_CSNEW_SAMPLER_VIEW)
       lp_csctx_set_sampler_views(llvmpipe->csctx,
                                  llvmpipe->num_sampler_views[PIPE_SHADER_COMPUTE],
@@ -1057,6 +1107,9 @@ lp_csctx_destroy(struct lp_cs_context *csctx)
    for (i = 0; i < ARRAY_SIZE(csctx->constants); i++) {
       pipe_resource_reference(&csctx->constants[i].current.buffer, NULL);
    }
+   for (i = 0; i < ARRAY_SIZE(csctx->ssbos); i++) {
+      pipe_resource_reference(&csctx->ssbos[i].current.buffer, NULL);
+   }
    FREE(csctx);
 }
 
index 031c1d317eab77c686d49b8ee12bc8f0d6456c18..fd72950a92799998a9e4c48d013f7b96d3e3d529 100644 (file)
@@ -106,6 +106,11 @@ struct lp_cs_context {
       unsigned stored_size;
       const void *stored_data;
    } constants[LP_MAX_TGSI_CONST_BUFFERS];
+
+   /** compute shader buffers */
+   struct {
+      struct pipe_shader_buffer current;
+   } ssbos[LP_MAX_TGSI_SHADER_BUFFERS];
 };
 
 struct lp_cs_context *lp_csctx_create(struct pipe_context *pipe);
index cf0e15e6d1031a69bd0ff4a16ae14e393d605bbe..91dee27deba2391c80b91b33b024d34882780cd2 100644 (file)
@@ -3203,6 +3203,8 @@ llvmpipe_set_shader_buffers(struct pipe_context *pipe,
             data += buffer->buffer_offset;
          draw_set_mapped_shader_buffer(llvmpipe->draw, shader,
                                        i, data, size);
+      } else if (shader == PIPE_SHADER_COMPUTE) {
+        llvmpipe->cs_dirty |= LP_CSNEW_SSBOS;
       } else if (shader == PIPE_SHADER_FRAGMENT) {
          llvmpipe->dirty |= LP_NEW_FS_SSBOS;
       }