summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Oliveira <igor.oliveira@openbossa.org>2010-02-10 13:30:29 -0400
committerIgor Trindade Oliveira <igor@Cygnus.(none)>2010-02-11 10:36:24 -0400
commit7b9da872aea516fe66df51cfd57c3bd94c75f492 (patch)
treeaa59f56cebb5765fe8c35971f9de008a52142c13
parente720cd6251956acd61af8d1ad08551f40264d9f6 (diff)
vega: add support to VG_BLEND_SOFTLIGHT_SVG_KHR blend advanced mode.
It is used by SVG1.2 and it is defined as: Darkens or lightens the colors, dependent on the source color value. If the source color is lighter than 0.5, the destination is lightened. If the source color is darker than 0.5, the destination is darkened, as if it were burned in. The degree of darkening or lightening 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 a distinctly darker or lighter area, but does not result in pure black or white
-rw-r--r--src/gallium/state_trackers/vega/api_params.c2
-rw-r--r--src/gallium/state_trackers/vega/asm_fill.h101
-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.h35
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c1
6 files changed, 136 insertions, 25 deletions
diff --git a/src/gallium/state_trackers/vega/api_params.c b/src/gallium/state_trackers/vega/api_params.c
index 4230660bdf..0ddc2514b9 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_HARDLIGHT_KHR)
+ value > VG_BLEND_SOFTLIGHT_SVG_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 d9f23870a0..acc47733d1 100644
--- a/src/gallium/state_trackers/vega/asm_fill.h
+++ b/src/gallium/state_trackers/vega/asm_fill.h
@@ -457,6 +457,105 @@ blend_hardlight_khr( struct ureg_program *ureg,
}
static INLINE void
+blend_softlight_svg_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;
+ struct ureg_src imm, imm2, imm3;
+
+ imm = ureg_imm4f(ureg, 8, 8, 8, 8);
+ imm2 = ureg_imm4f(ureg, 3, 3, 3, 3);
+ imm3 = ureg_imm4f(ureg, 0.5, 0.5, 0.5, 0.5);
+
+ 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_DIV(ureg, temp[2], ureg_src(temp[1]),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_SUB(ureg, temp[2], ureg_scalar(constant[1], TGSI_SWIZZLE_Y),
+ ureg_src(temp[2]));
+ ureg_ADD(ureg, temp[4], ureg_src(temp[0]), ureg_src(temp[0]));
+ ureg_SUB(ureg, temp[4], ureg_src(temp[4]),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[4]));
+ ureg_SUB(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_src(temp[2]));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[1]), 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_MUL(ureg, temp[2], ureg_src(temp[1]), imm);
+ ureg_SLE(ureg, temp[2], ureg_src(temp[2]),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+
+ label = ureg_get_instruction_number(ureg);
+ label += 2;
+
+ ureg_IF(ureg, ureg_src(temp[2]), &label);
+ ureg_DIV(ureg, temp[2], ureg_src(temp[1]), ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_SUB(ureg, temp[2], ureg_scalar(constant[1], TGSI_SWIZZLE_Y), ureg_src(temp[2]));
+ ureg_ADD(ureg, temp[4], ureg_src(temp[0]), ureg_src(temp[0]));
+ ureg_SUB(ureg, temp[4], ureg_src(temp[4]), ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[4]));
+ ureg_MUL(ureg, temp[4], ureg_src(temp[1]), imm);
+ ureg_DIV(ureg, temp[4], ureg_src(temp[4]), ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_SUB(ureg, temp[4], imm2, ureg_src(temp[4]));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[4]));
+ ureg_SUB(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_src(temp[2]));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[1]), ureg_src(temp[2]));
+ ureg_ADD(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3]));
+
+ label = ureg_get_instruction_number(ureg);
+ label += 2;
+
+ ureg_ELSE(ureg, &label);
+ ureg_MUL(ureg, temp[2], ureg_src(temp[1]), ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
+ ureg_DIV(ureg, temp[4], ureg_src(temp[1]), ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_POW(ureg, temp[4], ureg_src(temp[4]), imm3);
+ ureg_MUL(ureg, temp[4], ureg_src(temp[4]), ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_SUB(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[1]));
+ ureg_ADD(ureg, temp[5], ureg_src(temp[0]), ureg_src(temp[0]));
+ ureg_SUB(ureg, temp[5], ureg_src(temp[5]), ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
+ ureg_MUL(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[5]));
+ ureg_ADD(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[4]));
+ ureg_ADD(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_XYZ), ureg_src(temp[2]), ureg_src(temp[3]));
+ ureg_ENDIF(ureg);
+
+ 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,
@@ -567,6 +666,8 @@ static const struct shader_asm_info shaders_asm[] = {
VG_TRUE, 1, 1, 2, 1, 0, 6},
{VEGA_BLEND_HARDLIGHT_KHR_SHADER, blend_hardlight_khr,
VG_TRUE, 1, 1, 2, 1, 0, 6},
+ {VEGA_BLEND_SOFTLIGHT_SVG_KHR_SHADER, blend_softlight_svg_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 7538e36e76..432c2a8e81 100644
--- a/src/gallium/state_trackers/vega/shader.c
+++ b/src/gallium/state_trackers/vega/shader.c
@@ -128,7 +128,8 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
bmode == VG_BLEND_DARKEN ||
bmode == VG_BLEND_LIGHTEN ||
bmode == VG_BLEND_OVERLAY_KHR ||
- bmode == VG_BLEND_HARDLIGHT_KHR) {
+ bmode == VG_BLEND_HARDLIGHT_KHR ||
+ bmode == VG_BLEND_SOFTLIGHT_SVG_KHR) {
struct st_framebuffer *stfb = ctx->draw_buffer;
vg_prepare_blend_surface(ctx);
@@ -269,6 +270,9 @@ static void setup_shader_program(struct shader *shader)
case VG_BLEND_HARDLIGHT_KHR:
shader_id |= VEGA_BLEND_HARDLIGHT_KHR_SHADER;
break;
+ case VG_BLEND_SOFTLIGHT_SVG_KHR:
+ shader_id |= VEGA_BLEND_SOFTLIGHT_SVG_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 cd48999e9b..30deeca7dc 100644
--- a/src/gallium/state_trackers/vega/shaders_cache.c
+++ b/src/gallium/state_trackers/vega/shaders_cache.c
@@ -341,23 +341,27 @@ create_shader(struct pipe_context *pipe,
debug_assert(shaders_asm[13].id == VEGA_BLEND_HARDLIGHT_KHR_SHADER);
shaders[idx] = &shaders_asm[13];
++idx;
+ } else if ((id & VEGA_BLEND_SOFTLIGHT_SVG_KHR_SHADER)){
+ debug_assert(shaders_asm[14].id == VEGA_BLEND_SOFTLIGHT_SVG_KHR_SHADER);
+ shaders[idx] = &shaders_asm[14];
+ ++idx;
}
/* fifth stage */
if ((id & VEGA_PREMULTIPLY_SHADER)) {
- debug_assert(shaders_asm[14].id == VEGA_PREMULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[14];
+ debug_assert(shaders_asm[15].id == VEGA_PREMULTIPLY_SHADER);
+ shaders[idx] = &shaders_asm[15];
++idx;
} else if ((id & VEGA_UNPREMULTIPLY_SHADER)) {
- debug_assert(shaders_asm[15].id == VEGA_UNPREMULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[15];
+ debug_assert(shaders_asm[16].id == VEGA_UNPREMULTIPLY_SHADER);
+ shaders[idx] = &shaders_asm[16];
++idx;
}
/* sixth stage */
if ((id & VEGA_BW_SHADER)) {
- debug_assert(shaders_asm[16].id == VEGA_BW_SHADER);
- shaders[idx] = &shaders_asm[16];
+ debug_assert(shaders_asm[17].id == VEGA_BW_SHADER);
+ shaders[idx] = &shaders_asm[17];
++idx;
}
diff --git a/src/gallium/state_trackers/vega/shaders_cache.h b/src/gallium/state_trackers/vega/shaders_cache.h
index c0c76873e5..3495a4c5b9 100644
--- a/src/gallium/state_trackers/vega/shaders_cache.h
+++ b/src/gallium/state_trackers/vega/shaders_cache.h
@@ -34,27 +34,28 @@ 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_HARDLIGHT_KHR_SHADER = 1 << 13,
+ 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_BLEND_SOFTLIGHT_SVG_KHR_SHADER = 1 << 14,
- VEGA_PREMULTIPLY_SHADER = 1 << 14,
- VEGA_UNPREMULTIPLY_SHADER = 1 << 15,
+ VEGA_PREMULTIPLY_SHADER = 1 << 15,
+ VEGA_UNPREMULTIPLY_SHADER = 1 << 16,
- VEGA_BW_SHADER = 1 << 16
+ VEGA_BW_SHADER = 1 << 17
};
struct vg_shader {
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index 37baba9df9..d6ed464785 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -341,6 +341,7 @@ void vg_validate_state(struct vg_context *ctx)
case VG_BLEND_LIGHTEN:
case VG_BLEND_OVERLAY_KHR:
case VG_BLEND_HARDLIGHT_KHR:
+ case VG_BLEND_SOFTLIGHT_SVG_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;