2 * Copyright © 2012 Intel Corporation
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:
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
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
24 #include "brw_context.h"
25 #include "brw_state.h"
26 #include "brw_defines.h"
29 #include "intel_batchbuffer.h"
30 #include "main/macros.h"
31 #include "main/enums.h"
32 #include "main/glformats.h"
34 #define blend_factor(x) brw_translate_blend_factor(x)
35 #define blend_eqn(x) brw_translate_blend_equation(x)
38 gen8_upload_blend_state(struct brw_context
*brw
)
40 struct gl_context
*ctx
= &brw
->ctx
;
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
48 int nr_draw_buffers
= ctx
->DrawBuffer
->_NumColorDrawBuffers
;
49 if (nr_draw_buffers
== 0 && ctx
->Color
.AlphaEnabled
)
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
);
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."
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
;
69 if (ctx
->Multisample
.SampleAlphaToOne
)
70 blend
[0] |= GEN8_BLEND_ALPHA_TO_ONE_ENABLE
;
74 if (ctx
->Color
.AlphaEnabled
) {
76 GEN8_BLEND_ALPHA_TEST_ENABLE
|
77 SET_FIELD(intel_translate_compare_func(ctx
->Color
.AlphaFunc
),
78 GEN8_BLEND_ALPHA_TEST_FUNCTION
);
81 if (ctx
->Color
.DitherFlag
) {
82 blend
[0] |= GEN8_BLEND_COLOR_DITHER_ENABLE
;
86 for (int i
= 0; i
< nr_draw_buffers
; i
++) {
88 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[i
];
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."
96 bool integer
= ctx
->DrawBuffer
->_IntegerBuffers
& (0x1 << i
);
99 if (ctx
->Color
.ColorLogicOpEnabled
) {
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
;
113 if (eqRGB
== GL_MIN
|| eqRGB
== GL_MAX
)
114 srcRGB
= dstRGB
= GL_ONE
;
116 if (eqA
== GL_MIN
|| eqA
== GL_MAX
)
117 srcA
= dstA
= GL_ONE
;
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.
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
);
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
);
142 if (srcA
!= srcRGB
|| dstA
!= dstRGB
|| eqA
!= eqRGB
)
143 blend
[0] |= GEN8_BLEND_INDEPENDENT_ALPHA_BLEND_ENABLE
;
146 /* See section 8.1.6 "Pre-Blend Color Clamping" of the
147 * SandyBridge PRM Volume 2 Part 1 for HW requirements.
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:
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."
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
164 GEN8_BLEND_PRE_BLEND_COLOR_CLAMP_ENABLE
|
165 GEN8_BLEND_POST_BLEND_COLOR_CLAMP_ENABLE
|
166 GEN8_BLEND_COLOR_CLAMP_RANGE_RTFORMAT
;
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
;
177 /* From the BLEND_STATE docs, DWord 0, Bit 29 (AlphaToOne Enable):
178 * "If Dual Source Blending is enabled, this bit must be disabled."
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 "
185 if (ctx
->Color
.Blend
[i
]._UsesDualSrc
)
186 blend
[0] &= ~GEN8_BLEND_ALPHA_TO_ONE_ENABLE
;
190 OUT_BATCH(_3DSTATE_BLEND_STATE_POINTERS
<< 16 | (2 - 2));
191 OUT_BATCH(brw
->cc
.blend_state_offset
| 1);
195 const struct brw_tracked_state gen8_blend_state
= {
197 .mesa
= _NEW_BUFFERS
|
200 .brw
= BRW_NEW_BATCH
|
202 BRW_NEW_STATE_BASE_ADDRESS
,
204 .emit
= gen8_upload_blend_state
,
208 gen8_upload_ps_blend(struct brw_context
*brw
)
210 struct gl_context
*ctx
= &brw
->ctx
;
214 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[0];
215 const bool buffer0_is_integer
= ctx
->DrawBuffer
->_IntegerBuffers
& 0x1;
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
;
221 if(!buffer0_is_integer
) {
223 if (ctx
->Color
.AlphaEnabled
)
224 dw1
|= GEN8_PS_BLEND_ALPHA_TEST_ENABLE
;
226 /* _NEW_MULTISAMPLE */
227 if (_mesa_is_multisample_enabled(ctx
) &&
228 ctx
->Multisample
.SampleAlphaToCoverage
)
229 dw1
|= GEN8_PS_BLEND_ALPHA_TO_COVERAGE_ENABLE
;
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."
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."
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
;
251 if (eqRGB
== GL_MIN
|| eqRGB
== GL_MAX
)
252 srcRGB
= dstRGB
= GL_ONE
;
254 if (eqA
== GL_MIN
|| eqA
== GL_MAX
)
255 srcA
= dstA
= GL_ONE
;
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.
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
);
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
);
278 if (srcA
!= srcRGB
|| dstA
!= dstRGB
|| eqA
!= eqRGB
)
279 dw1
|= GEN8_PS_BLEND_INDEPENDENT_ALPHA_BLEND_ENABLE
;
283 OUT_BATCH(_3DSTATE_PS_BLEND
<< 16 | (2 - 2));
288 const struct brw_tracked_state gen8_ps_blend
= {
290 .mesa
= _NEW_BUFFERS
|
293 .brw
= BRW_NEW_BLORP
|
295 BRW_NEW_FRAGMENT_PROGRAM
,
297 .emit
= gen8_upload_ps_blend