tweaks: Add tweak to apply the dest swizzle for emulated BGRA surfaces

With vtest this swizzling is necessary, but with qemu it is not, so make
it a tweak.

v2: Use original blit format to check the format type in blitter

v3: Correct typo (Gurchetan)

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Gert Wollny 6 years ago
parent 8aee663a61
commit 4ea1510332
  1. 1
      src/virgl_protocol.h
  2. 16
      src/vrend_blitter.c
  3. 36
      src/vrend_renderer.c
  4. 3
      src/vrend_renderer.h
  5. 13
      src/vrend_shader.c
  6. 1
      src/vrend_shader.h
  7. 9
      src/vrend_tweaks.c

@ -600,6 +600,7 @@ enum virgl_context_cmd {
enum vrend_tweak_type { enum vrend_tweak_type {
virgl_tweak_gles_brga_emulate, virgl_tweak_gles_brga_emulate,
virgl_tweak_gles_brga_apply_dest_swizzle,
virgl_tweak_undefined virgl_tweak_undefined
}; };

@ -406,11 +406,12 @@ static GLuint blit_get_frag_tex_col(struct vrend_blitter_ctx *blit_ctx,
int pipe_tex_target, int pipe_tex_target,
unsigned nr_samples, unsigned nr_samples,
const struct vrend_format_table *src_entry, const struct vrend_format_table *src_entry,
const struct vrend_format_table *dst_entry) const struct vrend_format_table *dst_entry,
bool skip_dest_swizzle)
{ {
assert(pipe_tex_target < PIPE_MAX_TEXTURE_TYPES); assert(pipe_tex_target < PIPE_MAX_TEXTURE_TYPES);
bool needs_swizzle = dst_entry->flags & VIRGL_TEXTURE_NEED_SWIZZLE; bool needs_swizzle = !skip_dest_swizzle && (dst_entry->flags & VIRGL_TEXTURE_NEED_SWIZZLE);
if (needs_swizzle || nr_samples > 1) { if (needs_swizzle || nr_samples > 1) {
const uint8_t *swizzle = needs_swizzle ? dst_entry->swizzle : NULL; const uint8_t *swizzle = needs_swizzle ? dst_entry->swizzle : NULL;
@ -711,7 +712,8 @@ void vrend_renderer_blit_gl(struct vrend_context *ctx,
GLenum blit_views[2], GLenum blit_views[2],
const struct pipe_blit_info *info, const struct pipe_blit_info *info,
bool has_texture_srgb_decode, bool has_texture_srgb_decode,
bool has_srgb_write_control) bool has_srgb_write_control,
bool skip_dest_swizzle)
{ {
struct vrend_blitter_ctx *blit_ctx = &vrend_blit_ctx; struct vrend_blitter_ctx *blit_ctx = &vrend_blit_ctx;
GLuint buffers; GLuint buffers;
@ -731,9 +733,10 @@ void vrend_renderer_blit_gl(struct vrend_context *ctx,
const struct util_format_description *dst_desc = const struct util_format_description *dst_desc =
util_format_description(dst_res->base.format); util_format_description(dst_res->base.format);
const struct vrend_format_table *src_entry = const struct vrend_format_table *src_entry =
vrend_get_format_table_entry(info->src.format); vrend_get_format_table_entry_with_emulation(src_res->base.bind, info->src.format);
const struct vrend_format_table *orig_src_entry = vrend_get_format_table_entry(info->src.format);
const struct vrend_format_table *dst_entry = const struct vrend_format_table *dst_entry =
vrend_get_format_table_entry(info->dst.format); vrend_get_format_table_entry_with_emulation(dst_res->base.bind, info->dst.format);
has_depth = util_format_has_depth(src_desc) && has_depth = util_format_has_depth(src_desc) &&
util_format_has_depth(dst_desc); util_format_has_depth(dst_desc);
@ -779,7 +782,8 @@ void vrend_renderer_blit_gl(struct vrend_context *ctx,
} else { } else {
fs_id = blit_get_frag_tex_col(blit_ctx, src_res->base.target, fs_id = blit_get_frag_tex_col(blit_ctx, src_res->base.target,
src_res->base.nr_samples, src_res->base.nr_samples,
src_entry, dst_entry); orig_src_entry, dst_entry,
skip_dest_swizzle);
} }
glAttachShader(prog_id, fs_id); glAttachShader(prog_id, fs_id);

@ -596,6 +596,7 @@ struct vrend_sub_context {
struct vrend_abo abo[PIPE_MAX_HW_ATOMIC_BUFFERS]; struct vrend_abo abo[PIPE_MAX_HW_ATOMIC_BUFFERS];
uint32_t abo_used_mask; uint32_t abo_used_mask;
struct vrend_context_tweaks tweaks; struct vrend_context_tweaks tweaks;
uint8_t swizzle_output_rgb_to_bgr;
}; };
struct vrend_context { struct vrend_context {
@ -2259,6 +2260,22 @@ static void vrend_hw_emit_framebuffer_state(struct vrend_context *ctx)
glDisable(GL_FRAMEBUFFER_SRGB_EXT); glDisable(GL_FRAMEBUFFER_SRGB_EXT);
} }
} }
if (vrend_state.use_gles &&
vrend_get_tweak_is_active(&ctx->sub->tweaks, virgl_tweak_gles_brga_apply_dest_swizzle)) {
ctx->sub->swizzle_output_rgb_to_bgr = 0;
for (int i = 0; i < ctx->sub->nr_cbufs; i++) {
if (ctx->sub->surf[i]) {
struct vrend_surface *surf = ctx->sub->surf[i];
if (surf->texture->base.bind & VIRGL_BIND_PREFER_EMULATED_BGRA) {
VREND_DEBUG(dbg_tweak, ctx, "Swizzled BGRA output for 0x%x (%s)\n", i, util_format_name(surf->format));
ctx->sub->swizzle_output_rgb_to_bgr |= 1 << i;
}
}
}
}
glDrawBuffers(ctx->sub->nr_cbufs, buffers); glDrawBuffers(ctx->sub->nr_cbufs, buffers);
} }
@ -3044,6 +3061,9 @@ static inline void vrend_fill_shader_key(struct vrend_context *ctx,
key->coord_replace = ctx->sub->rs_state.point_quad_rasterization ? ctx->sub->rs_state.sprite_coord_enable : 0; key->coord_replace = ctx->sub->rs_state.point_quad_rasterization ? ctx->sub->rs_state.sprite_coord_enable : 0;
key->winsys_adjust_y_emitted = false; key->winsys_adjust_y_emitted = false;
if (type == PIPE_SHADER_FRAGMENT)
key->fs_swizzle_output_rgb_to_bgr = ctx->sub->swizzle_output_rgb_to_bgr;
if (ctx->sub->shaders[PIPE_SHADER_GEOMETRY]) if (ctx->sub->shaders[PIPE_SHADER_GEOMETRY])
key->gs_present = true; key->gs_present = true;
if (ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]) if (ctx->sub->shaders[PIPE_SHADER_TESS_CTRL])
@ -4177,7 +4197,7 @@ int vrend_draw_vbo(struct vrend_context *ctx,
if (ctx->sub->blend_state_dirty) if (ctx->sub->blend_state_dirty)
vrend_patch_blend_state(ctx); vrend_patch_blend_state(ctx);
if (ctx->sub->shader_dirty) { if (ctx->sub->shader_dirty || ctx->sub->swizzle_output_rgb_to_bgr) {
struct vrend_linked_shader_program *prog; struct vrend_linked_shader_program *prog;
bool fs_dirty, vs_dirty, gs_dirty, tcs_dirty, tes_dirty; bool fs_dirty, vs_dirty, gs_dirty, tcs_dirty, tes_dirty;
bool dual_src = util_blend_state_is_dual(&ctx->sub->blend_state, 0); bool dual_src = util_blend_state_is_dual(&ctx->sub->blend_state, 0);
@ -7864,6 +7884,7 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
int n_layers = 1, i; int n_layers = 1, i;
bool use_gl = false; bool use_gl = false;
bool make_intermediate_copy = false; bool make_intermediate_copy = false;
bool skip_dest_swizzle = false;
GLuint intermediate_fbo = 0; GLuint intermediate_fbo = 0;
struct vrend_resource *intermediate_copy = 0; struct vrend_resource *intermediate_copy = 0;
@ -7946,9 +7967,17 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
if (info->src.box.depth != info->dst.box.depth) if (info->src.box.depth != info->dst.box.depth)
use_gl = true; use_gl = true;
if (vrend_blit_needs_swizzle(info->dst.format, info->src.format)) if (vrend_blit_needs_swizzle(vrend_format_replace_emulated(dst_res->base.bind, info->dst.format),
vrend_format_replace_emulated(src_res->base.bind, info->src.format))) {
use_gl = true; use_gl = true;
if (vrend_state.use_gles &&
(dst_res->base.bind & VIRGL_BIND_PREFER_EMULATED_BGRA) &&
!vrend_get_tweak_is_active(&ctx->sub->tweaks, virgl_tweak_gles_brga_apply_dest_swizzle)) {
skip_dest_swizzle = true;
}
}
if ((src_res->base.format != info->src.format) && has_feature(feat_texture_view)) if ((src_res->base.format != info->src.format) && has_feature(feat_texture_view))
blitter_views[0] = vrend_make_view(src_res, info->src.format); blitter_views[0] = vrend_make_view(src_res, info->src.format);
@ -7960,7 +7989,8 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
VREND_DEBUG(dbg_blit, ctx, "BLIT_INT: use GL fallback\n"); VREND_DEBUG(dbg_blit, ctx, "BLIT_INT: use GL fallback\n");
vrend_renderer_blit_gl(ctx, src_res, dst_res, blitter_views, info, vrend_renderer_blit_gl(ctx, src_res, dst_res, blitter_views, info,
has_feature(feat_texture_srgb_decode), has_feature(feat_texture_srgb_decode),
has_feature(feat_srgb_write_control)); has_feature(feat_srgb_write_control),
skip_dest_swizzle);
vrend_clicbs->make_current(ctx->sub->gl_context); vrend_clicbs->make_current(ctx->sub->gl_context);
goto cleanup; goto cleanup;
} }

@ -440,7 +440,8 @@ void vrend_renderer_blit_gl(struct vrend_context *ctx,
GLenum blit_views[2], GLenum blit_views[2],
const struct pipe_blit_info *info, const struct pipe_blit_info *info,
bool has_texture_srgb_decode, bool has_texture_srgb_decode,
bool has_srgb_write_control); bool has_srgb_write_control,
bool skip_dest_swizzle);
void vrend_blitter_fini(void); void vrend_blitter_fini(void);
void vrend_renderer_reset(void); void vrend_renderer_reset(void);

