Reviewed-by: Marek Olšák <marek.ol...@amd.com> Marek
On Thu, Jun 11, 2015 at 2:14 AM, Rob Clark <robdcl...@gmail.com> wrote: > From: Rob Clark <robcl...@freedesktop.org> > > Some hardware needs to know the sampler type. Update the blit related > shaders to include SVIEW decl. > > Signed-off-by: Rob Clark <robcl...@freedesktop.org> > --- > Possibly I should have refactored the existing code to pass around a > return_type rather than doing the is_uint/is_sint thing everywhere. > And this does kind of ignore UNORM/SNORM.. although I'm not really > sure that we need shader variants for UNORM/SNORM (we don't have this > information in GLSL IR or NIR IR, and I don't know any hw that doesn't > just treat those as FLOAT in the shader compiler). Anyways, sending > it out as-is for comments. > > src/gallium/auxiliary/util/u_blit.c | 32 +++++++++---- > src/gallium/auxiliary/util/u_blitter.c | 42 ++++++++++++---- > src/gallium/auxiliary/util/u_simple_shaders.c | 69 > +++++++++++++++++++++++---- > src/gallium/auxiliary/util/u_simple_shaders.h | 15 ++++-- > src/gallium/auxiliary/util/u_tests.c | 3 +- > src/gallium/tests/trivial/quad-tex.c | 2 +- > 6 files changed, 132 insertions(+), 31 deletions(-) > > diff --git a/src/gallium/auxiliary/util/u_blit.c > b/src/gallium/auxiliary/util/u_blit.c > index 3f3b5fe..0062d96 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]; > + void *fs[PIPE_MAX_TEXTURE_TYPES][TGSI_WRITEMASK_XYZW + 1][3]; > > struct pipe_resource *vbuf; /**< quad vertices */ > unsigned vbuf_slot; > @@ -135,15 +135,17 @@ void > util_destroy_blit(struct blit_state *ctx) > { > struct pipe_context *pipe = ctx->pipe; > - unsigned i, j; > + unsigned i, j, k; > > if (ctx->vs) > pipe->delete_vs_state(pipe, ctx->vs); > > for (i = 0; i < Elements(ctx->fs); i++) { > for (j = 0; j < Elements(ctx->fs[i]); j++) { > - if (ctx->fs[i][j]) > - pipe->delete_fs_state(pipe, ctx->fs[i][j]); > + for (k = 0; k < Elements(ctx->fs[i][j]); k++) { > + if (ctx->fs[i][j][k]) > + pipe->delete_fs_state(pipe, ctx->fs[i][j][k]); > + } > } > } > > @@ -158,18 +160,31 @@ util_destroy_blit(struct blit_state *ctx) > */ > static INLINE void > set_fragment_shader(struct blit_state *ctx, uint writemask, > + enum pipe_format format, > enum pipe_texture_target pipe_tex) > { > - if (!ctx->fs[pipe_tex][writemask]) { > + boolean is_uint = util_format_is_pure_uint(format); > + boolean is_sint = util_format_is_pure_sint(format); > + unsigned type; > + > + if (is_uint) > + type = 0; > + else if (is_sint) > + type = 1; > + else > + type = 2; > + > + if (!ctx->fs[pipe_tex][writemask][type]) { > unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); > > - ctx->fs[pipe_tex][writemask] = > + ctx->fs[pipe_tex][writemask][type] = > util_make_fragment_tex_shader_writemask(ctx->pipe, tgsi_tex, > TGSI_INTERPOLATE_LINEAR, > - writemask); > + writemask, > + is_uint, is_sint); > } > > - cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask]); > + cso_set_fragment_shader_handle(ctx->cso, > ctx->fs[pipe_tex][writemask][type]); > } > > > @@ -571,6 +586,7 @@ util_blit_pixels_tex(struct blit_state *ctx, > > /* shaders */ > set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW, > + src_sampler_view->format, > src_sampler_view->texture->target); > set_vertex_shader(ctx); > cso_set_tessctrl_shader_handle(ctx->cso, NULL); > diff --git a/src/gallium/auxiliary/util/u_blitter.c > b/src/gallium/auxiliary/util/u_blitter.c > index 16bf90f..27e0d10 100644 > --- a/src/gallium/auxiliary/util/u_blitter.c > +++ b/src/gallium/auxiliary/util/u_blitter.c > @@ -81,6 +81,8 @@ struct blitter_context_priv > /* FS which outputs a color from a texture, > where the index is PIPE_TEXTURE_* to be sampled. */ > void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES]; > + void *fs_texfetch_col_uint[PIPE_MAX_TEXTURE_TYPES]; > + void *fs_texfetch_col_sint[PIPE_MAX_TEXTURE_TYPES]; > > /* FS which outputs a depth from a texture, > where the index is PIPE_TEXTURE_* to be sampled. */ > @@ -90,6 +92,8 @@ struct blitter_context_priv > > /* FS which outputs one sample from a multisample texture. */ > void *fs_texfetch_col_msaa[PIPE_MAX_TEXTURE_TYPES]; > + void *fs_texfetch_col_msaa_uint[PIPE_MAX_TEXTURE_TYPES]; > + void *fs_texfetch_col_msaa_sint[PIPE_MAX_TEXTURE_TYPES]; > void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES]; > void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES]; > void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES]; > @@ -438,6 +442,10 @@ void util_blitter_destroy(struct blitter_context > *blitter) > for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) { > if (ctx->fs_texfetch_col[i]) > ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[i]); > + if (ctx->fs_texfetch_col_sint[i]) > + ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_sint[i]); > + if (ctx->fs_texfetch_col_uint[i]) > + ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_uint[i]); > if (ctx->fs_texfetch_depth[i]) > ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]); > if (ctx->fs_texfetch_depthstencil[i]) > @@ -447,6 +455,10 @@ void util_blitter_destroy(struct blitter_context > *blitter) > > if (ctx->fs_texfetch_col_msaa[i]) > ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa[i]); > + if (ctx->fs_texfetch_col_msaa_sint[i]) > + ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa_sint[i]); > + if (ctx->fs_texfetch_col_msaa_uint[i]) > + ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa_uint[i]); > if (ctx->fs_texfetch_depth_msaa[i]) > ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth_msaa[i]); > if (ctx->fs_texfetch_depthstencil_msaa[i]) > @@ -844,20 +856,20 @@ static void *blitter_get_fs_texfetch_col(struct > blitter_context_priv *ctx, > { > struct pipe_context *pipe = ctx->base.pipe; > unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, src_nr_samples); > + boolean is_uint, is_sint; > > assert(target < PIPE_MAX_TEXTURE_TYPES); > > + is_uint = util_format_is_pure_uint(format); > + is_sint = util_format_is_pure_sint(format); > + > if (src_nr_samples > 1) { > void **shader; > > if (dst_nr_samples <= 1) { > /* The destination has one sample, so we'll do color resolve. */ > - boolean is_uint, is_sint; > unsigned index = GET_MSAA_RESOLVE_FS_IDX(src_nr_samples); > > - is_uint = util_format_is_pure_uint(format); > - is_sint = util_format_is_pure_sint(format); > - > assert(filter < 2); > > if (is_uint) > @@ -885,24 +897,38 @@ static void *blitter_get_fs_texfetch_col(struct > blitter_context_priv *ctx, > /* The destination has multiple samples, we'll do > * an MSAA->MSAA copy. > */ > - shader = &ctx->fs_texfetch_col_msaa[target]; > + if (is_uint) > + shader = &ctx->fs_texfetch_col_msaa_uint[target]; > + else if (is_sint) > + shader = &ctx->fs_texfetch_col_msaa_sint[target]; > + else > + shader = &ctx->fs_texfetch_col_msaa[target]; > > /* Create the fragment shader on-demand. */ > if (!*shader) { > assert(!ctx->cached_all_shaders); > - *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex); > + *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex, > + is_uint, is_sint); > } > } > > return *shader; > } else { > - void **shader = &ctx->fs_texfetch_col[target]; > + void **shader; > + > + if (is_uint) > + shader = &ctx->fs_texfetch_col_uint[target]; > + else if (is_sint) > + shader = &ctx->fs_texfetch_col_sint[target]; > + else > + shader = &ctx->fs_texfetch_col[target]; > > /* Create the fragment shader on-demand. */ > if (!*shader) { > assert(!ctx->cached_all_shaders); > *shader = util_make_fragment_tex_shader(pipe, tgsi_tex, > - TGSI_INTERPOLATE_LINEAR); > + TGSI_INTERPOLATE_LINEAR, > + is_uint, is_sint); > } > > return *shader; > diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c > b/src/gallium/auxiliary/util/u_simple_shaders.c > index c612b67..8b6b8a6 100644 > --- a/src/gallium/auxiliary/util/u_simple_shaders.c > +++ b/src/gallium/auxiliary/util/u_simple_shaders.c > @@ -201,6 +201,27 @@ void *util_make_layered_clear_geometry_shader(struct > pipe_context *pipe) > return pipe->create_gs_state(pipe, &state); > } > > +static struct ureg_src > +decl_sampler_view(struct ureg_program *ureg, > + unsigned nr, > + unsigned target, > + boolean is_uint, > + boolean is_sint) > +{ > + unsigned type; > + > + assert(!(is_uint && is_sint)); > + > + if (is_uint) > + type = TGSI_RETURN_TYPE_UINT; > + else if (is_sint) > + type = TGSI_RETURN_TYPE_SINT; > + else > + type = TGSI_RETURN_TYPE_FLOAT; > + > + return ureg_DECL_sampler_view(ureg, nr, target, type, type, type, type); > +} > + > /** > * Make simple fragment texture shader: > * IMM {0,0,0,1} // (if writemask != 0xf) > @@ -216,7 +237,9 @@ void * > util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, > unsigned tex_target, > unsigned interp_mode, > - unsigned writemask ) > + unsigned writemask, > + boolean is_uint, > + boolean is_sint) > { > struct ureg_program *ureg; > struct ureg_src sampler; > @@ -232,6 +255,8 @@ util_make_fragment_tex_shader_writemask(struct > pipe_context *pipe, > > sampler = ureg_DECL_sampler( ureg, 0 ); > > + decl_sampler_view(ureg, 0, tex_target, is_uint, is_sint); > + > tex = ureg_DECL_fs_input( ureg, > TGSI_SEMANTIC_GENERIC, 0, > interp_mode ); > @@ -268,12 +293,16 @@ util_make_fragment_tex_shader_writemask(struct > pipe_context *pipe, > */ > void * > util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target, > - unsigned interp_mode) > + unsigned interp_mode, > + boolean is_uint, > + boolean is_sint) > { > return util_make_fragment_tex_shader_writemask( pipe, > tex_target, > interp_mode, > - TGSI_WRITEMASK_XYZW ); > + TGSI_WRITEMASK_XYZW, > + is_uint, > + is_sint ); > } > > > @@ -298,6 +327,8 @@ util_make_fragment_tex_shader_writedepth(struct > pipe_context *pipe, > > sampler = ureg_DECL_sampler( ureg, 0 ); > > + decl_sampler_view(ureg, 0, tex_target, FALSE, FALSE); > + > tex = ureg_DECL_fs_input( ureg, > TGSI_SEMANTIC_GENERIC, 0, > interp_mode ); > @@ -343,7 +374,9 @@ util_make_fragment_tex_shader_writedepthstencil(struct > pipe_context *pipe, > return NULL; > > depth_sampler = ureg_DECL_sampler( ureg, 0 ); > + decl_sampler_view(ureg, 0, tex_target, FALSE, FALSE); > stencil_sampler = ureg_DECL_sampler( ureg, 1 ); > + decl_sampler_view(ureg, 1, tex_target, TRUE, FALSE); > > tex = ureg_DECL_fs_input( ureg, > TGSI_SEMANTIC_GENERIC, 0, > @@ -398,6 +431,8 @@ util_make_fragment_tex_shader_writestencil(struct > pipe_context *pipe, > > stencil_sampler = ureg_DECL_sampler( ureg, 0 ); > > + decl_sampler_view(ureg, 0, tex_target, TRUE, FALSE); > + > tex = ureg_DECL_fs_input( ureg, > TGSI_SEMANTIC_GENERIC, 0, > interp_mode ); > @@ -512,6 +547,7 @@ util_make_fragment_cloneinput_shader(struct pipe_context > *pipe, int num_cbufs, > static void * > util_make_fs_blit_msaa_gen(struct pipe_context *pipe, > unsigned tgsi_tex, > + const char *samp_type, > const char *output_semantic, > const char *output_mask) > { > @@ -519,6 +555,7 @@ util_make_fs_blit_msaa_gen(struct pipe_context *pipe, > "FRAG\n" > "DCL IN[0], GENERIC[0], LINEAR\n" > "DCL SAMP[0]\n" > + "DCL SVIEW[0], %s, %s\n" > "DCL OUT[0], %s\n" > "DCL TEMP[0]\n" > > @@ -534,7 +571,8 @@ util_make_fs_blit_msaa_gen(struct pipe_context *pipe, > assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA || > tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA); > > - sprintf(text, shader_templ, output_semantic, output_mask, type); > + sprintf(text, shader_templ, type, samp_type, > + output_semantic, output_mask, type); > > if (!tgsi_text_translate(text, tokens, Elements(tokens))) { > puts(text); > @@ -556,9 +594,22 @@ util_make_fs_blit_msaa_gen(struct pipe_context *pipe, > */ > void * > util_make_fs_blit_msaa_color(struct pipe_context *pipe, > - unsigned tgsi_tex) > + unsigned tgsi_tex, > + boolean is_uint, > + boolean is_sint) > { > - return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, > + const char *samp_type; > + > + assert(!(is_uint && is_sint)); > + > + if (is_uint) > + samp_type = "UINT"; > + else if (is_sint) > + samp_type = "SINT"; > + else > + samp_type = "FLOAT"; > + > + return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, samp_type, > "COLOR[0]", ""); > } > > @@ -572,7 +623,7 @@ void * > util_make_fs_blit_msaa_depth(struct pipe_context *pipe, > unsigned tgsi_tex) > { > - return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, > + return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, "FLOAT", > "POSITION", ".z"); > } > > @@ -586,7 +637,7 @@ void * > util_make_fs_blit_msaa_stencil(struct pipe_context *pipe, > unsigned tgsi_tex) > { > - return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, > + return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, "UINT", > "STENCIL", ".y"); > } > > @@ -653,6 +704,7 @@ util_make_fs_msaa_resolve(struct pipe_context *pipe, > > /* Declarations. */ > sampler = ureg_DECL_sampler(ureg, 0); > + decl_sampler_view(ureg, 0, tgsi_tex, is_uint, is_sint); > coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, > TGSI_INTERPOLATE_LINEAR); > out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); > @@ -713,6 +765,7 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context > *pipe, > > /* Declarations. */ > sampler = ureg_DECL_sampler(ureg, 0); > + decl_sampler_view(ureg, 0, tgsi_tex, is_uint, is_sint); > coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, > TGSI_INTERPOLATE_LINEAR); > out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); > diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h > b/src/gallium/auxiliary/util/u_simple_shaders.h > index dd282e0..89cb3570 100644 > --- a/src/gallium/auxiliary/util/u_simple_shaders.h > +++ b/src/gallium/auxiliary/util/u_simple_shaders.h > @@ -68,15 +68,18 @@ extern void * > util_make_layered_clear_geometry_shader(struct pipe_context *pipe); > > extern void * > -util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, > +util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, > unsigned tex_target, > unsigned interp_mode, > - unsigned writemask); > + unsigned writemask, > + boolean is_uint, > + boolean is_sint); > > extern void * > util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target, > - unsigned interp_mode); > - > + unsigned interp_mode, > + boolean is_uint, > + boolean is_sint); > > extern void * > util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe, > @@ -115,7 +118,9 @@ util_make_fragment_cloneinput_shader(struct pipe_context > *pipe, int num_cbufs, > > extern void * > util_make_fs_blit_msaa_color(struct pipe_context *pipe, > - unsigned tgsi_tex); > + unsigned tgsi_tex, > + boolean is_uint, > + boolean is_sint); > > > extern void * > diff --git a/src/gallium/auxiliary/util/u_tests.c > b/src/gallium/auxiliary/util/u_tests.c > index fe54972..e30ae55 100644 > --- a/src/gallium/auxiliary/util/u_tests.c > +++ b/src/gallium/auxiliary/util/u_tests.c > @@ -373,7 +373,8 @@ null_sampler_view(struct pipe_context *ctx, unsigned > tgsi_tex_target) > > /* Fragment shader. */ > fs = util_make_fragment_tex_shader(ctx, tgsi_tex_target, > - TGSI_INTERPOLATE_LINEAR); > + TGSI_INTERPOLATE_LINEAR, > + FALSE, FALSE); > cso_set_fragment_shader_handle(cso, fs); > > /* Vertex shader. */ > diff --git a/src/gallium/tests/trivial/quad-tex.c > b/src/gallium/tests/trivial/quad-tex.c > index abecedb..946dbec 100644 > --- a/src/gallium/tests/trivial/quad-tex.c > +++ b/src/gallium/tests/trivial/quad-tex.c > @@ -270,7 +270,7 @@ static void init_prog(struct program *p) > } > > /* fragment shader */ > - p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D, > TGSI_INTERPOLATE_LINEAR); > + p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D, > TGSI_INTERPOLATE_LINEAR, FALSE, FALSE); > } > > static void close_prog(struct program *p) > -- > 2.4.2 > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev