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 <gert.wollny@collabora.com>
Reviewed-by: maksym.wezdecki@collabora.com
macos/master
Gert Wollny 3 years ago
parent d755dfa28c
commit dc1486a7b8
  1. 3
      src/vrend_formats.c
  2. 13
      src/vrend_renderer.c
  3. 47
      src/vrend_shader.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;

@ -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;
}
}
}

@ -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 */

Loading…
Cancel
Save