st/vega: Add blend shaders for all blend modes.

This commit is contained in:
Chia-I Wu 2010-12-04 22:42:46 +08:00
parent 5d24411140
commit 0ee73edecc
4 changed files with 146 additions and 73 deletions

View file

@ -409,6 +409,70 @@ 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_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)
{
BLEND_GENERIC(VG_BLEND_SRC_OVER);
}
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);
}
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,
@ -417,16 +481,7 @@ blend_multiply( 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_MULTIPLY,
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_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(VG_BLEND_LIGHTEN);
}
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);
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[] = {

View file

@ -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;

View file

@ -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++;

View file

@ -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,