1 /* 2 * Copyright 2009 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 * Authors: 24 * Eric Anholt <eric (at) anholt.net> 25 * 26 */ 27 28 #include "brw_context.h" 29 #include "brw_state.h" 30 #include "brw_defines.h" 31 #include "brw_util.h" 32 #include "intel_batchbuffer.h" 33 #include "main/macros.h" 34 #include "main/enums.h" 35 #include "main/glformats.h" 36 #include "main/stencil.h" 37 38 static void 39 gen6_upload_blend_state(struct brw_context *brw) 40 { 41 bool is_buffer_zero_integer_format = false; 42 struct gl_context *ctx = &brw->ctx; 43 struct gen6_blend_state *blend; 44 int b; 45 int nr_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers; 46 int size; 47 48 /* We need at least one BLEND_STATE written, because we might do 49 * thread dispatch even if _NumColorDrawBuffers is 0 (for example 50 * for computed depth or alpha test), which will do an FB write 51 * with render target 0, which will reference BLEND_STATE[0] for 52 * alpha test enable. 53 */ 54 if (nr_draw_buffers == 0) 55 nr_draw_buffers = 1; 56 57 size = sizeof(*blend) * nr_draw_buffers; 58 blend = brw_state_batch(brw, AUB_TRACE_BLEND_STATE, 59 size, 64, &brw->cc.blend_state_offset); 60 61 memset(blend, 0, size); 62 63 for (b = 0; b < nr_draw_buffers; b++) { 64 /* _NEW_BUFFERS */ 65 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[b]; 66 GLenum rb_type; 67 bool integer; 68 69 if (rb) 70 rb_type = _mesa_get_format_datatype(rb->Format); 71 else 72 rb_type = GL_UNSIGNED_NORMALIZED; 73 74 /* Used for implementing the following bit of GL_EXT_texture_integer: 75 * "Per-fragment operations that require floating-point color 76 * components, including multisample alpha operations, alpha test, 77 * blending, and dithering, have no effect when the corresponding 78 * colors are written to an integer color buffer." 79 */ 80 integer = (rb_type == GL_INT || rb_type == GL_UNSIGNED_INT); 81 82 if(b == 0 && integer) 83 is_buffer_zero_integer_format = true; 84 85 /* _NEW_COLOR */ 86 if (ctx->Color.ColorLogicOpEnabled) { 87 /* Floating point RTs should have no effect from LogicOp, 88 * except for disabling of blending, but other types should. 89 * 90 * However, from the Sandy Bridge PRM, Vol 2 Par 1, Section 8.1.11, 91 * "Logic Ops", 92 * 93 * "Logic Ops are only supported on *_UNORM surfaces (excluding 94 * _SRGB variants), otherwise Logic Ops must be DISABLED." 95 */ 96 WARN_ONCE(ctx->Color.LogicOp != GL_COPY && 97 rb_type != GL_UNSIGNED_NORMALIZED && 98 rb_type != GL_FLOAT, "Ignoring %s logic op on %s " 99 "renderbuffer\n", 100 _mesa_enum_to_string(ctx->Color.LogicOp), 101 _mesa_enum_to_string(rb_type)); 102 if (rb_type == GL_UNSIGNED_NORMALIZED) { 103 blend[b].blend1.logic_op_enable = 1; 104 blend[b].blend1.logic_op_func = 105 intel_translate_logic_op(ctx->Color.LogicOp); 106 } 107 } else if (ctx->Color.BlendEnabled & (1 << b) && !integer && 108 !ctx->Color._AdvancedBlendMode) { 109 GLenum eqRGB = ctx->Color.Blend[b].EquationRGB; 110 GLenum eqA = ctx->Color.Blend[b].EquationA; 111 GLenum srcRGB = ctx->Color.Blend[b].SrcRGB; 112 GLenum dstRGB = ctx->Color.Blend[b].DstRGB; 113 GLenum srcA = ctx->Color.Blend[b].SrcA; 114 GLenum dstA = ctx->Color.Blend[b].DstA; 115 116 if (eqRGB == GL_MIN || eqRGB == GL_MAX) { 117 srcRGB = dstRGB = GL_ONE; 118 } 119 120 if (eqA == GL_MIN || eqA == GL_MAX) { 121 srcA = dstA = GL_ONE; 122 } 123 124 /* Due to hardware limitations, the destination may have information 125 * in an alpha channel even when the format specifies no alpha 126 * channel. In order to avoid getting any incorrect blending due to 127 * that alpha channel, coerce the blend factors to values that will 128 * not read the alpha channel, but will instead use the correct 129 * implicit value for alpha. 130 */ 131 if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat, GL_TEXTURE_ALPHA_TYPE)) 132 { 133 srcRGB = brw_fix_xRGB_alpha(srcRGB); 134 srcA = brw_fix_xRGB_alpha(srcA); 135 dstRGB = brw_fix_xRGB_alpha(dstRGB); 136 dstA = brw_fix_xRGB_alpha(dstA); 137 } 138 139 blend[b].blend0.dest_blend_factor = brw_translate_blend_factor(dstRGB); 140 blend[b].blend0.source_blend_factor = brw_translate_blend_factor(srcRGB); 141 blend[b].blend0.blend_func = brw_translate_blend_equation(eqRGB); 142 143 blend[b].blend0.ia_dest_blend_factor = brw_translate_blend_factor(dstA); 144 blend[b].blend0.ia_source_blend_factor = brw_translate_blend_factor(srcA); 145 blend[b].blend0.ia_blend_func = brw_translate_blend_equation(eqA); 146 147 blend[b].blend0.blend_enable = 1; 148 blend[b].blend0.ia_blend_enable = (srcA != srcRGB || 149 dstA != dstRGB || 150 eqA != eqRGB); 151 } 152 153 /* See section 8.1.6 "Pre-Blend Color Clamping" of the 154 * SandyBridge PRM Volume 2 Part 1 for HW requirements. 155 * 156 * We do our ARB_color_buffer_float CLAMP_FRAGMENT_COLOR 157 * clamping in the fragment shader. For its clamping of 158 * blending, the spec says: 159 * 160 * "RESOLVED: For fixed-point color buffers, the inputs and 161 * the result of the blending equation are clamped. For 162 * floating-point color buffers, no clamping occurs." 163 * 164 * So, generally, we want clamping to the render target's range. 165 * And, good news, the hardware tables for both pre- and 166 * post-blend color clamping are either ignored, or any are 167 * allowed, or clamping is required but RT range clamping is a 168 * valid option. 169 */ 170 blend[b].blend1.pre_blend_clamp_enable = 1; 171 blend[b].blend1.post_blend_clamp_enable = 1; 172 blend[b].blend1.clamp_range = BRW_RENDERTARGET_CLAMPRANGE_FORMAT; 173 174 /* _NEW_COLOR */ 175 if (ctx->Color.AlphaEnabled && !integer) { 176 blend[b].blend1.alpha_test_enable = 1; 177 blend[b].blend1.alpha_test_func = 178 intel_translate_compare_func(ctx->Color.AlphaFunc); 179 180 } 181 182 /* _NEW_COLOR */ 183 if (ctx->Color.DitherFlag && !integer) { 184 blend[b].blend1.dither_enable = 1; 185 blend[b].blend1.y_dither_offset = 0; 186 blend[b].blend1.x_dither_offset = 0; 187 } 188 189 blend[b].blend1.write_disable_r = !ctx->Color.ColorMask[b][0]; 190 blend[b].blend1.write_disable_g = !ctx->Color.ColorMask[b][1]; 191 blend[b].blend1.write_disable_b = !ctx->Color.ColorMask[b][2]; 192 blend[b].blend1.write_disable_a = !ctx->Color.ColorMask[b][3]; 193 194 /* OpenGL specification 3.3 (page 196), section 4.1.3 says: 195 * "If drawbuffer zero is not NONE and the buffer it references has an 196 * integer format, the SAMPLE_ALPHA_TO_COVERAGE and SAMPLE_ALPHA_TO_ONE 197 * operations are skipped." 198 */ 199 if(!is_buffer_zero_integer_format) { 200 /* _NEW_MULTISAMPLE */ 201 blend[b].blend1.alpha_to_coverage = 202 _mesa_is_multisample_enabled(ctx) && ctx->Multisample.SampleAlphaToCoverage; 203 204 /* From SandyBridge PRM, volume 2 Part 1, section 8.2.3, BLEND_STATE: 205 * DWord 1, Bit 30 (AlphaToOne Enable): 206 * "If Dual Source Blending is enabled, this bit must be disabled" 207 */ 208 WARN_ONCE(ctx->Color.Blend[b]._UsesDualSrc && 209 _mesa_is_multisample_enabled(ctx) && 210 ctx->Multisample.SampleAlphaToOne, 211 "HW workaround: disabling alpha to one with dual src " 212 "blending\n"); 213 if (ctx->Color.Blend[b]._UsesDualSrc) 214 blend[b].blend1.alpha_to_one = false; 215 else 216 blend[b].blend1.alpha_to_one = 217 _mesa_is_multisample_enabled(ctx) && ctx->Multisample.SampleAlphaToOne; 218 219 blend[b].blend1.alpha_to_coverage_dither = (brw->gen >= 7); 220 } 221 else { 222 blend[b].blend1.alpha_to_coverage = false; 223 blend[b].blend1.alpha_to_one = false; 224 } 225 } 226 227 /* Point the GPU at the new indirect state. */ 228 if (brw->gen == 6) { 229 BEGIN_BATCH(4); 230 OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (4 - 2)); 231 OUT_BATCH(brw->cc.blend_state_offset | 1); 232 OUT_BATCH(0); 233 OUT_BATCH(0); 234 ADVANCE_BATCH(); 235 } else { 236 BEGIN_BATCH(2); 237 OUT_BATCH(_3DSTATE_BLEND_STATE_POINTERS << 16 | (2 - 2)); 238 OUT_BATCH(brw->cc.blend_state_offset | 1); 239 ADVANCE_BATCH(); 240 } 241 } 242 243 const struct brw_tracked_state gen6_blend_state = { 244 .dirty = { 245 .mesa = _NEW_BUFFERS | 246 _NEW_COLOR | 247 _NEW_MULTISAMPLE, 248 .brw = BRW_NEW_BATCH | 249 BRW_NEW_BLORP | 250 BRW_NEW_STATE_BASE_ADDRESS, 251 }, 252 .emit = gen6_upload_blend_state, 253 }; 254 255 static void 256 gen6_upload_color_calc_state(struct brw_context *brw) 257 { 258 struct gl_context *ctx = &brw->ctx; 259 struct gen6_color_calc_state *cc; 260 261 cc = brw_state_batch(brw, AUB_TRACE_CC_STATE, 262 sizeof(*cc), 64, &brw->cc.state_offset); 263 memset(cc, 0, sizeof(*cc)); 264 265 /* _NEW_COLOR */ 266 cc->cc0.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8; 267 UNCLAMPED_FLOAT_TO_UBYTE(cc->cc1.alpha_ref_fi.ui, ctx->Color.AlphaRef); 268 269 if (brw->gen < 9) { 270 /* _NEW_STENCIL */ 271 cc->cc0.stencil_ref = _mesa_get_stencil_ref(ctx, 0); 272 cc->cc0.bf_stencil_ref = 273 _mesa_get_stencil_ref(ctx, ctx->Stencil._BackFace); 274 } 275 276 /* _NEW_COLOR */ 277 cc->constant_r = ctx->Color.BlendColorUnclamped[0]; 278 cc->constant_g = ctx->Color.BlendColorUnclamped[1]; 279 cc->constant_b = ctx->Color.BlendColorUnclamped[2]; 280 cc->constant_a = ctx->Color.BlendColorUnclamped[3]; 281 282 /* Point the GPU at the new indirect state. */ 283 if (brw->gen == 6) { 284 BEGIN_BATCH(4); 285 OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (4 - 2)); 286 OUT_BATCH(0); 287 OUT_BATCH(0); 288 OUT_BATCH(brw->cc.state_offset | 1); 289 ADVANCE_BATCH(); 290 } else { 291 BEGIN_BATCH(2); 292 OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (2 - 2)); 293 OUT_BATCH(brw->cc.state_offset | 1); 294 ADVANCE_BATCH(); 295 } 296 } 297 298 const struct brw_tracked_state gen6_color_calc_state = { 299 .dirty = { 300 .mesa = _NEW_COLOR | 301 _NEW_STENCIL, 302 .brw = BRW_NEW_BATCH | 303 BRW_NEW_BLORP | 304 BRW_NEW_CC_STATE | 305 BRW_NEW_STATE_BASE_ADDRESS, 306 }, 307 .emit = gen6_upload_color_calc_state, 308 }; 309