@ -2030,6 +2030,15 @@ static void emit_fragment_logicop(struct dump_ctx *ctx)
} }
} }
static void emit_cbuf_swizzle(struct dump_ctx *ctx)
{
for (uint i = 0; i < ctx->num_outputs; i++) {
if (ctx->key->fs_swizzle_output_rgb_to_bgr & (1 << i)) {
emit_buff(ctx, "fsout_c%d = fsout_c%d.zyxw;\n", i, i);
}
}
}
static void handle_fragment_proc_exit(struct dump_ctx *ctx) static void handle_fragment_proc_exit(struct dump_ctx *ctx)
{ {
if (ctx->key->pstipple_tex) if (ctx->key->pstipple_tex)
@ -2041,9 +2050,13 @@ static void handle_fragment_proc_exit(struct dump_ctx *ctx)
if (ctx->key->add_alpha_test) if (ctx->key->add_alpha_test)
emit_alpha_test(ctx); emit_alpha_test(ctx);
if (ctx->key->fs_logicop_enabled) if (ctx->key->fs_logicop_enabled)
emit_fragment_logicop(ctx); emit_fragment_logicop(ctx);
if (ctx->key->fs_swizzle_output_rgb_to_bgr)
emit_cbuf_swizzle(ctx);
if (ctx->write_all_cbufs) if (ctx->write_all_cbufs)
emit_cbuf_writes(ctx); emit_cbuf_writes(ctx);

@ -124,6 +124,7 @@ struct vrend_shader_key {
uint8_t num_indirect_generic_inputs; uint8_t num_indirect_generic_inputs;
uint8_t num_indirect_patch_inputs; uint8_t num_indirect_patch_inputs;
uint32_t generic_outputs_expected_mask; uint32_t generic_outputs_expected_mask;
uint8_t fs_swizzle_output_rgb_to_bgr;
}; };
struct vrend_shader_cfg { struct vrend_shader_cfg {

@ -49,6 +49,10 @@ const char *tweak_debug_table[] = {
[virgl_tweak_gles_brga_emulate] = [virgl_tweak_gles_brga_emulate] =
"GLES: Skip linearization in blits to BGRA_UNORM surfaces", "GLES: Skip linearization in blits to BGRA_UNORM surfaces",
[virgl_tweak_gles_brga_apply_dest_swizzle] =
"GLES: Apply dest swizzle when a BGRA surface is emulated by an RGBA surface",
[virgl_tweak_gles_tf3_samples_passes_multiplier] =
[virgl_tweak_undefined] = "Undefined tweak" [virgl_tweak_undefined] = "Undefined tweak"
}; };
@ -83,6 +87,11 @@ struct {
} tweak_table [] = { } tweak_table [] = {
{ virgl_tweak_gles_brga_emulate, "emu-bgra", { virgl_tweak_gles_brga_emulate, "emu-bgra",
"Emulate BGRA_UNORM and BGRA_SRB by using swizzled RGBA formats" }, "Emulate BGRA_UNORM and BGRA_SRB by using swizzled RGBA formats" },
{ virgl_tweak_gles_brga_apply_dest_swizzle, "bgra-dest-swz",
"Apply the destination swizzle of emulated BGRA surfaces in blits"},
{ virgl_tweak_gles_tf3_samples_passes_multiplier, "samples-passed",
{ virgl_tweak_undefined, NULL, NULL} { virgl_tweak_undefined, NULL, NULL}
}; };

Loading…
Cancel
Save