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