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 |