diff options
author | Chia-I Wu <[email protected]> | 2011-09-21 11:40:27 +0800 |
---|---|---|
committer | Chia-I Wu <[email protected]> | 2011-09-21 12:01:21 +0800 |
commit | 4a96a02de7c1b8c136ffc0cd278401c85faab233 (patch) | |
tree | 4013803f8828ec0fd99f9a4f557f7455d5b960fb /src/gallium/state_trackers | |
parent | ceb6d34906c7c03c102c7e78dd02f5b0ebab4ca9 (diff) |
st/vega: fix drawing images with alpha channel
Checking if the paints are opaque in renderer_validate_blend() does not
work. We could be drawing images. Remove the check from
renderer_validate_blend() and take image drawing into consideration in
blend_use_shader().
The bug was introduced by 3f0a966807f03a364edea0272ddf45f08ab7ce4f,
which affects the lookup demo.
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r-- | src/gallium/state_trackers/vega/renderer.c | 8 | ||||
-rw-r--r-- | src/gallium/state_trackers/vega/shader.c | 32 |
2 files changed, 22 insertions, 18 deletions
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c index 5715073e2d9..e4c1fd5e3a3 100644 --- a/src/gallium/state_trackers/vega/renderer.c +++ b/src/gallium/state_trackers/vega/renderer.c @@ -28,7 +28,6 @@ #include "renderer.h" #include "vg_context.h" -#include "paint.h" /* for paint_is_opaque */ #include "pipe/p_context.h" #include "pipe/p_state.h" @@ -1292,11 +1291,8 @@ static void renderer_validate_blend(struct renderer *renderer, blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; break; case VG_BLEND_SRC_OVER: - if (paint_is_opaque(state->fill_paint) && - paint_is_opaque(state->stroke_paint)) { - /* no blending */ - } - else if (!util_format_has_alpha(fb_format)) { + /* use the blend state only when there is no alpha channel */ + if (!util_format_has_alpha(fb_format)) { blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c index bee6d84001d..09ba4049cb6 100644 --- a/src/gallium/state_trackers/vega/shader.c +++ b/src/gallium/state_trackers/vega/shader.c @@ -127,17 +127,12 @@ static VGint setup_constant_buffer(struct shader *shader) return param_bytes; } -static VGboolean blend_use_shader(struct vg_context *ctx) +static VGboolean blend_use_shader(struct shader *shader) { + struct vg_context *ctx = shader->context; VGboolean advanced_blending; switch (ctx->state.vg.blend_mode) { - case VG_BLEND_SRC_OVER: - advanced_blending = - (!paint_is_opaque(ctx->state.vg.fill_paint) || - !paint_is_opaque(ctx->state.vg.stroke_paint)) && - util_format_has_alpha(ctx->draw_buffer->strb->format); - break; case VG_BLEND_DST_OVER: case VG_BLEND_MULTIPLY: case VG_BLEND_SCREEN: @@ -146,6 +141,18 @@ static VGboolean blend_use_shader(struct vg_context *ctx) case VG_BLEND_ADDITIVE: advanced_blending = VG_TRUE; break; + case VG_BLEND_SRC_OVER: + if (util_format_has_alpha(ctx->draw_buffer->strb->format)) { + /* no blending is required if the paints and the image are opaque */ + advanced_blending = !paint_is_opaque(ctx->state.vg.fill_paint) || + !paint_is_opaque(ctx->state.vg.stroke_paint); + if (!advanced_blending && shader->drawing_image) { + advanced_blending = + util_format_has_alpha(shader->image->sampler_view->format); + } + break; + } + /* fall through */ default: advanced_blending = VG_FALSE; break; @@ -154,11 +161,13 @@ static VGboolean blend_use_shader(struct vg_context *ctx) return advanced_blending; } -static VGint blend_bind_samplers(struct vg_context *ctx, +static VGint blend_bind_samplers(struct shader *shader, struct pipe_sampler_state **samplers, struct pipe_sampler_view **sampler_views) { - if (blend_use_shader(ctx)) { + if (blend_use_shader(shader)) { + struct vg_context *ctx = shader->context; + samplers[2] = &ctx->blend_sampler; sampler_views[2] = vg_prepare_blend_surface(ctx); @@ -180,7 +189,6 @@ static VGint setup_samplers(struct shader *shader, struct pipe_sampler_state **samplers, struct pipe_sampler_view **sampler_views) { - struct vg_context *ctx = shader->context; /* a little wonky: we use the num as a boolean that just says * whether any sampler/textures have been set. the actual numbering * for samplers is always the same: @@ -202,7 +210,7 @@ static VGint setup_samplers(struct shader *shader, num += paint_bind_samplers(shader->paint, samplers, sampler_views); num += mask_bind_samplers(samplers, sampler_views); - num += blend_bind_samplers(ctx, samplers, sampler_views); + num += blend_bind_samplers(shader, samplers, sampler_views); if (shader->drawing_image && shader->image) num += image_bind_samplers(shader->image, samplers, sampler_views); @@ -276,7 +284,7 @@ static void setup_shader_program(struct shader *shader) if (shader->color_transform) shader_id |= VEGA_COLOR_TRANSFORM_SHADER; - if (blend_use_shader(ctx)) { + if (blend_use_shader(shader)) { if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL) shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER; else |