mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-11 03:40:22 +01:00
st/vega: Add blend shaders for all blend modes.
This commit is contained in:
parent
5d24411140
commit
0ee73edecc
4 changed files with 146 additions and 73 deletions
|
|
@ -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[] = {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue