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"
34 struct brw_blend_state_key
{
35 GLboolean color_blend
, alpha_enabled
;
39 GLenum blend_eq_rgb
, blend_eq_a
;
40 GLenum blend_src_rgb
, blend_src_a
;
41 GLenum blend_dst_rgb
, blend_dst_a
;
49 blend_state_populate_key(struct brw_context
*brw
,
50 struct brw_blend_state_key
*key
)
52 GLcontext
*ctx
= &brw
->intel
.ctx
;
54 memset(key
, 0, sizeof(*key
));
57 if (ctx
->Color
._LogicOpEnabled
)
58 key
->logic_op
= ctx
->Color
.LogicOp
;
60 key
->logic_op
= GL_COPY
;
63 key
->color_blend
= ctx
->Color
.BlendEnabled
;
64 if (key
->color_blend
) {
65 key
->blend_eq_rgb
= ctx
->Color
.BlendEquationRGB
;
66 key
->blend_eq_a
= ctx
->Color
.BlendEquationA
;
67 key
->blend_src_rgb
= ctx
->Color
.BlendSrcRGB
;
68 key
->blend_dst_rgb
= ctx
->Color
.BlendDstRGB
;
69 key
->blend_src_a
= ctx
->Color
.BlendSrcA
;
70 key
->blend_dst_a
= ctx
->Color
.BlendDstA
;
74 key
->alpha_enabled
= ctx
->Color
.AlphaEnabled
;
75 if (key
->alpha_enabled
) {
76 key
->alpha_func
= ctx
->Color
.AlphaFunc
;
80 key
->dither
= ctx
->Color
.DitherFlag
;
84 * Creates the state cache entry for the given CC unit key.
87 blend_state_create_from_key(struct brw_context
*brw
,
88 struct brw_blend_state_key
*key
)
90 struct gen6_blend_state blend
;
93 memset(&blend
, 0, sizeof(blend
));
95 if (key
->logic_op
!= GL_COPY
) {
96 blend
.blend1
.logic_op_enable
= 1;
97 blend
.blend1
.logic_op_func
= intel_translate_logic_op(key
->logic_op
);
98 } else if (key
->color_blend
) {
99 GLenum eqRGB
= key
->blend_eq_rgb
;
100 GLenum eqA
= key
->blend_eq_a
;
101 GLenum srcRGB
= key
->blend_src_rgb
;
102 GLenum dstRGB
= key
->blend_dst_rgb
;
103 GLenum srcA
= key
->blend_src_a
;
104 GLenum dstA
= key
->blend_dst_a
;
106 if (eqRGB
== GL_MIN
|| eqRGB
== GL_MAX
) {
107 srcRGB
= dstRGB
= GL_ONE
;
110 if (eqA
== GL_MIN
|| eqA
== GL_MAX
) {
111 srcA
= dstA
= GL_ONE
;
114 blend
.blend0
.dest_blend_factor
= brw_translate_blend_factor(dstRGB
);
115 blend
.blend0
.source_blend_factor
= brw_translate_blend_factor(srcRGB
);
116 blend
.blend0
.blend_func
= brw_translate_blend_equation(eqRGB
);
118 blend
.blend0
.ia_dest_blend_factor
= brw_translate_blend_factor(dstA
);
119 blend
.blend0
.ia_source_blend_factor
= brw_translate_blend_factor(srcA
);
120 blend
.blend0
.ia_blend_func
= brw_translate_blend_equation(eqA
);
122 blend
.blend0
.blend_enable
= 1;
123 blend
.blend0
.ia_blend_enable
= (srcA
!= srcRGB
||
128 if (key
->alpha_enabled
) {
129 blend
.blend1
.alpha_test_enable
= 1;
130 blend
.blend1
.alpha_test_func
= intel_translate_compare_func(key
->alpha_func
);
135 blend
.blend1
.dither_enable
= 1;
136 blend
.blend1
.y_dither_offset
= 0;
137 blend
.blend1
.x_dither_offset
= 0;
140 bo
= brw_upload_cache(&brw
->cache
, BRW_BLEND_STATE
,
143 &blend
, sizeof(blend
));
149 prepare_blend_state(struct brw_context
*brw
)
151 struct brw_blend_state_key key
;
153 blend_state_populate_key(brw
, &key
);
155 drm_intel_bo_unreference(brw
->cc
.blend_state_bo
);
156 brw
->cc
.blend_state_bo
= brw_search_cache(&brw
->cache
, BRW_BLEND_STATE
,
161 if (brw
->cc
.blend_state_bo
== NULL
)
162 brw
->cc
.blend_state_bo
= blend_state_create_from_key(brw
, &key
);
165 const struct brw_tracked_state gen6_blend_state
= {
171 .prepare
= prepare_blend_state
,
174 struct brw_color_calc_state_key
{
175 GLubyte blend_constant_color
[4];
177 GLubyte stencil_ref
[2];
181 color_calc_state_populate_key(struct brw_context
*brw
,
182 struct brw_color_calc_state_key
*key
)
184 GLcontext
*ctx
= &brw
->intel
.ctx
;
186 memset(key
, 0, sizeof(*key
));
189 if (ctx
->Stencil
._Enabled
) {
190 const unsigned back
= ctx
->Stencil
._BackFace
;
192 key
->stencil_ref
[0] = ctx
->Stencil
.Ref
[0];
193 if (ctx
->Stencil
._TestTwoSide
)
194 key
->stencil_ref
[1] = ctx
->Stencil
.Ref
[back
];
198 if (ctx
->Color
.AlphaEnabled
)
199 key
->alpha_ref
= ctx
->Color
.AlphaRef
;
201 key
->blend_constant_color
[0] = ctx
->Color
.BlendColor
[0];
202 key
->blend_constant_color
[1] = ctx
->Color
.BlendColor
[1];
203 key
->blend_constant_color
[2] = ctx
->Color
.BlendColor
[2];
204 key
->blend_constant_color
[3] = ctx
->Color
.BlendColor
[3];
208 * Creates the state cache entry for the given CC state key.
210 static drm_intel_bo
*
211 color_calc_state_create_from_key(struct brw_context
*brw
,
212 struct brw_color_calc_state_key
*key
)
214 struct gen6_color_calc_state cc
;
217 memset(&cc
, 0, sizeof(cc
));
219 cc
.cc0
.alpha_test_format
= BRW_ALPHATEST_FORMAT_UNORM8
;
220 UNCLAMPED_FLOAT_TO_UBYTE(cc
.cc1
.alpha_ref_fi
.ui
, key
->alpha_ref
);
222 cc
.cc0
.stencil_ref
= key
->stencil_ref
[0];
223 cc
.cc0
.bf_stencil_ref
= key
->stencil_ref
[1];
225 cc
.constant_r
= key
->blend_constant_color
[0];
226 cc
.constant_g
= key
->blend_constant_color
[1];
227 cc
.constant_b
= key
->blend_constant_color
[2];
228 cc
.constant_a
= key
->blend_constant_color
[3];
230 bo
= brw_upload_cache(&brw
->cache
, BRW_COLOR_CALC_STATE
,
239 prepare_color_calc_state(struct brw_context
*brw
)
241 struct brw_color_calc_state_key key
;
243 color_calc_state_populate_key(brw
, &key
);
245 drm_intel_bo_unreference(brw
->cc
.state_bo
);
246 brw
->cc
.state_bo
= brw_search_cache(&brw
->cache
, BRW_COLOR_CALC_STATE
,
251 if (brw
->cc
.state_bo
== NULL
)
252 brw
->cc
.state_bo
= color_calc_state_create_from_key(brw
, &key
);
255 const struct brw_tracked_state gen6_color_calc_state
= {
261 .prepare
= prepare_color_calc_state
,
264 static void upload_cc_state_pointers(struct brw_context
*brw
)
266 struct intel_context
*intel
= &brw
->intel
;
269 OUT_BATCH(CMD_3D_CC_STATE_POINTERS
<< 16 | (4 - 2));
270 OUT_RELOC(brw
->cc
.state_bo
, I915_GEM_DOMAIN_INSTRUCTION
, 0, 1);
271 OUT_RELOC(brw
->cc
.blend_state_bo
, I915_GEM_DOMAIN_INSTRUCTION
, 0, 1);
272 OUT_RELOC(brw
->cc
.depth_stencil_state_bo
, I915_GEM_DOMAIN_INSTRUCTION
, 0, 1);
275 intel_batchbuffer_emit_mi_flush(intel
->batch
);
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
,