[Mesa-dev] [PATCH 2/2] u_blit, u_simple_shaders: add shader to convert from xrbias format
Jose Fonseca
jfonseca at vmware.com
Wed Feb 7 10:25:25 UTC 2018
On 07/02/18 04:20, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
>
> We need this to handle some oddball dx10 format
> (DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM). What you can do with this
> format is very limited, hence we don't want to add it as a gallium
> format (we could not express the properties of this format as
> ordinary format properties neither, so like all special formats
> it would need specific code for handling it in any case).
> While here, also nuke the array for different shaders for different
> writemasks, as it was not actually used (always full masks are
> passed in for generating shaders).
> ---
> src/gallium/auxiliary/util/u_blit.c | 40 +++++++++++++---------
> src/gallium/auxiliary/util/u_blit.h | 3 +-
> src/gallium/auxiliary/util/u_simple_shaders.c | 48 +++++++++++++++++++++++++++
> src/gallium/auxiliary/util/u_simple_shaders.h | 4 +++
> 4 files changed, 79 insertions(+), 16 deletions(-)
>
> diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
> index 3f92476..bf1dea7 100644
> --- a/src/gallium/auxiliary/util/u_blit.c
> +++ b/src/gallium/auxiliary/util/u_blit.c
> @@ -65,7 +65,7 @@ struct blit_state
> struct pipe_vertex_element velem[2];
>
> void *vs;
> - void *fs[PIPE_MAX_TEXTURE_TYPES][TGSI_WRITEMASK_XYZW + 1][3];
> + void *fs[PIPE_MAX_TEXTURE_TYPES][4];
>
> struct pipe_resource *vbuf; /**< quad vertices */
> unsigned vbuf_slot;
> @@ -135,17 +135,15 @@ void
> util_destroy_blit(struct blit_state *ctx)
> {
> struct pipe_context *pipe = ctx->pipe;
> - unsigned i, j, k;
> + unsigned i, j;
>
> if (ctx->vs)
> pipe->delete_vs_state(pipe, ctx->vs);
>
> for (i = 0; i < ARRAY_SIZE(ctx->fs); i++) {
> for (j = 0; j < ARRAY_SIZE(ctx->fs[i]); j++) {
> - for (k = 0; k < ARRAY_SIZE(ctx->fs[i][j]); k++) {
> - if (ctx->fs[i][j][k])
> - pipe->delete_fs_state(pipe, ctx->fs[i][j][k]);
> - }
> + if (ctx->fs[i][j])
> + pipe->delete_fs_state(pipe, ctx->fs[i][j]);
> }
> }
>
> @@ -159,8 +157,9 @@ util_destroy_blit(struct blit_state *ctx)
> * Helper function to set the fragment shaders.
> */
> static inline void
> -set_fragment_shader(struct blit_state *ctx, uint writemask,
> +set_fragment_shader(struct blit_state *ctx,
> enum pipe_format format,
> + boolean src_xrbias,
> enum pipe_texture_target pipe_tex)
> {
> enum tgsi_return_type stype;
> @@ -177,19 +176,29 @@ set_fragment_shader(struct blit_state *ctx, uint writemask,
> idx = 2;
> }
>
> - if (!ctx->fs[pipe_tex][writemask][idx]) {
> + if (src_xrbias) {
> + assert(stype == TGSI_RETURN_TYPE_FLOAT);
> + idx = 3;
> + if (!ctx->fs[pipe_tex][idx]) {
> + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
> + ctx->fs[pipe_tex][idx] =
> + util_make_fragment_tex_shader_xrbias(ctx->pipe, tgsi_tex);
> + }
> + }
> +
> + else if (!ctx->fs[pipe_tex][idx]) {
> unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
>
> /* OpenGL does not allow blits from signed to unsigned integer
> * or vice versa. */
> - ctx->fs[pipe_tex][writemask][idx] =
> + ctx->fs[pipe_tex][idx] =
> util_make_fragment_tex_shader_writemask(ctx->pipe, tgsi_tex,
> TGSI_INTERPOLATE_LINEAR,
> - writemask,
> + TGSI_WRITEMASK_XYZW,
> stype, stype, false, false);
> }
>
> - cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask][idx]);
> + cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][idx]);
> }
>
>
> @@ -491,8 +500,8 @@ util_blit_pixels(struct blit_state *ctx,
> * The sampler view's first_layer indicate the layer to use, but for
> * cube maps it must point to the first face. Face is passed in src_face.
> *
> - * The main advantage over util_blit_pixels is that it allows to specify swizzles in
> - * pipe_sampler_view::swizzle_?.
> + * The main advantage over util_blit_pixels is that it allows to specify
> + * swizzles in pipe_sampler_view::swizzle_?.
> *
> * But there is no control over blitting Z and/or stencil.
> */
> @@ -505,7 +514,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
> struct pipe_surface *dst,
> int dstX0, int dstY0,
> int dstX1, int dstY1,
> - float z, uint filter)
> + float z, uint filter,
> + boolean src_xrbias)
> {
> boolean normalized = src_sampler_view->texture->target != PIPE_TEXTURE_RECT;
> struct pipe_framebuffer_state fb;
> @@ -593,7 +603,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
> cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &src_sampler_view);
>
> /* shaders */
> - set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW,
> + set_fragment_shader(ctx, src_xrbias,
> src_sampler_view->format,
> src_sampler_view->texture->target);
> set_vertex_shader(ctx);
> diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h
> index b50edab..e2934d0 100644
> --- a/src/gallium/auxiliary/util/u_blit.h
> +++ b/src/gallium/auxiliary/util/u_blit.h
> @@ -72,7 +72,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
> struct pipe_surface *dst,
> int dstX0, int dstY0,
> int dstX1, int dstY1,
> - float z, uint filter);
> + float z, uint filter,
> + boolean src_xrbias);
>
> #ifdef __cplusplus
> }
> diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
> index a301c05..584d915 100644
> --- a/src/gallium/auxiliary/util/u_simple_shaders.c
> +++ b/src/gallium/auxiliary/util/u_simple_shaders.c
> @@ -222,6 +222,54 @@ ureg_load_tex(struct ureg_program *ureg, struct ureg_dst out,
> }
>
> /**
> + * Make simple fragment texture shader, with xrbias->float conversion:
> + * IMM {1023/510, -384/510, 0, 1}
> + * TEX TEMP[0], IN[0], SAMP[0], 2D;
> + * MAD TEMP[0].xyz TEMP[0], IMM[0].xxxx, IMM[0].yyyy
> + * MOV OUT[0], TEMP[0]
> + * END;
> + *
> + * \param tex_target one of PIPE_TEXTURE_x
> + */
> +void *
> +util_make_fragment_tex_shader_xrbias(struct pipe_context *pipe,
> + unsigned tex_target)
> +{
> + struct ureg_program *ureg;
> + struct ureg_src sampler;
> + struct ureg_src coord;
> + struct ureg_dst temp;
> + struct ureg_dst out;
> + struct ureg_src imm;
> + enum tgsi_return_type stype = TGSI_RETURN_TYPE_FLOAT;
> +
> + ureg = ureg_create(PIPE_SHADER_FRAGMENT);
> + if (!ureg)
> + return NULL;
> +
> + imm = ureg_imm4f(ureg, 1023.0f/510.0f,
> + -384.0f/510.0f, 0.0f, 1.0f);
> + sampler = ureg_DECL_sampler(ureg, 0);
> + ureg_DECL_sampler_view(ureg, 0, tex_target, stype, stype, stype, stype);
> + coord = ureg_DECL_fs_input(ureg,
> + TGSI_SEMANTIC_GENERIC, 0,
> + TGSI_INTERPOLATE_LINEAR);
> + out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
> + temp = ureg_DECL_temporary(ureg);
> +
> + ureg_TEX(ureg, temp, tex_target, coord, sampler);
> + ureg_MAD(ureg, ureg_writemask(temp, TGSI_WRITEMASK_XYZ),
> + ureg_src(temp),
> + ureg_scalar(imm, TGSI_SWIZZLE_X),
> + ureg_scalar(imm, TGSI_SWIZZLE_Y));
> + ureg_MOV(ureg, out, ureg_src(temp));
> + ureg_END(ureg);
> +
> + return ureg_create_shader_and_destroy(ureg, pipe);
> +}
> +
> +
> +/**
> * Make simple fragment texture shader:
> * IMM {0,0,0,1} // (if writemask != 0xf)
> * MOV TEMP[0], IMM[0] // (if writemask != 0xf)
> diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
> index a281f57..5e53313 100644
> --- a/src/gallium/auxiliary/util/u_simple_shaders.h
> +++ b/src/gallium/auxiliary/util/u_simple_shaders.h
> @@ -68,6 +68,10 @@ util_make_layered_clear_helper_vertex_shader(struct pipe_context *pipe);
> extern void *
> util_make_layered_clear_geometry_shader(struct pipe_context *pipe);
>
> +void *
> +util_make_fragment_tex_shader_xrbias(struct pipe_context *pipe,
> + unsigned tex_target);
> +
> extern void *
> util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
> unsigned tex_target,
>
LGTM.
Reviwed-by: Jose Fonseca <jfonseca at vmware.com>
More information about the mesa-dev
mailing list