[Mesa-dev] [PATCH] virgl: add ARB_tessellation_shader support. (v2)

Elie Tournier tournier.elie at gmail.com
Wed Jun 13 12:06:16 UTC 2018


On Wed, Jun 13, 2018 at 11:03:55AM +1000, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
> 
> This should add all the pieces to enable tess shaders on virgl.
> 
> v2: fixup transform to handle tess and strip out precise.
> set default for max patch varyings to work around issue when
> tess gets enabled from v1 caps but v2 caps aren't in place. (Elie)

Reviewed-by: Elie Tournier <elie.tournier at collabora.com>
> ---
>  src/gallium/auxiliary/tgsi/tgsi_transform.c |  4 --
>  src/gallium/drivers/virgl/virgl_context.c   | 69 +++++++++++++++++++++++++++++
>  src/gallium/drivers/virgl/virgl_encode.c    | 21 ++++++++-
>  src/gallium/drivers/virgl/virgl_encode.h    |  4 ++
>  src/gallium/drivers/virgl/virgl_protocol.h  |  5 +++
>  src/gallium/drivers/virgl/virgl_screen.c    | 10 ++++-
>  src/gallium/drivers/virgl/virgl_winsys.h    |  2 +-
>  7 files changed, 107 insertions(+), 8 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_transform.c b/src/gallium/auxiliary/tgsi/tgsi_transform.c
> index cd076c9e79e..4b2b10f50ad 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_transform.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_transform.c
> @@ -140,10 +140,6 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in,
>        return -1;
>     }
>     procType = parse.FullHeader.Processor.Processor;
> -   assert(procType == PIPE_SHADER_FRAGMENT ||
> -          procType == PIPE_SHADER_VERTEX ||
> -          procType == PIPE_SHADER_GEOMETRY);
> -
>  
>     /**
>      **  Setup output shader
> diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c
> index 8d701bb8f40..e6f8dc85256 100644
> --- a/src/gallium/drivers/virgl/virgl_context.c
> +++ b/src/gallium/drivers/virgl/virgl_context.c
> @@ -492,6 +492,18 @@ static void *virgl_create_vs_state(struct pipe_context *ctx,
>     return virgl_shader_encoder(ctx, shader, PIPE_SHADER_VERTEX);
>  }
>  
> +static void *virgl_create_tcs_state(struct pipe_context *ctx,
> +                                   const struct pipe_shader_state *shader)
> +{
> +   return virgl_shader_encoder(ctx, shader, PIPE_SHADER_TESS_CTRL);
> +}
> +
> +static void *virgl_create_tes_state(struct pipe_context *ctx,
> +                                   const struct pipe_shader_state *shader)
> +{
> +   return virgl_shader_encoder(ctx, shader, PIPE_SHADER_TESS_EVAL);
> +}
> +
>  static void *virgl_create_gs_state(struct pipe_context *ctx,
>                                     const struct pipe_shader_state *shader)
>  {
> @@ -534,6 +546,26 @@ virgl_delete_vs_state(struct pipe_context *ctx,
>     virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
>  }
>  
> +static void
> +virgl_delete_tcs_state(struct pipe_context *ctx,
> +                       void *tcs)
> +{
> +   uint32_t handle = (unsigned long)tcs;
> +   struct virgl_context *vctx = virgl_context(ctx);
> +
> +   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
> +}
> +
> +static void
> +virgl_delete_tes_state(struct pipe_context *ctx,
> +                      void *tes)
> +{
> +   uint32_t handle = (unsigned long)tes;
> +   struct virgl_context *vctx = virgl_context(ctx);
> +
> +   virgl_encode_delete_object(vctx, handle, VIRGL_OBJECT_SHADER);
> +}
> +
>  static void virgl_bind_vs_state(struct pipe_context *ctx,
>                                          void *vss)
>  {
> @@ -543,6 +575,24 @@ static void virgl_bind_vs_state(struct pipe_context *ctx,
>     virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_VERTEX);
>  }
>  
> +static void virgl_bind_tcs_state(struct pipe_context *ctx,
> +                               void *vss)
> +{
> +   uint32_t handle = (unsigned long)vss;
> +   struct virgl_context *vctx = virgl_context(ctx);
> +
> +   virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_TESS_CTRL);
> +}
> +
> +static void virgl_bind_tes_state(struct pipe_context *ctx,
> +                               void *vss)
> +{
> +   uint32_t handle = (unsigned long)vss;
> +   struct virgl_context *vctx = virgl_context(ctx);
> +
> +   virgl_encode_bind_shader(vctx, handle, PIPE_SHADER_TESS_EVAL);
> +}
> +
>  static void virgl_bind_gs_state(struct pipe_context *ctx,
>                                 void *vss)
>  {
> @@ -801,6 +851,18 @@ static void virgl_set_clip_state(struct pipe_context *ctx,
>     virgl_encoder_set_clip_state(vctx, clip);
>  }
>  
> +static void virgl_set_tess_state(struct pipe_context *ctx,
> +                                 const float default_outer_level[4],
> +                                 const float default_inner_level[2])
> +{
> +   struct virgl_context *vctx = virgl_context(ctx);
> +   struct virgl_screen *rs = virgl_screen(ctx->screen);
> +
> +   if (!rs->caps.caps.v1.bset.has_tessellation_shaders)
> +      return;
> +   virgl_encode_set_tess_state(vctx, default_outer_level, default_inner_level);
> +}
> +
>  static void virgl_resource_copy_region(struct pipe_context *ctx,
>                                        struct pipe_resource *dst,
>                                        unsigned dst_level,
> @@ -893,15 +955,22 @@ struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
>     vctx->base.set_vertex_buffers = virgl_set_vertex_buffers;
>     vctx->base.set_constant_buffer = virgl_set_constant_buffer;
>  
> +   vctx->base.set_tess_state = virgl_set_tess_state;
>     vctx->base.create_vs_state = virgl_create_vs_state;
> +   vctx->base.create_tcs_state = virgl_create_tcs_state;
> +   vctx->base.create_tes_state = virgl_create_tes_state;
>     vctx->base.create_gs_state = virgl_create_gs_state;
>     vctx->base.create_fs_state = virgl_create_fs_state;
>  
>     vctx->base.bind_vs_state = virgl_bind_vs_state;
> +   vctx->base.bind_tcs_state = virgl_bind_tcs_state;
> +   vctx->base.bind_tes_state = virgl_bind_tes_state;
>     vctx->base.bind_gs_state = virgl_bind_gs_state;
>     vctx->base.bind_fs_state = virgl_bind_fs_state;
>  
>     vctx->base.delete_vs_state = virgl_delete_vs_state;
> +   vctx->base.delete_tcs_state = virgl_delete_tcs_state;
> +   vctx->base.delete_tes_state = virgl_delete_tes_state;
>     vctx->base.delete_gs_state = virgl_delete_gs_state;
>     vctx->base.delete_fs_state = virgl_delete_fs_state;
>  
> diff --git a/src/gallium/drivers/virgl/virgl_encode.c b/src/gallium/drivers/virgl/virgl_encode.c
> index f3cbd1ca4b0..ad018bd1964 100644
> --- a/src/gallium/drivers/virgl/virgl_encode.c
> +++ b/src/gallium/drivers/virgl/virgl_encode.c
> @@ -419,6 +419,8 @@ int virgl_encoder_draw_vbo(struct virgl_context *ctx,
>                            const struct pipe_draw_info *info)
>  {
>     uint32_t length = VIRGL_DRAW_VBO_SIZE;
> +   if (info->mode == PIPE_PRIM_PATCHES)
> +      length = VIRGL_DRAW_VBO_SIZE_TESS;
>     if (info->indirect)
>        length = VIRGL_DRAW_VBO_SIZE_INDIRECT;
>     virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_DRAW_VBO, 0, length));
> @@ -437,9 +439,11 @@ int virgl_encoder_draw_vbo(struct virgl_context *ctx,
>        virgl_encoder_write_dword(ctx->cbuf, info->count_from_stream_output->buffer_size);
>     else
>        virgl_encoder_write_dword(ctx->cbuf, 0);
> +   if (length >= VIRGL_DRAW_VBO_SIZE_TESS) {
> +      virgl_encoder_write_dword(ctx->cbuf, info->vertices_per_patch); /* vertices per patch */
> +      virgl_encoder_write_dword(ctx->cbuf, info->drawid); /* drawid */
> +   }
>     if (length == VIRGL_DRAW_VBO_SIZE_INDIRECT) {
> -      virgl_encoder_write_dword(ctx->cbuf, 0); /* vertices per patch */
> -      virgl_encoder_write_dword(ctx->cbuf, 0); /* drawid */
>        virgl_encoder_write_res(ctx, virgl_resource(info->indirect->buffer));
>        virgl_encoder_write_dword(ctx->cbuf, info->indirect->offset);
>        virgl_encoder_write_dword(ctx->cbuf, 0); /* indirect stride */
> @@ -891,3 +895,16 @@ int virgl_encode_bind_shader(struct virgl_context *ctx,
>     virgl_encoder_write_dword(ctx->cbuf, type);
>     return 0;
>  }
> +
> +int virgl_encode_set_tess_state(struct virgl_context *ctx,
> +                                const float outer[4],
> +                                const float inner[2])
> +{
> +   int i;
> +   virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_TESS_STATE, 0, 6));
> +   for (i = 0; i < 4; i++)
> +      virgl_encoder_write_dword(ctx->cbuf, fui(outer[i]));
> +   for (i = 0; i < 2; i++)
> +      virgl_encoder_write_dword(ctx->cbuf, fui(inner[i]));
> +   return 0;
> +}
> diff --git a/src/gallium/drivers/virgl/virgl_encode.h b/src/gallium/drivers/virgl/virgl_encode.h
> index 02c032d673e..837075ea483 100644
> --- a/src/gallium/drivers/virgl/virgl_encode.h
> +++ b/src/gallium/drivers/virgl/virgl_encode.h
> @@ -251,4 +251,8 @@ int virgl_encoder_destroy_sub_ctx(struct virgl_context *ctx, uint32_t sub_ctx_id
>  
>  int virgl_encode_bind_shader(struct virgl_context *ctx,
>                               uint32_t handle, uint32_t type);
> +
> +int virgl_encode_set_tess_state(struct virgl_context *ctx,
> +                                const float outer[4],
> +                                const float inner[2]);
>  #endif
> diff --git a/src/gallium/drivers/virgl/virgl_protocol.h b/src/gallium/drivers/virgl/virgl_protocol.h
> index 5dc2874d1dd..bd5a8b40434 100644
> --- a/src/gallium/drivers/virgl/virgl_protocol.h
> +++ b/src/gallium/drivers/virgl/virgl_protocol.h
> @@ -83,6 +83,8 @@ enum virgl_context_cmd {
>     VIRGL_CCMD_CREATE_SUB_CTX,
>     VIRGL_CCMD_DESTROY_SUB_CTX,
>     VIRGL_CCMD_BIND_SHADER,
> +
> +   VIRGL_CCMD_SET_TESS_STATE,
>  };
>  
>  /*
> @@ -481,4 +483,7 @@ enum virgl_context_cmd {
>  #define VIRGL_BIND_SHADER_HANDLE 1
>  #define VIRGL_BIND_SHADER_TYPE 2
>  
> +/* tess state */
> +#define VIRGL_TESS_STATE_SIZE 6
> +
>  #endif
> diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c
> index 2ba9708ebac..f21526a60bd 100644
> --- a/src/gallium/drivers/virgl/virgl_screen.c
> +++ b/src/gallium/drivers/virgl/virgl_screen.c
> @@ -215,6 +215,8 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
>        return vscreen->caps.caps.v2.shader_buffer_offset_alignment;
>     case PIPE_CAP_DOUBLES:
>        return vscreen->caps.caps.v1.bset.has_fp64;
> +   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
> +      return vscreen->caps.caps.v2.max_shader_patch_varyings;
>     case PIPE_CAP_TEXTURE_GATHER_SM5:
>     case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
>     case PIPE_CAP_FAKE_SW_MSAA:
> @@ -229,7 +231,6 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
>     case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
>     case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
>     case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
> -   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
>     case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
>     case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
>     case PIPE_CAP_DEPTH_BOUNDS_TEST:
> @@ -316,11 +317,18 @@ virgl_get_shader_param(struct pipe_screen *screen,
>                         enum pipe_shader_cap param)
>  {
>     struct virgl_screen *vscreen = virgl_screen(screen);
> +
> +   if ((shader == PIPE_SHADER_TESS_CTRL || shader == PIPE_SHADER_TESS_EVAL) &&
> +       !vscreen->caps.caps.v1.bset.has_tessellation_shaders)
> +      return 0;
> +
>     switch(shader)
>     {
>     case PIPE_SHADER_FRAGMENT:
>     case PIPE_SHADER_VERTEX:
>     case PIPE_SHADER_GEOMETRY:
> +   case PIPE_SHADER_TESS_CTRL:
> +   case PIPE_SHADER_TESS_EVAL:
>        switch (param) {
>        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
>        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
> diff --git a/src/gallium/drivers/virgl/virgl_winsys.h b/src/gallium/drivers/virgl/virgl_winsys.h
> index 9ebb31a1e41..99ab4d38405 100644
> --- a/src/gallium/drivers/virgl/virgl_winsys.h
> +++ b/src/gallium/drivers/virgl/virgl_winsys.h
> @@ -127,7 +127,7 @@ static inline void virgl_ws_fill_new_caps_defaults(struct virgl_drm_caps *caps)
>     caps->caps.v2.max_geom_total_output_components = 1024;
>     caps->caps.v2.max_vertex_outputs = 32;
>     caps->caps.v2.max_vertex_attribs = 16;
> -   caps->caps.v2.max_shader_patch_varyings = 0;
> +   caps->caps.v2.max_shader_patch_varyings = 30;
>     caps->caps.v2.min_texel_offset = -8;
>     caps->caps.v2.max_texel_offset = 7;
>     caps->caps.v2.min_texture_gather_offset = -8;
> -- 
> 2.14.3
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list