Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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 
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 "main/stencil.h"
39
#include "intel_batchbuffer.h"
40
 
41
static void
42
brw_upload_cc_vp(struct brw_context *brw)
43
{
44
   struct gl_context *ctx = &brw->ctx;
45
   struct brw_cc_viewport *ccv;
46
 
47
   ccv = brw_state_batch(brw, AUB_TRACE_CC_VP_STATE,
48
			 sizeof(*ccv), 32, &brw->cc.vp_offset);
49
 
50
   /* _NEW_TRANSFORM */
51
   if (ctx->Transform.DepthClamp) {
52
      /* _NEW_VIEWPORT */
53
      ccv->min_depth = MIN2(ctx->Viewport.Near, ctx->Viewport.Far);
54
      ccv->max_depth = MAX2(ctx->Viewport.Near, ctx->Viewport.Far);
55
   } else {
56
      ccv->min_depth = 0.0;
57
      ccv->max_depth = 1.0;
58
   }
59
 
60
   brw->state.dirty.cache |= CACHE_NEW_CC_VP;
61
}
62
 
63
const struct brw_tracked_state brw_cc_vp = {
64
   .dirty = {
65
      .mesa = _NEW_VIEWPORT | _NEW_TRANSFORM,
66
      .brw = BRW_NEW_BATCH,
67
      .cache = 0
68
   },
69
   .emit = brw_upload_cc_vp
70
};
71
 
72
/**
73
 * Modify blend function to force destination alpha to 1.0
74
 *
75
 * If \c function specifies a blend function that uses destination alpha,
76
 * replace it with a function that hard-wires destination alpha to 1.0.  This
77
 * is used when rendering to xRGB targets.
78
 */
79
GLenum
80
brw_fix_xRGB_alpha(GLenum function)
81
{
82
   switch (function) {
83
   case GL_DST_ALPHA:
84
      return GL_ONE;
85
 
86
   case GL_ONE_MINUS_DST_ALPHA:
87
   case GL_SRC_ALPHA_SATURATE:
88
      return GL_ZERO;
89
   }
90
 
91
   return function;
92
}
93
 
94
/**
95
 * Creates the state cache entry for the given CC unit key.
96
 */
97
static void upload_cc_unit(struct brw_context *brw)
98
{
99
   struct gl_context *ctx = &brw->ctx;
100
   struct brw_cc_unit_state *cc;
101
 
102
   cc = brw_state_batch(brw, AUB_TRACE_CC_STATE,
103
			sizeof(*cc), 64, &brw->cc.state_offset);
104
   memset(cc, 0, sizeof(*cc));
105
 
106
   /* _NEW_STENCIL | _NEW_BUFFERS */
107
   if (ctx->Stencil._Enabled) {
108
      const unsigned back = ctx->Stencil._BackFace;
109
 
110
      cc->cc0.stencil_enable = 1;
111
      cc->cc0.stencil_func =
112
	 intel_translate_compare_func(ctx->Stencil.Function[0]);
113
      cc->cc0.stencil_fail_op =
114
	 intel_translate_stencil_op(ctx->Stencil.FailFunc[0]);
115
      cc->cc0.stencil_pass_depth_fail_op =
116
	 intel_translate_stencil_op(ctx->Stencil.ZFailFunc[0]);
117
      cc->cc0.stencil_pass_depth_pass_op =
118
	 intel_translate_stencil_op(ctx->Stencil.ZPassFunc[0]);
119
      cc->cc1.stencil_ref = _mesa_get_stencil_ref(ctx, 0);
120
      cc->cc1.stencil_write_mask = ctx->Stencil.WriteMask[0];
121
      cc->cc1.stencil_test_mask = ctx->Stencil.ValueMask[0];
122
 
123
      if (ctx->Stencil._TestTwoSide) {
124
	 cc->cc0.bf_stencil_enable = 1;
125
	 cc->cc0.bf_stencil_func =
126
	    intel_translate_compare_func(ctx->Stencil.Function[back]);
127
	 cc->cc0.bf_stencil_fail_op =
128
	    intel_translate_stencil_op(ctx->Stencil.FailFunc[back]);
129
	 cc->cc0.bf_stencil_pass_depth_fail_op =
130
	    intel_translate_stencil_op(ctx->Stencil.ZFailFunc[back]);
131
	 cc->cc0.bf_stencil_pass_depth_pass_op =
132
	    intel_translate_stencil_op(ctx->Stencil.ZPassFunc[back]);
133
	 cc->cc1.bf_stencil_ref = _mesa_get_stencil_ref(ctx, back);
134
	 cc->cc2.bf_stencil_write_mask = ctx->Stencil.WriteMask[back];
135
	 cc->cc2.bf_stencil_test_mask = ctx->Stencil.ValueMask[back];
136
      }
137
 
138
      /* Not really sure about this:
139
       */
140
      if (ctx->Stencil.WriteMask[0] ||
141
	  (ctx->Stencil._TestTwoSide && ctx->Stencil.WriteMask[back]))
142
	 cc->cc0.stencil_write_enable = 1;
143
   }
144
 
145
   /* _NEW_COLOR */
146
   if (ctx->Color.ColorLogicOpEnabled && ctx->Color.LogicOp != GL_COPY) {
147
      cc->cc2.logicop_enable = 1;
148
      cc->cc5.logicop_func = intel_translate_logic_op(ctx->Color.LogicOp);
149
   } else if (ctx->Color.BlendEnabled) {
150
      GLenum eqRGB = ctx->Color.Blend[0].EquationRGB;
151
      GLenum eqA = ctx->Color.Blend[0].EquationA;
152
      GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
153
      GLenum dstRGB = ctx->Color.Blend[0].DstRGB;
154
      GLenum srcA = ctx->Color.Blend[0].SrcA;
155
      GLenum dstA = ctx->Color.Blend[0].DstA;
156
 
157
      /* If the renderbuffer is XRGB, we have to frob the blend function to
158
       * force the destination alpha to 1.0.  This means replacing GL_DST_ALPHA
159
       * with GL_ONE and GL_ONE_MINUS_DST_ALPHA with GL_ZERO.
160
       */
161
      if (ctx->DrawBuffer->Visual.alphaBits == 0) {
162
	 srcRGB = brw_fix_xRGB_alpha(srcRGB);
163
	 srcA   = brw_fix_xRGB_alpha(srcA);
164
	 dstRGB = brw_fix_xRGB_alpha(dstRGB);
165
	 dstA   = brw_fix_xRGB_alpha(dstA);
166
      }
167
 
168
      if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
169
	 srcRGB = dstRGB = GL_ONE;
170
      }
171
 
172
      if (eqA == GL_MIN || eqA == GL_MAX) {
173
	 srcA = dstA = GL_ONE;
174
      }
175
 
176
      cc->cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB);
