st/xa: Fix render to xa_format_a8, which is backed by a gallium L8 texture
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
This commit is contained in:
parent
7a10976adb
commit
568d99cc6c
|
@ -79,6 +79,25 @@ static const struct xa_composite_blend xa_blends[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The alpha value stored in a luminance texture is read by the
|
||||||
|
* hardware as color.
|
||||||
|
*/
|
||||||
|
static unsigned
|
||||||
|
xa_convert_blend_for_luminance(unsigned factor)
|
||||||
|
{
|
||||||
|
switch(factor) {
|
||||||
|
case PIPE_BLENDFACTOR_DST_ALPHA:
|
||||||
|
return PIPE_BLENDFACTOR_DST_COLOR;
|
||||||
|
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
|
||||||
|
return PIPE_BLENDFACTOR_INV_DST_COLOR;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
blend_for_op(struct xa_composite_blend *blend,
|
blend_for_op(struct xa_composite_blend *blend,
|
||||||
enum xa_composite_op op,
|
enum xa_composite_op op,
|
||||||
|
@ -104,15 +123,20 @@ blend_for_op(struct xa_composite_blend *blend,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dst_pic->srf)
|
||||||
|
return supported;
|
||||||
|
|
||||||
|
if (dst_pic->srf->tex->format == PIPE_FORMAT_L8_UNORM) {
|
||||||
|
blend->rgb_src = xa_convert_blend_for_luminance(blend->rgb_src);
|
||||||
|
blend->rgb_dst = xa_convert_blend_for_luminance(blend->rgb_dst);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's no dst alpha channel, adjust the blend op so that we'll treat
|
* If there's no dst alpha channel, adjust the blend op so that we'll treat
|
||||||
* it as always 1.
|
* it as always 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (dst_pic &&
|
if (xa_format_a(dst_pic->pict_format) == 0 && blend->alpha_dst) {
|
||||||
xa_format_a(dst_pic->pict_format) == 0 &&
|
|
||||||
blend->alpha_dst) {
|
|
||||||
if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA)
|
if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA)
|
||||||
blend->rgb_src = PIPE_BLENDFACTOR_ONE;
|
blend->rgb_src = PIPE_BLENDFACTOR_ONE;
|
||||||
else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA)
|
else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA)
|
||||||
|
@ -237,7 +261,6 @@ bind_composite_blend_state(struct xa_context *ctx,
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
picture_format_fixups(struct xa_picture *src_pic,
|
picture_format_fixups(struct xa_picture *src_pic,
|
||||||
struct xa_picture *dst_pic,
|
|
||||||
int mask)
|
int mask)
|
||||||
{
|
{
|
||||||
boolean set_alpha = FALSE;
|
boolean set_alpha = FALSE;
|
||||||
|
@ -253,22 +276,17 @@ picture_format_fixups(struct xa_picture *src_pic,
|
||||||
src_hw_format = xa_surface_format(src);
|
src_hw_format = xa_surface_format(src);
|
||||||
src_pic_format = src_pic->pict_format;
|
src_pic_format = src_pic->pict_format;
|
||||||
|
|
||||||
if (!src || src_hw_format == src_pic_format) {
|
set_alpha = (xa_format_type_is_color(src_pic_format) &&
|
||||||
if (src_pic_format == xa_format_a8) {
|
xa_format_a(src_pic_format) == 0);
|
||||||
if (mask)
|
|
||||||
return FS_MASK_LUMINANCE;
|
|
||||||
else if (dst_pic->pict_format != xa_format_a8) {
|
|
||||||
|
|
||||||
/*
|
if (set_alpha)
|
||||||
* if both dst and src are luminance then
|
ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
|
||||||
* we don't want to swizzle the alpha (X) of the
|
|
||||||
* source into W component of the dst because
|
if (src_hw_format == src_pic_format) {
|
||||||
* it will break our destination
|
if (src->tex->format == PIPE_FORMAT_L8_UNORM)
|
||||||
*/
|
return ((mask) ? FS_MASK_LUMINANCE : FS_SRC_LUMINANCE);
|
||||||
return FS_SRC_LUMINANCE;
|
|
||||||
}
|
return ret;
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
src_hw_type = xa_format_type(src_hw_format);
|
src_hw_type = xa_format_type(src_hw_format);
|
||||||
|
@ -280,13 +298,8 @@ picture_format_fixups(struct xa_picture *src_pic,
|
||||||
src_pic_type == xa_type_argb)));
|
src_pic_type == xa_type_argb)));
|
||||||
|
|
||||||
if (!swizzle && (src_hw_type != src_pic_type))
|
if (!swizzle && (src_hw_type != src_pic_type))
|
||||||
return 0;
|
return ret;
|
||||||
|
|
||||||
set_alpha = (xa_format_type_is_color(src_pic_format) &&
|
|
||||||
xa_format_a(src_pic_type) == 0);
|
|
||||||
|
|
||||||
if (set_alpha)
|
|
||||||
ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
|
|
||||||
if (swizzle)
|
if (swizzle)
|
||||||
ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
|
ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
|
||||||
|
|
||||||
|
@ -300,7 +313,6 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
|
||||||
struct xa_shader shader;
|
struct xa_shader shader;
|
||||||
struct xa_picture *src_pic = comp->src;
|
struct xa_picture *src_pic = comp->src;
|
||||||
struct xa_picture *mask_pic = comp->mask;
|
struct xa_picture *mask_pic = comp->mask;
|
||||||
struct xa_picture *dst_pic = comp->dst;
|
|
||||||
|
|
||||||
ctx->has_solid_color = FALSE;
|
ctx->has_solid_color = FALSE;
|
||||||
|
|
||||||
|
@ -321,7 +333,7 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
|
||||||
vs_traits |= VS_COMPOSITE;
|
vs_traits |= VS_COMPOSITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_traits |= picture_format_fixups(src_pic, dst_pic, 0);
|
fs_traits |= picture_format_fixups(src_pic, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask_pic) {
|
if (mask_pic) {
|
||||||
|
@ -340,9 +352,12 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
|
||||||
fs_traits |= FS_CA_FULL;
|
fs_traits |= FS_CA_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_traits |= picture_format_fixups(mask_pic, dst_pic, 1);
|
fs_traits |= picture_format_fixups(mask_pic, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->dst->srf->format == PIPE_FORMAT_L8_UNORM)
|
||||||
|
fs_traits |= FS_DST_LUMINANCE;
|
||||||
|
|
||||||
shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
|
shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
|
||||||
cso_set_vertex_shader_handle(ctx->cso, shader.vs);
|
cso_set_vertex_shader_handle(ctx->cso, shader.vs);
|
||||||
cso_set_fragment_shader_handle(ctx->cso, shader.fs);
|
cso_set_fragment_shader_handle(ctx->cso, shader.fs);
|
||||||
|
@ -433,6 +448,7 @@ xa_composite_prepare(struct xa_context *ctx,
|
||||||
if (ret != XA_ERR_NONE)
|
if (ret != XA_ERR_NONE)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ctx->dst = dst_srf;
|
||||||
renderer_bind_destination(ctx, dst_srf->srf,
|
renderer_bind_destination(ctx, dst_srf->srf,
|
||||||
dst_srf->srf->width,
|
dst_srf->srf->width,
|
||||||
dst_srf->srf->height);
|
dst_srf->srf->height);
|
||||||
|
|
|
@ -278,13 +278,16 @@ xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst,
|
||||||
int width, height;
|
int width, height;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
xa_pixel_to_float4(fg, ctx->solid_color);
|
|
||||||
ctx->has_solid_color = 1;
|
|
||||||
|
|
||||||
ret = xa_surface_psurf_create(ctx, dst);
|
ret = xa_surface_psurf_create(ctx, dst);
|
||||||
if (ret != XA_ERR_NONE)
|
if (ret != XA_ERR_NONE)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (dst->srf->format == PIPE_FORMAT_L8_UNORM)
|
||||||
|
xa_pixel_to_float4_a8(fg, ctx->solid_color);
|
||||||
|
else
|
||||||
|
xa_pixel_to_float4(fg, ctx->solid_color);
|
||||||
|
ctx->has_solid_color = 1;
|
||||||
|
|
||||||
ctx->dst = dst;
|
ctx->dst = dst;
|
||||||
width = dst->srf->width;
|
width = dst->srf->width;
|
||||||
height = dst->srf->height;
|
height = dst->srf->height;
|
||||||
|
|
|
@ -135,6 +135,7 @@ enum xa_fs_traits {
|
||||||
FS_MASK_SET_ALPHA = 1 << 13,
|
FS_MASK_SET_ALPHA = 1 << 13,
|
||||||
FS_SRC_LUMINANCE = 1 << 14,
|
FS_SRC_LUMINANCE = 1 << 14,
|
||||||
FS_MASK_LUMINANCE = 1 << 15,
|
FS_MASK_LUMINANCE = 1 << 15,
|
||||||
|
FS_DST_LUMINANCE = 1 << 16,
|
||||||
|
|
||||||
FS_FILL = (FS_SOLID_FILL | FS_LINGRAD_FILL | FS_RADGRAD_FILL),
|
FS_FILL = (FS_SOLID_FILL | FS_LINGRAD_FILL | FS_RADGRAD_FILL),
|
||||||
FS_COMPONENT_ALPHA = (FS_CA_FULL | FS_CA_SRCALPHA)
|
FS_COMPONENT_ALPHA = (FS_CA_FULL | FS_CA_SRCALPHA)
|
||||||
|
@ -172,6 +173,17 @@ xa_pixel_to_float4(uint32_t pixel, float *color)
|
||||||
color[3] = ((float)a) / 255.;
|
color[3] = ((float)a) / 255.;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static INLINE void
|
||||||
|
xa_pixel_to_float4_a8(uint32_t pixel, float *color)
|
||||||
|
{
|
||||||
|
uint32_t a;
|
||||||
|
|
||||||
|
a = (pixel >> 24) & 0xff;
|
||||||
|
color[0] = ((float)a) / 255.;
|
||||||
|
color[1] = ((float)a) / 255.;
|
||||||
|
color[2] = ((float)a) / 255.;
|
||||||
|
color[3] = ((float)a) / 255.;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xa_tgsi.c
|
* xa_tgsi.c
|
||||||
|
|
|
@ -418,6 +418,7 @@ renderer_copy_prepare(struct xa_context *r,
|
||||||
struct pipe_context *pipe = r->pipe;
|
struct pipe_context *pipe = r->pipe;
|
||||||
struct pipe_screen *screen = pipe->screen;
|
struct pipe_screen *screen = pipe->screen;
|
||||||
struct xa_shader shader;
|
struct xa_shader shader;
|
||||||
|
uint32_t fs_traits = FS_COMPOSITE;
|
||||||
|
|
||||||
assert(screen->is_format_supported(screen, dst_surface->format,
|
assert(screen->is_format_supported(screen, dst_surface->format,
|
||||||
PIPE_TEXTURE_2D, 0,
|
PIPE_TEXTURE_2D, 0,
|
||||||
|
@ -469,7 +470,12 @@ renderer_copy_prepare(struct xa_context *r,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* shaders */
|
/* shaders */
|
||||||
shader = xa_shaders_get(r->shaders, VS_COMPOSITE, FS_COMPOSITE);
|
if (src_texture->format == PIPE_FORMAT_L8_UNORM)
|
||||||
|
fs_traits |= FS_SRC_LUMINANCE;
|
||||||
|
if (dst_surface->format == PIPE_FORMAT_L8_UNORM)
|
||||||
|
fs_traits |= FS_DST_LUMINANCE;
|
||||||
|
|
||||||
|
shader = xa_shaders_get(r->shaders, VS_COMPOSITE, fs_traits);
|
||||||
cso_set_vertex_shader_handle(r->cso, shader.vs);
|
cso_set_vertex_shader_handle(r->cso, shader.vs);
|
||||||
cso_set_fragment_shader_handle(r->cso, shader.fs);
|
cso_set_fragment_shader_handle(r->cso, shader.fs);
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ print_fs_traits(int fs_traits)
|
||||||
"FS_MASK_SET_ALPHA", /* = 1 << 13, */
|
"FS_MASK_SET_ALPHA", /* = 1 << 13, */
|
||||||
"FS_SRC_LUMINANCE", /* = 1 << 14, */
|
"FS_SRC_LUMINANCE", /* = 1 << 14, */
|
||||||
"FS_MASK_LUMINANCE", /* = 1 << 15, */
|
"FS_MASK_LUMINANCE", /* = 1 << 15, */
|
||||||
|
"FS_DST_LUMINANCE", /* = 1 << 15, */
|
||||||
};
|
};
|
||||||
int i, k;
|
int i, k;
|
||||||
|
|
||||||
|
@ -454,6 +455,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
|
||||||
unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0;
|
unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0;
|
||||||
unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0;
|
unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0;
|
||||||
unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0;
|
unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0;
|
||||||
|
unsigned dst_luminance = (fs_traits & FS_DST_LUMINANCE) != 0;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
print_fs_traits(fs_traits);
|
print_fs_traits(fs_traits);
|
||||||
|
@ -508,7 +510,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (is_composite) {
|
if (is_composite) {
|
||||||
if (has_mask || src_luminance)
|
if (has_mask || src_luminance || dst_luminance)
|
||||||
src = ureg_DECL_temporary(ureg);
|
src = ureg_DECL_temporary(ureg);
|
||||||
else
|
else
|
||||||
src = out;
|
src = out;
|
||||||
|
@ -516,14 +518,14 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
|
||||||
src_repeat_none, src_swizzle, src_set_alpha);
|
src_repeat_none, src_swizzle, src_set_alpha);
|
||||||
} else if (is_fill) {
|
} else if (is_fill) {
|
||||||
if (is_solid) {
|
if (is_solid) {
|
||||||
if (has_mask || src_luminance)
|
if (has_mask || src_luminance || dst_luminance)
|
||||||
src = ureg_dst(src_input);
|
src = ureg_dst(src_input);
|
||||||
else
|
else
|
||||||
ureg_MOV(ureg, out, src_input);
|
ureg_MOV(ureg, out, src_input);
|
||||||
} else if (is_lingrad || is_radgrad) {
|
} else if (is_lingrad || is_radgrad) {
|
||||||
struct ureg_src coords, const0124, matrow0, matrow1, matrow2;
|
struct ureg_src coords, const0124, matrow0, matrow1, matrow2;
|
||||||
|
|
||||||
if (has_mask || src_luminance)
|
if (has_mask || src_luminance || dst_luminance)
|
||||||
src = ureg_DECL_temporary(ureg);
|
src = ureg_DECL_temporary(ureg);
|
||||||
else
|
else
|
||||||
src = out;
|
src = out;
|
||||||
|
@ -550,7 +552,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
|
||||||
ureg_MOV(ureg, src, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X));
|
ureg_MOV(ureg, src, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X));
|
||||||
ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ),
|
ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ),
|
||||||
ureg_scalar(imm0, TGSI_SWIZZLE_X));
|
ureg_scalar(imm0, TGSI_SWIZZLE_X));
|
||||||
if (!has_mask)
|
if (!has_mask && !dst_luminance)
|
||||||
ureg_MOV(ureg, out, ureg_src(src));
|
ureg_MOV(ureg, out, ureg_src(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,11 +561,21 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
|
||||||
xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
|
xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
|
||||||
mask_repeat_none, mask_swizzle, mask_set_alpha);
|
mask_repeat_none, mask_swizzle, mask_set_alpha);
|
||||||
/* src IN mask */
|
/* src IN mask */
|
||||||
src_in_mask(ureg, out, ureg_src(src), ureg_src(mask),
|
|
||||||
|
src_in_mask(ureg, (dst_luminance) ? src : out, ureg_src(src),
|
||||||
|
ureg_src(mask),
|
||||||
comp_alpha_mask, mask_luminance);
|
comp_alpha_mask, mask_luminance);
|
||||||
|
|
||||||
ureg_release_temporary(ureg, mask);
|
ureg_release_temporary(ureg, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dst_luminance) {
|
||||||
|
/*
|
||||||
|
* Make sure the alpha channel goes into the output L8 surface.
|
||||||
|
*/
|
||||||
|
ureg_MOV(ureg, out, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_W));
|
||||||
|
}
|
||||||
|
|
||||||
ureg_END(ureg);
|
ureg_END(ureg);
|
||||||
|
|
||||||
return ureg_create_shader_and_destroy(ureg, pipe);
|
return ureg_create_shader_and_destroy(ureg, pipe);
|
||||||
|
|
Loading…
Reference in New Issue