[virglrenderer-devel] [PATCH 5/9] compute: handle launch grid.

Gert Wollny gert.wollny at collabora.com
Wed Aug 1 07:29:00 UTC 2018


I see you've already pushed this, so just to remember that nit for
refactoring: 


Am Mittwoch, den 01.08.2018, 08:28 +1000 schrieb Dave Airlie:
> 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]);
> +   }
> +}
I'd suggest to unify the if/else code path based on 
  if (indirect_handle) {
above.  

best, 
Gert



More information about the virglrenderer-devel mailing list