[virglrenderer-devel] [PATCH 3/6] compute: handle launch grid.
Dave Airlie
airlied at gmail.com
Mon Jul 30 18:54:01 UTC 2018
From: Dave Airlie <airlied at redhat.com>
This adds protocol for dispatch compute shaders using
the launch grid command from gallium.
---
src/virgl_protocol.h | 11 ++++++++
src/vrend_decode.c | 22 ++++++++++++++++
src/vrend_renderer.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/vrend_renderer.h | 5 ++++
4 files changed, 109 insertions(+)
diff --git a/src/virgl_protocol.h b/src/virgl_protocol.h
index 292565f..43c010e 100644
--- a/src/virgl_protocol.h
+++ b/src/virgl_protocol.h
@@ -88,6 +88,7 @@ enum virgl_context_cmd {
VIRGL_CCMD_SET_SHADER_BUFFERS,
VIRGL_CCMD_SET_SHADER_IMAGES,
VIRGL_CCMD_MEMORY_BARRIER,
+ VIRGL_CCMD_LAUNCH_GRID,
};
/*
@@ -517,4 +518,14 @@ enum virgl_context_cmd {
#define VIRGL_MEMORY_BARRIER_SIZE 1
#define VIRGL_MEMORY_BARRIER_FLAGS 1
+/* launch grid */
+#define VIRGL_LAUNCH_GRID_SIZE 8
+#define VIRGL_LAUNCH_BLOCK_X 1
+#define VIRGL_LAUNCH_BLOCK_Y 2
+#define VIRGL_LAUNCH_BLOCK_Z 3
+#define VIRGL_LAUNCH_GRID_X 4
+#define VIRGL_LAUNCH_GRID_Y 5
+#define VIRGL_LAUNCH_GRID_Z 6
+#define VIRGL_LAUNCH_INDIRECT_HANDLE 7
+#define VIRGL_LAUNCH_INDIRECT_OFFSET 8
#endif
diff --git a/src/vrend_decode.c b/src/vrend_decode.c
index 42ec832..e3deb65 100644
--- a/src/vrend_decode.c
+++ b/src/vrend_decode.c
@@ -1153,6 +1153,25 @@ static int vrend_decode_memory_barrier(struct vrend_decode_ctx *ctx, uint16_t le
return 0;
}
+static int vrend_decode_launch_grid(struct vrend_decode_ctx *ctx, uint16_t length)
+{
+ uint32_t block[3], grid[3];
+ uint32_t indirect_handle, indirect_offset;
+ if (length != VIRGL_LAUNCH_GRID_SIZE)
+ return EINVAL;
+
+ block[0] = get_buf_entry(ctx, VIRGL_LAUNCH_BLOCK_X);
+ block[1] = get_buf_entry(ctx, VIRGL_LAUNCH_BLOCK_Y);
+ block[2] = get_buf_entry(ctx, VIRGL_LAUNCH_BLOCK_Z);
+ grid[0] = get_buf_entry(ctx, VIRGL_LAUNCH_GRID_X);
+ grid[1] = get_buf_entry(ctx, VIRGL_LAUNCH_GRID_Y);
+ grid[2] = get_buf_entry(ctx, VIRGL_LAUNCH_GRID_Z);
+ indirect_handle = get_buf_entry(ctx, VIRGL_LAUNCH_INDIRECT_HANDLE);
+ indirect_offset = get_buf_entry(ctx, VIRGL_LAUNCH_INDIRECT_OFFSET);
+ vrend_launch_grid(ctx->grctx, block, grid, indirect_handle, indirect_offset);
+ return 0;
+}
+
static int vrend_decode_set_streamout_targets(struct vrend_decode_ctx *ctx,
uint16_t length)
{
@@ -1390,6 +1409,9 @@ int vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw)
case VIRGL_CCMD_MEMORY_BARRIER:
ret = vrend_decode_memory_barrier(gdctx, len);
break;
+ case VIRGL_CCMD_LAUNCH_GRID:
+ ret = vrend_decode_launch_grid(gdctx, len);
+ break;
default:
ret = EINVAL;
}
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 63862d5..f1571e0 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -3928,6 +3928,77 @@ int vrend_draw_vbo(struct vrend_context *ctx,
return 0;
}
+void vrend_launch_grid(struct vrend_context *ctx,
+ uint32_t *block,
+ uint32_t *grid,
+ uint32_t indirect_handle,
+ uint32_t indirect_offset)
+{
+ bool new_program = false;
+ struct vrend_resource *indirect_res = NULL;
+ if (ctx->sub->cs_shader_dirty) {
+ struct vrend_linked_shader_program *prog;
+ bool same_prog, cs_dirty;
+ if (!ctx->sub->shaders[PIPE_SHADER_COMPUTE]) {
+ fprintf(stderr,"dropping rendering due to missing shaders: %s\n", ctx->debug_name);
+ return;
+ }
+
+ vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_COMPUTE], &cs_dirty);
+ if (!ctx->sub->shaders[PIPE_SHADER_COMPUTE]->current) {
+ fprintf(stderr, "failure to compile shader variants: %s\n", ctx->debug_name);
+ return;
+ }
+ same_prog = true;
+ if (ctx->sub->shaders[PIPE_SHADER_COMPUTE]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_COMPUTE])
+ same_prog = false;
+ if (!same_prog) {
+ prog = lookup_cs_shader_program(ctx, ctx->sub->shaders[PIPE_SHADER_COMPUTE]->current->id);
+ if (!prog) {
+ prog = add_cs_shader_program(ctx, ctx->sub->shaders[PIPE_SHADER_COMPUTE]->current);
+ if (!prog)
+ return;
+ }
+ } else
+ prog = ctx->sub->prog;
+
+ if (ctx->sub->prog != prog) {
+ new_program = true;
+ ctx->sub->prog_ids[PIPE_SHADER_VERTEX] = -1;
+ ctx->sub->prog_ids[PIPE_SHADER_COMPUTE] = ctx->sub->shaders[PIPE_SHADER_COMPUTE]->current->id;
+ ctx->sub->prog = prog;
+ }
+ ctx->sub->shader_dirty = true;
+ }
+ vrend_use_program(ctx, ctx->sub->prog->id);
+
+ int sampler_id = 0, ubo_id = 0;
+ vrend_draw_bind_ubo_shader(ctx, PIPE_SHADER_COMPUTE, &ubo_id);
+ vrend_draw_bind_const_shader(ctx, PIPE_SHADER_COMPUTE, new_program);
+ vrend_draw_bind_samplers_shader(ctx, PIPE_SHADER_COMPUTE, &sampler_id);
+ vrend_draw_bind_images_shader(ctx, PIPE_SHADER_COMPUTE);
+ vrend_draw_bind_ssbo_shader(ctx, PIPE_SHADER_COMPUTE);
+
+ if (indirect_handle) {
+ indirect_res = vrend_renderer_ctx_res_lookup(ctx, indirect_handle);
+ if (!indirect_res) {
+ report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, indirect_handle);
+ return;
+ }
+ }
+
+ if (indirect_res)
+ glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, indirect_res->id);
+ else
+ glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0);
+
+ if (indirect_res) {
+ glDispatchComputeIndirect(indirect_offset);
+ } else {
+ glDispatchCompute(grid[0], grid[1], grid[2]);
+ }
+}
+
static GLenum translate_blend_func(uint32_t pipe_blend)
{
switch(pipe_blend){
diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
index a0766dd..79f4897 100644
--- a/src/vrend_renderer.h
+++ b/src/vrend_renderer.h
@@ -243,6 +243,11 @@ void vrend_set_single_ssbo(struct vrend_context *ctx,
uint32_t handle);
void vrend_memory_barrier(struct vrend_context *ctx,
unsigned flags);
+void vrend_launch_grid(struct vrend_context *ctx,
+ uint32_t *block,
+ uint32_t *grid,
+ uint32_t indirect_handle,
+ uint32_t indirect_offset);
#define VREND_TRANSFER_WRITE 1
#define VREND_TRANSFER_READ 2
int vrend_renderer_transfer_iov(const struct vrend_transfer_info *info, int transfer_mode);
--
2.14.3
More information about the virglrenderer-devel
mailing list