From: Dave Airlie Date: Tue, 27 Aug 2019 05:08:19 +0000 (+1000) Subject: llvmpipe: add support for compute constant buffers. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4ca40cc3dcbf34988fd614d8539938ffb17ce8ea;p=mesa.git llvmpipe: add support for compute constant buffers. This is mostly ported from the fragment shader code. Reviewed-by: Roland Scheidegger --- diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 8f22debed41..ca6e412df0b 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -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; diff --git a/src/gallium/drivers/llvmpipe/lp_state_cs.c b/src/gallium/drivers/llvmpipe/lp_state_cs.c index 8c5c815e7f0..41d845ace07 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_cs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_cs.c @@ -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); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_cs.h b/src/gallium/drivers/llvmpipe/lp_state_cs.h index cab0d41fe7d..35c8f75ae6a 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_cs.h +++ b/src/gallium/drivers/llvmpipe/lp_state_cs.h @@ -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); diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 86adfbd934a..cf0e15e6d10 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -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);