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 struct gl_renderbuffer
*rb0
= ctx
->DrawBuffer
->_ColorDrawBuffers
[0];
64 rb0
? _mesa_get_format_datatype(rb0
->Format
) : GL_UNSIGNED_NORMALIZED
;
66 if (rb_zero_type
!= GL_INT
&& rb_zero_type
!= GL_UNSIGNED_INT
) {
67 /* _NEW_MULTISAMPLE */
68 if (ctx
->Multisample
._Enabled
) {
69 if (ctx
->Multisample
.SampleAlphaToCoverage
) {
70 blend
[0] |= GEN8_BLEND_ALPHA_TO_COVERAGE_ENABLE
;
71 blend
[0] |= GEN8_BLEND_ALPHA_TO_COVERAGE_DITHER_ENABLE
;
73 if (ctx
->Multisample
.SampleAlphaToOne
)
74 blend
[0] |= GEN8_BLEND_ALPHA_TO_ONE_ENABLE
;
78 if (ctx
->Color
.AlphaEnabled
) {
80 GEN8_BLEND_ALPHA_TEST_ENABLE
|
81 SET_FIELD(intel_translate_compare_func(ctx
->Color
.AlphaFunc
),
82 GEN8_BLEND_ALPHA_TEST_FUNCTION
);
85 if (ctx
->Color
.DitherFlag
) {
86 blend
[0] |= GEN8_BLEND_COLOR_DITHER_ENABLE
;
90 for (int i
= 0; i
< nr_draw_buffers
; i
++) {
92 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[i
];
94 rb
? _mesa_get_format_datatype(rb
->Format
) : GL_UNSIGNED_NORMALIZED
;
96 /* Used for implementing the following bit of GL_EXT_texture_integer:
97 * "Per-fragment operations that require floating-point color
98 * components, including multisample alpha operations, alpha test,
99 * blending, and dithering, have no effect when the corresponding
100 * colors are written to an integer color buffer."
102 bool integer
= rb_type
== GL_INT
|| rb_type
== GL_UNSIGNED_INT
;
105 if (ctx
->Color
.ColorLogicOpEnabled
) {
107 GEN8_BLEND_LOGIC_OP_ENABLE
|
108 SET_FIELD(intel_translate_logic_op(ctx
->Color
.LogicOp
),
109 GEN8_BLEND_LOGIC_OP_FUNCTION
);
110 } else if (ctx
->Color
.BlendEnabled
& (1 << i
) && !integer
) {
111 GLenum eqRGB
= ctx
->Color
.Blend
[i
].EquationRGB
;
112 GLenum eqA
= ctx
->Color
.Blend
[i
].EquationA
;
113 GLenum srcRGB
= ctx
->Color
.Blend
[i
].SrcRGB
;
114 GLenum dstRGB
= ctx
->Color
.Blend
[i
].DstRGB
;
115 GLenum srcA
= ctx
->Color
.Blend
[i
].SrcA
;
116 GLenum dstA
= ctx
->Color
.Blend
[i
].DstA
;
118 if (eqRGB
== GL_MIN
|| eqRGB
== GL_MAX
)
119 srcRGB
= dstRGB
= GL_ONE
;
121 if (eqA
== GL_MIN
|| eqA
== GL_MAX
)
122 srcA
= dstA
= GL_ONE
;
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.
131 if (rb
&& !_mesa_base_format_has_channel(rb
->_BaseFormat
, GL_TEXTURE_ALPHA_TYPE
)) {
132 srcRGB
= brw_fix_xRGB_alpha(srcRGB
);
133 srcA
= brw_fix_xRGB_alpha(srcA
);
134 dstRGB
= brw_fix_xRGB_alpha(dstRGB
);
135 dstA
= brw_fix_xRGB_alpha(dstA
);
139 GEN8_BLEND_COLOR_BUFFER_BLEND_ENABLE
|
140 SET_FIELD(blend_factor(dstRGB
), GEN8_BLEND_DST_BLEND_FACTOR
) |
141 SET_FIELD(blend_factor(srcRGB
), GEN8_BLEND_SRC_BLEND_FACTOR
) |
142 SET_FIELD(blend_factor(dstA
), GEN8_BLEND_DST_ALPHA_BLEND_FACTOR
) |
143 SET_FIELD(blend_factor(srcA
), GEN8_BLEND_SRC_ALPHA_BLEND_FACTOR
) |
144 SET_FIELD(blend_eqn(eqRGB
), GEN8_BLEND_COLOR_BLEND_FUNCTION
) |
145 SET_FIELD(blend_eqn(eqA
), GEN8_BLEND_ALPHA_BLEND_FUNCTION
);
147 if (srcA
!= srcRGB
|| dstA
!= dstRGB
|| eqA
!= eqRGB
)
148 blend
[0] |= GEN8_BLEND_INDEPENDENT_ALPHA_BLEND_ENABLE
;
151 /* See section 8.1.6 "Pre-Blend Color Clamping" of the
152 * SandyBridge PRM Volume 2 Part 1 for HW requirements.
154 * We do our ARB_color_buffer_float CLAMP_FRAGMENT_COLOR
155 * clamping in the fragment shader. For its clamping of
156 * blending, the spec says:
158 * "RESOLVED: For fixed-point color buffers, the inputs and
159 * the result of the blending equation are clamped. For
160 * floating-point color buffers, no clamping occurs."
162 * So, generally, we want clamping to the render target's range.
163 * And, good news, the hardware tables for both pre- and
164 * post-blend color clamping are either ignored, or any are
165 * allowed, or clamping is required but RT range clamping is a
169 GEN8_BLEND_PRE_BLEND_COLOR_CLAMP_ENABLE
|
170 GEN8_BLEND_POST_BLEND_COLOR_CLAMP_ENABLE
|
171 GEN8_BLEND_COLOR_CLAMP_RANGE_RTFORMAT
;
173 if (!ctx
->Color
.ColorMask
[i
][0])
174 blend
[1 + 2*i
] |= GEN8_BLEND_WRITE_DISABLE_RED
;
175 if (!ctx
->Color
.ColorMask
[i
][1])
176 blend
[1 + 2*i
] |= GEN8_BLEND_WRITE_DISABLE_GREEN
;
177 if (!ctx
->Color
.ColorMask
[i
][2])
178 blend
[1 + 2*i
] |= GEN8_BLEND_WRITE_DISABLE_BLUE
;
179 if (!ctx
->Color
.ColorMask
[i
][3])
180 blend
[1 + 2*i
] |= GEN8_BLEND_WRITE_DISABLE_ALPHA
;
182 /* From the BLEND_STATE docs, DWord 0, Bit 29 (AlphaToOne Enable):
183 * "If Dual Source Blending is enabled, this bit must be disabled."
185 WARN_ONCE(ctx
->Color
.Blend
[i
]._UsesDualSrc
&&
186 ctx
->Multisample
._Enabled
&&
187 ctx
->Multisample
.SampleAlphaToOne
,
188 "HW workaround: disabling alpha to one with dual src "
190 if (ctx
->Color
.Blend
[i
]._UsesDualSrc
)
191 blend
[0] &= ~GEN8_BLEND_ALPHA_TO_ONE_ENABLE
;
195 OUT_BATCH(_3DSTATE_BLEND_STATE_POINTERS
<< 16 | (2 - 2));
196 OUT_BATCH(brw
->cc
.blend_state_offset
| 1);
200 const struct brw_tracked_state gen8_blend_state
= {
202 .mesa
= _NEW_BUFFERS
|
205 .brw
= BRW_NEW_BATCH
|
206 BRW_NEW_STATE_BASE_ADDRESS
,
208 .emit
= gen8_upload_blend_state
,
212 gen8_upload_ps_blend(struct brw_context
*brw
)
214 struct gl_context
*ctx
= &brw
->ctx
;
218 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[0];
220 /* BRW_NEW_FRAGMENT_PROGRAM | _NEW_BUFFERS | _NEW_COLOR */
221 if (brw_color_buffer_write_enabled(brw
))
222 dw1
|= GEN8_PS_BLEND_HAS_WRITEABLE_RT
;
225 if (ctx
->Color
.AlphaEnabled
)
226 dw1
|= GEN8_PS_BLEND_ALPHA_TEST_ENABLE
;
228 /* _NEW_MULTISAMPLE */
229 if (ctx
->Multisample
._Enabled
&& ctx
->Multisample
.SampleAlphaToCoverage
)
230 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."
244 rb
? _mesa_get_format_datatype(rb
->Format
) : GL_UNSIGNED_NORMALIZED
;
246 if (rb
&& rb_type
!= GL_INT
&& rb_type
!= GL_UNSIGNED_INT
&&
247 (ctx
->Color
.BlendEnabled
& 1)) {
248 GLenum eqRGB
= ctx
->Color
.Blend
[0].EquationRGB
;
249 GLenum eqA
= ctx
->Color
.Blend
[0].EquationA
;
250 GLenum srcRGB
= ctx
->Color
.Blend
[0].SrcRGB
;
251 GLenum dstRGB
= ctx
->Color
.Blend
[0].DstRGB
;
252 GLenum srcA
= ctx
->Color
.Blend
[0].SrcA
;
253 GLenum dstA
= ctx
->Color
.Blend
[0].DstA
;
255 if (eqRGB
== GL_MIN
|| eqRGB
== GL_MAX
)
256 srcRGB
= dstRGB
= GL_ONE
;
258 if (eqA
== GL_MIN
|| eqA
== GL_MAX
)
259 srcA
= dstA
= GL_ONE
;
261 /* Due to hardware limitations, the destination may have information
262 * in an alpha channel even when the format specifies no alpha
263 * channel. In order to avoid getting any incorrect blending due to
264 * that alpha channel, coerce the blend factors to values that will
265 * not read the alpha channel, but will instead use the correct
266 * implicit value for alpha.
268 if (!_mesa_base_format_has_channel(rb
->_BaseFormat
, GL_TEXTURE_ALPHA_TYPE
)) {
269 srcRGB
= brw_fix_xRGB_alpha(srcRGB
);
270 srcA
= brw_fix_xRGB_alpha(srcA
);
271 dstRGB
= brw_fix_xRGB_alpha(dstRGB
);
272 dstA
= brw_fix_xRGB_alpha(dstA
);
276 GEN8_PS_BLEND_COLOR_BUFFER_BLEND_ENABLE
|
277 SET_FIELD(blend_factor(dstRGB
), GEN8_PS_BLEND_DST_BLEND_FACTOR
) |
278 SET_FIELD(blend_factor(srcRGB
), GEN8_PS_BLEND_SRC_BLEND_FACTOR
) |
279 SET_FIELD(blend_factor(dstA
), GEN8_PS_BLEND_DST_ALPHA_BLEND_FACTOR
) |
280 SET_FIELD(blend_factor(srcA
), GEN8_PS_BLEND_SRC_ALPHA_BLEND_FACTOR
);
282 if (srcA
!= srcRGB
|| dstA
!= dstRGB
|| eqA
!= eqRGB
)
283 dw1
|= GEN8_PS_BLEND_INDEPENDENT_ALPHA_BLEND_ENABLE
;
287 OUT_BATCH(_3DSTATE_PS_BLEND
<< 16 | (2 - 2));
292 const struct brw_tracked_state gen8_ps_blend
= {
294 .mesa
= _NEW_BUFFERS
|
297 .brw
= BRW_NEW_CONTEXT
|
298 BRW_NEW_FRAGMENT_PROGRAM
,
300 .emit
= gen8_upload_ps_blend