2 * Copyright © 2009 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 * Eric Anholt <eric@anholt.net>
28 #include "brw_context.h"
29 #include "brw_state.h"
30 #include "brw_defines.h"
32 #include "intel_batchbuffer.h"
33 #include "main/macros.h"
34 #include "main/enums.h"
36 struct brw_blend_state_key
{
37 GLboolean color_blend
, alpha_enabled
;
41 GLenum blend_eq_rgb
, blend_eq_a
;
42 GLenum blend_src_rgb
, blend_src_a
;
43 GLenum blend_dst_rgb
, blend_dst_a
;
51 blend_state_populate_key(struct brw_context
*brw
,
52 struct brw_blend_state_key
*key
)
54 GLcontext
*ctx
= &brw
->intel
.ctx
;
56 memset(key
, 0, sizeof(*key
));
59 if (ctx
->Color
._LogicOpEnabled
)
60 key
->logic_op
= ctx
->Color
.LogicOp
;
62 key
->logic_op
= GL_COPY
;
65 key
->color_blend
= ctx
->Color
.BlendEnabled
;
66 if (key
->color_blend
) {
67 key
->blend_eq_rgb
= ctx
->Color
.BlendEquationRGB
;
68 key
->blend_eq_a
= ctx
->Color
.BlendEquationA
;
69 key
->blend_src_rgb
= ctx
->Color
.BlendSrcRGB
;
70 key
->blend_dst_rgb
= ctx
->Color
.BlendDstRGB
;
71 key
->blend_src_a
= ctx
->Color
.BlendSrcA
;
72 key
->blend_dst_a
= ctx
->Color
.BlendDstA
;
76 key
->alpha_enabled
= ctx
->Color
.AlphaEnabled
;
77 if (key
->alpha_enabled
) {
78 key
->alpha_func
= ctx
->Color
.AlphaFunc
;
82 key
->dither
= ctx
->Color
.DitherFlag
;
86 * Creates the state cache entry for the given CC unit key.
89 blend_state_create_from_key(struct brw_context
*brw
,
90 struct brw_blend_state_key
*key
)
92 struct gen6_blend_state blend
;
95 memset(&blend
, 0, sizeof(blend
));
97 if (key
->logic_op
!= GL_COPY
) {
98 blend
.blend1
.logic_op_enable
= 1;
99 blend
.blend1
.logic_op_func
= intel_translate_logic_op(key
->logic_op
);
100 } else if (key
->color_blend
) {
101 GLenum eqRGB
= key
->blend_eq_rgb
;
102 GLenum eqA
= key
->blend_eq_a
;
103 GLenum srcRGB
= key
->blend_src_rgb
;
104 GLenum dstRGB
= key
->blend_dst_rgb
;
105 GLenum srcA
= key
->blend_src_a
;
106 GLenum dstA
= key
->blend_dst_a
;
108 if (eqRGB
== GL_MIN
|| eqRGB
== GL_MAX
) {
109 srcRGB
= dstRGB
= GL_ONE
;
112 if (eqA
== GL_MIN
|| eqA
== GL_MAX
) {
113 srcA
= dstA
= GL_ONE
;
116 blend
.blend0
.dest_blend_factor
= brw_translate_blend_factor(dstRGB
);
117 blend
.blend0
.source_blend_factor
= brw_translate_blend_factor(srcRGB
);
118 blend
.blend0
.blend_func
= brw_translate_blend_equation(eqRGB
);
120 blend
.blend0
.ia_dest_blend_factor
= brw_translate_blend_factor(dstA
);
121 blend
.blend0
.ia_source_blend_factor
= brw_translate_blend_factor(srcA
);
122 blend
.blend0
.ia_blend_func
= brw_translate_blend_equation(eqA
);
124 blend
.blend0
.blend_enable
= 1;
125 blend
.blend0
.ia_blend_enable
= (srcA
!= srcRGB
||
130 if (key
->alpha_enabled
) {
131 blend
.blend1
.alpha_test_enable
= 1;
132 blend
.blend1
.alpha_test_func
= intel_translate_compare_func(key
->alpha_func
);
137 blend
.blend1
.dither_enable
= 1;
138 blend
.blend1
.y_dither_offset
= 0;
139 blend
.blend1
.x_dither_offset
= 0;
142 bo
= brw_upload_cache(&brw
->cache
, BRW_BLEND_STATE
,
145 &blend
, sizeof(blend
));
151 prepare_blend_state(struct brw_context
*brw
)
153 struct brw_blend_state_key key
;
155 blend_state_populate_key(brw
, &key
);
157 drm_intel_bo_unreference(brw
->cc
.blend_state_bo
);
158 brw
->cc
.blend_state_bo
= brw_search_cache(&brw
->cache
, BRW_BLEND_STATE
,
163 if (brw
->cc
.blend_state_bo
== NULL
)
164 brw
->cc
.blend_state_bo
= blend_state_create_from_key(brw
, &key
);
167 const struct brw_tracked_state gen6_blend_state
= {
173 .prepare
= prepare_blend_state
,
176 struct brw_color_calc_state_key
{
177 GLubyte blend_constant_color
[4];
179 GLubyte stencil_ref
[2];
183 color_calc_state_populate_key(struct brw_context
*brw
,
184 struct brw_color_calc_state_key
*key
)
186 GLcontext
*ctx
= &brw
->intel
.ctx
;
188 memset(key
, 0, sizeof(*key
));
191 if (ctx
->Stencil
._Enabled
) {
192 const unsigned back
= ctx
->Stencil
._BackFace
;
194 key
->stencil_ref
[0] = ctx
->Stencil
.Ref
[0];
195 if (ctx
->Stencil
._TestTwoSide
)
196 key
->stencil_ref
[1] = ctx
->Stencil
.Ref
[back
];
200 if (ctx
->Color
.AlphaEnabled
)
201 key
->alpha_ref
= ctx
->Color
.AlphaRef
;
203 key
->blend_constant_color
[0] = ctx
->Color
.BlendColor
[0];
204 key
->blend_constant_color
[1] = ctx
->Color
.BlendColor
[1];
205 key
->blend_constant_color
[2] = ctx
->Color
.BlendColor
[2];
206 key
->blend_constant_color
[3] = ctx
->Color
.BlendColor
[3];
210 * Creates the state cache entry for the given CC state key.
212 static drm_intel_bo
*
213 color_calc_state_create_from_key(struct brw_context
*brw
,
214 struct brw_color_calc_state_key
*key
)
216 struct gen6_color_calc_state cc
;
219 memset(&cc
, 0, sizeof(cc
));
221 cc
.cc0
.alpha_test_format
= BRW_ALPHATEST_FORMAT_UNORM8
;
222 UNCLAMPED_FLOAT_TO_UBYTE(cc
.cc1
.alpha_ref_fi
.ui
, key
->alpha_ref
);
224 cc
.cc0
.stencil_ref
= key
->stencil_ref
[0];
225 cc
.cc0
.bf_stencil_ref
= key
->stencil_ref
[1];
227 cc
.constant_r
= key
->blend_constant_color
[0];
228 cc
.constant_g
= key
->blend_constant_color
[1];
229 cc
.constant_b
= key
->blend_constant_color
[2];
230 cc
.constant_a
= key
->blend_constant_color
[3];
232 bo
= brw_upload_cache(&brw
->cache
, BRW_COLOR_CALC_STATE
,
241 prepare_color_calc_state(struct brw_context
*brw
)
243 struct brw_color_calc_state_key key
;
245 color_calc_state_populate_key(brw
, &key
);
247 drm_intel_bo_unreference(brw
->cc
.state_bo
);
248 brw
->cc
.state_bo
= brw_search_cache(&brw
->cache
, BRW_COLOR_CALC_STATE
,
253 if (brw
->cc
.state_bo
== NULL
)
254 brw
->cc
.state_bo
= color_calc_state_create_from_key(brw
, &key
);
257 const struct brw_tracked_state gen6_color_calc_state
= {
263 .prepare
= prepare_color_calc_state
,
266 static void upload_cc_state_pointers(struct brw_context
*brw
)
268 struct intel_context
*intel
= &brw
->intel
;
271 OUT_BATCH(CMD_3D_CC_STATE_POINTERS
<< 16 | (4 - 2));
272 OUT_RELOC(brw
->cc
.state_bo
, I915_GEM_DOMAIN_INSTRUCTION
, 0, 1);
273 OUT_RELOC(brw
->cc
.blend_state_bo
, I915_GEM_DOMAIN_INSTRUCTION
, 0, 1);
274 OUT_RELOC(brw
->cc
.depth_stencil_state_bo
, I915_GEM_DOMAIN_INSTRUCTION
, 0, 1);
279 static void prepare_cc_state_pointers(struct brw_context
*brw
)
281 brw_add_validated_bo(brw
, brw
->cc
.state_bo
);
282 brw_add_validated_bo(brw
, brw
->cc
.blend_state_bo
);
283 brw_add_validated_bo(brw
, brw
->cc
.depth_stencil_state_bo
);
286 const struct brw_tracked_state gen6_cc_state_pointers
= {
289 .brw
= BRW_NEW_BATCH
,
290 .cache
= (CACHE_NEW_BLEND_STATE
|
291 CACHE_NEW_COLOR_CALC_STATE
|
292 CACHE_NEW_DEPTH_STENCIL_STATE
)
294 .prepare
= prepare_cc_state_pointers
,
295 .emit
= upload_cc_state_pointers
,