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
 
34
#include "intel_fbo.h"
35
#include "brw_context.h"
36
#include "brw_state.h"
37
#include "brw_defines.h"
38
#include "brw_wm.h"
39
 
40
/***********************************************************************
41
 * WM unit - fragment programs and rasterization
42
 */
43
 
44
bool
45
brw_color_buffer_write_enabled(struct brw_context *brw)
46
{
47
   struct gl_context *ctx = &brw->ctx;
48
   const struct gl_fragment_program *fp = brw->fragment_program;
49
   int i;
50
 
51
   /* _NEW_BUFFERS */
52
   for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
53
      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
54
 
55
      /* _NEW_COLOR */
56
      if (rb &&
57
	  (fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR) ||
58
	   fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DATA0 + i)) &&
59
	  (ctx->Color.ColorMask[i][0] ||
60
	   ctx->Color.ColorMask[i][1] ||
61
	   ctx->Color.ColorMask[i][2] ||
62
	   ctx->Color.ColorMask[i][3])) {
63
	 return true;
64
      }
65
   }
66
 
67
   return false;
68
}
69
 
70
/**
71
 * Setup wm hardware state.  See page 225 of Volume 2
72
 */
73
static void
74
brw_upload_wm_unit(struct brw_context *brw)
75
{
76
   struct gl_context *ctx = &brw->ctx;
77
   const struct gl_fragment_program *fp = brw->fragment_program;
78
   struct brw_wm_unit_state *wm;
79
 
80
   wm = brw_state_batch(brw, AUB_TRACE_WM_STATE,
81
			sizeof(*wm), 32, &brw->wm.state_offset);
82
   memset(wm, 0, sizeof(*wm));
83
 
84
   if (brw->wm.prog_data->prog_offset_16) {
85
      /* These two fields should be the same pre-gen6, which is why we
86
       * only have one hardware field to program for both dispatch
87
       * widths.
88
       */
89
      assert(brw->wm.prog_data->first_curbe_grf ==
90
	     brw->wm.prog_data->first_curbe_grf_16);
91
   }
92
 
93
   /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_WM_PROG */
94
   wm->thread0.grf_reg_count = brw->wm.prog_data->reg_blocks;
95
   wm->wm9.grf_reg_count_2 = brw->wm.prog_data->reg_blocks_16;
96
 
97
   wm->thread0.kernel_start_pointer =
98
      brw_program_reloc(brw,
99
			brw->wm.state_offset +
100
			offsetof(struct brw_wm_unit_state, thread0),
101
			brw->wm.prog_offset +
102
			(wm->thread0.grf_reg_count << 1)) >> 6;
103
 
104
   wm->wm9.kernel_start_pointer_2 =
105
      brw_program_reloc(brw,
106
			brw->wm.state_offset +
107
			offsetof(struct brw_wm_unit_state, wm9),
108
			brw->wm.prog_offset +
109
			brw->wm.prog_data->prog_offset_16 +
110
			(wm->wm9.grf_reg_count_2 << 1)) >> 6;
111
 
112
   wm->thread1.depth_coef_urb_read_offset = 1;
113
   /* Use ALT floating point mode for ARB fragment programs, because they
114
    * require 0^0 == 1.  Even though _CurrentFragmentProgram is used for
115
    * rendering, CurrentFragmentProgram is used for this check to
116
    * differentiate between the GLSL and non-GLSL cases.
117
    */
118
   if (ctx->Shader.CurrentFragmentProgram == NULL)
119
      wm->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
120
   else
121
      wm->thread1.floating_point_mode = BRW_FLOATING_POINT_IEEE_754;
122
 
123
   wm->thread1.binding_table_entry_count = 0;
124
 
125
   if (brw->wm.prog_data->total_scratch != 0) {
126
      wm->thread2.scratch_space_base_pointer =
127
	 brw->wm.scratch_bo->offset >> 10; /* reloc */
128
      wm->thread2.per_thread_scratch_space =
129
	 ffs(brw->wm.prog_data->total_scratch) - 11;
130
   } else {
131
      wm->thread2.scratch_space_base_pointer = 0;
132
      wm->thread2.per_thread_scratch_space = 0;
133
   }
134
 
135
   wm->thread3.dispatch_grf_start_reg = brw->wm.prog_data->first_curbe_grf;
136
   wm->thread3.urb_entry_read_length = brw->wm.prog_data->urb_read_length;
137
   wm->thread3.urb_entry_read_offset = 0;
138
   wm->thread3.const_urb_entry_read_length =
139
      brw->wm.prog_data->curb_read_length;
140
   /* BRW_NEW_CURBE_OFFSETS */
141
   wm->thread3.const_urb_entry_read_offset = brw->curbe.wm_start * 2;
142
 
143
   if (brw->gen == 5)
144
      wm->wm4.sampler_count = 0; /* hardware requirement */
145
   else {
146
      /* CACHE_NEW_SAMPLER */
147
      wm->wm4.sampler_count = (brw->sampler.count + 1) / 4;
148
   }
149
 
150
   if (brw->sampler.count) {
151
      /* reloc */
152
      wm->wm4.sampler_state_pointer = (brw->batch.bo->offset +
153
				       brw->sampler.offset) >> 5;
154
   } else {
155
      wm->wm4.sampler_state_pointer = 0;
156
   }
157
 
158
   /* BRW_NEW_FRAGMENT_PROGRAM */
159
   wm->wm5.program_uses_depth = (fp->Base.InputsRead &
160
				 (1 << VARYING_SLOT_POS)) != 0;
161
   wm->wm5.program_computes_depth = (fp->Base.OutputsWritten &
162
				     BITFIELD64_BIT(FRAG_RESULT_DEPTH)) != 0;
163
   /* _NEW_BUFFERS
164
    * Override for NULL depthbuffer case, required by the Pixel Shader Computed
165
    * Depth field.
166
    */
167
   if (!intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_DEPTH))
