summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2010-12-04 22:42:46 +0800
committerChia-I Wu <[email protected]>2010-12-04 23:41:35 +0800
commit0ee73edeccd21034e03e9e43dd0d09fa6fbf7842 (patch)
tree41c7e3f17738a6d1539a5516dfe2a29ec30700e2
parent5d244111404fc36c55266f9703f81b27a5200a47 (diff)
st/vega: Add blend shaders for all blend modes.
-rw-r--r--src/gallium/state_trackers/vega/asm_fill.h135
-rw-r--r--src/gallium/state_trackers/vega/shader.c60
-rw-r--r--src/gallium/state_trackers/vega/shaders_cache.c6
-rw-r--r--src/gallium/state_trackers/vega/shaders_cache.h16
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,