177
      cc->cc6.src_blend_factor = brw_translate_blend_factor(srcRGB);
178
      cc->cc6.blend_function = brw_translate_blend_equation(eqRGB);
179
 
180
      cc->cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
181
      cc->cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA);
182
      cc->cc5.ia_blend_function = brw_translate_blend_equation(eqA);
183
 
184
      cc->cc3.blend_enable = 1;
185
      cc->cc3.ia_blend_enable = (srcA != srcRGB ||
186
				dstA != dstRGB ||
187
				eqA != eqRGB);
188
   }
189
 
190
   if (ctx->Color.AlphaEnabled) {
191
      cc->cc3.alpha_test = 1;
192
      cc->cc3.alpha_test_func =
193
	 intel_translate_compare_func(ctx->Color.AlphaFunc);
194
      cc->cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
195
 
196
      UNCLAMPED_FLOAT_TO_UBYTE(cc->cc7.alpha_ref.ub[0], ctx->Color.AlphaRef);
197
   }
198
 
199
   if (ctx->Color.DitherFlag) {
200
      cc->cc5.dither_enable = 1;
201
      cc->cc6.y_dither_offset = 0;
202
      cc->cc6.x_dither_offset = 0;
203
   }
204
 
205
   /* _NEW_DEPTH */
206
   if (ctx->Depth.Test) {
207
      cc->cc2.depth_test = 1;
208
      cc->cc2.depth_test_function =
209
	 intel_translate_compare_func(ctx->Depth.Func);
210
      cc->cc2.depth_write_enable = ctx->Depth.Mask;
211
   }
212
 
213
   if (brw->stats_wm || unlikely(INTEL_DEBUG & DEBUG_STATS))
214
      cc->cc5.statistics_enable = 1;
215
 
216
   /* CACHE_NEW_CC_VP */
217
   cc->cc4.cc_viewport_state_offset = (brw->batch.bo->offset +
218
				       brw->cc.vp_offset) >> 5; /* reloc */
219
 
220
   brw->state.dirty.cache |= CACHE_NEW_CC_UNIT;
221
 
222
   /* Emit CC viewport relocation */
223
   drm_intel_bo_emit_reloc(brw->batch.bo,
224
			   (brw->cc.state_offset +
225
			    offsetof(struct brw_cc_unit_state, cc4)),
226
			   brw->batch.bo, brw->cc.vp_offset,
227
			   I915_GEM_DOMAIN_INSTRUCTION, 0);
228
}
229
 
230
const struct brw_tracked_state brw_cc_unit = {
231
   .dirty = {
232
      .mesa = _NEW_STENCIL | _NEW_COLOR | _NEW_DEPTH | _NEW_BUFFERS,
233
      .brw = BRW_NEW_BATCH | BRW_NEW_STATS_WM,
234
      .cache = CACHE_NEW_CC_VP
235
   },
236
   .emit = upload_cc_unit,
237
};
238
 
239
static void upload_blend_constant_color(struct brw_context *brw)
240
{
241
   struct gl_context *ctx = &brw->ctx;
242
 
243
   BEGIN_BATCH(5);
244
   OUT_BATCH(_3DSTATE_BLEND_CONSTANT_COLOR << 16 | (5-2));
245
   OUT_BATCH_F(ctx->Color.BlendColorUnclamped[0]);
246
   OUT_BATCH_F(ctx->Color.BlendColorUnclamped[1]);
247
   OUT_BATCH_F(ctx->Color.BlendColorUnclamped[2]);
248
   OUT_BATCH_F(ctx->Color.BlendColorUnclamped[3]);
249
   CACHED_BATCH();
250
}
251
 
252
const struct brw_tracked_state brw_blend_constant_color = {
253
   .dirty = {
254
      .mesa = _NEW_COLOR,
255
      .brw = BRW_NEW_CONTEXT,
256
      .cache = 0
257
   },
258
   .emit = upload_blend_constant_color
259
};