1/* 2 * Copyright © 2012 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include "brw_context.h" 25#include "brw_state.h" 26#include "brw_defines.h" 27#include "brw_util.h" 28#include "brw_wm.h" 29#include "intel_batchbuffer.h" 30#include "main/macros.h" 31#include "main/enums.h" 32#include "main/glformats.h" 33 34#define blend_factor(x) brw_translate_blend_factor(x) 35#define blend_eqn(x) brw_translate_blend_equation(x) 36 37static void 38gen8_upload_blend_state(struct brw_context *brw) 39{ 40 struct gl_context *ctx = &brw->ctx; 41 42 /* We need at least one BLEND_STATE written, because we might do 43 * thread dispatch even if _NumColorDrawBuffers is 0 (for example 44 * for computed depth or alpha test), which will do an FB write 45 * with render target 0, which will reference BLEND_STATE[0] for 46 * alpha test enable. 47 */ 48 int nr_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers; 49 if (nr_draw_buffers == 0 && ctx->Color.AlphaEnabled) 50 nr_draw_buffers = 1; 51 52 int size = 4 + 8 * nr_draw_buffers; 53 uint32_t *blend = brw_state_batch(brw, AUB_TRACE_BLEND_STATE, 54 size, 64, &brw->cc.blend_state_offset); 55 memset(blend, 0, size); 56 57 /* OpenGL specification 3.3 (page 196), section 4.1.3 says: 58 * "If drawbuffer zero is not NONE and the buffer it references has an 59 * integer format, the SAMPLE_ALPHA_TO_COVERAGE and SAMPLE_ALPHA_TO_ONE 60 * operations are skipped." 61 */ 62 if (!(ctx->DrawBuffer->_IntegerBuffers & 0x1)) { 63 /* _NEW_MULTISAMPLE */ 64 if (_mesa_is_multisample_enabled(ctx)) { 65 if (ctx->Multisample.SampleAlphaToCoverage) { 66 blend[0] |= GEN8_BLEND_ALPHA_TO_COVERAGE_ENABLE; 67 blend[0] |= GEN8_BLEND_ALPHA_TO_COVERAGE_DITHER_ENABLE; 68 } 69 if (ctx->Multisample.SampleAlphaToOne) 70 blend[0] |= GEN8_BLEND_ALPHA_TO_ONE_ENABLE; 71 } 72 73 /* _NEW_COLOR */ 74 if (ctx->Color.AlphaEnabled) { 75 blend[0] |= 76 GEN8_BLEND_ALPHA_TEST_ENABLE | 77 SET_FIELD(intel_translate_compare_func(ctx->Color.AlphaFunc), 78 GEN8_BLEND_ALPHA_TEST_FUNCTION); 79 } 80 81 if (ctx->Color.DitherFlag) { 82 blend[0] |= GEN8_BLEND_COLOR_DITHER_ENABLE; 83 } 84 } 85 86 for (int i = 0; i < nr_draw_buffers; i++) { 87 /* _NEW_BUFFERS */ 88 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i]; 89 90 /* Used for implementing the following bit of GL_EXT_texture_integer: 91 * "Per-fragment operations that require floating-point color 92 * components, including multisample alpha operations, alpha test, 93 * blending, and dithering, have no effect when the corresponding 94 * colors are written to an integer color buffer." 95 */ 96 bool integer = ctx->DrawBuffer->_IntegerBuffers & (0x1 << i); 97 98 /* _NEW_COLOR */ 99 if (ctx->Color.ColorLogicOpEnabled) { 100 blend[1 + 2*i+1] |= 101 GEN8_BLEND_LOGIC_OP_ENABLE | 102 SET_FIELD(intel_translate_logic_op(ctx->Color.LogicOp), 103 GEN8_BLEND_LOGIC_OP_FUNCTION); 104 } else if (ctx->Color.BlendEnabled & (1 << i) && !integer && 105 !ctx->Color._AdvancedBlendMode) { 106 GLenum eqRGB = ctx->Color.Blend[i].EquationRGB; 107 GLenum eqA = ctx->Color.Blend[i].EquationA; 108 GLenum srcRGB = ctx->Color.Blend[i].SrcRGB; 109 GLenum dstRGB = ctx->Color.Blend[i].DstRGB; 110 GLenum srcA = ctx->Color.Blend[i].SrcA; 111 GLenum dstA = ctx->Color.Blend[i].DstA; 112 113 if (eqRGB == GL_MIN || eqRGB == GL_MAX) 114 srcRGB = dstRGB = GL_ONE; 115 116 if (eqA == GL_MIN || eqA == GL_MAX) 117 srcA = dstA = GL_ONE; 118 119 /* Due to hardware limitations, the destination may have information 120 * in an alpha channel even when the format specifies no alpha 121 * channel. In order to avoid getting any incorrect blending due to 122 * that alpha channel, coerce the blend factors to values that will 123 * not read the alpha channel, but will instead use the correct 124 * implicit value for alpha. 125 */ 126 if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat, GL_TEXTURE_ALPHA_TYPE)) { 127 srcRGB = brw_fix_xRGB_alpha(srcRGB); 128 srcA = brw_fix_xRGB_alpha(srcA); 129 dstRGB = brw_fix_xRGB_alpha(dstRGB); 130 dstA = brw_fix_xRGB_alpha(dstA); 131 } 132 133 blend[1 + 2*i] |= 134 GEN8_BLEND_COLOR_BUFFER_BLEND_ENABLE | 135 SET_FIELD(blend_factor(dstRGB), GEN8_BLEND_DST_BLEND_FACTOR) | 136 SET_FIELD(blend_factor(srcRGB), GEN8_BLEND_SRC_BLEND_FACTOR) | 137 SET_FIELD(blend_factor(dstA), GEN8_BLEND_DST_ALPHA_BLEND_FACTOR) | 138 SET_FIELD(blend_factor(srcA), GEN8_BLEND_SRC_ALPHA_BLEND_FACTOR) | 139 SET_FIELD(blend_eqn(eqRGB), GEN8_BLEND_COLOR_BLEND_FUNCTION) | 140 SET_FIELD(blend_eqn(eqA), GEN8_BLEND_ALPHA_BLEND_FUNCTION); 141 142 if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) 143 blend[0] |= GEN8_BLEND_INDEPENDENT_ALPHA_BLEND_ENABLE; 144 } 145 146 /* See section 8.1.6 "Pre-Blend Color Clamping" of the 147 * SandyBridge PRM Volume 2 Part 1 for HW requirements. 148 * 149 * We do our ARB_color_buffer_float CLAMP_FRAGMENT_COLOR 150 * clamping in the fragment shader. For its clamping of 151 * blending, the spec says: 152 * 153 * "RESOLVED: For fixed-point color buffers, the inputs and 154 * the result of the blending equation are clamped. For 155 * floating-point color buffers, no clamping occurs." 156 * 157 * So, generally, we want clamping to the render target's range. 158 * And, good news, the hardware tables for both pre- and 159 * post-blend color clamping are either ignored, or any are 160 * allowed, or clamping is required but RT range clamping is a 161 * valid option. 162 */ 163 blend[1 + 2*i+1] |= 164 GEN8_BLEND_PRE_BLEND_COLOR_CLAMP_ENABLE | 165 GEN8_BLEND_POST_BLEND_COLOR_CLAMP_ENABLE | 166 GEN8_BLEND_COLOR_CLAMP_RANGE_RTFORMAT; 167 168 if (!ctx->Color.ColorMask[i][0]) 169 blend[1 + 2*i] |= GEN8_BLEND_WRITE_DISABLE_RED; 170 if (!ctx->Color.ColorMask[i][1]) 171 blend[1 + 2*i] |= GEN8_BLEND_WRITE_DISABLE_GREEN; 172 if (!ctx->Color.ColorMask[i][2]) 173 blend[1 + 2*i] |= GEN8_BLEND_WRITE_DISABLE_BLUE; 174 if (!ctx->Color.ColorMask[i][3]) 175 blend[1 + 2*i] |= GEN8_BLEND_WRITE_DISABLE_ALPHA; 176 177 /* From the BLEND_STATE docs, DWord 0, Bit 29 (AlphaToOne Enable): 178 * "If Dual Source Blending is enabled, this bit must be disabled." 179 */ 180 WARN_ONCE(ctx->Color.Blend[i]._UsesDualSrc && 181 _mesa_is_multisample_enabled(ctx) && 182 ctx->Multisample.SampleAlphaToOne, 183 "HW workaround: disabling alpha to one with dual src " 184 "blending\n"); 185 if (ctx->Color.Blend[i]._UsesDualSrc) 186 blend[0] &= ~GEN8_BLEND_ALPHA_TO_ONE_ENABLE; 187 } 188 189 BEGIN_BATCH(2); 190 OUT_BATCH(_3DSTATE_BLEND_STATE_POINTERS << 16 | (2 - 2)); 191 OUT_BATCH(brw->cc.blend_state_offset | 1); 192 ADVANCE_BATCH(); 193} 194 195const struct brw_tracked_state gen8_blend_state = { 196 .dirty = { 197 .mesa = _NEW_BUFFERS | 198 _NEW_COLOR | 199 _NEW_MULTISAMPLE, 200 .brw = BRW_NEW_BATCH | 201 BRW_NEW_BLORP | 202 BRW_NEW_STATE_BASE_ADDRESS, 203 }, 204 .emit = gen8_upload_blend_state, 205}; 206 207static void 208gen8_upload_ps_blend(struct brw_context *brw) 209{ 210 struct gl_context *ctx = &brw->ctx; 211 uint32_t dw1 = 0; 212 213 /* _NEW_BUFFERS */ 214 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; 215 const bool buffer0_is_integer = ctx->DrawBuffer->_IntegerBuffers & 0x1; 216 217 /* BRW_NEW_FRAGMENT_PROGRAM | _NEW_BUFFERS | _NEW_COLOR */ 218 if (brw_color_buffer_write_enabled(brw)) 219 dw1 |= GEN8_PS_BLEND_HAS_WRITEABLE_RT; 220 221 if (!buffer0_is_integer) { 222 /* _NEW_COLOR */ 223 if (ctx->Color.AlphaEnabled) 224 dw1 |= GEN8_PS_BLEND_ALPHA_TEST_ENABLE; 225 226 /* _NEW_MULTISAMPLE */ 227 if (_mesa_is_multisample_enabled(ctx) && 228 ctx->Multisample.SampleAlphaToCoverage) 229 dw1 |= GEN8_PS_BLEND_ALPHA_TO_COVERAGE_ENABLE; 230 } 231 232 /* Used for implementing the following bit of GL_EXT_texture_integer: 233 * "Per-fragment operations that require floating-point color 234 * components, including multisample alpha operations, alpha test, 235 * blending, and dithering, have no effect when the corresponding 236 * colors are written to an integer color buffer." 237 * 238 * The OpenGL specification 3.3 (page 196), section 4.1.3 says: 239 * "If drawbuffer zero is not NONE and the buffer it references has an 240 * integer format, the SAMPLE_ALPHA_TO_COVERAGE and SAMPLE_ALPHA_TO_ONE 241 * operations are skipped." 242 */ 243 if (rb && !buffer0_is_integer && (ctx->Color.BlendEnabled & 1)) { 244 GLenum eqRGB = ctx->Color.Blend[0].EquationRGB; 245 GLenum eqA = ctx->Color.Blend[0].EquationA; 246 GLenum srcRGB = ctx->Color.Blend[0].SrcRGB; 247 GLenum dstRGB = ctx->Color.Blend[0].DstRGB; 248 GLenum srcA = ctx->Color.Blend[0].SrcA; 249 GLenum dstA = ctx->Color.Blend[0].DstA; 250 251 if (eqRGB == GL_MIN || eqRGB == GL_MAX) 252 srcRGB = dstRGB = GL_ONE; 253 254 if (eqA == GL_MIN || eqA == GL_MAX) 255 srcA = dstA = GL_ONE; 256 257 /* Due to hardware limitations, the destination may have information 258 * in an alpha channel even when the format specifies no alpha 259 * channel. In order to avoid getting any incorrect blending due to 260 * that alpha channel, coerce the blend factors to values that will 261 * not read the alpha channel, but will instead use the correct 262 * implicit value for alpha. 263 */ 264 if (!_mesa_base_format_has_channel(rb->_BaseFormat, GL_TEXTURE_ALPHA_TYPE)) { 265 srcRGB = brw_fix_xRGB_alpha(srcRGB); 266 srcA = brw_fix_xRGB_alpha(srcA); 267 dstRGB = brw_fix_xRGB_alpha(dstRGB); 268 dstA = brw_fix_xRGB_alpha(dstA); 269 } 270 271 dw1 |= 272 GEN8_PS_BLEND_COLOR_BUFFER_BLEND_ENABLE | 273 SET_FIELD(blend_factor(dstRGB), GEN8_PS_BLEND_DST_BLEND_FACTOR) | 274 SET_FIELD(blend_factor(srcRGB), GEN8_PS_BLEND_SRC_BLEND_FACTOR) | 275 SET_FIELD(blend_factor(dstA), GEN8_PS_BLEND_DST_ALPHA_BLEND_FACTOR) | 276 SET_FIELD(blend_factor(srcA), GEN8_PS_BLEND_SRC_ALPHA_BLEND_FACTOR); 277 278 if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) 279 dw1 |= GEN8_PS_BLEND_INDEPENDENT_ALPHA_BLEND_ENABLE; 280 } 281 282 BEGIN_BATCH(2); 283 OUT_BATCH(_3DSTATE_PS_BLEND << 16 | (2 - 2)); 284 OUT_BATCH(dw1); 285 ADVANCE_BATCH(); 286} 287 288const struct brw_tracked_state gen8_ps_blend = { 289 .dirty = { 290 .mesa = _NEW_BUFFERS | 291 _NEW_COLOR | 292 _NEW_MULTISAMPLE, 293 .brw = BRW_NEW_BLORP | 294 BRW_NEW_CONTEXT | 295 BRW_NEW_FRAGMENT_PROGRAM, 296 }, 297 .emit = gen8_upload_ps_blend 298}; 299