From 0ee73edeccd21034e03e9e43dd0d09fa6fbf7842 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sat, 4 Dec 2010 22:42:46 +0800 Subject: [PATCH] st/vega: Add blend shaders for all blend modes. --- src/gallium/state_trackers/vega/asm_fill.h | 135 ++++++++++++------ src/gallium/state_trackers/vega/shader.c | 60 +++++--- .../state_trackers/vega/shaders_cache.c | 6 + .../state_trackers/vega/shaders_cache.h | 16 ++- 4 files changed, 145 insertions(+), 72 deletions(-) diff --git a/src/gallium/state_trackers/vega/asm_fill.h b/src/gallium/state_trackers/vega/asm_fill.h index 5ff76975e22..77e6a14fe99 100644 --- a/src/gallium/state_trackers/vega/asm_fill.h +++ b/src/gallium/state_trackers/vega/asm_fill.h @@ -409,24 +409,79 @@ blend_generic(struct ureg_program *ureg, blend_unpremultiply(ureg, src, one, temp); } +#define BLEND_GENERIC(mode) \ + do { \ + ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]); \ + blend_generic(ureg, (mode), ureg_src(temp[0]), ureg_src(temp[1]), \ + ureg_src(temp[2]), \ + ureg_scalar(constant[3], TGSI_SWIZZLE_Y), temp + 3); \ + ureg_MOV(ureg, *out, ureg_src(temp[0])); \ + } while (0) + static INLINE void -blend_multiply( struct ureg_program *ureg, +blend_src( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + BLEND_GENERIC(VG_BLEND_SRC); +} + +static INLINE void +blend_src_over( struct ureg_program *ureg, struct ureg_dst *out, struct ureg_src *in, struct ureg_src *sampler, struct ureg_dst *temp, struct ureg_src *constant) { - ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]); + BLEND_GENERIC(VG_BLEND_SRC_OVER); +} - blend_generic(ureg, VG_BLEND_MULTIPLY, - ureg_src(temp[0]), - ureg_src(temp[1]), - ureg_src(temp[2]), - ureg_scalar(constant[3], TGSI_SWIZZLE_Y), - temp + 3); +static INLINE void +blend_dst_over( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + BLEND_GENERIC(VG_BLEND_DST_OVER); +} - ureg_MOV(ureg, *out, ureg_src(temp[0])); +static INLINE void +blend_src_in( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + BLEND_GENERIC(VG_BLEND_SRC_IN); +} + +static INLINE void +blend_dst_in( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + BLEND_GENERIC(VG_BLEND_DST_IN); +} + +static INLINE void +blend_multiply( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + BLEND_GENERIC(VG_BLEND_MULTIPLY); } static INLINE void @@ -437,16 +492,7 @@ blend_screen( struct ureg_program *ureg, struct ureg_dst *temp, struct ureg_src *constant) { - ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]); - - blend_generic(ureg, VG_BLEND_SCREEN, - ureg_src(temp[0]), - ureg_src(temp[1]), - ureg_src(temp[2]), - ureg_scalar(constant[3], TGSI_SWIZZLE_Y), - temp + 3); - - ureg_MOV(ureg, *out, ureg_src(temp[0])); + BLEND_GENERIC(VG_BLEND_SCREEN); } static INLINE void @@ -457,16 +503,7 @@ blend_darken( struct ureg_program *ureg, struct ureg_dst *temp, struct ureg_src *constant) { - ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]); - - blend_generic(ureg, VG_BLEND_DARKEN, - ureg_src(temp[0]), - ureg_src(temp[1]), - ureg_src(temp[2]), - ureg_scalar(constant[3], TGSI_SWIZZLE_Y), - temp + 3); - - ureg_MOV(ureg, *out, ureg_src(temp[0])); + BLEND_GENERIC(VG_BLEND_DARKEN); } static INLINE void @@ -477,16 +514,18 @@ blend_lighten( struct ureg_program *ureg, struct ureg_dst *temp, struct ureg_src *constant) { - ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]); - - blend_generic(ureg, VG_BLEND_LIGHTEN, - ureg_src(temp[0]), - ureg_src(temp[1]), - ureg_src(temp[2]), - ureg_scalar(constant[3], TGSI_SWIZZLE_Y), - temp + 3); + BLEND_GENERIC(VG_BLEND_LIGHTEN); +} - ureg_MOV(ureg, *out, ureg_src(temp[0])); +static INLINE void +blend_additive( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + BLEND_GENERIC(VG_BLEND_ADDITIVE); } static INLINE void @@ -618,14 +657,18 @@ static const struct shader_asm_info shaders_alpha_asm[] = { /* extra blend modes */ static const struct shader_asm_info shaders_blend_asm[] = { - {VEGA_BLEND_MULTIPLY_SHADER, blend_multiply, - VG_TRUE, 3, 1, 2, 1, 0, 5}, - {VEGA_BLEND_SCREEN_SHADER, blend_screen, - VG_TRUE, 3, 1, 2, 1, 0, 5}, - {VEGA_BLEND_DARKEN_SHADER, blend_darken, - VG_TRUE, 3, 1, 2, 1, 0, 5}, - {VEGA_BLEND_LIGHTEN_SHADER, blend_lighten, - VG_TRUE, 3, 1, 2, 1, 0, 5}, +#define BLEND_ASM_INFO(id, func) { (id), (func), VG_TRUE, 3, 1, 2, 1, 0, 5 } + BLEND_ASM_INFO(VEGA_BLEND_SRC_SHADER, blend_src), + BLEND_ASM_INFO(VEGA_BLEND_SRC_OVER_SHADER, blend_src_over), + BLEND_ASM_INFO(VEGA_BLEND_DST_OVER_SHADER, blend_dst_over), + BLEND_ASM_INFO(VEGA_BLEND_SRC_IN_SHADER, blend_src_in), + BLEND_ASM_INFO(VEGA_BLEND_DST_IN_SHADER, blend_dst_in), + BLEND_ASM_INFO(VEGA_BLEND_MULTIPLY_SHADER, blend_multiply), + BLEND_ASM_INFO(VEGA_BLEND_SCREEN_SHADER, blend_screen), + BLEND_ASM_INFO(VEGA_BLEND_DARKEN_SHADER, blend_darken), + BLEND_ASM_INFO(VEGA_BLEND_LIGHTEN_SHADER, blend_lighten), + BLEND_ASM_INFO(VEGA_BLEND_ADDITIVE_SHADER, blend_additive) +#undef BLEND_ASM_INFO }; static const struct shader_asm_info shaders_mask_asm[] = { diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c index 8577d21efe4..92d3f5549e9 100644 --- a/src/gallium/state_trackers/vega/shader.c +++ b/src/gallium/state_trackers/vega/shader.c @@ -128,16 +128,30 @@ static VGint setup_constant_buffer(struct shader *shader) return param_bytes; } +static VGboolean blend_use_shader(struct vg_context *ctx) +{ + VGboolean advanced_blending; + + switch (ctx->state.vg.blend_mode) { + case VG_BLEND_MULTIPLY: + case VG_BLEND_SCREEN: + case VG_BLEND_DARKEN: + case VG_BLEND_LIGHTEN: + advanced_blending = VG_TRUE; + break; + default: + advanced_blending = VG_FALSE; + break; + } + + return advanced_blending; +} + static VGint blend_bind_samplers(struct vg_context *ctx, struct pipe_sampler_state **samplers, struct pipe_sampler_view **sampler_views) { - VGBlendMode bmode = ctx->state.vg.blend_mode; - - if (bmode == VG_BLEND_MULTIPLY || - bmode == VG_BLEND_SCREEN || - bmode == VG_BLEND_DARKEN || - bmode == VG_BLEND_LIGHTEN) { + if (blend_use_shader(ctx)) { samplers[2] = &ctx->blend_sampler; sampler_views[2] = vg_prepare_blend_surface(ctx); @@ -209,7 +223,6 @@ 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 || @@ -256,26 +269,28 @@ static void setup_shader_program(struct shader *shader) if (shader->color_transform) shader_id |= VEGA_COLOR_TRANSFORM_SHADER; - switch(blend_mode) { - case VG_BLEND_MULTIPLY: - case VG_BLEND_SCREEN: - case VG_BLEND_DARKEN: - case VG_BLEND_LIGHTEN: - advanced_blend = VG_TRUE; - break; - default: - /* handled by pipe_blend_state */ - advanced_blend = VG_FALSE; - break; - } - - if (advanced_blend) { + if (blend_use_shader(ctx)) { 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_SRC: + shader_id |= VEGA_BLEND_SRC_SHADER; + break; + case VG_BLEND_SRC_OVER: + shader_id |= VEGA_BLEND_SRC_OVER_SHADER; + break; + case VG_BLEND_DST_OVER: + shader_id |= VEGA_BLEND_DST_OVER_SHADER; + break; + case VG_BLEND_SRC_IN: + shader_id |= VEGA_BLEND_SRC_IN_SHADER; + break; + case VG_BLEND_DST_IN: + shader_id |= VEGA_BLEND_DST_IN_SHADER; + break; case VG_BLEND_MULTIPLY: shader_id |= VEGA_BLEND_MULTIPLY_SHADER; break; @@ -288,6 +303,9 @@ static void setup_shader_program(struct shader *shader) case VG_BLEND_LIGHTEN: shader_id |= VEGA_BLEND_LIGHTEN_SHADER; break; + case VG_BLEND_ADDITIVE: + shader_id |= VEGA_BLEND_ADDITIVE_SHADER; + break; default: assert(0); break; diff --git a/src/gallium/state_trackers/vega/shaders_cache.c b/src/gallium/state_trackers/vega/shaders_cache.c index e9873eb18b2..023996ce2d8 100644 --- a/src/gallium/state_trackers/vega/shaders_cache.c +++ b/src/gallium/state_trackers/vega/shaders_cache.c @@ -318,10 +318,16 @@ create_shader(struct pipe_context *pipe, /* fifth stage */ sh = SHADERS_GET_BLEND_SHADER(id); switch (sh) { + case VEGA_BLEND_SRC_SHADER: + case VEGA_BLEND_SRC_OVER_SHADER: + case VEGA_BLEND_DST_OVER_SHADER: + case VEGA_BLEND_SRC_IN_SHADER: + case VEGA_BLEND_DST_IN_SHADER: case VEGA_BLEND_MULTIPLY_SHADER: case VEGA_BLEND_SCREEN_SHADER: case VEGA_BLEND_DARKEN_SHADER: case VEGA_BLEND_LIGHTEN_SHADER: + case VEGA_BLEND_ADDITIVE_SHADER: shaders[idx] = &shaders_blend_asm[(sh >> SHADERS_BLEND_SHIFT) - 1]; assert(shaders[idx]->id == sh); idx++; diff --git a/src/gallium/state_trackers/vega/shaders_cache.h b/src/gallium/state_trackers/vega/shaders_cache.h index 9265c547ed3..05014f25dcc 100644 --- a/src/gallium/state_trackers/vega/shaders_cache.h +++ b/src/gallium/state_trackers/vega/shaders_cache.h @@ -37,7 +37,7 @@ struct shaders_cache; #define _SHADERS_IMAGE_BITS 2 #define _SHADERS_COLOR_TRANSFORM_BITS 1 #define _SHADERS_ALPHA_BITS 2 -#define _SHADERS_BLEND_BITS 3 +#define _SHADERS_BLEND_BITS 4 #define _SHADERS_MASK_BITS 1 #define _SHADERS_PREMULTIPLY_BITS 2 #define _SHADERS_BW_BITS 1 @@ -79,10 +79,16 @@ enum VegaShaderType { VEGA_ALPHA_NORMAL_SHADER = 1 << SHADERS_ALPHA_SHIFT, VEGA_ALPHA_PER_CHANNEL_SHADER = 2 << SHADERS_ALPHA_SHIFT, - VEGA_BLEND_MULTIPLY_SHADER = 1 << SHADERS_BLEND_SHIFT, - VEGA_BLEND_SCREEN_SHADER = 2 << SHADERS_BLEND_SHIFT, - VEGA_BLEND_DARKEN_SHADER = 3 << SHADERS_BLEND_SHIFT, - VEGA_BLEND_LIGHTEN_SHADER = 4 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_SRC_SHADER = 1 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_SRC_OVER_SHADER = 2 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_DST_OVER_SHADER = 3 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_SRC_IN_SHADER = 4 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_DST_IN_SHADER = 5 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_MULTIPLY_SHADER = 6 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_SCREEN_SHADER = 7 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_DARKEN_SHADER = 8 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_LIGHTEN_SHADER = 9 << SHADERS_BLEND_SHIFT, + VEGA_BLEND_ADDITIVE_SHADER = 10<< SHADERS_BLEND_SHIFT, VEGA_MASK_SHADER = 1 << SHADERS_MASK_SHIFT, -- 2.30.2