Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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