summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2011-09-21 11:40:27 +0800
committerChia-I Wu <[email protected]>2011-09-21 12:01:21 +0800
commit4a96a02de7c1b8c136ffc0cd278401c85faab233 (patch)
tree4013803f8828ec0fd99f9a4f557f7455d5b960fb /src
parentceb6d34906c7c03c102c7e78dd02f5b0ebab4ca9 (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')
-rw-r--r--src/gallium/state_trackers/vega/renderer.c8
-rw-r--r--src/gallium/state_trackers/vega/shader.c32
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