168
      wm->wm5.program_computes_depth = 0;
169
 
170
   /* _NEW_COLOR */
171
   wm->wm5.program_uses_killpixel = fp->UsesKill || ctx->Color.AlphaEnabled;
172
 
173
   wm->wm5.enable_8_pix = 1;
174
   if (brw->wm.prog_data->prog_offset_16)
175
      wm->wm5.enable_16_pix = 1;
176
 
177
   wm->wm5.max_threads = brw->max_wm_threads - 1;
178
 
179
   /* _NEW_BUFFERS | _NEW_COLOR */
180
   if (brw_color_buffer_write_enabled(brw) ||
181
       wm->wm5.program_uses_killpixel ||
182
       wm->wm5.program_computes_depth) {
183
      wm->wm5.thread_dispatch_enable = 1;
184
   }
185
 
186
   wm->wm5.legacy_line_rast = 0;
187
   wm->wm5.legacy_global_depth_bias = 0;
188
   wm->wm5.early_depth_test = 1;	        /* never need to disable */
189
   wm->wm5.line_aa_region_width = 0;
190
   wm->wm5.line_endcap_aa_region_width = 1;
191
 
192
   /* _NEW_POLYGONSTIPPLE */
193
   wm->wm5.polygon_stipple = ctx->Polygon.StippleFlag;
194
 
195
   /* _NEW_POLYGON */
196
   if (ctx->Polygon.OffsetFill) {
197
      wm->wm5.depth_offset = 1;
198
      /* Something wierd going on with legacy_global_depth_bias,
199
       * offset_constant, scaling and MRD.  This value passes glean
200
       * but gives some odd results elsewere (eg. the
201
       * quad-offset-units test).
202
       */
203
      wm->global_depth_offset_constant = ctx->Polygon.OffsetUnits * 2;
204
 
205
      /* This is the only value that passes glean:
206
       */
207
      wm->global_depth_offset_scale = ctx->Polygon.OffsetFactor;
208
   }
209
 
210
   /* _NEW_LINE */
211
   wm->wm5.line_stipple = ctx->Line.StippleFlag;
212
 
213
   /* BRW_NEW_STATS_WM */
214
   if (unlikely(INTEL_DEBUG & DEBUG_STATS) || brw->stats_wm)
215
      wm->wm4.stats_enable = 1;
216
 
217
   /* Emit scratch space relocation */
218
   if (brw->wm.prog_data->total_scratch != 0) {
219
      drm_intel_bo_emit_reloc(brw->batch.bo,
220
			      brw->wm.state_offset +
221
			      offsetof(struct brw_wm_unit_state, thread2),
222
			      brw->wm.scratch_bo,
223
			      wm->thread2.per_thread_scratch_space,
224
			      I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
225
   }
226
 
227
   /* Emit sampler state relocation */
228
   if (brw->sampler.count != 0) {
229
      drm_intel_bo_emit_reloc(brw->batch.bo,
230
			      brw->wm.state_offset +
231
			      offsetof(struct brw_wm_unit_state, wm4),
232
			      brw->batch.bo, (brw->sampler.offset |
233
						wm->wm4.stats_enable |
234
						(wm->wm4.sampler_count << 2)),
235
			      I915_GEM_DOMAIN_INSTRUCTION, 0);
236
   }
237
 
238
   brw->state.dirty.cache |= CACHE_NEW_WM_UNIT;
239
}
240
 
241
const struct brw_tracked_state brw_wm_unit = {
242
   .dirty = {
243
      .mesa = (_NEW_POLYGON |
244
	       _NEW_POLYGONSTIPPLE |
245
	       _NEW_LINE |
246
	       _NEW_COLOR |
247
	       _NEW_BUFFERS),
248
 
249
      .brw = (BRW_NEW_BATCH |
250
	      BRW_NEW_PROGRAM_CACHE |
251
	      BRW_NEW_FRAGMENT_PROGRAM |
252
	      BRW_NEW_CURBE_OFFSETS |
253
              BRW_NEW_STATS_WM),
254
 
255
      .cache = (CACHE_NEW_WM_PROG |
256
		CACHE_NEW_SAMPLER)
257
   },
258
   .emit = brw_upload_wm_unit,
259
};
260