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
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
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
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
/* 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[] = {
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);
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 ||
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;
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;
#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
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,