mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 09:28:07 +02:00
r300g: fix colormask with non-BGRA formats
NOTE: This is a candidate for the stable branches.
(cherry picked from commit 1e51d368eb)
This commit is contained in:
parent
86735d78e6
commit
e81717e9e7
4 changed files with 160 additions and 31 deletions
|
|
@ -41,6 +41,16 @@ struct r300_fragment_shader;
|
|||
struct r300_vertex_shader;
|
||||
struct r300_stencilref_context;
|
||||
|
||||
enum colormask_swizzle {
|
||||
COLORMASK_BGRA,
|
||||
COLORMASK_RGBA,
|
||||
COLORMASK_RRRR,
|
||||
COLORMASK_AAAA,
|
||||
COLORMASK_GRRG,
|
||||
COLORMASK_ARRA,
|
||||
COLORMASK_NUM_SWIZZLES
|
||||
};
|
||||
|
||||
struct r300_atom {
|
||||
/* Name, for debugging. */
|
||||
const char* name;
|
||||
|
|
@ -66,7 +76,7 @@ struct r300_aa_state {
|
|||
struct r300_blend_state {
|
||||
struct pipe_blend_state state;
|
||||
|
||||
uint32_t cb_clamp[8];
|
||||
uint32_t cb_clamp[COLORMASK_NUM_SWIZZLES][8];
|
||||
uint32_t cb_noclamp[8];
|
||||
uint32_t cb_no_readwrite[8];
|
||||
};
|
||||
|
|
@ -320,6 +330,8 @@ struct r300_surface {
|
|||
|
||||
/* Whether the CBZB clear is allowed on the surface. */
|
||||
boolean cbzb_allowed;
|
||||
|
||||
unsigned colormask_swizzle;
|
||||
};
|
||||
|
||||
struct r300_texture_desc {
|
||||
|
|
|
|||
|
|
@ -45,10 +45,12 @@ void r300_emit_blend_state(struct r300_context* r300,
|
|||
CS_LOCALS(r300);
|
||||
|
||||
if (fb->nr_cbufs) {
|
||||
if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT)
|
||||
if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) {
|
||||
WRITE_CS_TABLE(blend->cb_noclamp, size);
|
||||
else
|
||||
WRITE_CS_TABLE(blend->cb_clamp, size);
|
||||
} else {
|
||||
unsigned swz = r300_surface(fb->cbufs[0])->colormask_swizzle;
|
||||
WRITE_CS_TABLE(blend->cb_clamp[swz], size);
|
||||
}
|
||||
} else {
|
||||
WRITE_CS_TABLE(blend->cb_no_readwrite, size);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,15 +169,52 @@ static boolean blend_discard_if_src_alpha_color_1(unsigned srcRGB, unsigned srcA
|
|||
dstA == PIPE_BLENDFACTOR_ONE);
|
||||
}
|
||||
|
||||
/* The hardware colormask is clunky a must be swizzled depending on the format.
|
||||
* This was figured out by trial-and-error. */
|
||||
static unsigned bgra_cmask(unsigned mask)
|
||||
{
|
||||
/* Gallium uses RGBA color ordering while R300 expects BGRA. */
|
||||
|
||||
return ((mask & PIPE_MASK_R) << 2) |
|
||||
((mask & PIPE_MASK_B) >> 2) |
|
||||
(mask & (PIPE_MASK_G | PIPE_MASK_A));
|
||||
}
|
||||
|
||||
static unsigned rgba_cmask(unsigned mask)
|
||||
{
|
||||
return mask & PIPE_MASK_RGBA;
|
||||
}
|
||||
|
||||
static unsigned rrrr_cmask(unsigned mask)
|
||||
{
|
||||
return (mask & PIPE_MASK_R) |
|
||||
((mask & PIPE_MASK_R) << 1) |
|
||||
((mask & PIPE_MASK_R) << 2) |
|
||||
((mask & PIPE_MASK_R) << 3);
|
||||
}
|
||||
|
||||
static unsigned aaaa_cmask(unsigned mask)
|
||||
{
|
||||
return ((mask & PIPE_MASK_A) >> 3) |
|
||||
((mask & PIPE_MASK_A) >> 2) |
|
||||
((mask & PIPE_MASK_A) >> 1) |
|
||||
(mask & PIPE_MASK_A);
|
||||
}
|
||||
|
||||
static unsigned grrg_cmask(unsigned mask)
|
||||
{
|
||||
return ((mask & PIPE_MASK_R) << 1) |
|
||||
((mask & PIPE_MASK_R) << 2) |
|
||||
((mask & PIPE_MASK_G) >> 1) |
|
||||
((mask & PIPE_MASK_G) << 2);
|
||||
}
|
||||
|
||||
static unsigned arra_cmask(unsigned mask)
|
||||
{
|
||||
return ((mask & PIPE_MASK_R) << 1) |
|
||||
((mask & PIPE_MASK_R) << 2) |
|
||||
((mask & PIPE_MASK_A) >> 3) |
|
||||
(mask & PIPE_MASK_A);
|
||||
}
|
||||
|
||||
/* Create a new blend state based on the CSO blend state.
|
||||
*
|
||||
* This encompasses alpha blending, logic/raster ops, and blend dithering. */
|
||||
|
|
@ -190,9 +227,9 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
|
|||
uint32_t blend_control_noclamp = 0; /* R300_RB3D_CBLEND: 0x4e04 */
|
||||
uint32_t alpha_blend_control = 0; /* R300_RB3D_ABLEND: 0x4e08 */
|
||||
uint32_t alpha_blend_control_noclamp = 0; /* R300_RB3D_ABLEND: 0x4e08 */
|
||||
uint32_t color_channel_mask = 0; /* R300_RB3D_COLOR_CHANNEL_MASK: 0x4e0c */
|
||||
uint32_t rop = 0; /* R300_RB3D_ROPCNTL: 0x4e18 */
|
||||
uint32_t dither = 0; /* R300_RB3D_DITHER_CTL: 0x4e50 */
|
||||
int i;
|
||||
CB_LOCALS;
|
||||
|
||||
blend->state = *state;
|
||||
|
|
@ -331,20 +368,6 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
|
|||
(state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT;
|
||||
}
|
||||
|
||||
/* Color channel masks for all MRTs. */
|
||||
color_channel_mask = bgra_cmask(state->rt[0].colormask);
|
||||
if (r300screen->caps.is_r500 && state->independent_blend_enable) {
|
||||
if (state->rt[1].blend_enable) {
|
||||
color_channel_mask |= bgra_cmask(state->rt[1].colormask) << 4;
|
||||
}
|
||||
if (state->rt[2].blend_enable) {
|
||||
color_channel_mask |= bgra_cmask(state->rt[2].colormask) << 8;
|
||||
}
|
||||
if (state->rt[3].blend_enable) {
|
||||
color_channel_mask |= bgra_cmask(state->rt[3].colormask) << 12;
|
||||
}
|
||||
}
|
||||
|
||||
/* Neither fglrx nor classic r300 ever set this, regardless of dithering
|
||||
* state. Since it's an optional implementation detail, we can leave it
|
||||
* out and never dither.
|
||||
|
|
@ -358,14 +381,27 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
|
|||
*/
|
||||
|
||||
/* Build a command buffer. */
|
||||
BEGIN_CB(blend->cb_clamp, 8);
|
||||
OUT_CB_REG(R300_RB3D_ROPCNTL, rop);
|
||||
OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);
|
||||
OUT_CB(blend_control);
|
||||
OUT_CB(alpha_blend_control);
|
||||
OUT_CB(color_channel_mask);
|
||||
OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);
|
||||
END_CB;
|
||||
{
|
||||
unsigned (*func[COLORMASK_NUM_SWIZZLES])(unsigned) = {
|
||||
bgra_cmask,
|
||||
rgba_cmask,
|
||||
rrrr_cmask,
|
||||
aaaa_cmask,
|
||||
grrg_cmask,
|
||||
arra_cmask
|
||||
};
|
||||
|
||||
for (i = 0; i < COLORMASK_NUM_SWIZZLES; i++) {
|
||||
BEGIN_CB(blend->cb_clamp[i], 8);
|
||||
OUT_CB_REG(R300_RB3D_ROPCNTL, rop);
|
||||
OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);
|
||||
OUT_CB(blend_control);
|
||||
OUT_CB(alpha_blend_control);
|
||||
OUT_CB(func[i](state->rt[0].colormask));
|
||||
OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);
|
||||
END_CB;
|
||||
}
|
||||
}
|
||||
|
||||
/* Build a command buffer. */
|
||||
BEGIN_CB(blend->cb_noclamp, 8);
|
||||
|
|
@ -373,7 +409,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
|
|||
OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);
|
||||
OUT_CB(blend_control_noclamp);
|
||||
OUT_CB(alpha_blend_control_noclamp);
|
||||
OUT_CB(color_channel_mask);
|
||||
OUT_CB(rgba_cmask(state->rt[0].colormask));
|
||||
OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);
|
||||
END_CB;
|
||||
|
||||
|
|
|
|||
|
|
@ -704,10 +704,87 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t r300_translate_colormask_swizzle(enum pipe_format format)
|
||||
{
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_A8_UNORM:
|
||||
case PIPE_FORMAT_A8_SNORM:
|
||||
case PIPE_FORMAT_A16_UNORM:
|
||||
case PIPE_FORMAT_A16_SNORM:
|
||||
case PIPE_FORMAT_A16_FLOAT:
|
||||
case PIPE_FORMAT_A32_FLOAT:
|
||||
return COLORMASK_AAAA;
|
||||
|
||||
case PIPE_FORMAT_I8_UNORM:
|
||||
case PIPE_FORMAT_I8_SNORM:
|
||||
case PIPE_FORMAT_L8_UNORM:
|
||||
case PIPE_FORMAT_L8_SNORM:
|
||||
case PIPE_FORMAT_R8_UNORM:
|
||||
case PIPE_FORMAT_R8_SNORM:
|
||||
case PIPE_FORMAT_R32_FLOAT:
|
||||
case PIPE_FORMAT_L32_FLOAT:
|
||||
case PIPE_FORMAT_I32_FLOAT:
|
||||
return COLORMASK_RRRR;
|
||||
|
||||
case PIPE_FORMAT_L8A8_SNORM:
|
||||
case PIPE_FORMAT_L8A8_UNORM:
|
||||
case PIPE_FORMAT_L16A16_UNORM:
|
||||
case PIPE_FORMAT_L16A16_SNORM:
|
||||
case PIPE_FORMAT_L16A16_FLOAT:
|
||||
case PIPE_FORMAT_L32A32_FLOAT:
|
||||
return COLORMASK_ARRA;
|
||||
|
||||
case PIPE_FORMAT_R8G8_SNORM:
|
||||
case PIPE_FORMAT_R8G8_UNORM:
|
||||
case PIPE_FORMAT_R16G16_UNORM:
|
||||
case PIPE_FORMAT_R16G16_SNORM:
|
||||
case PIPE_FORMAT_R16G16_FLOAT:
|
||||
case PIPE_FORMAT_R32G32_FLOAT:
|
||||
return COLORMASK_GRRG;
|
||||
|
||||
case PIPE_FORMAT_B5G6R5_UNORM:
|
||||
case PIPE_FORMAT_B5G5R5A1_UNORM:
|
||||
case PIPE_FORMAT_B5G5R5X1_UNORM:
|
||||
case PIPE_FORMAT_B4G4R4A4_UNORM:
|
||||
case PIPE_FORMAT_B4G4R4X4_UNORM:
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
/*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
|
||||
case PIPE_FORMAT_B8G8R8X8_UNORM:
|
||||
/*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
|
||||
case PIPE_FORMAT_B10G10R10A2_UNORM:
|
||||
return COLORMASK_BGRA;
|
||||
|
||||
case PIPE_FORMAT_R8G8B8X8_UNORM:
|
||||
/*case PIPE_FORMAT_R8G8B8X8_SNORM:*/
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
||||
case PIPE_FORMAT_R8G8B8A8_SNORM:
|
||||
case PIPE_FORMAT_R10G10B10A2_UNORM:
|
||||
case PIPE_FORMAT_R10G10B10X2_SNORM:
|
||||
case PIPE_FORMAT_R16_UNORM:
|
||||
case PIPE_FORMAT_R16G16B16A16_UNORM:
|
||||
case PIPE_FORMAT_R16_SNORM:
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
case PIPE_FORMAT_R16_FLOAT:
|
||||
case PIPE_FORMAT_R16G16B16A16_FLOAT:
|
||||
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
||||
case PIPE_FORMAT_L16_UNORM:
|
||||
case PIPE_FORMAT_L16_SNORM:
|
||||
case PIPE_FORMAT_L16_FLOAT:
|
||||
case PIPE_FORMAT_I16_UNORM:
|
||||
case PIPE_FORMAT_I16_SNORM:
|
||||
case PIPE_FORMAT_I16_FLOAT:
|
||||
return COLORMASK_RGBA;
|
||||
|
||||
default:
|
||||
return ~0; /* Unsupported. */
|
||||
}
|
||||
}
|
||||
|
||||
boolean r300_is_colorbuffer_format_supported(enum pipe_format format)
|
||||
{
|
||||
return r300_translate_colorformat(format) != ~0 &&
|
||||
r300_translate_out_fmt(format) != ~0;
|
||||
r300_translate_out_fmt(format) != ~0 &&
|
||||
r300_translate_colormask_swizzle(format) != ~0;
|
||||
}
|
||||
|
||||
boolean r300_is_zs_format_supported(enum pipe_format format)
|
||||
|
|
@ -827,6 +904,8 @@ static void r300_texture_setup_fb_state(struct r300_surface *surf)
|
|||
R300_COLOR_TILE(tex->tex.macrotile[level]) |
|
||||
R300_COLOR_MICROTILE(tex->tex.microtile);
|
||||
surf->format = r300_translate_out_fmt(surf->base.format);
|
||||
surf->colormask_swizzle =
|
||||
r300_translate_colormask_swizzle(surf->base.format);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue