llvmpipe: add support for compute constant buffers.
authorDave Airlie <airlied@redhat.com>
Tue, 27 Aug 2019 05:08:19 +0000 (15:08 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 4 Sep 2019 05:22:20 +0000 (15:22 +1000)
This is mostly ported from the fragment shader code.

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 8f22debed41420e7c202d76cf67ae9da338db2ac..ca6e412df0b1fb4a7f8c2c5997f62544bce823d0 100644 (file)
@@ -60,6 +60,7 @@
 #define LP_NEW_FS_IMAGES    0x100000
 
 #define LP_CSNEW_CS 0x1
+#define LP_CSNEW_CONSTANTS 0x2
 
 struct vertex_info;
 struct pipe_context;
index 8c5c815e7f055cc3b5bc84b47e0e867c8acd6df2..41d845ace0783dbe1b70c999af9bbe59fdeabb74 100644 (file)
@@ -622,12 +622,69 @@ llvmpipe_update_cs(struct llvmpipe_context *lp)
    lp_cs_ctx_set_cs_variant(lp->csctx, variant);
 }
 
+static void
+lp_csctx_set_cs_constants(struct lp_cs_context *csctx,
+                          unsigned num,
+                          struct pipe_constant_buffer *buffers)
+{
+   unsigned i;
+
+   LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffers);
+
+   assert(num <= ARRAY_SIZE(csctx->constants));
+
+   for (i = 0; i < num; ++i) {
+      util_copy_constant_buffer(&csctx->constants[i].current, &buffers[i]);
+   }
+   for (; i < ARRAY_SIZE(csctx->constants); i++) {
+      util_copy_constant_buffer(&csctx->constants[i].current, NULL);
+   }
+}
+
+static void
+update_csctx_consts(struct llvmpipe_context *llvmpipe)
+{
+   struct lp_cs_context *csctx = llvmpipe->csctx;
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(csctx->constants); ++i) {
+      struct pipe_resource *buffer = csctx->constants[i].current.buffer;
+      const ubyte *current_data = NULL;
+
+      if (buffer) {
+         /* resource buffer */
+         current_data = (ubyte *) llvmpipe_resource_data(buffer);
+      }
+      else if (csctx->constants[i].current.user_buffer) {
+         /* user-space buffer */
+         current_data = (ubyte *) csctx->constants[i].current.user_buffer;
+      }
+
+      if (current_data) {
+         current_data += csctx->constants[i].current.buffer_offset;
+
+         csctx->cs.current.jit_context.constants[i] = (const float *)current_data;
+         csctx->cs.current.jit_context.num_constants[i] = csctx->constants[i].current.buffer_size;
+      } else {
+         csctx->cs.current.jit_context.constants[i] = NULL;
+         csctx->cs.current.jit_context.num_constants[i] = 0;
+      }
+   }
+}
+
 static void
 llvmpipe_cs_update_derived(struct llvmpipe_context *llvmpipe)
 {
    if (llvmpipe->cs_dirty & (LP_CSNEW_CS))
       llvmpipe_update_cs(llvmpipe);
 
+   if (llvmpipe->cs_dirty & LP_CSNEW_CONSTANTS) {
+      lp_csctx_set_cs_constants(llvmpipe->csctx,
+                                ARRAY_SIZE(llvmpipe->constants[PIPE_SHADER_COMPUTE]),
+                                llvmpipe->constants[PIPE_SHADER_COMPUTE]);
+      update_csctx_consts(llvmpipe);
+   }
+
    llvmpipe->cs_dirty = 0;
 }
 
@@ -720,6 +777,10 @@ llvmpipe_init_compute_funcs(struct llvmpipe_context *llvmpipe)
 void
 lp_csctx_destroy(struct lp_cs_context *csctx)
 {
+   unsigned i;
+   for (i = 0; i < ARRAY_SIZE(csctx->constants); i++) {
+      pipe_resource_reference(&csctx->constants[i].current.buffer, NULL);
+   }
    FREE(csctx);
 }
 
index cab0d41fe7d63b6de65caeb802761bb318eaaabf..35c8f75ae6ae188624b0e5290947d1f4dfd9f3f9 100644 (file)
@@ -93,6 +93,13 @@ struct lp_cs_context {
    struct {
       struct lp_cs_exec current;
    } cs;
+
+   /** compute shader constants */
+   struct {
+      struct pipe_constant_buffer current;
+      unsigned stored_size;
+      const void *stored_data;
+   } constants[LP_MAX_TGSI_CONST_BUFFERS];
 };
 
 struct lp_cs_context *lp_csctx_create(struct pipe_context *pipe);
index 86adfbd934a96332cbe23b6c533e4374cc5706a8..cf0e15e6d1031a69bd0ff4a16ae14e393d605bbe 100644 (file)
@@ -3170,9 +3170,10 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
       draw_set_mapped_constant_buffer(llvmpipe->draw, shader,
                                       index, data, size);
    }
-   else {
+   else if (shader == PIPE_SHADER_COMPUTE)
+      llvmpipe->cs_dirty |= LP_CSNEW_CONSTANTS;
+   else
       llvmpipe->dirty |= LP_NEW_FS_CONSTANTS;
-   }
 
    if (cb && cb->user_buffer) {
       pipe_resource_reference(&constants, NULL);