From c96686a6cc0f53965b99a55046d1c55a867f93b3 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 29 Nov 2012 18:43:59 -0800 Subject: [PATCH] i965: Add the new 3DSTATE_PS_BLEND state packet. v2: Only set GEN8_PS_BLEND_HAS_WRITEABLE_RT if color buffer writes are enabled (caught by Eric Anholt). v3: Set non-blending flags (writeable RT, alpha test, alpha to coverage) for integer formats too. +14 Piglits. Signed-off-by: Kenneth Graunke Reviewed-by: Eric Anholt [v2] --- src/mesa/drivers/dri/i965/Makefile.sources | 1 + src/mesa/drivers/dri/i965/brw_defines.h | 16 +++ src/mesa/drivers/dri/i965/brw_state.h | 1 + src/mesa/drivers/dri/i965/brw_state_upload.c | 1 + src/mesa/drivers/dri/i965/gen8_blend_state.c | 123 +++++++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 src/mesa/drivers/dri/i965/gen8_blend_state.c diff --git a/src/mesa/drivers/dri/i965/Makefile.sources b/src/mesa/drivers/dri/i965/Makefile.sources index ecee9edb3ba..b0f84b9c32f 100644 --- a/src/mesa/drivers/dri/i965/Makefile.sources +++ b/src/mesa/drivers/dri/i965/Makefile.sources @@ -141,6 +141,7 @@ i965_FILES = \ gen7_vs_state.c \ gen7_wm_state.c \ gen7_wm_surface_state.c \ + gen8_blend_state.c \ gen8_disasm.c \ gen8_fs_generator.cpp \ gen8_generator.cpp \ diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 56af37aaf5c..72f41adf178 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -1673,6 +1673,22 @@ enum brw_message_target { # define GEN8_RASTER_SCISSOR_ENABLE (1 << 1) # define GEN8_RASTER_VIEWPORT_Z_CLIP_TEST_ENABLE (1 << 0) +#define _3DSTATE_PS_BLEND 0x784D /* GEN8+ */ +/* DW1 */ +# define GEN8_PS_BLEND_ALPHA_TO_COVERAGE_ENABLE (1 << 31) +# define GEN8_PS_BLEND_HAS_WRITEABLE_RT (1 << 30) +# define GEN8_PS_BLEND_COLOR_BUFFER_BLEND_ENABLE (1 << 29) +# define GEN8_PS_BLEND_SRC_ALPHA_BLEND_FACTOR_MASK INTEL_MASK(28, 24) +# define GEN8_PS_BLEND_SRC_ALPHA_BLEND_FACTOR_SHIFT 24 +# define GEN8_PS_BLEND_DST_ALPHA_BLEND_FACTOR_MASK INTEL_MASK(23, 19) +# define GEN8_PS_BLEND_DST_ALPHA_BLEND_FACTOR_SHIFT 19 +# define GEN8_PS_BLEND_SRC_BLEND_FACTOR_MASK INTEL_MASK(18, 14) +# define GEN8_PS_BLEND_SRC_BLEND_FACTOR_SHIFT 14 +# define GEN8_PS_BLEND_DST_BLEND_FACTOR_MASK INTEL_MASK(13, 9) +# define GEN8_PS_BLEND_DST_BLEND_FACTOR_SHIFT 9 +# define GEN8_PS_BLEND_ALPHA_TEST_ENABLE (1 << 8) +# define GEN8_PS_BLEND_INDEPENDENT_ALPHA_BLEND_ENABLE (1 << 7) + #define _3DSTATE_WM_DEPTH_STENCIL 0x784E /* GEN8+ */ /* DW1 */ # define GEN8_WM_DS_STENCIL_FAIL_OP_SHIFT 29 diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 748db535a11..669c16307ef 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -131,6 +131,7 @@ extern const struct brw_tracked_state gen7_urb; extern const struct brw_tracked_state gen7_vs_state; extern const struct brw_tracked_state gen7_wm_state; extern const struct brw_tracked_state haswell_cut_index; +extern const struct brw_tracked_state gen8_ps_blend; extern const struct brw_tracked_state gen8_wm_depth_stencil; extern const struct brw_tracked_state gen8_raster_state; extern const struct brw_tracked_state gen8_sbe_state; diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 5aceffcc114..f91368753fc 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -304,6 +304,7 @@ static const struct brw_tracked_state *gen8_atoms[] = &gen8_raster_state, &gen8_sbe_state, &gen8_sf_state, + &gen8_ps_blend, &gen8_wm_depth_stencil, &gen7_wm_state, &gen7_ps_state, diff --git a/src/mesa/drivers/dri/i965/gen8_blend_state.c b/src/mesa/drivers/dri/i965/gen8_blend_state.c new file mode 100644 index 00000000000..2efdfa7c82c --- /dev/null +++ b/src/mesa/drivers/dri/i965/gen8_blend_state.c @@ -0,0 +1,123 @@ +/* + * Copyright © 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" +#include "brw_util.h" +#include "brw_wm.h" +#include "intel_batchbuffer.h" +#include "main/macros.h" +#include "main/enums.h" +#include "main/glformats.h" + +#define blend_factor(x) brw_translate_blend_factor(x) + +static void +gen8_upload_ps_blend(struct brw_context *brw) +{ + struct gl_context *ctx = &brw->ctx; + uint32_t dw1 = 0; + + /* _NEW_BUFFERS */ + struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; + + if (brw_color_buffer_write_enabled(brw)) + dw1 |= GEN8_PS_BLEND_HAS_WRITEABLE_RT; + + /* _NEW_COLOR */ + if (ctx->Color.AlphaEnabled) + dw1 |= GEN8_PS_BLEND_ALPHA_TEST_ENABLE; + + /* _NEW_MULTISAMPLE */ + if (ctx->Multisample._Enabled && ctx->Multisample.SampleAlphaToCoverage) + dw1 |= GEN8_PS_BLEND_ALPHA_TO_COVERAGE_ENABLE; + + /* Used for implementing the following bit of GL_EXT_texture_integer: + * "Per-fragment operations that require floating-point color + * components, including multisample alpha operations, alpha test, + * blending, and dithering, have no effect when the corresponding + * colors are written to an integer color buffer." + * + * The OpenGL specification 3.3 (page 196), section 4.1.3 says: + * "If drawbuffer zero is not NONE and the buffer it references has an + * integer format, the SAMPLE_ALPHA_TO_COVERAGE and SAMPLE_ALPHA_TO_ONE + * operations are skipped." + */ + GLenum rb_type = + rb ? _mesa_get_format_datatype(rb->Format) : GL_UNSIGNED_NORMALIZED; + + if (rb && rb_type != GL_INT && rb_type != GL_UNSIGNED_INT && + (ctx->Color.BlendEnabled & 1)) { + GLenum eqRGB = ctx->Color.Blend[0].EquationRGB; + GLenum eqA = ctx->Color.Blend[0].EquationA; + GLenum srcRGB = ctx->Color.Blend[0].SrcRGB; + GLenum dstRGB = ctx->Color.Blend[0].DstRGB; + GLenum srcA = ctx->Color.Blend[0].SrcA; + GLenum dstA = ctx->Color.Blend[0].DstA; + + if (eqRGB == GL_MIN || eqRGB == GL_MAX) + srcRGB = dstRGB = GL_ONE; + + if (eqA == GL_MIN || eqA == GL_MAX) + srcA = dstA = GL_ONE; + + /* Due to hardware limitations, the destination may have information + * in an alpha channel even when the format specifies no alpha + * channel. In order to avoid getting any incorrect blending due to + * that alpha channel, coerce the blend factors to values that will + * not read the alpha channel, but will instead use the correct + * implicit value for alpha. + */ + if (!_mesa_base_format_has_channel(rb->_BaseFormat, GL_TEXTURE_ALPHA_TYPE)) { + srcRGB = brw_fix_xRGB_alpha(srcRGB); + srcA = brw_fix_xRGB_alpha(srcA); + dstRGB = brw_fix_xRGB_alpha(dstRGB); + dstA = brw_fix_xRGB_alpha(dstA); + } + + dw1 |= + GEN8_PS_BLEND_COLOR_BUFFER_BLEND_ENABLE | + SET_FIELD(blend_factor(dstRGB), GEN8_PS_BLEND_DST_BLEND_FACTOR) | + SET_FIELD(blend_factor(srcRGB), GEN8_PS_BLEND_SRC_BLEND_FACTOR) | + SET_FIELD(blend_factor(dstA), GEN8_PS_BLEND_DST_ALPHA_BLEND_FACTOR) | + SET_FIELD(blend_factor(srcA), GEN8_PS_BLEND_SRC_ALPHA_BLEND_FACTOR); + + if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) + dw1 |= GEN8_PS_BLEND_INDEPENDENT_ALPHA_BLEND_ENABLE; + } + + BEGIN_BATCH(2); + OUT_BATCH(_3DSTATE_PS_BLEND << 16 | (2 - 2)); + OUT_BATCH(dw1); + ADVANCE_BATCH(); +} + +const struct brw_tracked_state gen8_ps_blend = { + .dirty = { + .mesa = _NEW_BUFFERS | _NEW_COLOR | _NEW_MULTISAMPLE, + .brw = BRW_NEW_CONTEXT, + .cache = 0, + }, + .emit = gen8_upload_ps_blend +};