From dc1486a7b8996e82c6e8b66a608ff5e50b98797e Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Wed, 3 Nov 2021 07:43:17 +0100 Subject: [PATCH] vrend/shader: Fix TEXTURE_BUFFER swizzling for emulated formats The swizzling didn't take into account that the destination might actually only read a few components or just one, so that the applied swizzling could even become invalid because code like dest.z = vec4(dest.z.x, dest.z.y.dest.z.z. dest.z.w) could be created. The check for when to apply the swizzling was also not correct because the two values compared came from different name-spaces. To fix this, just check whether the TEXTURE_NEEDS_SWIZZLE is set, and when loweing in the shader, take only the components into account that are actually written. This also needs a fix for the alpha-format override to add the TEXTURE_NEEDS_SWIZZLE flag. Finally take the shader type into account when checking the number of sampler views. v2: Correct the shader code to apply the swizzling (Maksym) v3: Fix formatting (Maksym) Fixes: 29c6b9177541f189ebed5158a432b21d0d82211 vrend: apply format swizzling during GLSL generation Signed-off-by: Gert Wollny Reviewed-by: maksym.wezdecki@collabora.com --- src/vrend_formats.c | 3 ++- src/vrend_renderer.c | 13 ++++++------ src/vrend_shader.c | 47 ++++++++++++++++++++++++++++++++------------ 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/vrend_formats.c b/src/vrend_formats.c index 11b3cc4..a69763e 100644 --- a/src/vrend_formats.c +++ b/src/vrend_formats.c @@ -483,12 +483,13 @@ static void vrend_add_formats(struct vrend_format_table *table, int num_entries) entry = &rg_base_formats[0]; swizzle[0] = swizzle[1] = swizzle[2] = PIPE_SWIZZLE_ZERO; swizzle[3] = PIPE_SWIZZLE_RED; - + flags |= VIRGL_TEXTURE_NEED_SWIZZLE; break; case VIRGL_FORMAT_A16_UNORM: entry = &rg_base_formats[2]; swizzle[0] = swizzle[1] = swizzle[2] = PIPE_SWIZZLE_ZERO; swizzle[3] = PIPE_SWIZZLE_RED; + flags |= VIRGL_TEXTURE_NEED_SWIZZLE; break; default: break; diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 855253f..801057d 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -3576,15 +3576,16 @@ static inline void vrend_fill_shader_key(struct vrend_sub_context *sub_ctx, if (type != PIPE_SHADER_COMPUTE) vrend_sync_shader_io(sub_ctx, sel, key); - for (int i = 0; i < sub_ctx->views->num_views; i++) { + for (int i = 0; i < sub_ctx->views[type].num_views; i++) { struct vrend_sampler_view *view = sub_ctx->views[type].views[i]; if (view && view->texture->target == GL_TEXTURE_BUFFER && - view->format != tex_conv_table[view->format].internalformat) { + tex_conv_table[view->format].flags & VIRGL_TEXTURE_NEED_SWIZZLE) { + key->sampler_views_lower_swizzle_mask |= 1 << i; - key->tex_swizzle[i] = to_pipe_swizzle(view->gl_swizzle[0]) | - to_pipe_swizzle(view->gl_swizzle[1]) << 3 | - to_pipe_swizzle(view->gl_swizzle[2]) << 6 | - to_pipe_swizzle(view->gl_swizzle[3]) << 9 ; + key->tex_swizzle[i] = to_pipe_swizzle(view->gl_swizzle[0]) | + to_pipe_swizzle(view->gl_swizzle[1]) << 3 | + to_pipe_swizzle(view->gl_swizzle[2]) << 6 | + to_pipe_swizzle(view->gl_swizzle[3]) << 9; } } } diff --git a/src/vrend_shader.c b/src/vrend_shader.c index 57a3e75..428dc59 100644 --- a/src/vrend_shader.c +++ b/src/vrend_shader.c @@ -2964,22 +2964,43 @@ static void translate_tex(struct dump_ctx *ctx, dinfo->dst_override_no_wm[0] ? "" : writemask); } } else { - emit_buff(&ctx->glsl_strbufs, "%s = %s(%s(texelFetch%s(%s, %s(%s%s)%s%s)%s));\n", - dst, get_string(dinfo->dstconv), get_string(dtypeprefix), + + /* To inject the swizzle for texturebufffers with emulated formats do + * + * { + * vec4 val = texelFetch( ) + * val = vec4(0/1/swizzle_x, ...); + * dest.writemask = val.writemask; + * } + * + */ + emit_buff(&ctx->glsl_strbufs, "{\n vec4 val = %s(texelFetch%s(%s, %s(%s%s)%s%s));\n", + get_string(dtypeprefix), tex_ext, srcs[sampler_index], get_string(txfi), srcs[0], - get_wm_string(twm), bias, offset, - dinfo->dst_override_no_wm[0] ? "" : writemask); + get_wm_string(twm), bias, offset); + if (ctx->key->sampler_views_lower_swizzle_mask & (1 << sinfo->sreg_index)) { - uint8_t swizzle_r = ctx->key->tex_swizzle[sinfo->sreg_index] & 7; - uint8_t swizzle_g = (ctx->key->tex_swizzle[sinfo->sreg_index] & (7 << 3)) >> 3; - uint8_t swizzle_b = (ctx->key->tex_swizzle[sinfo->sreg_index] & (7 << 6)) >> 6; - uint8_t swizzle_a = (ctx->key->tex_swizzle[sinfo->sreg_index] & (7 << 9)) >> 9; - emit_buff(&ctx->glsl_strbufs, "%s = vec4(%s%s, %s%s, %s%s, %s%s);\n", dst, - swizzle_r == PIPE_SWIZZLE_ZERO ? "0" : (swizzle_r == PIPE_SWIZZLE_ONE ? "1" : dst), get_swizzle_string(swizzle_r), - swizzle_g == PIPE_SWIZZLE_ZERO ? "0" : (swizzle_g == PIPE_SWIZZLE_ONE ? "1" : dst), get_swizzle_string(swizzle_g), - swizzle_b == PIPE_SWIZZLE_ZERO ? "0" : (swizzle_b == PIPE_SWIZZLE_ONE ? "1" : dst), get_swizzle_string(swizzle_b), - swizzle_a == PIPE_SWIZZLE_ZERO ? "0" : (swizzle_a == PIPE_SWIZZLE_ONE ? "1" : dst), get_swizzle_string(swizzle_a)); + int16_t packed_swizzles = ctx->key->tex_swizzle[sinfo->sreg_index]; + emit_buff(&ctx->glsl_strbufs, " val = vec4("); + + for (int i = 0; i < 4; ++i) { + if (i > 0) + emit_buff(&ctx->glsl_strbufs, ", "); + + int swz = (packed_swizzles >> (i * 3)) & 7; + switch (swz) { + case PIPE_SWIZZLE_ZERO : emit_buf(&ctx->glsl_strbufs, "0.0"); break; + case PIPE_SWIZZLE_ONE : emit_buf(&ctx->glsl_strbufs, "1.0"); break; + default: + emit_buff(&ctx->glsl_strbufs, "val%s", get_swizzle_string(swz)); + } + } + + emit_buff(&ctx->glsl_strbufs, ");\n"); } + + emit_buff(&ctx->glsl_strbufs, " %s = val%s;\n}\n", + dst, dinfo->dst_override_no_wm[0] ? "" : writemask); } } else if (ctx->cfg->glsl_version < 140 && (ctx->shader_req_bits & SHADER_REQ_SAMPLER_RECT)) { /* rect is special in GLSL 1.30 */