diff options
author | Igor Oliveira <igor.oliveira@openbossa.org> | 2010-02-10 13:30:29 -0400 |
---|---|---|
committer | Igor Trindade Oliveira <igor@Cygnus.(none)> | 2010-02-11 10:36:24 -0400 |
commit | 7b9da872aea516fe66df51cfd57c3bd94c75f492 (patch) | |
tree | aa59f56cebb5765fe8c35971f9de008a52142c13 | |
parent | e720cd6251956acd61af8d1ad08551f40264d9f6 (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.c | 2 | ||||
-rw-r--r-- | src/gallium/state_trackers/vega/asm_fill.h | 101 | ||||
-rw-r--r-- | src/gallium/state_trackers/vega/shader.c | 6 | ||||
-rw-r--r-- | src/gallium/state_trackers/vega/shaders_cache.c | 16 | ||||
-rw-r--r-- | src/gallium/state_trackers/vega/shaders_cache.h | 35 | ||||
-rw-r--r-- | src/gallium/state_trackers/vega/vg_context.c | 1 |
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; |