This series is:

Reviewed-by: Gurchetan Singh <gurchetansi...@chromium.org>
On Tue, Jul 31, 2018 at 3:29 PM Dave Airlie <airl...@gmail.com> wrote:
>
> From: Dave Airlie <airl...@redhat.com>
>
> This hooks up compute shader creation and launch grid support.
> ---
>  src/gallium/drivers/virgl/virgl_context.c  | 55 ++++++++++++++++++++++++++--
>  src/gallium/drivers/virgl/virgl_encode.c   | 25 ++++++++++++-
>  src/gallium/drivers/virgl/virgl_encode.h   |  3 ++
>  src/gallium/drivers/virgl/virgl_hw.h       |  5 +++
>  src/gallium/drivers/virgl/virgl_protocol.h | 11 ++++++
>  src/gallium/drivers/virgl/virgl_screen.c   | 59 
> ++++++++++++++++++++++++++++--
>  src/gallium/drivers/virgl/virgl_winsys.h   |  2 +
>  7 files changed, 153 insertions(+), 7 deletions(-)
>
> diff --git a/src/gallium/drivers/virgl/virgl_context.c 
> b/src/gallium/drivers/virgl/virgl_context.c
> index d224b68cfcd..ae1da337994 100644
> --- a/src/gallium/drivers/virgl/virgl_context.c
> +++ b/src/gallium/drivers/virgl/virgl_context.c
> @@ -506,7 +506,7 @@ static void *virgl_shader_encoder(struct pipe_context 
> *ctx,
>     handle = virgl_object_assign_handle();
>     /* encode VS state */
>     ret = virgl_encode_shader_state(vctx, handle, type,
> -                                   &shader->stream_output,
> +                                   &shader->stream_output, 0,
>                                     new_tokens);
>     if (ret) {
>        return NULL;
> @@ -961,7 +961,7 @@ static void virgl_set_shader_buffers(struct pipe_context 
> *ctx,
>        pipe_resource_reference(&vctx->ssbos[shader][idx], NULL);
>     }
>
> -   uint32_t max_shader_buffer = shader == PIPE_SHADER_FRAGMENT ?
> +   uint32_t max_shader_buffer = (shader == PIPE_SHADER_FRAGMENT || shader == 
> PIPE_SHADER_COMPUTE) ?
>        rs->caps.caps.v2.max_shader_buffer_frag_compute :
>        rs->caps.caps.v2.max_shader_buffer_other_stages;
>     if (!max_shader_buffer)
> @@ -989,7 +989,7 @@ static void virgl_set_shader_images(struct pipe_context 
> *ctx,
>        pipe_resource_reference(&vctx->images[shader][idx], NULL);
>     }
>
> -   uint32_t max_shader_images = shader == PIPE_SHADER_FRAGMENT ?
> +   uint32_t max_shader_images = (shader == PIPE_SHADER_FRAGMENT || shader == 
> PIPE_SHADER_COMPUTE) ?
>       rs->caps.caps.v2.max_shader_image_frag_compute :
>       rs->caps.caps.v2.max_shader_image_other_stages;
>     if (!max_shader_images)
> @@ -1008,6 +1008,50 @@ static void virgl_memory_barrier(struct pipe_context 
> *ctx,
>     virgl_encode_memory_barrier(vctx, flags);
>  }
>
> +static void *virgl_create_compute_state(struct pipe_context *ctx,
> +                                        const struct pipe_compute_state 
> *state)
> +{
> +   struct virgl_context *vctx = virgl_context(ctx);
> +   uint32_t handle;
> +   const struct tgsi_token *new_tokens = state->prog;
> +   struct pipe_stream_output_info so_info = {};
> +   int ret;
> +
> +   handle = virgl_object_assign_handle();
> +   ret = virgl_encode_shader_state(vctx, handle, PIPE_SHADER_COMPUTE,
> +                                   &so_info,
> +                                   state->req_local_mem,
> +                                   new_tokens);
> +   if (ret) {
> +      return NULL;
> +   }
> +
> +   return (void *)(unsigned long)handle;
> +}
> +
> +static void virgl_bind_compute_state(struct pipe_context *ctx, void *state)
> +{
> +   uint32_t handle = (unsigned long)state;
> +   struct virgl_context *vctx = virgl_context(ctx);
> +
> +   virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_COMPUTE);
> +}
> +
> +static void virgl_delete_compute_state(struct pipe_context *ctx, void *state)
> +{
> +   uint32_t handle = (unsigned long)state;
> +   struct virgl_context *vctx = virgl_context(ctx);
> +
> +   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
> +}
> +
> +static void virgl_launch_grid(struct pipe_context *ctx,
> +                              const struct pipe_grid_info *info)
> +{
> +   struct virgl_context *vctx = virgl_context(ctx);
> +   virgl_encode_launch_grid(vctx, info);
> +}
> +
>  static void
>  virgl_context_destroy( struct pipe_context *ctx )
>  {
> @@ -1118,6 +1162,11 @@ struct pipe_context *virgl_context_create(struct 
> pipe_screen *pscreen,
>     vctx->base.delete_gs_state = virgl_delete_gs_state;
>     vctx->base.delete_fs_state = virgl_delete_fs_state;
>
> +   vctx->base.create_compute_state = virgl_create_compute_state;
> +   vctx->base.bind_compute_state = virgl_bind_compute_state;
> +   vctx->base.delete_compute_state = virgl_delete_compute_state;
> +   vctx->base.launch_grid = virgl_launch_grid;
> +
>     vctx->base.clear = virgl_clear;
>     vctx->base.draw_vbo = virgl_draw_vbo;
>     vctx->base.flush = virgl_flush_from_st;
> diff --git a/src/gallium/drivers/virgl/virgl_encode.c 
> b/src/gallium/drivers/virgl/virgl_encode.c
> index 1d193ae6c7f..0cb5184d193 100644
> --- a/src/gallium/drivers/virgl/virgl_encode.c
> +++ b/src/gallium/drivers/virgl/virgl_encode.c
> @@ -241,6 +241,7 @@ int virgl_encode_shader_state(struct virgl_context *ctx,
>                                uint32_t handle,
>                                uint32_t type,
>                                const struct pipe_stream_output_info *so_info,
> +                              uint32_t cs_req_local_mem,
>                                const struct tgsi_token *tokens)
>  {
>     char *str, *sptr;
> @@ -298,7 +299,10 @@ int virgl_encode_shader_state(struct virgl_context *ctx,
>
>        virgl_emit_shader_header(ctx, handle, len, type, offlen, num_tokens);
>
> -      virgl_emit_shader_streamout(ctx, first_pass ? so_info : NULL);
> +      if (type == PIPE_SHADER_COMPUTE)
> +         virgl_encoder_write_dword(ctx->cbuf, cs_req_local_mem);
> +      else
> +         virgl_emit_shader_streamout(ctx, first_pass ? so_info : NULL);
>
>        virgl_encoder_write_block(ctx->cbuf, (uint8_t *)sptr, length);
>
> @@ -980,3 +984,22 @@ int virgl_encode_memory_barrier(struct virgl_context 
> *ctx,
>     virgl_encoder_write_dword(ctx->cbuf, flags);
>     return 0;
>  }
> +
> +int virgl_encode_launch_grid(struct virgl_context *ctx,
> +                             const struct pipe_grid_info *grid_info)
> +{
> +   virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_LAUNCH_GRID, 0, 
> VIRGL_LAUNCH_GRID_SIZE));
> +   virgl_encoder_write_dword(ctx->cbuf, grid_info->block[0]);
> +   virgl_encoder_write_dword(ctx->cbuf, grid_info->block[1]);
> +   virgl_encoder_write_dword(ctx->cbuf, grid_info->block[2]);
> +   virgl_encoder_write_dword(ctx->cbuf, grid_info->grid[0]);
> +   virgl_encoder_write_dword(ctx->cbuf, grid_info->grid[1]);
> +   virgl_encoder_write_dword(ctx->cbuf, grid_info->grid[2]);
> +   if (grid_info->indirect) {
> +      struct virgl_resource *res = virgl_resource(grid_info->indirect);
> +      virgl_encoder_write_res(ctx, res);
> +   } else
> +      virgl_encoder_write_dword(ctx->cbuf, 0);
> +   virgl_encoder_write_dword(ctx->cbuf, grid_info->indirect_offset);
> +   return 0;
> +}
> diff --git a/src/gallium/drivers/virgl/virgl_encode.h 
> b/src/gallium/drivers/virgl/virgl_encode.h
> index e353c3d04d5..c982eb954f3 100644
> --- a/src/gallium/drivers/virgl/virgl_encode.h
> +++ b/src/gallium/drivers/virgl/virgl_encode.h
> @@ -90,6 +90,7 @@ extern int virgl_encode_shader_state(struct virgl_context 
> *ctx,
>                                       uint32_t handle,
>                                       uint32_t type,
>                                       const struct pipe_stream_output_info 
> *so_info,
> +                                     uint32_t cs_req_local_mem,
>                                       const struct tgsi_token *tokens);
>
>  int virgl_encode_stream_output_info(struct virgl_context *ctx,
> @@ -269,4 +270,6 @@ int virgl_encode_set_shader_images(struct virgl_context 
> *ctx,
>                                     const struct pipe_image_view *images);
>  int virgl_encode_memory_barrier(struct virgl_context *ctx,
>                                  unsigned flags);
> +int virgl_encode_launch_grid(struct virgl_context *ctx,
> +                             const struct pipe_grid_info *grid_info);
>  #endif
> diff --git a/src/gallium/drivers/virgl/virgl_hw.h 
> b/src/gallium/drivers/virgl/virgl_hw.h
> index 6bb11f6598a..d58b347020b 100644
> --- a/src/gallium/drivers/virgl/virgl_hw.h
> +++ b/src/gallium/drivers/virgl/virgl_hw.h
> @@ -206,6 +206,7 @@ enum virgl_formats {
>  #define VIRGL_CAP_TGSI_PRECISE         (1 << 4)
>  #define VIRGL_CAP_TXQS                 (1 << 5)
>  #define VIRGL_CAP_MEMORY_BARRIER       (1 << 6)
> +#define VIRGL_CAP_COMPUTE_SHADER       (1 << 7)
>
>  #define VIRGL_BIND_DEPTH_STENCIL (1 << 0)
>  #define VIRGL_BIND_RENDER_TARGET (1 << 1)
> @@ -312,6 +313,10 @@ struct virgl_caps_v2 {
>          uint32_t max_shader_image_frag_compute;
>          uint32_t max_shader_image_other_stages;
>          uint32_t max_image_samples;
> +        uint32_t max_compute_work_group_invocations;
> +        uint32_t max_compute_shared_memory_size;
> +        uint32_t max_compute_grid_size[3];
> +        uint32_t max_compute_block_size[3];
>  };
>
>  union virgl_caps {
> diff --git a/src/gallium/drivers/virgl/virgl_protocol.h 
> b/src/gallium/drivers/virgl/virgl_protocol.h
> index 0c38b1fc2ed..b94b7528c0c 100644
> --- a/src/gallium/drivers/virgl/virgl_protocol.h
> +++ b/src/gallium/drivers/virgl/virgl_protocol.h
> @@ -89,6 +89,7 @@ enum virgl_context_cmd {
>     VIRGL_CCMD_SET_SHADER_BUFFERS,
>     VIRGL_CCMD_SET_SHADER_IMAGES,
>     VIRGL_CCMD_MEMORY_BARRIER,
> +   VIRGL_CCMD_LAUNCH_GRID,
>  };
>
>  /*
> @@ -518,4 +519,14 @@ enum virgl_context_cmd {
>  #define VIRGL_MEMORY_BARRIER_SIZE 1
>  #define VIRGL_MEMORY_BARRIER_FLAGS 1
>
> +#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/gallium/drivers/virgl/virgl_screen.c 
> b/src/gallium/drivers/virgl/virgl_screen.c
> index 01e8eaec720..be21a35bf08 100644
> --- a/src/gallium/drivers/virgl/virgl_screen.c
> +++ b/src/gallium/drivers/virgl/virgl_screen.c
> @@ -139,7 +139,7 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap 
> param)
>     case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
>        return 0;
>     case PIPE_CAP_COMPUTE:
> -      return 0;
> +      return vscreen->caps.caps.v2.capability_bits & 
> VIRGL_CAP_COMPUTE_SHADER;
>     case PIPE_CAP_USER_VERTEX_BUFFERS:
>        return 0;
>     case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
> @@ -327,6 +327,10 @@ virgl_get_shader_param(struct pipe_screen *screen,
>         !vscreen->caps.caps.v1.bset.has_tessellation_shaders)
>        return 0;
>
> +   if (shader == PIPE_SHADER_COMPUTE &&
> +       !(vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_COMPUTE_SHADER))
> +     return 0;
> +
>     switch(shader)
>     {
>     case PIPE_SHADER_FRAGMENT:
> @@ -334,6 +338,7 @@ virgl_get_shader_param(struct pipe_screen *screen,
>     case PIPE_SHADER_GEOMETRY:
>     case PIPE_SHADER_TESS_CTRL:
>     case PIPE_SHADER_TESS_EVAL:
> +   case PIPE_SHADER_COMPUTE:
>        switch (param) {
>        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
>        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
> @@ -372,15 +377,17 @@ virgl_get_shader_param(struct pipe_screen *screen,
>        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
>           return 4096 * sizeof(float[4]);
>        case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
> -         if (shader == PIPE_SHADER_FRAGMENT)
> +         if (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE)
>              return vscreen->caps.caps.v2.max_shader_buffer_frag_compute;
>           else
>              return vscreen->caps.caps.v2.max_shader_buffer_other_stages;
>        case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
> -         if (shader == PIPE_SHADER_FRAGMENT)
> +         if (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE)
>              return vscreen->caps.caps.v2.max_shader_image_frag_compute;
>           else
>              return vscreen->caps.caps.v2.max_shader_image_other_stages;
> +      case PIPE_SHADER_CAP_SUPPORTED_IRS:
> +         return (1 << PIPE_SHADER_IR_TGSI);
>        case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
>        case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
>        case PIPE_SHADER_CAP_INT64_ATOMICS:
> @@ -425,6 +432,51 @@ virgl_get_paramf(struct pipe_screen *screen, enum 
> pipe_capf param)
>     return 0.0;
>  }
>
> +static int
> +virgl_get_compute_param(struct pipe_screen *screen,
> +                        enum pipe_shader_ir ir_type,
> +                        enum pipe_compute_cap param,
> +                        void *ret)
> +{
> +   struct virgl_screen *vscreen = virgl_screen(screen);
> +   if (!(vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_COMPUTE_SHADER))
> +      return 0;
> +   switch (param) {
> +   case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
> +      if (ret) {
> +         uint64_t *grid_size = ret;
> +         grid_size[0] = vscreen->caps.caps.v2.max_compute_grid_size[0];
> +         grid_size[1] = vscreen->caps.caps.v2.max_compute_grid_size[1];
> +         grid_size[2] = vscreen->caps.caps.v2.max_compute_grid_size[2];
> +      }
> +      return 3 * sizeof(uint64_t) ;
> +   case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
> +      if (ret) {
> +         uint64_t *block_size = ret;
> +         block_size[0] = vscreen->caps.caps.v2.max_compute_block_size[0];
> +         block_size[1] = vscreen->caps.caps.v2.max_compute_block_size[1];
> +         block_size[2] = vscreen->caps.caps.v2.max_compute_block_size[2];
> +      }
> +      return 3 * sizeof(uint64_t);
> +   case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
> +      if (ret) {
> +         uint64_t *max_threads_per_block = ret;
> +         *max_threads_per_block = 
> vscreen->caps.caps.v2.max_compute_work_group_invocations;
> +      }
> +      return sizeof(uint64_t);
> +   case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
> +      if (ret) {
> +         uint64_t *max_local_size = ret;
> +         /* Value reported by the closed source driver. */
> +         *max_local_size = 
> vscreen->caps.caps.v2.max_compute_shared_memory_size;
> +      }
> +      return sizeof(uint64_t);
> +   default:
> +      break;
> +   }
> +   return 0;
> +}
> +
>  static boolean
>  virgl_is_vertex_format_supported(struct pipe_screen *screen,
>                                   enum pipe_format format)
> @@ -661,6 +713,7 @@ virgl_create_screen(struct virgl_winsys *vws)
>     screen->base.get_vendor = virgl_get_vendor;
>     screen->base.get_param = virgl_get_param;
>     screen->base.get_shader_param = virgl_get_shader_param;
> +   screen->base.get_compute_param = virgl_get_compute_param;
>     screen->base.get_paramf = virgl_get_paramf;
>     screen->base.is_format_supported = virgl_is_format_supported;
>     screen->base.destroy = virgl_destroy_screen;
> diff --git a/src/gallium/drivers/virgl/virgl_winsys.h 
> b/src/gallium/drivers/virgl/virgl_winsys.h
> index 315ca55f954..0e6cb7953f6 100644
> --- a/src/gallium/drivers/virgl/virgl_winsys.h
> +++ b/src/gallium/drivers/virgl/virgl_winsys.h
> @@ -138,5 +138,7 @@ static inline void virgl_ws_fill_new_caps_defaults(struct 
> virgl_drm_caps *caps)
>     caps->caps.v2.capability_bits = 0;
>     caps->caps.v2.max_vertex_attrib_stride = 0;
>     caps->caps.v2.max_image_samples = 0;
> +   caps->caps.v2.max_compute_work_group_invocations = 0;
> +   caps->caps.v2.max_compute_shared_memory_size = 0;
>  }
>  #endif
> --
> 2.14.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to