summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Oliveira <igor.oliveira@openbossa.org>2010-02-06 13:56:18 -0400
committerIgor Trindade Oliveira <igor@Cygnus.(none)>2010-02-11 10:36:24 -0400
commite720cd6251956acd61af8d1ad08551f40264d9f6 (patch)
tree6421f91bacb2121d3e908540f8bdb1b2202e52be
parentb3f1842c3f5d9ebd62a942e7e53b6b4be26c0aba (diff)
vega: add support for VG_BLEND_HARDLIGHT_KHR blend advanced mode.
It is used by SVG1.2 and it is defined as: Multiplies or screens the colors, dependent on the source color value. If the source color is lighter than 0.5, the destination is lightened as if it were screened. If the source color is darker than 0.5, the destination is darkened, as if it were multiplied. The degree of lightening or darkening is proportional to the difference between the source color and 0.5. If it is equal to 0.5 the destination is unchanged. Painting with pure black or white produces black or white
-rw-r--r--src/gallium/state_trackers/vega/api_params.c2
-rw-r--r--src/gallium/state_trackers/vega/asm_fill.h62
-rw-r--r--src/gallium/state_trackers/vega/shader.c6
-rw-r--r--src/gallium/state_trackers/vega/shaders_cache.c16
-rw-r--r--src/gallium/state_trackers/vega/shaders_cache.h33
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c1
6 files changed, 96 insertions, 24 deletions
diff --git a/src/gallium/state_trackers/vega/api_params.c b/src/gallium/state_trackers/vega/api_params.c
index fde5950ffd..4230660bdf 100644
--- a/src/gallium/state_trackers/vega/api_params.c
+++ b/src/gallium/state_trackers/vega/api_params.c
@@ -161,7 +161,7 @@ void vgSeti (VGParamType type, VGint value)
break;
case VG_BLEND_MODE:
if (value < VG_BLEND_SRC ||
- value > VG_BLEND_OVERLAY_KHR)
+ value > VG_BLEND_HARDLIGHT_KHR)
error = VG_ILLEGAL_ARGUMENT_ERROR;
else {
ctx->state.dirty |= BLEND_DIRTY;
diff --git a/src/gallium/state_trackers/vega/asm_fill.h b/src/gallium/state_trackers/vega/asm_fill.h
index b225c17e0e..d9f23870a0 100644
--- a/src/gallium/state_trackers/vega/asm_fill.h
+++ b/src/gallium/state_trackers/vega/asm_fill.h
@@ -397,6 +397,66 @@ blend_overlay_khr( struct ureg_program *ureg,
}
static INLINE void
+blend_hardlight_khr( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ unsigned label;
+
+ ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
+
+ ureg_ADD(ureg, temp[2], ureg_src(temp[0]), ureg_src(temp[0]));
+
+ ureg_SLT(ureg, temp[2], ureg_src(temp[2]),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
+ ureg_MOV(ureg,
+ ureg_writemask(temp[2], TGSI_WRITEMASK_W),
+ ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
+
+ EXTENDED_BLENDER_OVER_FUNC
+
+ label = ureg_get_instruction_number(ureg);
+ label += 2;
+
+ ureg_IF(ureg, ureg_src(temp[2]), &label);
+ ureg_MUL(ureg,
+ ureg_writemask(temp[2], TGSI_WRITEMASK_XYZ),
+ ureg_src(temp[0]), ureg_src(temp[1]));
+ ureg_ADD(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[2]));
+ ureg_ADD(ureg, temp[1], ureg_src(temp[2]), ureg_src(temp[3]));
+
+ label = ureg_get_instruction_number(ureg);
+ label += 2;
+
+ ureg_ELSE(ureg, &label);
+ ureg_SUB(ureg, temp[2],
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W),
+ ureg_src(temp[1]));
+ ureg_SUB(ureg, temp[4], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_src(temp[0]));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[4]));
+ ureg_ADD(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[2]));
+ ureg_MUL(ureg, temp[4], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_SUB(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_XYZ),
+ ureg_src(temp[4]), ureg_src(temp[2]));
+ ureg_ADD(ureg, temp[1], ureg_src(temp[2]), ureg_src(temp[3]));
+ ureg_ENDIF(ureg);
+
+ ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
+ ureg_src(temp[3]), ureg_src(temp[2]));
+
+ ureg_MOV(ureg, *out, ureg_src(temp[1]));
+}
+
+static INLINE void
premultiply( struct ureg_program *ureg,
struct ureg_dst *out,
struct ureg_src *in,
@@ -505,6 +565,8 @@ static const struct shader_asm_info shaders_asm[] = {
VG_TRUE, 1, 1, 2, 1, 0, 6},
{VEGA_BLEND_OVERLAY_KHR_SHADER, blend_overlay_khr,
VG_TRUE, 1, 1, 2, 1, 0, 6},
+ {VEGA_BLEND_HARDLIGHT_KHR_SHADER, blend_hardlight_khr,
+ VG_TRUE, 1, 1, 2, 1, 0, 6},
/* premultiply */
{VEGA_PREMULTIPLY_SHADER, premultiply,
diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c
index 4f82d03a86..7538e36e76 100644
--- a/src/gallium/state_trackers/vega/shader.c
+++ b/src/gallium/state_trackers/vega/shader.c
@@ -127,7 +127,8 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
bmode == VG_BLEND_SCREEN ||
bmode == VG_BLEND_DARKEN ||
bmode == VG_BLEND_LIGHTEN ||
- bmode == VG_BLEND_OVERLAY_KHR) {
+ bmode == VG_BLEND_OVERLAY_KHR ||
+ bmode == VG_BLEND_HARDLIGHT_KHR) {
struct st_framebuffer *stfb = ctx->draw_buffer;
vg_prepare_blend_surface(ctx);
@@ -265,6 +266,9 @@ static void setup_shader_program(struct shader *shader)
case VG_BLEND_OVERLAY_KHR:
shader_id |= VEGA_BLEND_OVERLAY_KHR_SHADER;
break;
+ case VG_BLEND_HARDLIGHT_KHR:
+ shader_id |= VEGA_BLEND_HARDLIGHT_KHR_SHADER;
+ break;
default:
/* handled by pipe_blend_state */
break;
diff --git a/src/gallium/state_trackers/vega/shaders_cache.c b/src/gallium/state_trackers/vega/shaders_cache.c
index 4f388dc7af..cd48999e9b 100644
--- a/src/gallium/state_trackers/vega/shaders_cache.c
+++ b/src/gallium/state_trackers/vega/shaders_cache.c
@@ -337,23 +337,27 @@ create_shader(struct pipe_context *pipe,
debug_assert(shaders_asm[12].id == VEGA_BLEND_OVERLAY_KHR_SHADER);
shaders[idx] = &shaders_asm[12];
++idx;
+ } else if ((id & VEGA_BLEND_HARDLIGHT_KHR_SHADER)) {
+ debug_assert(shaders_asm[13].id == VEGA_BLEND_HARDLIGHT_KHR_SHADER);
+ shaders[idx] = &shaders_asm[13];
+ ++idx;
}
/* fifth stage */
if ((id & VEGA_PREMULTIPLY_SHADER)) {
- debug_assert(shaders_asm[13].id == VEGA_PREMULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[13];
+ debug_assert(shaders_asm[14].id == VEGA_PREMULTIPLY_SHADER);
+ shaders[idx] = &shaders_asm[14];
++idx;
} else if ((id & VEGA_UNPREMULTIPLY_SHADER)) {
- debug_assert(shaders_asm[14].id == VEGA_UNPREMULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[14];
+ debug_assert(shaders_asm[15].id == VEGA_UNPREMULTIPLY_SHADER);
+ shaders[idx] = &shaders_asm[15];
++idx;
}
/* sixth stage */
if ((id & VEGA_BW_SHADER)) {
- debug_assert(shaders_asm[15].id == VEGA_BW_SHADER);
- shaders[idx] = &shaders_asm[15];
+ debug_assert(shaders_asm[16].id == VEGA_BW_SHADER);
+ shaders[idx] = &shaders_asm[16];
++idx;
}
diff --git a/src/gallium/state_trackers/vega/shaders_cache.h b/src/gallium/state_trackers/vega/shaders_cache.h
index 8e91fdd5e7..c0c76873e5 100644
--- a/src/gallium/state_trackers/vega/shaders_cache.h
+++ b/src/gallium/state_trackers/vega/shaders_cache.h
@@ -34,26 +34,27 @@ struct tgsi_token;
struct shaders_cache;
enum VegaShaderType {
- VEGA_SOLID_FILL_SHADER = 1 << 0,
- VEGA_LINEAR_GRADIENT_SHADER = 1 << 1,
- VEGA_RADIAL_GRADIENT_SHADER = 1 << 2,
- VEGA_PATTERN_SHADER = 1 << 3,
- VEGA_IMAGE_NORMAL_SHADER = 1 << 4,
- VEGA_IMAGE_MULTIPLY_SHADER = 1 << 5,
- VEGA_IMAGE_STENCIL_SHADER = 1 << 6,
+ VEGA_SOLID_FILL_SHADER = 1 << 0,
+ VEGA_LINEAR_GRADIENT_SHADER = 1 << 1,
+ VEGA_RADIAL_GRADIENT_SHADER = 1 << 2,
+ VEGA_PATTERN_SHADER = 1 << 3,
+ VEGA_IMAGE_NORMAL_SHADER = 1 << 4,
+ VEGA_IMAGE_MULTIPLY_SHADER = 1 << 5,
+ VEGA_IMAGE_STENCIL_SHADER = 1 << 6,
- VEGA_MASK_SHADER = 1 << 7,
+ VEGA_MASK_SHADER = 1 << 7,
- VEGA_BLEND_MULTIPLY_SHADER = 1 << 8,
- VEGA_BLEND_SCREEN_SHADER = 1 << 9,
- VEGA_BLEND_DARKEN_SHADER = 1 << 10,
- VEGA_BLEND_LIGHTEN_SHADER = 1 << 11,
- VEGA_BLEND_OVERLAY_KHR_SHADER = 1 << 12,
+ VEGA_BLEND_MULTIPLY_SHADER = 1 << 8,
+ VEGA_BLEND_SCREEN_SHADER = 1 << 9,
+ VEGA_BLEND_DARKEN_SHADER = 1 << 10,
+ VEGA_BLEND_LIGHTEN_SHADER = 1 << 11,
+ VEGA_BLEND_OVERLAY_KHR_SHADER = 1 << 12,
+ VEGA_BLEND_HARDLIGHT_KHR_SHADER = 1 << 13,
- VEGA_PREMULTIPLY_SHADER = 1 << 13,
- VEGA_UNPREMULTIPLY_SHADER = 1 << 14,
+ VEGA_PREMULTIPLY_SHADER = 1 << 14,
+ VEGA_UNPREMULTIPLY_SHADER = 1 << 15,
- VEGA_BW_SHADER = 1 << 15
+ VEGA_BW_SHADER = 1 << 16
};
struct vg_shader {
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index 390b2918fa..37baba9df9 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -340,6 +340,7 @@ void vg_validate_state(struct vg_context *ctx)
case VG_BLEND_DARKEN:
case VG_BLEND_LIGHTEN:
case VG_BLEND_OVERLAY_KHR:
+ case VG_BLEND_HARDLIGHT_KHR:
blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;