brw_cc.c revision aac120977d1ead319141d48d65c9bba626ec03b8
1/* 2 Copyright (C) Intel Corp. 2006. All Rights Reserved. 3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to 4 develop this 3D driver. 5 6 Permission is hereby granted, free of charge, to any person obtaining 7 a copy of this software and associated documentation files (the 8 "Software"), to deal in the Software without restriction, including 9 without limitation the rights to use, copy, modify, merge, publish, 10 distribute, sublicense, and/or sell copies of the Software, and to 11 permit persons to whom the Software is furnished to do so, subject to 12 the following conditions: 13 14 The above copyright notice and this permission notice (including the 15 next paragraph) shall be included in all copies or substantial 16 portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 26 **********************************************************************/ 27 /* 28 * Authors: 29 * Keith Whitwell <keith@tungstengraphics.com> 30 */ 31 32 33#include "brw_context.h" 34#include "brw_state.h" 35#include "brw_defines.h" 36#include "brw_util.h" 37#include "main/macros.h" 38#include "intel_batchbuffer.h" 39 40void 41brw_update_cc_vp(struct brw_context *brw) 42{ 43 struct gl_context *ctx = &brw->intel.ctx; 44 struct brw_cc_viewport ccv; 45 46 memset(&ccv, 0, sizeof(ccv)); 47 48 /* _NEW_TRANSOFORM */ 49 if (ctx->Transform.DepthClamp) { 50 /* _NEW_VIEWPORT */ 51 ccv.min_depth = MIN2(ctx->Viewport.Near, ctx->Viewport.Far); 52 ccv.max_depth = MAX2(ctx->Viewport.Near, ctx->Viewport.Far); 53 } else { 54 ccv.min_depth = 0.0; 55 ccv.max_depth = 1.0; 56 } 57 58 drm_intel_bo_unreference(brw->cc.vp_bo); 59 brw->cc.vp_bo = brw_cache_data(&brw->cache, BRW_CC_VP, &ccv, sizeof(ccv)); 60} 61 62/** 63 * Modify blend function to force destination alpha to 1.0 64 * 65 * If \c function specifies a blend function that uses destination alpha, 66 * replace it with a function that hard-wires destination alpha to 1.0. This 67 * is used when rendering to xRGB targets. 68 */ 69static GLenum 70fix_xRGB_alpha(GLenum function) 71{ 72 switch (function) { 73 case GL_DST_ALPHA: 74 return GL_ONE; 75 76 case GL_ONE_MINUS_DST_ALPHA: 77 case GL_SRC_ALPHA_SATURATE: 78 return GL_ZERO; 79 } 80 81 return function; 82} 83 84static void prepare_cc_unit(struct brw_context *brw) 85{ 86 brw_add_validated_bo(brw, brw->cc.vp_bo); 87} 88 89/** 90 * Creates the state cache entry for the given CC unit key. 91 */ 92static void upload_cc_unit(struct brw_context *brw) 93{ 94 struct intel_context *intel = &brw->intel; 95 struct gl_context *ctx = &brw->intel.ctx; 96 struct brw_cc_unit_state *cc; 97 98 cc = brw_state_batch(brw, sizeof(*cc), 64, &brw->cc.state_offset); 99 memset(cc, 0, sizeof(*cc)); 100 101 /* _NEW_STENCIL */ 102 if (ctx->Stencil._Enabled) { 103 const unsigned back = ctx->Stencil._BackFace; 104 105 cc->cc0.stencil_enable = 1; 106 cc->cc0.stencil_func = 107 intel_translate_compare_func(ctx->Stencil.Function[0]); 108 cc->cc0.stencil_fail_op = 109 intel_translate_stencil_op(ctx->Stencil.FailFunc[0]); 110 cc->cc0.stencil_pass_depth_fail_op = 111 intel_translate_stencil_op(ctx->Stencil.ZFailFunc[0]); 112 cc->cc0.stencil_pass_depth_pass_op = 113 intel_translate_stencil_op(ctx->Stencil.ZPassFunc[0]); 114 cc->cc1.stencil_ref = ctx->Stencil.Ref[0]; 115 cc->cc1.stencil_write_mask = ctx->Stencil.WriteMask[0]; 116 cc->cc1.stencil_test_mask = ctx->Stencil.ValueMask[0]; 117 118 if (ctx->Stencil._TestTwoSide) { 119 cc->cc0.bf_stencil_enable = 1; 120 cc->cc0.bf_stencil_func = 121 intel_translate_compare_func(ctx->Stencil.Function[back]); 122 cc->cc0.bf_stencil_fail_op = 123 intel_translate_stencil_op(ctx->Stencil.FailFunc[back]); 124 cc->cc0.bf_stencil_pass_depth_fail_op = 125 intel_translate_stencil_op(ctx->Stencil.ZFailFunc[back]); 126 cc->cc0.bf_stencil_pass_depth_pass_op = 127 intel_translate_stencil_op(ctx->Stencil.ZPassFunc[back]); 128 cc->cc1.bf_stencil_ref = ctx->Stencil.Ref[back]; 129 cc->cc2.bf_stencil_write_mask = ctx->Stencil.WriteMask[back]; 130 cc->cc2.bf_stencil_test_mask = ctx->Stencil.ValueMask[back]; 131 } 132 133 /* Not really sure about this: 134 */ 135 if (ctx->Stencil.WriteMask[0] || 136 (ctx->Stencil._TestTwoSide && ctx->Stencil.WriteMask[back])) 137 cc->cc0.stencil_write_enable = 1; 138 } 139 140 /* _NEW_COLOR */ 141 if (ctx->Color._LogicOpEnabled && ctx->Color.LogicOp != GL_COPY) { 142 cc->cc2.logicop_enable = 1; 143 cc->cc5.logicop_func = intel_translate_logic_op(ctx->Color.LogicOp); 144 } else if (ctx->Color.BlendEnabled) { 145 GLenum eqRGB = ctx->Color.Blend[0].EquationRGB; 146 GLenum eqA = ctx->Color.Blend[0].EquationA; 147 GLenum srcRGB = ctx->Color.Blend[0].SrcRGB; 148 GLenum dstRGB = ctx->Color.Blend[0].DstRGB; 149 GLenum srcA = ctx->Color.Blend[0].SrcA; 150 GLenum dstA = ctx->Color.Blend[0].DstA; 151 152 /* If the renderbuffer is XRGB, we have to frob the blend function to 153 * force the destination alpha to 1.0. This means replacing GL_DST_ALPHA 154 * with GL_ONE and GL_ONE_MINUS_DST_ALPHA with GL_ZERO. 155 */ 156 if (ctx->DrawBuffer->Visual.alphaBits == 0) { 157 srcRGB = fix_xRGB_alpha(srcRGB); 158 srcA = fix_xRGB_alpha(srcA); 159 dstRGB = fix_xRGB_alpha(dstRGB); 160 dstA = fix_xRGB_alpha(dstA); 161 } 162 163 if (eqRGB == GL_MIN || eqRGB == GL_MAX) { 164 srcRGB = dstRGB = GL_ONE; 165 } 166 167 if (eqA == GL_MIN || eqA == GL_MAX) { 168 srcA = dstA = GL_ONE; 169 } 170 171 cc->cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB); 172 cc->cc6.src_blend_factor = brw_translate_blend_factor(srcRGB); 173 cc->cc6.blend_function = brw_translate_blend_equation(eqRGB); 174 175 cc->cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA); 176 cc->cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA); 177 cc->cc5.ia_blend_function = brw_translate_blend_equation(eqA); 178 179 cc->cc3.blend_enable = 1; 180 cc->cc3.ia_blend_enable = (srcA != srcRGB || 181 dstA != dstRGB || 182 eqA != eqRGB); 183 } 184 185 if (ctx->Color.AlphaEnabled) { 186 cc->cc3.alpha_test = 1; 187 cc->cc3.alpha_test_func = 188 intel_translate_compare_func(ctx->Color.AlphaFunc); 189 cc->cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8; 190 191 UNCLAMPED_FLOAT_TO_UBYTE(cc->cc7.alpha_ref.ub[0], ctx->Color.AlphaRef); 192 } 193 194 if (ctx->Color.DitherFlag) { 195 cc->cc5.dither_enable = 1; 196 cc->cc6.y_dither_offset = 0; 197 cc->cc6.x_dither_offset = 0; 198 } 199 200 /* _NEW_DEPTH */ 201 if (ctx->Depth.Test) { 202 cc->cc2.depth_test = 1; 203 cc->cc2.depth_test_function = 204 intel_translate_compare_func(ctx->Depth.Func); 205 cc->cc2.depth_write_enable = ctx->Depth.Mask; 206 } 207 208 if (intel->stats_wm || unlikely(INTEL_DEBUG & DEBUG_STATS)) 209 cc->cc5.statistics_enable = 1; 210 211 /* CACHE_NEW_CC_VP */ 212 cc->cc4.cc_viewport_state_offset = brw->cc.vp_bo->offset >> 5; /* reloc */ 213 214 brw->state.dirty.cache |= CACHE_NEW_CC_UNIT; 215 216 /* Emit CC viewport relocation */ 217 drm_intel_bo_emit_reloc(brw->intel.batch.bo, 218 (brw->cc.state_offset + 219 offsetof(struct brw_cc_unit_state, cc4)), 220 brw->cc.vp_bo, 0, 221 I915_GEM_DOMAIN_INSTRUCTION, 0); 222} 223 224const struct brw_tracked_state brw_cc_unit = { 225 .dirty = { 226 .mesa = _NEW_STENCIL | _NEW_COLOR | _NEW_DEPTH, 227 .brw = BRW_NEW_BATCH, 228 .cache = CACHE_NEW_CC_VP 229 }, 230 .prepare = prepare_cc_unit, 231 .emit = upload_cc_unit, 232}; 233 234static void upload_blend_constant_color(struct brw_context *brw) 235{ 236 struct intel_context *intel = &brw->intel; 237 struct gl_context *ctx = &intel->ctx; 238 239 BEGIN_BATCH(5); 240 OUT_BATCH(_3DSTATE_BLEND_CONSTANT_COLOR << 16 | (5-2)); 241 OUT_BATCH(ctx->Color.BlendColor[0]); 242 OUT_BATCH(ctx->Color.BlendColor[1]); 243 OUT_BATCH(ctx->Color.BlendColor[2]); 244 OUT_BATCH(ctx->Color.BlendColor[3]); 245 CACHED_BATCH(); 246} 247 248const struct brw_tracked_state brw_blend_constant_color = { 249 .dirty = { 250 .mesa = _NEW_COLOR, 251 .brw = BRW_NEW_CONTEXT, 252 .cache = 0 253 }, 254 .emit = upload_blend_constant_color 255}; 256