[Mesa-dev] [PATCH 5/7] util/blitter (and friends): generate appropriate SVIEW decls
Rob Clark
robdclark at gmail.com
Thu Jun 11 08:33:31 PDT 2015
On Thu, Jun 11, 2015 at 10:53 AM, Roland Scheidegger <sroland at vmware.com> wrote:
> For 1-4/7, 6/7:
> Reviewed-by: Roland Scheidegger <sroland at vmware.com>
>
> I think though using two exclusive booleans is really ugly. Probably
> should just use a tgsi_return_type enum instead indeed, and treat the
> unorm/snorm cases as float. I'm not entirely sure what the unorm/snorm
> types are for neither, this is a d3d10-ism but I'm not sure it serves
> much purpose (since, of course, for the purposes of the shader, the
> results indeed are floats). At least for now llvmpipe actually doesn't
> use that information (as we recompile the shader anyway if the texture
> "type" changes in the actually bound sampler views we get all the
> information from there).
>
>
> (FWIW I believe there's a slight catch with the
> util_format_is_pure_uint/sint functions - because right now in gallium
> it is sort of ok to sample from things like D24S8 textures, which means
> the depth component is sampled (so same as D24X8, opposed to X24S8), and
> depending if the D or S channel is first the answer may not quite be
> right...)
fwiw, the u_blitter (or rather u_simple_shader) is actually creating
separate samplers for depth+stencil. So I don't *think* we use
_is_pure_uint/sint() on zs formats..
Currently I'm always treating stencil SVIEW as uint and depth SVIEW as
float (since at least from u_format.csv this seemed to be the case..)
BR,
-R
> Roland
>
> Am 11.06.2015 um 02:14 schrieb Rob Clark:
>> From: Rob Clark <robclark at freedesktop.org>
>>
>> Some hardware needs to know the sampler type. Update the blit related
>> shaders to include SVIEW decl.
>>
>> Signed-off-by: Rob Clark <robclark at 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)
>>
>
More information about the mesa-dev
mailing list