r300g: fix blending and alpha-test with RGBX16F and enable MSAA for it
This commit is contained in:
@@ -187,7 +187,8 @@ static void r300_set_clear_color(struct r300_context *r300,
|
|||||||
memset(&uc, 0, sizeof(uc));
|
memset(&uc, 0, sizeof(uc));
|
||||||
util_pack_color(color->f, fb->cbufs[0]->format, &uc);
|
util_pack_color(color->f, fb->cbufs[0]->format, &uc);
|
||||||
|
|
||||||
if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) {
|
if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
|
||||||
|
fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16X16_FLOAT) {
|
||||||
/* (0,1,2,3) maps to (B,G,R,A) */
|
/* (0,1,2,3) maps to (B,G,R,A) */
|
||||||
r300->color_clear_value_gb = uc.h[0] | ((uint32_t)uc.h[1] << 16);
|
r300->color_clear_value_gb = uc.h[0] | ((uint32_t)uc.h[1] << 16);
|
||||||
r300->color_clear_value_ar = uc.h[2] | ((uint32_t)uc.h[3] << 16);
|
r300->color_clear_value_ar = uc.h[2] | ((uint32_t)uc.h[3] << 16);
|
||||||
|
@@ -82,6 +82,7 @@ struct r300_blend_state {
|
|||||||
|
|
||||||
uint32_t cb_clamp[COLORMASK_NUM_SWIZZLES][8];
|
uint32_t cb_clamp[COLORMASK_NUM_SWIZZLES][8];
|
||||||
uint32_t cb_noclamp[8];
|
uint32_t cb_noclamp[8];
|
||||||
|
uint32_t cb_noclamp_noalpha[8];
|
||||||
uint32_t cb_no_readwrite[8];
|
uint32_t cb_no_readwrite[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -47,6 +47,8 @@ void r300_emit_blend_state(struct r300_context* r300,
|
|||||||
if (fb->nr_cbufs) {
|
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);
|
WRITE_CS_TABLE(blend->cb_noclamp, size);
|
||||||
|
} else if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16X16_FLOAT) {
|
||||||
|
WRITE_CS_TABLE(blend->cb_noclamp_noalpha, size);
|
||||||
} else {
|
} else {
|
||||||
unsigned swz = r300_surface(fb->cbufs[0])->colormask_swizzle;
|
unsigned swz = r300_surface(fb->cbufs[0])->colormask_swizzle;
|
||||||
WRITE_CS_TABLE(blend->cb_clamp[swz], size);
|
WRITE_CS_TABLE(blend->cb_clamp[swz], size);
|
||||||
@@ -86,7 +88,9 @@ void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state)
|
|||||||
/* Choose the alpha ref value between 8-bit (FG_ALPHA_FUNC.AM_VAL) and
|
/* Choose the alpha ref value between 8-bit (FG_ALPHA_FUNC.AM_VAL) and
|
||||||
* 16-bit (FG_ALPHA_VALUE). */
|
* 16-bit (FG_ALPHA_VALUE). */
|
||||||
if (is_r500 && (alpha_func & R300_FG_ALPHA_FUNC_ENABLE)) {
|
if (is_r500 && (alpha_func & R300_FG_ALPHA_FUNC_ENABLE)) {
|
||||||
if (fb->nr_cbufs && fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) {
|
if (fb->nr_cbufs &&
|
||||||
|
(fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
|
||||||
|
fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16X16_FLOAT)) {
|
||||||
alpha_func |= R500_FG_ALPHA_FUNC_FP16_ENABLE;
|
alpha_func |= R500_FG_ALPHA_FUNC_FP16_ENABLE;
|
||||||
} else {
|
} else {
|
||||||
alpha_func |= R500_FG_ALPHA_FUNC_8BIT;
|
alpha_func |= R500_FG_ALPHA_FUNC_8BIT;
|
||||||
|
@@ -414,7 +414,8 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
|
|||||||
boolean is_half_float = format == PIPE_FORMAT_R16_FLOAT ||
|
boolean is_half_float = format == PIPE_FORMAT_R16_FLOAT ||
|
||||||
format == PIPE_FORMAT_R16G16_FLOAT ||
|
format == PIPE_FORMAT_R16G16_FLOAT ||
|
||||||
format == PIPE_FORMAT_R16G16B16_FLOAT ||
|
format == PIPE_FORMAT_R16G16B16_FLOAT ||
|
||||||
format == PIPE_FORMAT_R16G16B16A16_FLOAT;
|
format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
|
||||||
|
format == PIPE_FORMAT_R16G16B16X16_FLOAT;
|
||||||
const struct util_format_description *desc;
|
const struct util_format_description *desc;
|
||||||
|
|
||||||
if (!util_format_is_supported(format, usage))
|
if (!util_format_is_supported(format, usage))
|
||||||
@@ -451,7 +452,8 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
|
|||||||
if (!util_format_is_depth_or_stencil(format) &&
|
if (!util_format_is_depth_or_stencil(format) &&
|
||||||
!util_format_is_rgba8_variant(desc) &&
|
!util_format_is_rgba8_variant(desc) &&
|
||||||
!util_format_is_rgba1010102_variant(desc) &&
|
!util_format_is_rgba1010102_variant(desc) &&
|
||||||
format != PIPE_FORMAT_R16G16B16A16_FLOAT) {
|
format != PIPE_FORMAT_R16G16B16A16_FLOAT &&
|
||||||
|
format != PIPE_FORMAT_R16G16B16X16_FLOAT) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -344,9 +344,11 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
|
|||||||
uint32_t blend_control = 0; /* R300_RB3D_CBLEND: 0x4e04 */
|
uint32_t blend_control = 0; /* R300_RB3D_CBLEND: 0x4e04 */
|
||||||
uint32_t blend_control_noclamp = 0; /* R300_RB3D_CBLEND: 0x4e04 */
|
uint32_t blend_control_noclamp = 0; /* R300_RB3D_CBLEND: 0x4e04 */
|
||||||
uint32_t blend_control_noalpha = 0; /* R300_RB3D_CBLEND: 0x4e04 */
|
uint32_t blend_control_noalpha = 0; /* R300_RB3D_CBLEND: 0x4e04 */
|
||||||
|
uint32_t blend_control_noalpha_noclamp = 0; /* R300_RB3D_CBLEND: 0x4e04 */
|
||||||
uint32_t alpha_blend_control = 0; /* R300_RB3D_ABLEND: 0x4e08 */
|
uint32_t alpha_blend_control = 0; /* R300_RB3D_ABLEND: 0x4e08 */
|
||||||
uint32_t alpha_blend_control_noclamp = 0; /* R300_RB3D_ABLEND: 0x4e08 */
|
uint32_t alpha_blend_control_noclamp = 0; /* R300_RB3D_ABLEND: 0x4e08 */
|
||||||
uint32_t alpha_blend_control_noalpha = 0; /* R300_RB3D_ABLEND: 0x4e08 */
|
uint32_t alpha_blend_control_noalpha = 0; /* R300_RB3D_ABLEND: 0x4e08 */
|
||||||
|
uint32_t alpha_blend_control_noalpha_noclamp = 0; /* R300_RB3D_ABLEND: 0x4e08 */
|
||||||
uint32_t rop = 0; /* R300_RB3D_ROPCNTL: 0x4e18 */
|
uint32_t rop = 0; /* R300_RB3D_ROPCNTL: 0x4e18 */
|
||||||
uint32_t dither = 0; /* R300_RB3D_DITHER_CTL: 0x4e50 */
|
uint32_t dither = 0; /* R300_RB3D_DITHER_CTL: 0x4e50 */
|
||||||
int i;
|
int i;
|
||||||
@@ -386,7 +388,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
|
|||||||
|
|
||||||
/* Get blending register values. */
|
/* Get blending register values. */
|
||||||
if (state->rt[0].blend_enable) {
|
if (state->rt[0].blend_enable) {
|
||||||
unsigned blend_eq;
|
unsigned blend_eq, blend_eq_noclamp;
|
||||||
|
|
||||||
/* despite the name, ALPHA_BLEND_ENABLE has nothing to do with alpha,
|
/* despite the name, ALPHA_BLEND_ENABLE has nothing to do with alpha,
|
||||||
* this is just the crappy D3D naming */
|
* this is just the crappy D3D naming */
|
||||||
@@ -395,15 +397,18 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
|
|||||||
( r300_translate_blend_factor(srcRGB) << R300_SRC_BLEND_SHIFT) |
|
( r300_translate_blend_factor(srcRGB) << R300_SRC_BLEND_SHIFT) |
|
||||||
( r300_translate_blend_factor(dstRGB) << R300_DST_BLEND_SHIFT);
|
( r300_translate_blend_factor(dstRGB) << R300_DST_BLEND_SHIFT);
|
||||||
|
|
||||||
blend_control_noalpha =
|
blend_control_noalpha = blend_control_noalpha_noclamp =
|
||||||
R300_ALPHA_BLEND_ENABLE |
|
R300_ALPHA_BLEND_ENABLE |
|
||||||
( r300_translate_blend_factor(srcRGBX) << R300_SRC_BLEND_SHIFT) |
|
( r300_translate_blend_factor(srcRGBX) << R300_SRC_BLEND_SHIFT) |
|
||||||
( r300_translate_blend_factor(dstRGBX) << R300_DST_BLEND_SHIFT);
|
( r300_translate_blend_factor(dstRGBX) << R300_DST_BLEND_SHIFT);
|
||||||
|
|
||||||
blend_eq = r300_translate_blend_function(eqRGB, TRUE);
|
blend_eq = r300_translate_blend_function(eqRGB, TRUE);
|
||||||
|
blend_eq_noclamp = r300_translate_blend_function(eqRGB, FALSE);
|
||||||
|
|
||||||
blend_control |= blend_eq;
|
blend_control |= blend_eq;
|
||||||
blend_control_noalpha |= blend_eq;
|
blend_control_noalpha |= blend_eq;
|
||||||
blend_control_noclamp |= r300_translate_blend_function(eqRGB, FALSE);
|
blend_control_noclamp |= blend_eq_noclamp;
|
||||||
|
blend_control_noalpha_noclamp |= blend_eq_noclamp;
|
||||||
|
|
||||||
/* Optimization: some operations do not require the destination color. */
|
/* Optimization: some operations do not require the destination color. */
|
||||||
blend_control |= blend_read_enable(eqRGB, eqA, dstRGB, dstA,
|
blend_control |= blend_read_enable(eqRGB, eqA, dstRGB, dstA,
|
||||||
@@ -412,6 +417,8 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
|
|||||||
srcRGB, srcA, FALSE);
|
srcRGB, srcA, FALSE);
|
||||||
blend_control_noalpha |= blend_read_enable(eqRGB, eqA, dstRGBX, dstA,
|
blend_control_noalpha |= blend_read_enable(eqRGB, eqA, dstRGBX, dstA,
|
||||||
srcRGBX, srcA, r300screen->caps.is_r500);
|
srcRGBX, srcA, r300screen->caps.is_r500);
|
||||||
|
blend_control_noalpha_noclamp |= blend_read_enable(eqRGB, eqA, dstRGBX, dstA,
|
||||||
|
srcRGBX, srcA, FALSE);
|
||||||
|
|
||||||
/* Optimization: discard pixels which don't change the colorbuffer.
|
/* Optimization: discard pixels which don't change the colorbuffer.
|
||||||
* It cannot be used with FP16 AA. */
|
* It cannot be used with FP16 AA. */
|
||||||
@@ -433,11 +440,13 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
|
|||||||
}
|
}
|
||||||
if (srcA != srcRGBX || dstA != dstRGBX || eqA != eqRGB) {
|
if (srcA != srcRGBX || dstA != dstRGBX || eqA != eqRGB) {
|
||||||
blend_control_noalpha |= R300_SEPARATE_ALPHA_ENABLE;
|
blend_control_noalpha |= R300_SEPARATE_ALPHA_ENABLE;
|
||||||
|
blend_control_noalpha_noclamp |= R300_SEPARATE_ALPHA_ENABLE;
|
||||||
|
|
||||||
alpha_blend_control_noalpha =
|
alpha_blend_control_noalpha = alpha_blend_control_noalpha_noclamp =
|
||||||
(r300_translate_blend_factor(srcA) << R300_SRC_BLEND_SHIFT) |
|
(r300_translate_blend_factor(srcA) << R300_SRC_BLEND_SHIFT) |
|
||||||
(r300_translate_blend_factor(dstA) << R300_DST_BLEND_SHIFT) |
|
(r300_translate_blend_factor(dstA) << R300_DST_BLEND_SHIFT);
|
||||||
r300_translate_blend_function(eqA, TRUE);
|
alpha_blend_control_noalpha |= r300_translate_blend_function(eqA, TRUE);
|
||||||
|
alpha_blend_control_noalpha_noclamp |= r300_translate_blend_function(eqA, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,7 +495,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build a command buffer (for FP16). */
|
/* Build a command buffer (for RGBA16F). */
|
||||||
BEGIN_CB(blend->cb_noclamp, 8);
|
BEGIN_CB(blend->cb_noclamp, 8);
|
||||||
OUT_CB_REG(R300_RB3D_ROPCNTL, rop);
|
OUT_CB_REG(R300_RB3D_ROPCNTL, rop);
|
||||||
OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);
|
OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);
|
||||||
@@ -496,6 +505,16 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
|
|||||||
OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);
|
OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);
|
||||||
END_CB;
|
END_CB;
|
||||||
|
|
||||||
|
/* Build a command buffer (for RGB16F). */
|
||||||
|
BEGIN_CB(blend->cb_noclamp_noalpha, 8);
|
||||||
|
OUT_CB_REG(R300_RB3D_ROPCNTL, rop);
|
||||||
|
OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);
|
||||||
|
OUT_CB(blend_control_noalpha_noclamp);
|
||||||
|
OUT_CB(alpha_blend_control_noalpha_noclamp);
|
||||||
|
OUT_CB(rgba_cmask(state->rt[0].colormask));
|
||||||
|
OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);
|
||||||
|
END_CB;
|
||||||
|
|
||||||
/* The same as above, but with no colorbuffer reads and writes. */
|
/* The same as above, but with no colorbuffer reads and writes. */
|
||||||
BEGIN_CB(blend->cb_no_readwrite, 8);
|
BEGIN_CB(blend->cb_no_readwrite, 8);
|
||||||
OUT_CB_REG(R300_RB3D_ROPCNTL, rop);
|
OUT_CB_REG(R300_RB3D_ROPCNTL, rop);
|
||||||
@@ -605,6 +624,7 @@ static void r300_set_blend_color(struct pipe_context* pipe,
|
|||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case PIPE_FORMAT_R16G16B16A16_FLOAT:
|
case PIPE_FORMAT_R16G16B16A16_FLOAT:
|
||||||
|
case PIPE_FORMAT_R16G16B16X16_FLOAT:
|
||||||
OUT_CB(util_float_to_half(c.color[2]) |
|
OUT_CB(util_float_to_half(c.color[2]) |
|
||||||
(util_float_to_half(c.color[3]) << 16));
|
(util_float_to_half(c.color[3]) << 16));
|
||||||
OUT_CB(util_float_to_half(c.color[0]) |
|
OUT_CB(util_float_to_half(c.color[0]) |
|
||||||
|
@@ -424,7 +424,8 @@ static void r300_setup_cmask_properties(struct r300_screen *screen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* FP16 AA needs R500 and a fairly new DRM. */
|
/* FP16 AA needs R500 and a fairly new DRM. */
|
||||||
if (tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT &&
|
if ((tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
|
||||||
|
tex->b.b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
|
||||||
(!screen->caps.is_r500 || screen->info.drm_minor < 29)) {
|
(!screen->caps.is_r500 || screen->info.drm_minor < 29)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -553,13 +554,15 @@ void r300_texture_desc_init(struct r300_screen *rscreen,
|
|||||||
* for rendering. */
|
* for rendering. */
|
||||||
if (rscreen->caps.is_r500) {
|
if (rscreen->caps.is_r500) {
|
||||||
/* FP16 6x MSAA buffers are limited to a width of 1360 pixels. */
|
/* FP16 6x MSAA buffers are limited to a width of 1360 pixels. */
|
||||||
if (tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT &&
|
if ((tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
|
||||||
|
tex->b.b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
|
||||||
tex->b.b.nr_samples == 6 && tex->b.b.width0 > 1360) {
|
tex->b.b.nr_samples == 6 && tex->b.b.width0 > 1360) {
|
||||||
tex->b.b.nr_samples = 4;
|
tex->b.b.nr_samples = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FP16 4x MSAA buffers are limited to a width of 2048 pixels. */
|
/* FP16 4x MSAA buffers are limited to a width of 2048 pixels. */
|
||||||
if (tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT &&
|
if ((tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
|
||||||
|
tex->b.b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
|
||||||
tex->b.b.nr_samples == 4 && tex->b.b.width0 > 2048) {
|
tex->b.b.nr_samples == 4 && tex->b.b.width0 > 2048) {
|
||||||
tex->b.b.nr_samples = 2;
|
tex->b.b.nr_samples = 2;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user