diff options
author | Igor Oliveira <igor.oliveira@openbossa.org> | 2010-02-10 15:03:12 -0400 |
---|---|---|
committer | Igor Trindade Oliveira <igor@Cygnus.(none)> | 2010-02-11 10:36:24 -0400 |
commit | 817247803d641b928cd24a1f97e155ffa4674763 (patch) | |
tree | a72da8c9f1c8a8e440c7ea3c658c19b46c382ce5 | |
parent | 7b9da872aea516fe66df51cfd57c3bd94c75f492 (diff) |
vega: add support to VG_BLEND_SOFTLIGHT_KHR advanced blend mode.
it is a alternative version of softlight blend and it is common used by rendering and svg authoring tools
-rw-r--r-- | src/gallium/state_trackers/vega/api_params.c | 2 | ||||
-rw-r--r-- | src/gallium/state_trackers/vega/asm_fill.h | 104 | ||||
-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 | 7 | ||||
-rw-r--r-- | src/gallium/state_trackers/vega/vg_context.c | 1 |
6 files changed, 125 insertions, 11 deletions
diff --git a/src/gallium/state_trackers/vega/api_params.c b/src/gallium/state_trackers/vega/api_params.c index 0ddc2514b9..acd450527d 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_SOFTLIGHT_SVG_KHR) + value > VG_BLEND_SOFTLIGHT_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 acc47733d1..3d7e0ed32b 100644 --- a/src/gallium/state_trackers/vega/asm_fill.h +++ b/src/gallium/state_trackers/vega/asm_fill.h @@ -556,6 +556,108 @@ blend_softlight_svg_khr( struct ureg_program *ureg, } static INLINE void +blend_softlight_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, imm4, imm5; + + imm = ureg_imm4f(ureg, 4, 4, 4, 4); + imm2 = ureg_imm4f(ureg, 3, 3, 3, 3); + imm3 = ureg_imm4f(ureg, 0.5, 0.5, 0.5, 0.5); + imm4 = ureg_imm4f(ureg, 16, 16, 16, 16); + imm5 = ureg_imm4f(ureg, 12, 12, 12, 12); + + 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_MUL(ureg, temp[2], imm4, ureg_src(temp[1])); + ureg_DIV(ureg, temp[2], ureg_src(temp[2]), ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); + ureg_SUB(ureg, temp[2], ureg_src(temp[2]), imm5); + ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[1])); + ureg_DIV(ureg, temp[2], ureg_src(temp[2]), ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); + ureg_ADD(ureg, temp[2], ureg_src(temp[2]), imm2); + 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[2], ureg_src(temp[2]), ureg_src(temp[1])); + ureg_MUL(ureg, temp[4], ureg_src(temp[1]), ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W)); + ureg_ADD(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[4])); + 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]), 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, @@ -668,6 +770,8 @@ static const struct shader_asm_info shaders_asm[] = { 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}, + {VEGA_BLEND_SOFTLIGHT_KHR_SHADER, blend_softlight_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 432c2a8e81..66af2cad06 100644 --- a/src/gallium/state_trackers/vega/shader.c +++ b/src/gallium/state_trackers/vega/shader.c @@ -129,7 +129,8 @@ static VGint blend_bind_samplers(struct vg_context *ctx, bmode == VG_BLEND_LIGHTEN || bmode == VG_BLEND_OVERLAY_KHR || bmode == VG_BLEND_HARDLIGHT_KHR || - bmode == VG_BLEND_SOFTLIGHT_SVG_KHR) { + bmode == VG_BLEND_SOFTLIGHT_SVG_KHR || + bmode == VG_BLEND_SOFTLIGHT_KHR) { struct st_framebuffer *stfb = ctx->draw_buffer; vg_prepare_blend_surface(ctx); @@ -273,6 +274,9 @@ static void setup_shader_program(struct shader *shader) case VG_BLEND_SOFTLIGHT_SVG_KHR: shader_id |= VEGA_BLEND_SOFTLIGHT_SVG_KHR_SHADER; break; + case VG_BLEND_SOFTLIGHT_KHR: + shader_id |= VEGA_BLEND_SOFTLIGHT_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 30deeca7dc..d1eaa5bad6 100644 --- a/src/gallium/state_trackers/vega/shaders_cache.c +++ b/src/gallium/state_trackers/vega/shaders_cache.c @@ -345,23 +345,27 @@ create_shader(struct pipe_context *pipe, debug_assert(shaders_asm[14].id == VEGA_BLEND_SOFTLIGHT_SVG_KHR_SHADER); shaders[idx] = &shaders_asm[14]; ++idx; + } else if ((id & VEGA_BLEND_SOFTLIGHT_KHR_SHADER)){ + debug_assert(shaders_asm[15].id == VEGA_BLEND_SOFTLIGHT_KHR_SHADER); + shaders[idx] = &shaders_asm[15]; + ++idx; } /* fifth stage */ if ((id & VEGA_PREMULTIPLY_SHADER)) { - debug_assert(shaders_asm[15].id == VEGA_PREMULTIPLY_SHADER); - shaders[idx] = &shaders_asm[15]; + debug_assert(shaders_asm[16].id == VEGA_PREMULTIPLY_SHADER); + shaders[idx] = &shaders_asm[16]; ++idx; } else if ((id & VEGA_UNPREMULTIPLY_SHADER)) { - debug_assert(shaders_asm[16].id == VEGA_UNPREMULTIPLY_SHADER); - shaders[idx] = &shaders_asm[16]; + debug_assert(shaders_asm[17].id == VEGA_UNPREMULTIPLY_SHADER); + shaders[idx] = &shaders_asm[17]; ++idx; } /* sixth stage */ if ((id & VEGA_BW_SHADER)) { - debug_assert(shaders_asm[17].id == VEGA_BW_SHADER); - shaders[idx] = &shaders_asm[17]; + debug_assert(shaders_asm[18].id == VEGA_BW_SHADER); + shaders[idx] = &shaders_asm[18]; ++idx; } diff --git a/src/gallium/state_trackers/vega/shaders_cache.h b/src/gallium/state_trackers/vega/shaders_cache.h index 3495a4c5b9..300e9d0e65 100644 --- a/src/gallium/state_trackers/vega/shaders_cache.h +++ b/src/gallium/state_trackers/vega/shaders_cache.h @@ -51,11 +51,12 @@ enum VegaShaderType { VEGA_BLEND_OVERLAY_KHR_SHADER = 1 << 12, VEGA_BLEND_HARDLIGHT_KHR_SHADER = 1 << 13, VEGA_BLEND_SOFTLIGHT_SVG_KHR_SHADER = 1 << 14, + VEGA_BLEND_SOFTLIGHT_KHR_SHADER = 1 << 15, - VEGA_PREMULTIPLY_SHADER = 1 << 15, - VEGA_UNPREMULTIPLY_SHADER = 1 << 16, + VEGA_PREMULTIPLY_SHADER = 1 << 16, + VEGA_UNPREMULTIPLY_SHADER = 1 << 17, - VEGA_BW_SHADER = 1 << 17 + VEGA_BW_SHADER = 1 << 18 }; struct vg_shader { diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index d6ed464785..779dbf5f3f 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -342,6 +342,7 @@ void vg_validate_state(struct vg_context *ctx) case VG_BLEND_OVERLAY_KHR: case VG_BLEND_HARDLIGHT_KHR: case VG_BLEND_SOFTLIGHT_SVG_KHR: + case VG_BLEND_SOFTLIGHT_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; |