Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /* |
2 | * Copyright © 2011 Intel Corporation |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
5 | * copy of this software and associated documentation files (the "Software"), |
||
6 | * to deal in the Software without restriction, including without limitation |
||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
8 | * and/or sell copies of the Software, and to permit persons to whom the |
||
9 | * Software is furnished to do so, subject to the following conditions: |
||
10 | * |
||
11 | * The above copyright notice and this permission notice (including the next |
||
12 | * paragraph) shall be included in all copies or substantial portions of the |
||
13 | * Software. |
||
14 | * |
||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||
21 | * IN THE SOFTWARE. |
||
22 | */ |
||
23 | |||
24 | #include |
||
25 | |||
26 | #include "intel_batchbuffer.h" |
||
27 | #include "intel_fbo.h" |
||
28 | #include "intel_mipmap_tree.h" |
||
29 | |||
30 | #include "brw_context.h" |
||
31 | #include "brw_defines.h" |
||
32 | #include "brw_state.h" |
||
33 | |||
34 | #include "brw_blorp.h" |
||
35 | #include "gen6_blorp.h" |
||
36 | |||
37 | /** |
||
38 | * \name Constants for BLORP VBO |
||
39 | * \{ |
||
40 | */ |
||
41 | #define GEN6_BLORP_NUM_VERTICES 3 |
||
42 | #define GEN6_BLORP_NUM_VUE_ELEMS 8 |
||
43 | #define GEN6_BLORP_VBO_SIZE (GEN6_BLORP_NUM_VERTICES \ |
||
44 | * GEN6_BLORP_NUM_VUE_ELEMS \ |
||
45 | * sizeof(float)) |
||
46 | /** \} */ |
||
47 | |||
48 | void |
||
49 | gen6_blorp_emit_batch_head(struct brw_context *brw, |
||
50 | const brw_blorp_params *params) |
||
51 | { |
||
52 | struct gl_context *ctx = &brw->ctx; |
||
53 | |||
54 | /* To ensure that the batch contains only the resolve, flush the batch |
||
55 | * before beginning and after finishing emitting the resolve packets. |
||
56 | */ |
||
57 | intel_flush(ctx); |
||
58 | } |
||
59 | |||
60 | |||
61 | /** |
||
62 | * CMD_STATE_BASE_ADDRESS |
||
63 | * |
||
64 | * From the Sandy Bridge PRM, Volume 1, Part 1, Table STATE_BASE_ADDRESS: |
||
65 | * The following commands must be reissued following any change to the |
||
66 | * base addresses: |
||
67 | * 3DSTATE_CC_POINTERS |
||
68 | * 3DSTATE_BINDING_TABLE_POINTERS |
||
69 | * 3DSTATE_SAMPLER_STATE_POINTERS |
||
70 | * 3DSTATE_VIEWPORT_STATE_POINTERS |
||
71 | * MEDIA_STATE_POINTERS |
||
72 | */ |
||
73 | void |
||
74 | gen6_blorp_emit_state_base_address(struct brw_context *brw, |
||
75 | const brw_blorp_params *params) |
||
76 | { |
||
77 | BEGIN_BATCH(10); |
||
78 | OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (10 - 2)); |
||
79 | OUT_BATCH(1); /* GeneralStateBaseAddressModifyEnable */ |
||
80 | /* SurfaceStateBaseAddress */ |
||
81 | OUT_RELOC(brw->batch.bo, I915_GEM_DOMAIN_SAMPLER, 0, 1); |
||
82 | /* DynamicStateBaseAddress */ |
||
83 | OUT_RELOC(brw->batch.bo, (I915_GEM_DOMAIN_RENDER | |
||
84 | I915_GEM_DOMAIN_INSTRUCTION), 0, 1); |
||
85 | OUT_BATCH(1); /* IndirectObjectBaseAddress */ |
||
86 | if (params->use_wm_prog) { |
||
87 | OUT_RELOC(brw->cache.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, |
||
88 | 1); /* Instruction base address: shader kernels */ |
||
89 | } else { |
||
90 | OUT_BATCH(1); /* InstructionBaseAddress */ |
||
91 | } |
||
92 | OUT_BATCH(1); /* GeneralStateUpperBound */ |
||
93 | /* Dynamic state upper bound. Although the documentation says that |
||
94 | * programming it to zero will cause it to be ignored, that is a lie. |
||
95 | * If this isn't programmed to a real bound, the sampler border color |
||
96 | * pointer is rejected, causing border color to mysteriously fail. |
||
97 | */ |
||
98 | OUT_BATCH(0xfffff001); |
||
99 | OUT_BATCH(1); /* IndirectObjectUpperBound*/ |
||
100 | OUT_BATCH(1); /* InstructionAccessUpperBound */ |
||
101 | ADVANCE_BATCH(); |
||
102 | } |
||
103 | |||
104 | |||
105 | void |
||
106 | gen6_blorp_emit_vertices(struct brw_context *brw, |
||
107 | const brw_blorp_params *params) |
||
108 | { |
||
109 | uint32_t vertex_offset; |
||
110 | |||
111 | /* Setup VBO for the rectangle primitive.. |
||
112 | * |
||
113 | * A rectangle primitive (3DPRIM_RECTLIST) consists of only three |
||
114 | * vertices. The vertices reside in screen space with DirectX coordinates |
||
115 | * (that is, (0, 0) is the upper left corner). |
||
116 | * |
||
117 | * v2 ------ implied |
||
118 | * | | |
||
119 | * | | |
||
120 | * v0 ----- v1 |
||
121 | * |
||
122 | * Since the VS is disabled, the clipper loads each VUE directly from |
||
123 | * the URB. This is controlled by the 3DSTATE_VERTEX_BUFFERS and |
||
124 | * 3DSTATE_VERTEX_ELEMENTS packets below. The VUE contents are as follows: |
||
125 | * dw0: Reserved, MBZ. |
||
126 | * dw1: Render Target Array Index. The HiZ op does not use indexed |
||
127 | * vertices, so set the dword to 0. |
||
128 | * dw2: Viewport Index. The HiZ op disables viewport mapping and |
||
129 | * scissoring, so set the dword to 0. |
||
130 | * dw3: Point Width: The HiZ op does not emit the POINTLIST primitive, so |
||
131 | * set the dword to 0. |
||
132 | * dw4: Vertex Position X. |
||
133 | * dw5: Vertex Position Y. |
||
134 | * dw6: Vertex Position Z. |
||
135 | * dw7: Vertex Position W. |
||
136 | * |
||
137 | * For details, see the Sandybridge PRM, Volume 2, Part 1, Section 1.5.1 |
||
138 | * "Vertex URB Entry (VUE) Formats". |
||
139 | */ |
||
140 | { |
||
141 | float *vertex_data; |
||
142 | |||
143 | const float vertices[GEN6_BLORP_VBO_SIZE] = { |
||
144 | /* v0 */ 0, 0, 0, 0, (float) params->x0, (float) params->y1, 0, 1, |
||
145 | /* v1 */ 0, 0, 0, 0, (float) params->x1, (float) params->y1, 0, 1, |
||
146 | /* v2 */ 0, 0, 0, 0, (float) params->x0, (float) params->y0, 0, 1, |
||
147 | }; |
||
148 | |||
149 | vertex_data = (float *) brw_state_batch(brw, AUB_TRACE_VERTEX_BUFFER, |
||
150 | GEN6_BLORP_VBO_SIZE, 32, |
||
151 | &vertex_offset); |
||
152 | memcpy(vertex_data, vertices, GEN6_BLORP_VBO_SIZE); |
||
153 | } |
||
154 | |||
155 | /* 3DSTATE_VERTEX_BUFFERS */ |
||
156 | { |
||
157 | const int num_buffers = 1; |
||
158 | const int batch_length = 1 + 4 * num_buffers; |
||
159 | |||
160 | uint32_t dw0 = GEN6_VB0_ACCESS_VERTEXDATA | |
||
161 | (GEN6_BLORP_NUM_VUE_ELEMS * sizeof(float)) << BRW_VB0_PITCH_SHIFT; |
||
162 | |||
163 | if (brw->gen >= 7) |
||
164 | dw0 |= GEN7_VB0_ADDRESS_MODIFYENABLE; |
||
165 | |||
166 | if (brw->is_haswell) |
||
167 | dw0 |= GEN7_MOCS_L3 << 16; |
||
168 | |||
169 | BEGIN_BATCH(batch_length); |
||
170 | OUT_BATCH((_3DSTATE_VERTEX_BUFFERS << 16) | (batch_length - 2)); |
||
171 | OUT_BATCH(dw0); |
||
172 | /* start address */ |
||
173 | OUT_RELOC(brw->batch.bo, I915_GEM_DOMAIN_VERTEX, 0, |
||
174 | vertex_offset); |
||
175 | /* end address */ |
||
176 | OUT_RELOC(brw->batch.bo, I915_GEM_DOMAIN_VERTEX, 0, |
||
177 | vertex_offset + GEN6_BLORP_VBO_SIZE - 1); |
||
178 | OUT_BATCH(0); |
||
179 | ADVANCE_BATCH(); |
||
180 | } |
||
181 | |||
182 | /* 3DSTATE_VERTEX_ELEMENTS |
||
183 | * |
||
184 | * Fetch dwords 0 - 7 from each VUE. See the comments above where |
||
185 | * the vertex_bo is filled with data. |
||
186 | */ |
||
187 | { |
||
188 | const int num_elements = 2; |
||
189 | const int batch_length = 1 + 2 * num_elements; |
||
190 | |||
191 | BEGIN_BATCH(batch_length); |
||
192 | OUT_BATCH((_3DSTATE_VERTEX_ELEMENTS << 16) | (batch_length - 2)); |
||
193 | /* Element 0 */ |
||
194 | OUT_BATCH(GEN6_VE0_VALID | |
||
195 | BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT | |
||
196 | |||
197 | OUT_BATCH(BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT | |
||
198 | BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_1_SHIFT | |
||
199 | BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_2_SHIFT | |
||
200 | BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_3_SHIFT); |
||
201 | /* Element 1 */ |
||
202 | OUT_BATCH(GEN6_VE0_VALID | |
||
203 | BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT | |
||
204 | 16 << BRW_VE0_SRC_OFFSET_SHIFT); |
||
205 | OUT_BATCH(BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT | |
||
206 | BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_1_SHIFT | |
||
207 | BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_2_SHIFT | |
||
208 | BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_3_SHIFT); |
||
209 | ADVANCE_BATCH(); |
||
210 | } |
||
211 | } |
||
212 | |||
213 | |||
214 | /* 3DSTATE_URB |
||
215 | * |
||
216 | * Assign the entire URB to the VS. Even though the VS disabled, URB space |
||
217 | * is still needed because the clipper loads the VUE's from the URB. From |
||
218 | * the Sandybridge PRM, Volume 2, Part 1, Section 3DSTATE, |
||
219 | * Dword 1.15:0 "VS Number of URB Entries": |
||
220 | * This field is always used (even if VS Function Enable is DISABLED). |
||
221 | * |
||
222 | * The warning below appears in the PRM (Section 3DSTATE_URB), but we can |
||
223 | * safely ignore it because this batch contains only one draw call. |
||
224 | * Because of URB corruption caused by allocating a previous GS unit |
||
225 | * URB entry to the VS unit, software is required to send a “GS NULL |
||
226 | * Fence” (Send URB fence with VS URB size == 1 and GS URB size == 0) |
||
227 | * plus a dummy DRAW call before any case where VS will be taking over |
||
228 | * GS URB space. |
||
229 | */ |
||
230 | static void |
||
231 | gen6_blorp_emit_urb_config(struct brw_context *brw, |
||
232 | const brw_blorp_params *params) |
||
233 | { |
||
234 | BEGIN_BATCH(3); |
||
235 | OUT_BATCH(_3DSTATE_URB << 16 | (3 - 2)); |
||
236 | OUT_BATCH(brw->urb.max_vs_entries << GEN6_URB_VS_ENTRIES_SHIFT); |
||
237 | OUT_BATCH(0); |
||
238 | ADVANCE_BATCH(); |
||
239 | } |
||
240 | |||
241 | |||
242 | /* BLEND_STATE */ |
||
243 | uint32_t |
||
244 | gen6_blorp_emit_blend_state(struct brw_context *brw, |
||
245 | const brw_blorp_params *params) |
||
246 | { |
||
247 | uint32_t cc_blend_state_offset; |
||
248 | |||
249 | struct gen6_blend_state *blend = (struct gen6_blend_state *) |
||
250 | brw_state_batch(brw, AUB_TRACE_BLEND_STATE, |
||
251 | sizeof(struct gen6_blend_state), 64, |
||
252 | &cc_blend_state_offset); |
||
253 | |||
254 | memset(blend, 0, sizeof(*blend)); |
||
255 | |||
256 | blend->blend1.pre_blend_clamp_enable = 1; |
||
257 | blend->blend1.post_blend_clamp_enable = 1; |
||
258 | blend->blend1.clamp_range = BRW_RENDERTARGET_CLAMPRANGE_FORMAT; |
||
259 | |||
260 | blend->blend1.write_disable_r = params->color_write_disable[0]; |
||
261 | blend->blend1.write_disable_g = params->color_write_disable[1]; |
||
262 | blend->blend1.write_disable_b = params->color_write_disable[2]; |
||
263 | blend->blend1.write_disable_a = params->color_write_disable[3]; |
||
264 | |||
265 | /* When blitting from an XRGB source to a ARGB destination, we need to |
||
266 | * interpret the missing channel as 1.0. Blending can do that for us: |
||
267 | * we simply use the RGB values from the fragment shader ("source RGB"), |
||
268 | * but smash the alpha channel to 1. |
||
269 | */ |
||
270 | if (params->src.mt && |
||
271 | _mesa_get_format_bits(params->dst.mt->format, GL_ALPHA_BITS) > 0 && |
||
272 | _mesa_get_format_bits(params->src.mt->format, GL_ALPHA_BITS) == 0) { |
||
273 | blend->blend0.blend_enable = 1; |
||
274 | blend->blend0.ia_blend_enable = 1; |
||
275 | |||
276 | blend->blend0.blend_func = BRW_BLENDFUNCTION_ADD; |
||
277 | blend->blend0.ia_blend_func = BRW_BLENDFUNCTION_ADD; |
||
278 | |||
279 | blend->blend0.source_blend_factor = BRW_BLENDFACTOR_SRC_COLOR; |
||
280 | blend->blend0.dest_blend_factor = BRW_BLENDFACTOR_ZERO; |
||
281 | blend->blend0.ia_source_blend_factor = BRW_BLENDFACTOR_ONE; |
||
282 | blend->blend0.ia_dest_blend_factor = BRW_BLENDFACTOR_ZERO; |
||
283 | } |
||
284 | |||
285 | return cc_blend_state_offset; |
||
286 | } |
||
287 | |||
288 | |||
289 | /* CC_STATE */ |
||
290 | uint32_t |
||
291 | gen6_blorp_emit_cc_state(struct brw_context *brw, |
||
292 | const brw_blorp_params *params) |
||
293 | { |
||
294 | uint32_t cc_state_offset; |
||
295 | |||
296 | struct gen6_color_calc_state *cc = (struct gen6_color_calc_state *) |
||
297 | brw_state_batch(brw, AUB_TRACE_CC_STATE, |
||
298 | sizeof(gen6_color_calc_state), 64, |
||
299 | &cc_state_offset); |
||
300 | memset(cc, 0, sizeof(*cc)); |
||
301 | |||
302 | return cc_state_offset; |
||
303 | } |
||
304 | |||
305 | |||
306 | /** |
||
307 | * \param out_offset is relative to |
||
308 | * CMD_STATE_BASE_ADDRESS.DynamicStateBaseAddress. |
||
309 | */ |
||
310 | uint32_t |
||
311 | gen6_blorp_emit_depth_stencil_state(struct brw_context *brw, |
||
312 | const brw_blorp_params *params) |
||
313 | { |
||
314 | uint32_t depthstencil_offset; |
||
315 | |||
316 | struct gen6_depth_stencil_state *state; |
||
317 | state = (struct gen6_depth_stencil_state *) |
||
318 | brw_state_batch(brw, AUB_TRACE_DEPTH_STENCIL_STATE, |
||
319 | sizeof(*state), 64, |
||
320 | &depthstencil_offset); |
||
321 | memset(state, 0, sizeof(*state)); |
||
322 | |||
323 | /* See the following sections of the Sandy Bridge PRM, Volume 1, Part2: |
||
324 | * - 7.5.3.1 Depth Buffer Clear |
||
325 | * - 7.5.3.2 Depth Buffer Resolve |
||
326 | * - 7.5.3.3 Hierarchical Depth Buffer Resolve |
||
327 | */ |
||
328 | state->ds2.depth_write_enable = 1; |
||
329 | if (params->hiz_op == GEN6_HIZ_OP_DEPTH_RESOLVE) { |
||
330 | state->ds2.depth_test_enable = 1; |
||
331 | state->ds2.depth_test_func = BRW_COMPAREFUNCTION_NEVER; |
||
332 | } |
||
333 | |||
334 | return depthstencil_offset; |
||
335 | } |
||
336 | |||
337 | |||
338 | /* 3DSTATE_CC_STATE_POINTERS |
||
339 | * |
||
340 | * The pointer offsets are relative to |
||
341 | * CMD_STATE_BASE_ADDRESS.DynamicStateBaseAddress. |
||
342 | * |
||
343 | * The HiZ op doesn't use BLEND_STATE or COLOR_CALC_STATE. |
||
344 | */ |
||
345 | static void |
||
346 | gen6_blorp_emit_cc_state_pointers(struct brw_context *brw, |
||
347 | const brw_blorp_params *params, |
||
348 | uint32_t cc_blend_state_offset, |
||
349 | uint32_t depthstencil_offset, |
||
350 | uint32_t cc_state_offset) |
||
351 | { |
||
352 | BEGIN_BATCH(4); |
||
353 | OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (4 - 2)); |
||
354 | OUT_BATCH(cc_blend_state_offset | 1); /* BLEND_STATE offset */ |
||
355 | OUT_BATCH(depthstencil_offset | 1); /* DEPTH_STENCIL_STATE offset */ |
||
356 | OUT_BATCH(cc_state_offset | 1); /* COLOR_CALC_STATE offset */ |
||
357 | ADVANCE_BATCH(); |
||
358 | } |
||
359 | |||
360 | |||
361 | /* WM push constants */ |
||
362 | uint32_t |
||
363 | gen6_blorp_emit_wm_constants(struct brw_context *brw, |
||
364 | const brw_blorp_params *params) |
||
365 | { |
||
366 | uint32_t wm_push_const_offset; |
||
367 | |||
368 | void *constants = brw_state_batch(brw, AUB_TRACE_WM_CONSTANTS, |
||
369 | sizeof(params->wm_push_consts), |
||
370 | 32, &wm_push_const_offset); |
||
371 | memcpy(constants, ¶ms->wm_push_consts, |
||
372 | sizeof(params->wm_push_consts)); |
||
373 | |||
374 | return wm_push_const_offset; |
||
375 | } |
||
376 | |||
377 | |||
378 | /* SURFACE_STATE for renderbuffer or texture surface (see |
||
379 | * brw_update_renderbuffer_surface and brw_update_texture_surface) |
||
380 | */ |
||
381 | static uint32_t |
||
382 | gen6_blorp_emit_surface_state(struct brw_context *brw, |
||
383 | const brw_blorp_params *params, |
||
384 | const brw_blorp_surface_info *surface, |
||
385 | uint32_t read_domains, uint32_t write_domain) |
||
386 | { |
||
387 | uint32_t wm_surf_offset; |
||
388 | uint32_t width = surface->width; |
||
389 | uint32_t height = surface->height; |
||
390 | if (surface->num_samples > 1) { |
||
391 | /* Since gen6 uses INTEL_MSAA_LAYOUT_IMS, width and height are measured |
||
392 | * in samples. But SURFACE_STATE wants them in pixels, so we need to |
||
393 | * divide them each by 2. |
||
394 | */ |
||
395 | width /= 2; |
||
396 | height /= 2; |
||
397 | } |
||
398 | struct intel_region *region = surface->mt->region; |
||
399 | uint32_t tile_x, tile_y; |
||
400 | |||
401 | uint32_t *surf = (uint32_t *) |
||
402 | brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32, |
||
403 | &wm_surf_offset); |
||
404 | |||
405 | surf[0] = (BRW_SURFACE_2D << BRW_SURFACE_TYPE_SHIFT | |
||
406 | BRW_SURFACE_MIPMAPLAYOUT_BELOW << BRW_SURFACE_MIPLAYOUT_SHIFT | |
||
407 | BRW_SURFACE_CUBEFACE_ENABLES | |
||
408 | surface->brw_surfaceformat << BRW_SURFACE_FORMAT_SHIFT); |
||
409 | |||
410 | /* reloc */ |
||
411 | surf[1] = (surface->compute_tile_offsets(&tile_x, &tile_y) + |
||
412 | region->bo->offset); |
||
413 | |||
414 | surf[2] = (0 << BRW_SURFACE_LOD_SHIFT | |
||
415 | (width - 1) << BRW_SURFACE_WIDTH_SHIFT | |
||
416 | (height - 1) << BRW_SURFACE_HEIGHT_SHIFT); |
||
417 | |||
418 | uint32_t tiling = surface->map_stencil_as_y_tiled |
||
419 | ? BRW_SURFACE_TILED | BRW_SURFACE_TILED_Y |
||
420 | : brw_get_surface_tiling_bits(region->tiling); |
||
421 | uint32_t pitch_bytes = region->pitch; |
||
422 | if (surface->map_stencil_as_y_tiled) |
||
423 | pitch_bytes *= 2; |
||
424 | surf[3] = (tiling | |
||
425 | |||
426 | (pitch_bytes - 1) << BRW_SURFACE_PITCH_SHIFT); |
||
427 | |||
428 | surf[4] = brw_get_surface_num_multisamples(surface->num_samples); |
||
429 | |||
430 | /* Note that the low bits of these fields are missing, so |
||
431 | * there's the possibility of getting in trouble. |
||
432 | */ |
||
433 | assert(tile_x % 4 == 0); |
||
434 | assert(tile_y % 2 == 0); |
||
435 | surf[5] = ((tile_x / 4) << BRW_SURFACE_X_OFFSET_SHIFT | |
||
436 | (tile_y / 2) << BRW_SURFACE_Y_OFFSET_SHIFT | |
||
437 | (surface->mt->align_h == 4 ? |
||
438 | BRW_SURFACE_VERTICAL_ALIGN_ENABLE : 0)); |
||
439 | |||
440 | /* Emit relocation to surface contents */ |
||
441 | drm_intel_bo_emit_reloc(brw->batch.bo, |
||
442 | wm_surf_offset + 4, |
||
443 | region->bo, |
||
444 | surf[1] - region->bo->offset, |
||
445 | read_domains, write_domain); |
||
446 | |||
447 | return wm_surf_offset; |
||
448 | } |
||
449 | |||
450 | |||
451 | /* BINDING_TABLE. See brw_wm_binding_table(). */ |
||
452 | uint32_t |
||
453 | gen6_blorp_emit_binding_table(struct brw_context *brw, |
||
454 | const brw_blorp_params *params, |
||
455 | uint32_t wm_surf_offset_renderbuffer, |
||
456 | uint32_t wm_surf_offset_texture) |
||
457 | { |
||
458 | uint32_t wm_bind_bo_offset; |
||
459 | uint32_t *bind = (uint32_t *) |
||
460 | brw_state_batch(brw, AUB_TRACE_BINDING_TABLE, |
||
461 | sizeof(uint32_t) * |
||
462 | BRW_BLORP_NUM_BINDING_TABLE_ENTRIES, |
||
463 | 32, /* alignment */ |
||
464 | &wm_bind_bo_offset); |
||
465 | bind[BRW_BLORP_RENDERBUFFER_BINDING_TABLE_INDEX] = |
||
466 | wm_surf_offset_renderbuffer; |
||
467 | bind[BRW_BLORP_TEXTURE_BINDING_TABLE_INDEX] = wm_surf_offset_texture; |
||
468 | |||
469 | return wm_bind_bo_offset; |
||
470 | } |
||
471 | |||
472 | |||
473 | /** |
||
474 | * SAMPLER_STATE. See brw_update_sampler_state(). |
||
475 | */ |
||
476 | static uint32_t |
||
477 | gen6_blorp_emit_sampler_state(struct brw_context *brw, |
||
478 | const brw_blorp_params *params) |
||
479 | { |
||
480 | uint32_t sampler_offset; |
||
481 | |||
482 | struct brw_sampler_state *sampler = (struct brw_sampler_state *) |
||
483 | brw_state_batch(brw, AUB_TRACE_SAMPLER_STATE, |
||
484 | sizeof(struct brw_sampler_state), |
||
485 | 32, &sampler_offset); |
||
486 | memset(sampler, 0, sizeof(*sampler)); |
||
487 | |||
488 | sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR; |
||
489 | sampler->ss0.mip_filter = BRW_MIPFILTER_NONE; |
||
490 | sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR; |
||
491 | |||
492 | sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; |
||
493 | sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; |
||
494 | sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; |
||
495 | |||
496 | sampler->ss0.min_mag_neq = 1; |
||
497 | |||
498 | /* Set LOD bias: |
||
499 | */ |
||
500 | sampler->ss0.lod_bias = 0; |
||
501 | |||
502 | sampler->ss0.lod_preclamp = 1; /* OpenGL mode */ |
||
503 | sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */ |
||
504 | |||
505 | /* Set BaseMipLevel, MaxLOD, MinLOD: |
||
506 | * |
||
507 | * XXX: I don't think that using firstLevel, lastLevel works, |
||
508 | * because we always setup the surface state as if firstLevel == |
||
509 | * level zero. Probably have to subtract firstLevel from each of |
||
510 | * these: |
||
511 | */ |
||
512 | sampler->ss0.base_level = U_FIXED(0, 1); |
||
513 | |||
514 | sampler->ss1.max_lod = U_FIXED(0, 6); |
||
515 | sampler->ss1.min_lod = U_FIXED(0, 6); |
||
516 | |||
517 | sampler->ss3.non_normalized_coord = 1; |
||
518 | |||
519 | sampler->ss3.address_round |= BRW_ADDRESS_ROUNDING_ENABLE_U_MIN | |
||
520 | BRW_ADDRESS_ROUNDING_ENABLE_V_MIN | |
||
521 | BRW_ADDRESS_ROUNDING_ENABLE_R_MIN; |
||
522 | sampler->ss3.address_round |= BRW_ADDRESS_ROUNDING_ENABLE_U_MAG | |
||
523 | BRW_ADDRESS_ROUNDING_ENABLE_V_MAG | |
||
524 | BRW_ADDRESS_ROUNDING_ENABLE_R_MAG; |
||
525 | |||
526 | return sampler_offset; |
||
527 | } |
||
528 | |||
529 | |||
530 | /** |
||
531 | * 3DSTATE_SAMPLER_STATE_POINTERS. See upload_sampler_state_pointers(). |
||
532 | */ |
||
533 | static void |
||
534 | gen6_blorp_emit_sampler_state_pointers(struct brw_context *brw, |
||
535 | const brw_blorp_params *params, |
||
536 | uint32_t sampler_offset) |
||
537 | { |
||
538 | BEGIN_BATCH(4); |
||
539 | OUT_BATCH(_3DSTATE_SAMPLER_STATE_POINTERS << 16 | |
||
540 | VS_SAMPLER_STATE_CHANGE | |
||
541 | GS_SAMPLER_STATE_CHANGE | |
||
542 | PS_SAMPLER_STATE_CHANGE | |
||
543 | (4 - 2)); |
||
544 | OUT_BATCH(0); /* VS */ |
||
545 | OUT_BATCH(0); /* GS */ |
||
546 | OUT_BATCH(sampler_offset); |
||
547 | ADVANCE_BATCH(); |
||
548 | } |
||
549 | |||
550 | |||
551 | /* 3DSTATE_VS |
||
552 | * |
||
553 | * Disable vertex shader. |
||
554 | */ |
||
555 | void |
||
556 | gen6_blorp_emit_vs_disable(struct brw_context *brw, |
||
557 | const brw_blorp_params *params) |
||
558 | { |
||
559 | if (brw->gen == 6) { |
||
560 | /* From the BSpec, 3D Pipeline > Geometry > Vertex Shader > State, |
||
561 | * 3DSTATE_VS, Dword 5.0 "VS Function Enable": |
||
562 | * |
||
563 | * [DevSNB] A pipeline flush must be programmed prior to a |
||
564 | * 3DSTATE_VS command that causes the VS Function Enable to |
||
565 | * toggle. Pipeline flush can be executed by sending a PIPE_CONTROL |
||
566 | * command with CS stall bit set and a post sync operation. |
||
567 | */ |
||
568 | intel_emit_post_sync_nonzero_flush(brw); |
||
569 | } |
||
570 | |||
571 | /* Disable the push constant buffers. */ |
||
572 | BEGIN_BATCH(5); |
||
573 | OUT_BATCH(_3DSTATE_CONSTANT_VS << 16 | (5 - 2)); |
||
574 | OUT_BATCH(0); |
||
575 | OUT_BATCH(0); |
||
576 | OUT_BATCH(0); |
||
577 | OUT_BATCH(0); |
||
578 | ADVANCE_BATCH(); |
||
579 | |||
580 | BEGIN_BATCH(6); |
||
581 | OUT_BATCH(_3DSTATE_VS << 16 | (6 - 2)); |
||
582 | OUT_BATCH(0); |
||
583 | OUT_BATCH(0); |
||
584 | OUT_BATCH(0); |
||
585 | OUT_BATCH(0); |
||
586 | OUT_BATCH(0); |
||
587 | ADVANCE_BATCH(); |
||
588 | } |
||
589 | |||
590 | |||
591 | /* 3DSTATE_GS |
||
592 | * |
||
593 | * Disable the geometry shader. |
||
594 | */ |
||
595 | void |
||
596 | gen6_blorp_emit_gs_disable(struct brw_context *brw, |
||
597 | const brw_blorp_params *params) |
||
598 | { |
||
599 | /* Disable all the constant buffers. */ |
||
600 | BEGIN_BATCH(5); |
||
601 | OUT_BATCH(_3DSTATE_CONSTANT_GS << 16 | (5 - 2)); |
||
602 | OUT_BATCH(0); |
||
603 | OUT_BATCH(0); |
||
604 | OUT_BATCH(0); |
||
605 | OUT_BATCH(0); |
||
606 | ADVANCE_BATCH(); |
||
607 | |||
608 | BEGIN_BATCH(7); |
||
609 | OUT_BATCH(_3DSTATE_GS << 16 | (7 - 2)); |
||
610 | OUT_BATCH(0); |
||
611 | OUT_BATCH(0); |
||
612 | OUT_BATCH(0); |
||
613 | OUT_BATCH(0); |
||
614 | OUT_BATCH(0); |
||
615 | OUT_BATCH(0); |
||
616 | ADVANCE_BATCH(); |
||
617 | } |
||
618 | |||
619 | |||
620 | /* 3DSTATE_CLIP |
||
621 | * |
||
622 | * Disable the clipper. |
||
623 | * |
||
624 | * The BLORP op emits a rectangle primitive, which requires clipping to |
||
625 | * be disabled. From page 10 of the Sandy Bridge PRM Volume 2 Part 1 |
||
626 | * Section 1.3 "3D Primitives Overview": |
||
627 | * RECTLIST: |
||
628 | * Either the CLIP unit should be DISABLED, or the CLIP unit's Clip |
||
629 | * Mode should be set to a value other than CLIPMODE_NORMAL. |
||
630 | * |
||
631 | * Also disable perspective divide. This doesn't change the clipper's |
||
632 | * output, but does spare a few electrons. |
||
633 | */ |
||
634 | void |
||
635 | gen6_blorp_emit_clip_disable(struct brw_context *brw, |
||
636 | const brw_blorp_params *params) |
||
637 | { |
||
638 | BEGIN_BATCH(4); |
||
639 | OUT_BATCH(_3DSTATE_CLIP << 16 | (4 - 2)); |
||
640 | OUT_BATCH(0); |
||
641 | OUT_BATCH(GEN6_CLIP_PERSPECTIVE_DIVIDE_DISABLE); |
||
642 | OUT_BATCH(0); |
||
643 | ADVANCE_BATCH(); |
||
644 | } |
||
645 | |||
646 | |||
647 | /* 3DSTATE_SF |
||
648 | * |
||
649 | * Disable ViewportTransformEnable (dw2.1) |
||
650 | * |
||
651 | * From the SandyBridge PRM, Volume 2, Part 1, Section 1.3, "3D |
||
652 | * Primitives Overview": |
||
653 | * RECTLIST: Viewport Mapping must be DISABLED (as is typical with the |
||
654 | * use of screen- space coordinates). |
||
655 | * |
||
656 | * A solid rectangle must be rendered, so set FrontFaceFillMode (dw2.4:3) |
||
657 | * and BackFaceFillMode (dw2.5:6) to SOLID(0). |
||
658 | * |
||
659 | * From the Sandy Bridge PRM, Volume 2, Part 1, Section |
||
660 | * 6.4.1.1 3DSTATE_SF, Field FrontFaceFillMode: |
||
661 | * SOLID: Any triangle or rectangle object found to be front-facing |
||
662 | * is rendered as a solid object. This setting is required when |
||
663 | * (rendering rectangle (RECTLIST) objects. |
||
664 | */ |
||
665 | static void |
||
666 | gen6_blorp_emit_sf_config(struct brw_context *brw, |
||
667 | const brw_blorp_params *params) |
||
668 | { |
||
669 | BEGIN_BATCH(20); |
||
670 | OUT_BATCH(_3DSTATE_SF << 16 | (20 - 2)); |
||
671 | OUT_BATCH((1 - 1) << GEN6_SF_NUM_OUTPUTS_SHIFT | /* only position */ |
||
672 | 1 << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT | |
||
673 | |||
674 | OUT_BATCH(0); /* dw2 */ |
||
675 | OUT_BATCH(params->num_samples > 1 ? GEN6_SF_MSRAST_ON_PATTERN : 0); |
||
676 | for (int i = 0; i < 16; ++i) |
||
677 | OUT_BATCH(0); |
||
678 | ADVANCE_BATCH(); |
||
679 | } |
||
680 | |||
681 | |||
682 | /** |
||
683 | * Enable or disable thread dispatch and set the HiZ op appropriately. |
||
684 | */ |
||
685 | static void |
||
686 | gen6_blorp_emit_wm_config(struct brw_context *brw, |
||
687 | const brw_blorp_params *params, |
||
688 | uint32_t prog_offset, |
||
689 | brw_blorp_prog_data *prog_data) |
||
690 | { |
||
691 | uint32_t dw2, dw4, dw5, dw6; |
||
692 | |||
693 | /* Even when thread dispatch is disabled, max threads (dw5.25:31) must be |
||
694 | * nonzero to prevent the GPU from hanging. While the documentation doesn't |
||
695 | * mention this explicitly, it notes that the valid range for the field is |
||
696 | * [1,39] = [2,40] threads, which excludes zero. |
||
697 | * |
||
698 | * To be safe (and to minimize extraneous code) we go ahead and fully |
||
699 | * configure the WM state whether or not there is a WM program. |
||
700 | */ |
||
701 | |||
702 | dw2 = dw4 = dw5 = dw6 = 0; |
||
703 | switch (params->hiz_op) { |
||
704 | case GEN6_HIZ_OP_DEPTH_CLEAR: |
||
705 | dw4 |= GEN6_WM_DEPTH_CLEAR; |
||
706 | break; |
||
707 | case GEN6_HIZ_OP_DEPTH_RESOLVE: |
||
708 | dw4 |= GEN6_WM_DEPTH_RESOLVE; |
||
709 | break; |
||
710 | case GEN6_HIZ_OP_HIZ_RESOLVE: |
||
711 | dw4 |= GEN6_WM_HIERARCHICAL_DEPTH_RESOLVE; |
||
712 | break; |
||
713 | case GEN6_HIZ_OP_NONE: |
||
714 | break; |
||
715 | default: |
||
716 | assert(0); |
||
717 | break; |
||
718 | } |
||
719 | dw5 |= GEN6_WM_LINE_AA_WIDTH_1_0; |
||
720 | dw5 |= GEN6_WM_LINE_END_CAP_AA_WIDTH_0_5; |
||
721 | dw5 |= (brw->max_wm_threads - 1) << GEN6_WM_MAX_THREADS_SHIFT; |
||
722 | dw6 |= 0 << GEN6_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT; /* No interp */ |
||
723 | dw6 |= 0 << GEN6_WM_NUM_SF_OUTPUTS_SHIFT; /* No inputs from SF */ |
||
724 | if (params->use_wm_prog) { |
||
725 | dw2 |= 1 << GEN6_WM_SAMPLER_COUNT_SHIFT; /* Up to 4 samplers */ |
||
726 | dw4 |= prog_data->first_curbe_grf << GEN6_WM_DISPATCH_START_GRF_SHIFT_0; |
||
727 | dw5 |= GEN6_WM_16_DISPATCH_ENABLE; |
||
728 | dw5 |= GEN6_WM_KILL_ENABLE; /* TODO: temporarily smash on */ |
||
729 | dw5 |= GEN6_WM_DISPATCH_ENABLE; /* We are rendering */ |
||
730 | } |
||
731 | |||
732 | if (params->num_samples > 1) { |
||
733 | dw6 |= GEN6_WM_MSRAST_ON_PATTERN; |
||
734 | if (prog_data && prog_data->persample_msaa_dispatch) |
||
735 | dw6 |= GEN6_WM_MSDISPMODE_PERSAMPLE; |
||
736 | else |
||
737 | dw6 |= GEN6_WM_MSDISPMODE_PERPIXEL; |
||
738 | } else { |
||
739 | dw6 |= GEN6_WM_MSRAST_OFF_PIXEL; |
||
740 | dw6 |= GEN6_WM_MSDISPMODE_PERSAMPLE; |
||
741 | } |
||
742 | |||
743 | BEGIN_BATCH(9); |
||
744 | OUT_BATCH(_3DSTATE_WM << 16 | (9 - 2)); |
||
745 | OUT_BATCH(params->use_wm_prog ? prog_offset : 0); |
||
746 | OUT_BATCH(dw2); |
||
747 | OUT_BATCH(0); /* No scratch needed */ |
||
748 | OUT_BATCH(dw4); |
||
749 | OUT_BATCH(dw5); |
||
750 | OUT_BATCH(dw6); |
||
751 | OUT_BATCH(0); /* No other programs */ |
||
752 | OUT_BATCH(0); /* No other programs */ |
||
753 | ADVANCE_BATCH(); |
||
754 | } |
||
755 | |||
756 | |||
757 | static void |
||
758 | gen6_blorp_emit_constant_ps(struct brw_context *brw, |
||
759 | const brw_blorp_params *params, |
||
760 | uint32_t wm_push_const_offset) |
||
761 | { |
||
762 | /* Make sure the push constants fill an exact integer number of |
||
763 | * registers. |
||
764 | */ |
||
765 | assert(sizeof(brw_blorp_wm_push_constants) % 32 == 0); |
||
766 | |||
767 | /* There must be at least one register worth of push constant data. */ |
||
768 | assert(BRW_BLORP_NUM_PUSH_CONST_REGS > 0); |
||
769 | |||
770 | /* Enable push constant buffer 0. */ |
||
771 | BEGIN_BATCH(5); |
||
772 | OUT_BATCH(_3DSTATE_CONSTANT_PS << 16 | |
||
773 | GEN6_CONSTANT_BUFFER_0_ENABLE | |
||
774 | (5 - 2)); |
||
775 | OUT_BATCH(wm_push_const_offset + (BRW_BLORP_NUM_PUSH_CONST_REGS - 1)); |
||
776 | OUT_BATCH(0); |
||
777 | OUT_BATCH(0); |
||
778 | OUT_BATCH(0); |
||
779 | ADVANCE_BATCH(); |
||
780 | } |
||
781 | |||
782 | static void |
||
783 | gen6_blorp_emit_constant_ps_disable(struct brw_context *brw, |
||
784 | const brw_blorp_params *params) |
||
785 | { |
||
786 | /* Disable the push constant buffers. */ |
||
787 | BEGIN_BATCH(5); |
||
788 | OUT_BATCH(_3DSTATE_CONSTANT_PS << 16 | (5 - 2)); |
||
789 | OUT_BATCH(0); |
||
790 | OUT_BATCH(0); |
||
791 | OUT_BATCH(0); |
||
792 | OUT_BATCH(0); |
||
793 | ADVANCE_BATCH(); |
||
794 | } |
||
795 | |||
796 | /** |
||
797 | * 3DSTATE_BINDING_TABLE_POINTERS |
||
798 | */ |
||
799 | static void |
||
800 | gen6_blorp_emit_binding_table_pointers(struct brw_context *brw, |
||
801 | const brw_blorp_params *params, |
||
802 | uint32_t wm_bind_bo_offset) |
||
803 | { |
||
804 | BEGIN_BATCH(4); |
||
805 | OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | |
||
806 | GEN6_BINDING_TABLE_MODIFY_PS | |
||
807 | (4 - 2)); |
||
808 | OUT_BATCH(0); /* vs -- ignored */ |
||
809 | OUT_BATCH(0); /* gs -- ignored */ |
||
810 | OUT_BATCH(wm_bind_bo_offset); /* wm/ps */ |
||
811 | ADVANCE_BATCH(); |
||
812 | } |
||
813 | |||
814 | |||
815 | static void |
||
816 | gen6_blorp_emit_depth_stencil_config(struct brw_context *brw, |
||
817 | const brw_blorp_params *params) |
||
818 | { |
||
819 | struct gl_context *ctx = &brw->ctx; |
||
820 | uint32_t draw_x = params->depth.x_offset; |
||
821 | uint32_t draw_y = params->depth.y_offset; |
||
822 | uint32_t tile_mask_x, tile_mask_y; |
||
823 | |||
824 | brw_get_depthstencil_tile_masks(params->depth.mt, |
||
825 | params->depth.level, |
||
826 | params->depth.layer, |
||
827 | NULL, |
||
828 | &tile_mask_x, &tile_mask_y); |
||
829 | |||
830 | /* 3DSTATE_DEPTH_BUFFER */ |
||
831 | { |
||
832 | uint32_t tile_x = draw_x & tile_mask_x; |
||
833 | uint32_t tile_y = draw_y & tile_mask_y; |
||
834 | uint32_t offset = |
||
835 | intel_region_get_aligned_offset(params->depth.mt->region, |
||
836 | draw_x & ~tile_mask_x, |
||
837 | draw_y & ~tile_mask_y, false); |
||
838 | |||
839 | /* According to the Sandy Bridge PRM, volume 2 part 1, pp326-327 |
||
840 | * (3DSTATE_DEPTH_BUFFER dw5), in the documentation for "Depth |
||
841 | * Coordinate Offset X/Y": |
||
842 | * |
||
843 | * "The 3 LSBs of both offsets must be zero to ensure correct |
||
844 | * alignment" |
||
845 | * |
||
846 | * We have no guarantee that tile_x and tile_y are correctly aligned, |
||
847 | * since they are determined by the mipmap layout, which is only aligned |
||
848 | * to multiples of 4. |
||
849 | * |
||
850 | * So, to avoid hanging the GPU, just smash the low order 3 bits of |
||
851 | * tile_x and tile_y to 0. This is a temporary workaround until we come |
||
852 | * up with a better solution. |
||
853 | */ |
||
854 | WARN_ONCE((tile_x & 7) || (tile_y & 7), |
||
855 | "Depth/stencil buffer needs alignment to 8-pixel boundaries.\n" |
||
856 | "Truncating offset, bad rendering may occur.\n"); |
||
857 | tile_x &= ~7; |
||
858 | tile_y &= ~7; |
||
859 | |||
860 | intel_emit_post_sync_nonzero_flush(brw); |
||
861 | intel_emit_depth_stall_flushes(brw); |
||
862 | |||
863 | BEGIN_BATCH(7); |
||
864 | OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2)); |
||
865 | OUT_BATCH((params->depth.mt->region->pitch - 1) | |
||
866 | params->depth_format << 18 | |
||
867 | 1 << 21 | /* separate stencil enable */ |
||
868 | 1 << 22 | /* hiz enable */ |
||
869 | BRW_TILEWALK_YMAJOR << 26 | |
||
870 | 1 << 27 | /* y-tiled */ |
||
871 | BRW_SURFACE_2D << 29); |
||
872 | OUT_RELOC(params->depth.mt->region->bo, |
||
873 | I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, |
||
874 | offset); |
||
875 | OUT_BATCH(BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1 | |
||
876 | (params->depth.width + tile_x - 1) << 6 | |
||
877 | (params->depth.height + tile_y - 1) << 19); |
||
878 | OUT_BATCH(0); |
||
879 | OUT_BATCH(tile_x | |
||
880 | tile_y << 16); |
||
881 | OUT_BATCH(0); |
||
882 | ADVANCE_BATCH(); |
||
883 | } |
||
884 | |||
885 | /* 3DSTATE_HIER_DEPTH_BUFFER */ |
||
886 | { |
||
887 | struct intel_region *hiz_region = params->depth.mt->hiz_mt->region; |
||
888 | uint32_t hiz_offset = |
||
889 | intel_region_get_aligned_offset(hiz_region, |
||
890 | draw_x & ~tile_mask_x, |
||
891 | (draw_y & ~tile_mask_y) / 2, false); |
||
892 | |||
893 | BEGIN_BATCH(3); |
||
894 | OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2)); |
||
895 | OUT_BATCH(hiz_region->pitch - 1); |
||
896 | OUT_RELOC(hiz_region->bo, |
||
897 | I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, |
||
898 | hiz_offset); |
||
899 | ADVANCE_BATCH(); |
||
900 | } |
||
901 | |||
902 | /* 3DSTATE_STENCIL_BUFFER */ |
||
903 | { |
||
904 | BEGIN_BATCH(3); |
||
905 | OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2)); |
||
906 | OUT_BATCH(0); |
||
907 | OUT_BATCH(0); |
||
908 | ADVANCE_BATCH(); |
||
909 | } |
||
910 | } |
||
911 | |||
912 | |||
913 | static void |
||
914 | gen6_blorp_emit_depth_disable(struct brw_context *brw, |
||
915 | const brw_blorp_params *params) |
||
916 | { |
||
917 | BEGIN_BATCH(7); |
||
918 | OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2)); |
||
919 | OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) | |
||
920 | (BRW_SURFACE_NULL << 29)); |
||
921 | OUT_BATCH(0); |
||
922 | OUT_BATCH(0); |
||
923 | OUT_BATCH(0); |
||
924 | OUT_BATCH(0); |
||
925 | OUT_BATCH(0); |
||
926 | ADVANCE_BATCH(); |
||
4401 | Serge | 927 | |
928 | BEGIN_BATCH(3); |
||
929 | OUT_BATCH(_3DSTATE_HIER_DEPTH_BUFFER << 16 | (3 - 2)); |
||
930 | OUT_BATCH(0); |
||
931 | OUT_BATCH(0); |
||
932 | ADVANCE_BATCH(); |
||
933 | |||
934 | BEGIN_BATCH(3); |
||
935 | OUT_BATCH(_3DSTATE_STENCIL_BUFFER << 16 | (3 - 2)); |
||
936 | OUT_BATCH(0); |
||
937 | OUT_BATCH(0); |
||
938 | ADVANCE_BATCH(); |
||
4358 | Serge | 939 | } |
940 | |||
941 | |||
942 | /* 3DSTATE_CLEAR_PARAMS |
||
943 | * |
||
944 | * From the Sandybridge PRM, Volume 2, Part 1, Section 3DSTATE_CLEAR_PARAMS: |
||
945 | * [DevSNB] 3DSTATE_CLEAR_PARAMS packet must follow the DEPTH_BUFFER_STATE |
||
946 | * packet when HiZ is enabled and the DEPTH_BUFFER_STATE changes. |
||
947 | */ |
||
948 | static void |
||
949 | gen6_blorp_emit_clear_params(struct brw_context *brw, |
||
950 | const brw_blorp_params *params) |
||
951 | { |
||
952 | BEGIN_BATCH(2); |
||
953 | OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 | |
||
954 | GEN5_DEPTH_CLEAR_VALID | |
||
955 | (2 - 2)); |
||
956 | OUT_BATCH(params->depth.mt ? params->depth.mt->depth_clear_value : 0); |
||
957 | ADVANCE_BATCH(); |
||
958 | } |
||
959 | |||
960 | |||
961 | /* 3DSTATE_DRAWING_RECTANGLE */ |
||
962 | void |
||
963 | gen6_blorp_emit_drawing_rectangle(struct brw_context *brw, |
||
964 | const brw_blorp_params *params) |
||
965 | { |
||
4401 | Serge | 966 | if (brw->gen == 6) |
967 | intel_emit_post_sync_nonzero_flush(brw); |
||
968 | |||
4358 | Serge | 969 | BEGIN_BATCH(4); |
970 | OUT_BATCH(_3DSTATE_DRAWING_RECTANGLE << 16 | (4 - 2)); |
||
971 | OUT_BATCH(0); |
||
972 | OUT_BATCH(((params->x1 - 1) & 0xffff) | |
||
973 | ((params->y1 - 1) << 16)); |
||
974 | OUT_BATCH(0); |
||
975 | ADVANCE_BATCH(); |
||
976 | } |
||
977 | |||
978 | /* 3DSTATE_VIEWPORT_STATE_POINTERS */ |
||
979 | void |
||
980 | gen6_blorp_emit_viewport_state(struct brw_context *brw, |
||
981 | const brw_blorp_params *params) |
||
982 | { |
||
983 | struct brw_cc_viewport *ccv; |
||
984 | uint32_t cc_vp_offset; |
||
985 | |||
986 | ccv = (struct brw_cc_viewport *)brw_state_batch(brw, AUB_TRACE_CC_VP_STATE, |
||
987 | sizeof(*ccv), 32, |
||
988 | &cc_vp_offset); |
||
989 | |||
990 | ccv->min_depth = 0.0; |
||
991 | ccv->max_depth = 1.0; |
||
992 | |||
993 | BEGIN_BATCH(4); |
||
994 | OUT_BATCH(_3DSTATE_VIEWPORT_STATE_POINTERS << 16 | (4 - 2) | |
||
995 | GEN6_CC_VIEWPORT_MODIFY); |
||
996 | OUT_BATCH(0); /* clip VP */ |
||
997 | OUT_BATCH(0); /* SF VP */ |
||
998 | OUT_BATCH(cc_vp_offset); |
||
999 | ADVANCE_BATCH(); |
||
1000 | } |
||
1001 | |||
1002 | |||
1003 | /* 3DPRIMITIVE */ |
||
1004 | static void |
||
1005 | gen6_blorp_emit_primitive(struct brw_context *brw, |
||
1006 | const brw_blorp_params *params) |
||
1007 | { |
||
1008 | BEGIN_BATCH(6); |
||
1009 | OUT_BATCH(CMD_3D_PRIM << 16 | (6 - 2) | |
||
1010 | _3DPRIM_RECTLIST << GEN4_3DPRIM_TOPOLOGY_TYPE_SHIFT | |
||
1011 | GEN4_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL); |
||
1012 | OUT_BATCH(3); /* vertex count per instance */ |
||
1013 | OUT_BATCH(0); |
||
1014 | OUT_BATCH(1); /* instance count */ |
||
1015 | OUT_BATCH(0); |
||
1016 | OUT_BATCH(0); |
||
1017 | ADVANCE_BATCH(); |
||
1018 | } |
||
1019 | |||
1020 | |||
1021 | /** |
||
1022 | * \brief Execute a blit or render pass operation. |
||
1023 | * |
||
1024 | * To execute the operation, this function manually constructs and emits a |
||
1025 | * batch to draw a rectangle primitive. The batchbuffer is flushed before |
||
1026 | * constructing and after emitting the batch. |
||
1027 | * |
||
1028 | * This function alters no GL state. |
||
1029 | */ |
||
1030 | void |
||
1031 | gen6_blorp_exec(struct brw_context *brw, |
||
1032 | const brw_blorp_params *params) |
||
1033 | { |
||
1034 | brw_blorp_prog_data *prog_data = NULL; |
||
1035 | uint32_t cc_blend_state_offset = 0; |
||
1036 | uint32_t cc_state_offset = 0; |
||
1037 | uint32_t depthstencil_offset; |
||
1038 | uint32_t wm_push_const_offset = 0; |
||
1039 | uint32_t wm_bind_bo_offset = 0; |
||
1040 | |||
1041 | uint32_t prog_offset = params->get_wm_prog(brw, &prog_data); |
||
1042 | gen6_blorp_emit_batch_head(brw, params); |
||
1043 | gen6_emit_3dstate_multisample(brw, params->num_samples); |
||
1044 | gen6_emit_3dstate_sample_mask(brw, params->num_samples, 1.0, false, ~0u); |
||
1045 | gen6_blorp_emit_state_base_address(brw, params); |
||
1046 | gen6_blorp_emit_vertices(brw, params); |
||
1047 | gen6_blorp_emit_urb_config(brw, params); |
||
1048 | if (params->use_wm_prog) { |
||
1049 | cc_blend_state_offset = gen6_blorp_emit_blend_state(brw, params); |
||
1050 | cc_state_offset = gen6_blorp_emit_cc_state(brw, params); |
||
1051 | } |
||
1052 | depthstencil_offset = gen6_blorp_emit_depth_stencil_state(brw, params); |
||
1053 | gen6_blorp_emit_cc_state_pointers(brw, params, cc_blend_state_offset, |
||
1054 | depthstencil_offset, cc_state_offset); |
||
1055 | if (params->use_wm_prog) { |
||
1056 | uint32_t wm_surf_offset_renderbuffer; |
||
1057 | uint32_t wm_surf_offset_texture = 0; |
||
1058 | uint32_t sampler_offset; |
||
1059 | wm_push_const_offset = gen6_blorp_emit_wm_constants(brw, params); |
||
1060 | intel_miptree_used_for_rendering(params->dst.mt); |
||
1061 | wm_surf_offset_renderbuffer = |
||
1062 | gen6_blorp_emit_surface_state(brw, params, ¶ms->dst, |
||
1063 | I915_GEM_DOMAIN_RENDER, |
||
1064 | I915_GEM_DOMAIN_RENDER); |
||
1065 | if (params->src.mt) { |
||
1066 | wm_surf_offset_texture = |
||
1067 | gen6_blorp_emit_surface_state(brw, params, ¶ms->src, |
||
1068 | I915_GEM_DOMAIN_SAMPLER, 0); |
||
1069 | } |
||
1070 | wm_bind_bo_offset = |
||
1071 | gen6_blorp_emit_binding_table(brw, params, |
||
1072 | wm_surf_offset_renderbuffer, |
||
1073 | wm_surf_offset_texture); |
||
1074 | sampler_offset = gen6_blorp_emit_sampler_state(brw, params); |
||
1075 | gen6_blorp_emit_sampler_state_pointers(brw, params, sampler_offset); |
||
1076 | } |
||
1077 | gen6_blorp_emit_vs_disable(brw, params); |
||
1078 | gen6_blorp_emit_gs_disable(brw, params); |
||
1079 | gen6_blorp_emit_clip_disable(brw, params); |
||
1080 | gen6_blorp_emit_sf_config(brw, params); |
||
1081 | if (params->use_wm_prog) |
||
1082 | gen6_blorp_emit_constant_ps(brw, params, wm_push_const_offset); |
||
1083 | else |
||
1084 | gen6_blorp_emit_constant_ps_disable(brw, params); |
||
1085 | gen6_blorp_emit_wm_config(brw, params, prog_offset, prog_data); |
||
1086 | if (params->use_wm_prog) |
||
1087 | gen6_blorp_emit_binding_table_pointers(brw, params, wm_bind_bo_offset); |
||
1088 | gen6_blorp_emit_viewport_state(brw, params); |
||
1089 | |||
1090 | if (params->depth.mt) |
||
1091 | gen6_blorp_emit_depth_stencil_config(brw, params); |
||
1092 | else |
||
1093 | gen6_blorp_emit_depth_disable(brw, params); |
||
1094 | gen6_blorp_emit_clear_params(brw, params); |
||
1095 | gen6_blorp_emit_drawing_rectangle(brw, params); |
||
1096 | gen6_blorp_emit_primitive(brw, params); |
||
1097 | }><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><> |
||
1098 |