summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/vrend_formats.c2
-rw-r--r--src/vrend_renderer.c86
-rw-r--r--src/vrend_shader.c16
-rw-r--r--src/vrend_shader.h1
4 files changed, 84 insertions, 21 deletions
diff --git a/src/vrend_formats.c b/src/vrend_formats.c
index 655c9fe..976f063 100644
--- a/src/vrend_formats.c
+++ b/src/vrend_formats.c
@@ -261,7 +261,7 @@ static void vrend_add_formats(struct vrend_format_table *table, int num_entries)
if (status == GL_INVALID_VALUE) {
struct vrend_format_table *entry = NULL;
uint8_t swizzle[4];
- binding = VREND_BIND_SAMPLER | VREND_BIND_NEED_SWIZZLE;
+ binding = VREND_BIND_SAMPLER | VREND_BIND_RENDER | VREND_BIND_NEED_SWIZZLE;
switch (table[i].format) {
case PIPE_FORMAT_A8_UNORM:
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 5f1a644..11eef76 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -412,6 +412,14 @@ bool vrend_is_ds_format(enum virgl_formats format)
return vrend_format_is_ds(format);
}
+static inline bool vrend_format_is_emulated_alpha(enum virgl_formats format)
+{
+ if (!vrend_state.use_core_profile)
+ return false;
+ return (format == VIRGL_FORMAT_A8_UNORM ||
+ format == VIRGL_FORMAT_A16_UNORM);
+}
+
static inline const char *pipe_shader_to_prefix(int shader_type)
{
switch (shader_type) {
@@ -1508,6 +1516,7 @@ void vrend_set_framebuffer_state(struct vrend_context *ctx,
if (status != GL_FRAMEBUFFER_COMPLETE)
fprintf(stderr,"failed to complete framebuffer 0x%x %s\n", status, ctx->debug_name);
}
+ ctx->sub->shader_dirty = true;
}
/*
@@ -1921,9 +1930,12 @@ static inline void vrend_fill_shader_key(struct vrend_context *ctx,
if (vrend_state.use_core_profile == true) {
int i;
bool add_alpha_test = true;
+ key->cbufs_are_a8_bitmask = 0;
for (i = 0; i < ctx->sub->nr_cbufs; i++) {
if (!ctx->sub->surf[i])
continue;
+ if (vrend_format_is_emulated_alpha(ctx->sub->surf[i]->format))
+ key->cbufs_are_a8_bitmask |= (1 << i);
if (util_format_is_pure_integer(ctx->sub->surf[i]->format))
add_alpha_test = false;
}
@@ -2216,8 +2228,13 @@ void vrend_clear(struct vrend_context *ctx,
vrend_use_program(ctx, 0);
- if (buffers & PIPE_CLEAR_COLOR)
- glClearColor(color->f[0], color->f[1], color->f[2], color->f[3]);
+ if (buffers & PIPE_CLEAR_COLOR) {
+ if (ctx->sub->nr_cbufs && ctx->sub->surf[0] && vrend_format_is_emulated_alpha(ctx->sub->surf[0]->format)) {
+ glClearColor(color->f[3], 0.0, 0.0, 0.0);
+ } else {
+ glClearColor(color->f[0], color->f[1], color->f[2], color->f[3]);
+ }
+ }
if (buffers & PIPE_CLEAR_DEPTH) {
/* gallium clears don't respect depth mask */
@@ -2849,6 +2866,15 @@ static inline bool is_dst_blend(int blend_factor)
blend_factor == PIPE_BLENDFACTOR_INV_DST_ALPHA);
}
+static inline int conv_a8_blend(int blend_factor)
+{
+ if (blend_factor == PIPE_BLENDFACTOR_DST_ALPHA)
+ return PIPE_BLENDFACTOR_DST_COLOR;
+ if (blend_factor == PIPE_BLENDFACTOR_INV_DST_ALPHA)
+ return PIPE_BLENDFACTOR_INV_DST_COLOR;
+ return blend_factor;
+}
+
static inline int conv_dst_blend(int blend_factor)
{
if (blend_factor == PIPE_BLENDFACTOR_DST_ALPHA)
@@ -2863,12 +2889,17 @@ static void vrend_patch_blend_func(struct vrend_context *ctx)
struct pipe_blend_state *state = &ctx->sub->blend_state;
int i;
int rsf, rdf, asf, adf;
+ bool a8_conv = false;
if (ctx->sub->nr_cbufs == 0)
return;
for (i = 0; i < ctx->sub->nr_cbufs; i++) {
if (!ctx->sub->surf[i])
continue;
+ if (vrend_format_is_emulated_alpha(ctx->sub->surf[i]->format)) {
+ a8_conv = true;
+ break;
+ }
if (!util_format_has_alpha(ctx->sub->surf[i]->format))
break;
}
@@ -2880,32 +2911,47 @@ static void vrend_patch_blend_func(struct vrend_context *ctx)
/* ARB_draw_buffers_blend is required for this */
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
if (state->rt[i].blend_enable) {
- if (!(is_dst_blend(state->rt[i].rgb_src_factor) ||
- is_dst_blend(state->rt[i].rgb_dst_factor) ||
- is_dst_blend(state->rt[i].alpha_src_factor) ||
- is_dst_blend(state->rt[i].alpha_dst_factor)))
- continue;
- rsf = translate_blend_factor(conv_dst_blend(state->rt[i].rgb_src_factor));
- rdf = translate_blend_factor(conv_dst_blend(state->rt[i].rgb_dst_factor));
- asf = translate_blend_factor(conv_dst_blend(state->rt[i].alpha_src_factor));
- adf = translate_blend_factor(conv_dst_blend(state->rt[i].alpha_dst_factor));
+ if (a8_conv) {
+ rsf = translate_blend_factor(conv_a8_blend(state->rt[i].alpha_src_factor));
+ rdf = translate_blend_factor(conv_a8_blend(state->rt[i].alpha_dst_factor));
+ asf = translate_blend_factor(PIPE_BLENDFACTOR_ZERO);
+ adf = translate_blend_factor(PIPE_BLENDFACTOR_ZERO);
+ } else {
+ if (!(is_dst_blend(state->rt[i].rgb_src_factor) ||
+ is_dst_blend(state->rt[i].rgb_dst_factor) ||
+ is_dst_blend(state->rt[i].alpha_src_factor) ||
+ is_dst_blend(state->rt[i].alpha_dst_factor)))
+ continue;
+
+ rsf = translate_blend_factor(conv_dst_blend(state->rt[i].rgb_src_factor));
+ rdf = translate_blend_factor(conv_dst_blend(state->rt[i].rgb_dst_factor));
+ asf = translate_blend_factor(conv_dst_blend(state->rt[i].alpha_src_factor));
+ adf = translate_blend_factor(conv_dst_blend(state->rt[i].alpha_dst_factor));
+ }
glBlendFuncSeparateiARB(i, rsf, rdf, asf, adf);
}
}
} else {
if (state->rt[0].blend_enable) {
- if (!(is_dst_blend(state->rt[0].rgb_src_factor) ||
- is_dst_blend(state->rt[0].rgb_dst_factor) ||
- is_dst_blend(state->rt[0].alpha_src_factor) ||
- is_dst_blend(state->rt[0].alpha_dst_factor)))
- return;
+ if (a8_conv) {
+ rsf = translate_blend_factor(conv_a8_blend(state->rt[i].alpha_src_factor));
+ rdf = translate_blend_factor(conv_a8_blend(state->rt[i].alpha_dst_factor));
+ asf = translate_blend_factor(PIPE_BLENDFACTOR_ZERO);
+ adf = translate_blend_factor(PIPE_BLENDFACTOR_ZERO);
+ } else {
+ if (!(is_dst_blend(state->rt[0].rgb_src_factor) ||
+ is_dst_blend(state->rt[0].rgb_dst_factor) ||
+ is_dst_blend(state->rt[0].alpha_src_factor) ||
+ is_dst_blend(state->rt[0].alpha_dst_factor)))
+ return;
- rsf = translate_blend_factor(conv_dst_blend(state->rt[i].rgb_src_factor));
- rdf = translate_blend_factor(conv_dst_blend(state->rt[i].rgb_dst_factor));
- asf = translate_blend_factor(conv_dst_blend(state->rt[i].alpha_src_factor));
- adf = translate_blend_factor(conv_dst_blend(state->rt[i].alpha_dst_factor));
+ rsf = translate_blend_factor(conv_dst_blend(state->rt[i].rgb_src_factor));
+ rdf = translate_blend_factor(conv_dst_blend(state->rt[i].rgb_dst_factor));
+ asf = translate_blend_factor(conv_dst_blend(state->rt[i].alpha_src_factor));
+ adf = translate_blend_factor(conv_dst_blend(state->rt[i].alpha_dst_factor));
+ }
glBlendFuncSeparate(rsf, rdf, asf, adf);
}
diff --git a/src/vrend_shader.c b/src/vrend_shader.c
index 1db3278..5ac5287 100644
--- a/src/vrend_shader.c
+++ b/src/vrend_shader.c
@@ -681,6 +681,17 @@ static const char *atests[PIPE_FUNC_ALWAYS + 1] = {
"true",
};
+static int emit_a8_swizzle(struct dump_ctx *ctx)
+{
+ char buf[255];
+ char *sret;
+ snprintf(buf, 255, "fsout_c0.x = fsout_c0.w;\n");
+ sret = add_str_to_glsl_main(ctx, buf);
+ if (!sret)
+ return ENOMEM;
+ return 0;
+}
+
static int emit_alpha_test(struct dump_ctx *ctx)
{
char buf[255];
@@ -1757,6 +1768,11 @@ iter_instruction(struct tgsi_iterate_context *iter,
if (ret)
return FALSE;
}
+ if (ctx->key->cbufs_are_a8_bitmask) {
+ ret = emit_a8_swizzle(ctx);
+ if (ret)
+ return FALSE;
+ }
if (ctx->key->add_alpha_test) {
ret = emit_alpha_test(ctx);
if (ret)
diff --git a/src/vrend_shader.h b/src/vrend_shader.h
index be506cb..5d9bc17 100644
--- a/src/vrend_shader.h
+++ b/src/vrend_shader.h
@@ -63,6 +63,7 @@ struct vrend_shader_key {
bool gs_present;
bool flatshade;
float alpha_ref_val;
+ uint32_t cbufs_are_a8_bitmask;
};
struct vrend_shader_cfg {