From 4dc142d521f9161275deb030efcde112f835307c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 1 Feb 2013 21:45:15 +0100 Subject: [PATCH] r300g: fix blending and alpha-test with RGBX16F and enable MSAA for it --- src/gallium/drivers/r300/r300_blit.c | 3 +- src/gallium/drivers/r300/r300_context.h | 1 + src/gallium/drivers/r300/r300_emit.c | 6 +++- src/gallium/drivers/r300/r300_screen.c | 6 ++-- src/gallium/drivers/r300/r300_state.c | 34 ++++++++++++++++---- src/gallium/drivers/r300/r300_texture_desc.c | 9 ++++-- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index e903e9a57cc..76f83273cf2 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -187,7 +187,8 @@ static void r300_set_clear_color(struct r300_context *r300, memset(&uc, 0, sizeof(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) */ 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); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index d88ba3f7ed7..e6b0181cd84 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -82,6 +82,7 @@ struct r300_blend_state { uint32_t cb_clamp[COLORMASK_NUM_SWIZZLES][8]; uint32_t cb_noclamp[8]; + uint32_t cb_noclamp_noalpha[8]; uint32_t cb_no_readwrite[8]; }; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 93f710c6e5c..b038a9719ae 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -47,6 +47,8 @@ void r300_emit_blend_state(struct r300_context* r300, if (fb->nr_cbufs) { if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) { 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 { unsigned swz = r300_surface(fb->cbufs[0])->colormask_swizzle; 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 * 16-bit (FG_ALPHA_VALUE). */ 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; } else { alpha_func |= R500_FG_ALPHA_FUNC_8BIT; diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 60759160b0e..d644ebb6153 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -414,7 +414,8 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, boolean is_half_float = format == PIPE_FORMAT_R16_FLOAT || format == PIPE_FORMAT_R16G16_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; 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) && !util_format_is_rgba8_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; } } else { diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 19c7d4eb322..bf4163cea42 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -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_noclamp = 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_noclamp = 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 dither = 0; /* R300_RB3D_DITHER_CTL: 0x4e50 */ int i; @@ -386,7 +388,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe, /* Get blending register values. */ 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, * 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(dstRGB) << R300_DST_BLEND_SHIFT); - blend_control_noalpha = + blend_control_noalpha = blend_control_noalpha_noclamp = R300_ALPHA_BLEND_ENABLE | ( r300_translate_blend_factor(srcRGBX) << R300_SRC_BLEND_SHIFT) | ( r300_translate_blend_factor(dstRGBX) << R300_DST_BLEND_SHIFT); blend_eq = r300_translate_blend_function(eqRGB, TRUE); + blend_eq_noclamp = r300_translate_blend_function(eqRGB, FALSE); + blend_control |= 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. */ 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); blend_control_noalpha |= blend_read_enable(eqRGB, eqA, dstRGBX, dstA, 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. * 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) { 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(dstA) << R300_DST_BLEND_SHIFT) | - r300_translate_blend_function(eqA, TRUE); + (r300_translate_blend_factor(dstA) << R300_DST_BLEND_SHIFT); + 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); OUT_CB_REG(R300_RB3D_ROPCNTL, rop); 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); 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. */ BEGIN_CB(blend->cb_no_readwrite, 8); OUT_CB_REG(R300_RB3D_ROPCNTL, rop); @@ -605,6 +624,7 @@ static void r300_set_blend_color(struct pipe_context* pipe, switch (format) { case PIPE_FORMAT_R16G16B16A16_FLOAT: + case PIPE_FORMAT_R16G16B16X16_FLOAT: OUT_CB(util_float_to_half(c.color[2]) | (util_float_to_half(c.color[3]) << 16)); OUT_CB(util_float_to_half(c.color[0]) | diff --git a/src/gallium/drivers/r300/r300_texture_desc.c b/src/gallium/drivers/r300/r300_texture_desc.c index 6d645288f98..eb31f82f9d6 100644 --- a/src/gallium/drivers/r300/r300_texture_desc.c +++ b/src/gallium/drivers/r300/r300_texture_desc.c @@ -424,7 +424,8 @@ static void r300_setup_cmask_properties(struct r300_screen *screen, } /* 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)) { return; } @@ -553,13 +554,15 @@ void r300_texture_desc_init(struct r300_screen *rscreen, * for rendering. */ if (rscreen->caps.is_r500) { /* 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 = 4; } /* 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 = 2; } -- 2.30.2