summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/vega/shader.c
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2010-12-04 12:03:07 +0800
committerChia-I Wu <[email protected]>2010-12-04 13:20:38 +0800
commite8ff3931f801dffdfd54832c298351e933688235 (patch)
tree44a830b96b474489bce1b7b02fa3d0008e799a35 /src/gallium/state_trackers/vega/shader.c
parenta19eaaa6c1956add5343295af7e9f682efa08d74 (diff)
st/vega: Add support for per-channel alpha.
Drawing an image in VG_DRAW_IMAGE_STENCIL mode produces per-channel alpha for use in blending. Add a new shader stage to produce and save it in TEMP[1]. For other modes that do not need per-channel alpha, the stage does MOV TEMP[1], TEMP[0].wwww
Diffstat (limited to 'src/gallium/state_trackers/vega/shader.c')
-rw-r--r--src/gallium/state_trackers/vega/shader.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c
index 20ced813b4b..8577d21efe4 100644
--- a/src/gallium/state_trackers/vega/shader.c
+++ b/src/gallium/state_trackers/vega/shader.c
@@ -209,6 +209,7 @@ static void setup_shader_program(struct shader *shader)
VGint shader_id = 0;
VGBlendMode blend_mode = ctx->state.vg.blend_mode;
VGboolean black_white = is_format_bw(shader);
+ VGboolean advanced_blend;
/* 1st stage: fill */
if (!shader->drawing_image ||
@@ -257,22 +258,47 @@ static void setup_shader_program(struct shader *shader)
switch(blend_mode) {
case VG_BLEND_MULTIPLY:
- shader_id |= VEGA_BLEND_MULTIPLY_SHADER;
- break;
case VG_BLEND_SCREEN:
- shader_id |= VEGA_BLEND_SCREEN_SHADER;
- break;
case VG_BLEND_DARKEN:
- shader_id |= VEGA_BLEND_DARKEN_SHADER;
- break;
case VG_BLEND_LIGHTEN:
- shader_id |= VEGA_BLEND_LIGHTEN_SHADER;
+ advanced_blend = VG_TRUE;
break;
default:
/* handled by pipe_blend_state */
+ advanced_blend = VG_FALSE;
break;
}
+ if (advanced_blend) {
+ if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL)
+ shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER;
+ else
+ shader_id |= VEGA_ALPHA_NORMAL_SHADER;
+
+ switch(blend_mode) {
+ case VG_BLEND_MULTIPLY:
+ shader_id |= VEGA_BLEND_MULTIPLY_SHADER;
+ break;
+ case VG_BLEND_SCREEN:
+ shader_id |= VEGA_BLEND_SCREEN_SHADER;
+ break;
+ case VG_BLEND_DARKEN:
+ shader_id |= VEGA_BLEND_DARKEN_SHADER;
+ break;
+ case VG_BLEND_LIGHTEN:
+ shader_id |= VEGA_BLEND_LIGHTEN_SHADER;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ else {
+ /* update alpha of the source */
+ if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL)
+ shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER;
+ }
+
if (shader->masking)
shader_id |= VEGA_MASK_SHADER;