ilo: allow ilo_view_surface to skip layer offsetting
[mesa.git] / src / gallium / drivers / ilo / ilo_gpe_gen7.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2013 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28 #include "util/u_resource.h"
29 #include "brw_defines.h"
30 #include "intel_reg.h"
31
32 #include "ilo_format.h"
33 #include "ilo_resource.h"
34 #include "ilo_shader.h"
35 #include "ilo_gpe_gen7.h"
36
37 void
38 ilo_gpe_init_gs_cso_gen7(const struct ilo_dev_info *dev,
39 const struct ilo_shader_state *gs,
40 struct ilo_shader_cso *cso)
41 {
42 int start_grf, vue_read_len, max_threads;
43 uint32_t dw2, dw4, dw5;
44
45 ILO_GPE_VALID_GEN(dev, 7, 7.5);
46
47 start_grf = ilo_shader_get_kernel_param(gs, ILO_KERNEL_URB_DATA_START_REG);
48 vue_read_len = ilo_shader_get_kernel_param(gs, ILO_KERNEL_INPUT_COUNT);
49
50 /* in pairs */
51 vue_read_len = (vue_read_len + 1) / 2;
52
53 switch (dev->gen) {
54 case ILO_GEN(7.5):
55 max_threads = (dev->gt >= 2) ? 256 : 70;
56 break;
57 case ILO_GEN(7):
58 max_threads = (dev->gt == 2) ? 128 : 36;
59 break;
60 default:
61 max_threads = 1;
62 break;
63 }
64
65 dw2 = (true) ? 0 : GEN6_GS_FLOATING_POINT_MODE_ALT;
66
67 dw4 = vue_read_len << GEN6_GS_URB_READ_LENGTH_SHIFT |
68 GEN7_GS_INCLUDE_VERTEX_HANDLES |
69 0 << GEN6_GS_URB_ENTRY_READ_OFFSET_SHIFT |
70 start_grf << GEN6_GS_DISPATCH_START_GRF_SHIFT;
71
72 dw5 = (max_threads - 1) << GEN6_GS_MAX_THREADS_SHIFT |
73 GEN6_GS_STATISTICS_ENABLE |
74 GEN6_GS_ENABLE;
75
76 STATIC_ASSERT(Elements(cso->payload) >= 3);
77 cso->payload[0] = dw2;
78 cso->payload[1] = dw4;
79 cso->payload[2] = dw5;
80 }
81
82 void
83 ilo_gpe_init_rasterizer_wm_gen7(const struct ilo_dev_info *dev,
84 const struct pipe_rasterizer_state *state,
85 struct ilo_rasterizer_wm *wm)
86 {
87 uint32_t dw1, dw2;
88
89 ILO_GPE_VALID_GEN(dev, 7, 7.5);
90
91 dw1 = GEN7_WM_POSITION_ZW_PIXEL |
92 GEN7_WM_LINE_AA_WIDTH_2_0 |
93 GEN7_WM_MSRAST_OFF_PIXEL;
94
95 /* same value as in 3DSTATE_SF */
96 if (state->line_smooth)
97 dw1 |= GEN7_WM_LINE_END_CAP_AA_WIDTH_1_0;
98
99 if (state->poly_stipple_enable)
100 dw1 |= GEN7_WM_POLYGON_STIPPLE_ENABLE;
101 if (state->line_stipple_enable)
102 dw1 |= GEN7_WM_LINE_STIPPLE_ENABLE;
103
104 if (state->bottom_edge_rule)
105 dw1 |= GEN7_WM_POINT_RASTRULE_UPPER_RIGHT;
106
107 dw2 = GEN7_WM_MSDISPMODE_PERSAMPLE;
108
109 /*
110 * assertion that makes sure
111 *
112 * dw1 |= wm->dw_msaa_rast;
113 * dw2 |= wm->dw_msaa_disp;
114 *
115 * is valid
116 */
117 STATIC_ASSERT(GEN7_WM_MSRAST_OFF_PIXEL == 0 &&
118 GEN7_WM_MSDISPMODE_PERSAMPLE == 0);
119
120 wm->dw_msaa_rast =
121 (state->multisample) ? GEN7_WM_MSRAST_ON_PATTERN : 0;
122 wm->dw_msaa_disp = GEN7_WM_MSDISPMODE_PERPIXEL;
123
124 STATIC_ASSERT(Elements(wm->payload) >= 2);
125 wm->payload[0] = dw1;
126 wm->payload[1] = dw2;
127 }
128
129 void
130 ilo_gpe_init_fs_cso_gen7(const struct ilo_dev_info *dev,
131 const struct ilo_shader_state *fs,
132 struct ilo_shader_cso *cso)
133 {
134 int start_grf, max_threads;
135 uint32_t dw2, dw4, dw5;
136 uint32_t wm_interps, wm_dw1;
137
138 ILO_GPE_VALID_GEN(dev, 7, 7.5);
139
140 start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);
141
142 dw2 = (true) ? 0 : GEN7_PS_FLOATING_POINT_MODE_ALT;
143
144 dw4 = GEN7_PS_POSOFFSET_NONE;
145
146 /* see brwCreateContext() */
147 switch (dev->gen) {
148 case ILO_GEN(7.5):
149 max_threads = (dev->gt == 3) ? 408 : (dev->gt == 2) ? 204 : 102;
150 dw4 |= (max_threads - 1) << HSW_PS_MAX_THREADS_SHIFT;
151 dw4 |= 1 << HSW_PS_SAMPLE_MASK_SHIFT;
152 break;
153 case ILO_GEN(7):
154 default:
155 max_threads = (dev->gt == 2) ? 172 : 48;
156 dw4 |= (max_threads - 1) << IVB_PS_MAX_THREADS_SHIFT;
157 break;
158 }
159
160 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_PCB_CBUF0_SIZE))
161 dw4 |= GEN7_PS_PUSH_CONSTANT_ENABLE;
162
163 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT))
164 dw4 |= GEN7_PS_ATTRIBUTE_ENABLE;
165
166 assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
167 dw4 |= GEN7_PS_8_DISPATCH_ENABLE;
168
169 dw5 = start_grf << GEN7_PS_DISPATCH_START_GRF_SHIFT_0 |
170 0 << GEN7_PS_DISPATCH_START_GRF_SHIFT_1 |
171 0 << GEN7_PS_DISPATCH_START_GRF_SHIFT_2;
172
173 /* FS affects 3DSTATE_WM too */
174 wm_dw1 = 0;
175
176 /*
177 * TODO set this bit only when
178 *
179 * a) fs writes colors and color is not masked, or
180 * b) fs writes depth, or
181 * c) fs or cc kills
182 */
183 wm_dw1 |= GEN7_WM_DISPATCH_ENABLE;
184
185 /*
186 * From the Ivy Bridge PRM, volume 2 part 1, page 278:
187 *
188 * "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that
189 * the PS kernel or color calculator has the ability to kill
190 * (discard) pixels or samples, other than due to depth or stencil
191 * testing. This bit is required to be ENABLED in the following
192 * situations:
193 *
194 * - The API pixel shader program contains "killpix" or "discard"
195 * instructions, or other code in the pixel shader kernel that
196 * can cause the final pixel mask to differ from the pixel mask
197 * received on dispatch.
198 *
199 * - A sampler with chroma key enabled with kill pixel mode is used
200 * by the pixel shader.
201 *
202 * - Any render target has Alpha Test Enable or AlphaToCoverage
203 * Enable enabled.
204 *
205 * - The pixel shader kernel generates and outputs oMask.
206 *
207 * Note: As ClipDistance clipping is fully supported in hardware
208 * and therefore not via PS instructions, there should be no need
209 * to ENABLE this bit due to ClipDistance clipping."
210 */
211 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
212 wm_dw1 |= GEN7_WM_KILL_ENABLE;
213
214 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
215 wm_dw1 |= GEN7_WM_PSCDEPTH_ON;
216
217 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
218 wm_dw1 |= GEN7_WM_USES_SOURCE_DEPTH;
219
220 if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
221 wm_dw1 |= GEN7_WM_USES_SOURCE_W;
222
223 wm_interps = ilo_shader_get_kernel_param(fs,
224 ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS);
225
226 wm_dw1 |= wm_interps << GEN7_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT;
227
228 STATIC_ASSERT(Elements(cso->payload) >= 4);
229 cso->payload[0] = dw2;
230 cso->payload[1] = dw4;
231 cso->payload[2] = dw5;
232 cso->payload[3] = wm_dw1;
233 }
234
235 void
236 ilo_gpe_init_view_surface_null_gen7(const struct ilo_dev_info *dev,
237 unsigned width, unsigned height,
238 unsigned depth, unsigned level,
239 struct ilo_view_surface *surf)
240 {
241 uint32_t *dw;
242
243 ILO_GPE_VALID_GEN(dev, 7, 7.5);
244
245 /*
246 * From the Ivy Bridge PRM, volume 4 part 1, page 62:
247 *
248 * "A null surface is used in instances where an actual surface is not
249 * bound. When a write message is generated to a null surface, no
250 * actual surface is written to. When a read message (including any
251 * sampling engine message) is generated to a null surface, the result
252 * is all zeros. Note that a null surface type is allowed to be used
253 * with all messages, even if it is not specificially indicated as
254 * supported. All of the remaining fields in surface state are ignored
255 * for null surfaces, with the following exceptions:
256 *
257 * * Width, Height, Depth, LOD, and Render Target View Extent fields
258 * must match the depth buffer's corresponding state for all render
259 * target surfaces, including null.
260 * * All sampling engine and data port messages support null surfaces
261 * with the above behavior, even if not mentioned as specifically
262 * supported, except for the following:
263 * * Data Port Media Block Read/Write messages.
264 * * The Surface Type of a surface used as a render target (accessed
265 * via the Data Port's Render Target Write message) must be the same
266 * as the Surface Type of all other render targets and of the depth
267 * buffer (defined in 3DSTATE_DEPTH_BUFFER), unless either the depth
268 * buffer or render targets are SURFTYPE_NULL."
269 *
270 * From the Ivy Bridge PRM, volume 4 part 1, page 65:
271 *
272 * "If Surface Type is SURFTYPE_NULL, this field (Tiled Surface) must be
273 * true"
274 */
275
276 STATIC_ASSERT(Elements(surf->payload) >= 8);
277 dw = surf->payload;
278
279 dw[0] = BRW_SURFACE_NULL << BRW_SURFACE_TYPE_SHIFT |
280 BRW_SURFACEFORMAT_B8G8R8A8_UNORM << BRW_SURFACE_FORMAT_SHIFT |
281 BRW_SURFACE_TILED << 13;
282
283 dw[1] = 0;
284
285 dw[2] = SET_FIELD(height - 1, GEN7_SURFACE_HEIGHT) |
286 SET_FIELD(width - 1, GEN7_SURFACE_WIDTH);
287
288 dw[3] = SET_FIELD(depth - 1, BRW_SURFACE_DEPTH);
289
290 dw[4] = 0;
291 dw[5] = level;
292
293 dw[6] = 0;
294 dw[7] = 0;
295
296 surf->bo = NULL;
297 }
298
299 void
300 ilo_gpe_init_view_surface_for_buffer_gen7(const struct ilo_dev_info *dev,
301 const struct ilo_buffer *buf,
302 unsigned offset, unsigned size,
303 unsigned struct_size,
304 enum pipe_format elem_format,
305 bool is_rt, bool render_cache_rw,
306 struct ilo_view_surface *surf)
307 {
308 const bool typed = (elem_format != PIPE_FORMAT_NONE);
309 const bool structured = (!typed && struct_size > 1);
310 const int elem_size = (typed) ?
311 util_format_get_blocksize(elem_format) : 1;
312 int width, height, depth, pitch;
313 int surface_type, surface_format, num_entries;
314 uint32_t *dw;
315
316 ILO_GPE_VALID_GEN(dev, 7, 7.5);
317
318 surface_type = (structured) ? 5 : BRW_SURFACE_BUFFER;
319
320 surface_format = (typed) ?
321 ilo_translate_color_format(elem_format) : BRW_SURFACEFORMAT_RAW;
322
323 num_entries = size / struct_size;
324 /* see if there is enough space to fit another element */
325 if (size % struct_size >= elem_size && !structured)
326 num_entries++;
327
328 /*
329 * From the Ivy Bridge PRM, volume 4 part 1, page 67:
330 *
331 * "For SURFTYPE_BUFFER render targets, this field (Surface Base
332 * Address) specifies the base address of first element of the
333 * surface. The surface is interpreted as a simple array of that
334 * single element type. The address must be naturally-aligned to the
335 * element size (e.g., a buffer containing R32G32B32A32_FLOAT elements
336 * must be 16-byte aligned)
337 *
338 * For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
339 * the base address of the first element of the surface, computed in
340 * software by adding the surface base address to the byte offset of
341 * the element in the buffer."
342 */
343 if (is_rt)
344 assert(offset % elem_size == 0);
345
346 /*
347 * From the Ivy Bridge PRM, volume 4 part 1, page 68:
348 *
349 * "For typed buffer and structured buffer surfaces, the number of
350 * entries in the buffer ranges from 1 to 2^27. For raw buffer
351 * surfaces, the number of entries in the buffer is the number of
352 * bytes which can range from 1 to 2^30."
353 */
354 assert(num_entries >= 1 &&
355 num_entries <= 1 << ((typed || structured) ? 27 : 30));
356
357 /*
358 * From the Ivy Bridge PRM, volume 4 part 1, page 69:
359 *
360 * "For SURFTYPE_BUFFER: The low two bits of this field (Width) must be
361 * 11 if the Surface Format is RAW (the size of the buffer must be a
362 * multiple of 4 bytes)."
363 *
364 * From the Ivy Bridge PRM, volume 4 part 1, page 70:
365 *
366 * "For surfaces of type SURFTYPE_BUFFER and SURFTYPE_STRBUF, this
367 * field (Surface Pitch) indicates the size of the structure."
368 *
369 * "For linear surfaces with Surface Type of SURFTYPE_STRBUF, the pitch
370 * must be a multiple of 4 bytes."
371 */
372 if (structured)
373 assert(struct_size % 4 == 0);
374 else if (!typed)
375 assert(num_entries % 4 == 0);
376
377 pitch = struct_size;
378
379 pitch--;
380 num_entries--;
381 /* bits [6:0] */
382 width = (num_entries & 0x0000007f);
383 /* bits [20:7] */
384 height = (num_entries & 0x001fff80) >> 7;
385 /* bits [30:21] */
386 depth = (num_entries & 0x7fe00000) >> 21;
387 /* limit to [26:21] */
388 if (typed || structured)
389 depth &= 0x3f;
390
391 STATIC_ASSERT(Elements(surf->payload) >= 8);
392 dw = surf->payload;
393
394 dw[0] = surface_type << BRW_SURFACE_TYPE_SHIFT |
395 surface_format << BRW_SURFACE_FORMAT_SHIFT;
396 if (render_cache_rw)
397 dw[0] |= BRW_SURFACE_RC_READ_WRITE;
398
399 dw[1] = offset;
400
401 dw[2] = SET_FIELD(height, GEN7_SURFACE_HEIGHT) |
402 SET_FIELD(width, GEN7_SURFACE_WIDTH);
403
404 dw[3] = SET_FIELD(depth, BRW_SURFACE_DEPTH) |
405 pitch;
406
407 dw[4] = 0;
408 dw[5] = 0;
409
410 dw[6] = 0;
411 dw[7] = 0;
412
413 if (dev->gen >= ILO_GEN(7.5)) {
414 dw[7] |= SET_FIELD(HSW_SCS_RED, GEN7_SURFACE_SCS_R) |
415 SET_FIELD(HSW_SCS_GREEN, GEN7_SURFACE_SCS_G) |
416 SET_FIELD(HSW_SCS_BLUE, GEN7_SURFACE_SCS_B) |
417 SET_FIELD(HSW_SCS_ALPHA, GEN7_SURFACE_SCS_A);
418 }
419
420 /* do not increment reference count */
421 surf->bo = buf->bo;
422 }
423
424 void
425 ilo_gpe_init_view_surface_for_texture_gen7(const struct ilo_dev_info *dev,
426 const struct ilo_texture *tex,
427 enum pipe_format format,
428 unsigned first_level,
429 unsigned num_levels,
430 unsigned first_layer,
431 unsigned num_layers,
432 bool is_rt, bool offset_to_layer,
433 struct ilo_view_surface *surf)
434 {
435 int surface_type, surface_format;
436 int width, height, depth, pitch, lod;
437 unsigned layer_offset, x_offset, y_offset;
438 uint32_t *dw;
439
440 ILO_GPE_VALID_GEN(dev, 7, 7.5);
441
442 surface_type = ilo_gpe_gen6_translate_texture(tex->base.target);
443 assert(surface_type != BRW_SURFACE_BUFFER);
444
445 if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT && tex->separate_s8)
446 format = PIPE_FORMAT_Z32_FLOAT;
447
448 if (is_rt)
449 surface_format = ilo_translate_render_format(format);
450 else
451 surface_format = ilo_translate_texture_format(format);
452 assert(surface_format >= 0);
453
454 width = tex->base.width0;
455 height = tex->base.height0;
456 depth = (tex->base.target == PIPE_TEXTURE_3D) ?
457 tex->base.depth0 : num_layers;
458 pitch = tex->bo_stride;
459
460 if (surface_type == BRW_SURFACE_CUBE) {
461 /*
462 * From the Ivy Bridge PRM, volume 4 part 1, page 70:
463 *
464 * "For SURFTYPE_CUBE:For Sampling Engine Surfaces, the range of
465 * this field is [0,340], indicating the number of cube array
466 * elements (equal to the number of underlying 2D array elements
467 * divided by 6). For other surfaces, this field must be zero."
468 *
469 * When is_rt is true, we treat the texture as a 2D one to avoid the
470 * restriction.
471 */
472 if (is_rt) {
473 surface_type = BRW_SURFACE_2D;
474 }
475 else {
476 assert(num_layers % 6 == 0);
477 depth = num_layers / 6;
478 }
479 }
480
481 /* sanity check the size */
482 assert(width >= 1 && height >= 1 && depth >= 1 && pitch >= 1);
483 assert(first_layer < 2048 && num_layers <= 2048);
484 switch (surface_type) {
485 case BRW_SURFACE_1D:
486 assert(width <= 16384 && height == 1 && depth <= 2048);
487 break;
488 case BRW_SURFACE_2D:
489 assert(width <= 16384 && height <= 16384 && depth <= 2048);
490 break;
491 case BRW_SURFACE_3D:
492 assert(width <= 2048 && height <= 2048 && depth <= 2048);
493 if (!is_rt)
494 assert(first_layer == 0);
495 break;
496 case BRW_SURFACE_CUBE:
497 assert(width <= 16384 && height <= 16384 && depth <= 86);
498 assert(width == height);
499 if (is_rt)
500 assert(first_layer == 0);
501 break;
502 default:
503 assert(!"unexpected surface type");
504 break;
505 }
506
507 if (is_rt) {
508 assert(num_levels == 1);
509 lod = first_level;
510 }
511 else {
512 lod = num_levels - 1;
513 }
514
515 /*
516 * Offset to the layer. When rendering, the hardware requires LOD and
517 * Depth to be the same for all render targets and the depth buffer. We
518 * need to offset to the layer manually and always set LOD and Depth to 0.
519 */
520 if (offset_to_layer) {
521 /* we lose the capability for layered rendering */
522 assert(is_rt && num_layers == 1);
523
524 layer_offset = ilo_texture_get_slice_offset(tex,
525 first_level, first_layer, &x_offset, &y_offset);
526
527 assert(x_offset % 4 == 0);
528 assert(y_offset % 2 == 0);
529 x_offset /= 4;
530 y_offset /= 2;
531
532 /* derive the size for the LOD */
533 width = u_minify(width, first_level);
534 height = u_minify(height, first_level);
535
536 first_level = 0;
537 first_layer = 0;
538
539 lod = 0;
540 depth = 1;
541 }
542 else {
543 layer_offset = 0;
544 x_offset = 0;
545 y_offset = 0;
546 }
547
548 /*
549 * From the Ivy Bridge PRM, volume 4 part 1, page 68:
550 *
551 * "The Base Address for linear render target surfaces and surfaces
552 * accessed with the typed surface read/write data port messages must
553 * be element-size aligned, for non-YUV surface formats, or a multiple
554 * of 2 element-sizes for YUV surface formats. Other linear surfaces
555 * have no alignment requirements (byte alignment is sufficient)."
556 *
557 * From the Ivy Bridge PRM, volume 4 part 1, page 70:
558 *
559 * "For linear render target surfaces and surfaces accessed with the
560 * typed data port messages, the pitch must be a multiple of the
561 * element size for non-YUV surface formats. Pitch must be a multiple
562 * of 2 * element size for YUV surface formats. For linear surfaces
563 * with Surface Type of SURFTYPE_STRBUF, the pitch must be a multiple
564 * of 4 bytes.For other linear surfaces, the pitch can be any multiple
565 * of bytes."
566 *
567 * From the Ivy Bridge PRM, volume 4 part 1, page 74:
568 *
569 * "For linear surfaces, this field (X Offset) must be zero."
570 */
571 if (tex->tiling == INTEL_TILING_NONE) {
572 if (is_rt) {
573 const int elem_size = util_format_get_blocksize(format);
574 assert(layer_offset % elem_size == 0);
575 assert(pitch % elem_size == 0);
576 }
577
578 assert(!x_offset);
579 }
580
581 STATIC_ASSERT(Elements(surf->payload) >= 8);
582 dw = surf->payload;
583
584 dw[0] = surface_type << BRW_SURFACE_TYPE_SHIFT |
585 surface_format << BRW_SURFACE_FORMAT_SHIFT |
586 ilo_gpe_gen6_translate_winsys_tiling(tex->tiling) << 13;
587
588 /*
589 * From the Ivy Bridge PRM, volume 4 part 1, page 63:
590 *
591 * "If this field (Surface Array) is enabled, the Surface Type must be
592 * SURFTYPE_1D, SURFTYPE_2D, or SURFTYPE_CUBE. If this field is
593 * disabled and Surface Type is SURFTYPE_1D, SURFTYPE_2D, or
594 * SURFTYPE_CUBE, the Depth field must be set to zero."
595 *
596 * For non-3D sampler surfaces, resinfo (the sampler message) always
597 * returns zero for the number of layers when this field is not set.
598 */
599 if (surface_type != BRW_SURFACE_3D) {
600 if (util_resource_is_array_texture(&tex->base))
601 dw[0] |= GEN7_SURFACE_IS_ARRAY;
602 else
603 assert(depth == 1);
604 }
605
606 if (tex->valign_4)
607 dw[0] |= GEN7_SURFACE_VALIGN_4;
608
609 if (tex->halign_8)
610 dw[0] |= GEN7_SURFACE_HALIGN_8;
611
612 if (tex->array_spacing_full)
613 dw[0] |= GEN7_SURFACE_ARYSPC_FULL;
614 else
615 dw[0] |= GEN7_SURFACE_ARYSPC_LOD0;
616
617 if (is_rt)
618 dw[0] |= BRW_SURFACE_RC_READ_WRITE;
619
620 if (surface_type == BRW_SURFACE_CUBE && !is_rt)
621 dw[0] |= BRW_SURFACE_CUBEFACE_ENABLES;
622
623 dw[1] = layer_offset;
624
625 dw[2] = SET_FIELD(height - 1, GEN7_SURFACE_HEIGHT) |
626 SET_FIELD(width - 1, GEN7_SURFACE_WIDTH);
627
628 dw[3] = SET_FIELD(depth - 1, BRW_SURFACE_DEPTH) |
629 (pitch - 1);
630
631 dw[4] = first_layer << 18 |
632 (num_layers - 1) << 7;
633
634 /*
635 * MSFMT_MSS means the samples are not interleaved and MSFMT_DEPTH_STENCIL
636 * means the samples are interleaved. The layouts are the same when the
637 * number of samples is 1.
638 */
639 if (tex->interleaved && tex->base.nr_samples > 1) {
640 assert(!is_rt);
641 dw[4] |= GEN7_SURFACE_MSFMT_DEPTH_STENCIL;
642 }
643 else {
644 dw[4] |= GEN7_SURFACE_MSFMT_MSS;
645 }
646
647 if (tex->base.nr_samples > 4)
648 dw[4] |= GEN7_SURFACE_MULTISAMPLECOUNT_8;
649 else if (tex->base.nr_samples > 2)
650 dw[4] |= GEN7_SURFACE_MULTISAMPLECOUNT_4;
651 else
652 dw[4] |= GEN7_SURFACE_MULTISAMPLECOUNT_1;
653
654 dw[5] = x_offset << BRW_SURFACE_X_OFFSET_SHIFT |
655 y_offset << BRW_SURFACE_Y_OFFSET_SHIFT |
656 SET_FIELD(first_level, GEN7_SURFACE_MIN_LOD) |
657 lod;
658
659 dw[6] = 0;
660 dw[7] = 0;
661
662 if (dev->gen >= ILO_GEN(7.5)) {
663 dw[7] |= SET_FIELD(HSW_SCS_RED, GEN7_SURFACE_SCS_R) |
664 SET_FIELD(HSW_SCS_GREEN, GEN7_SURFACE_SCS_G) |
665 SET_FIELD(HSW_SCS_BLUE, GEN7_SURFACE_SCS_B) |
666 SET_FIELD(HSW_SCS_ALPHA, GEN7_SURFACE_SCS_A);
667 }
668
669 /* do not increment reference count */
670 surf->bo = tex->bo;
671 }
672
673 int
674 ilo_gpe_gen7_estimate_command_size(const struct ilo_dev_info *dev,
675 enum ilo_gpe_gen7_command cmd,
676 int arg)
677 {
678 static const struct {
679 int header;
680 int body;
681 } gen7_command_size_table[ILO_GPE_GEN7_COMMAND_COUNT] = {
682 [ILO_GPE_GEN7_STATE_BASE_ADDRESS] = { 0, 10 },
683 [ILO_GPE_GEN7_STATE_SIP] = { 0, 2 },
684 [ILO_GPE_GEN7_3DSTATE_VF_STATISTICS] = { 0, 1 },
685 [ILO_GPE_GEN7_PIPELINE_SELECT] = { 0, 1 },
686 [ILO_GPE_GEN7_MEDIA_VFE_STATE] = { 0, 8 },
687 [ILO_GPE_GEN7_MEDIA_CURBE_LOAD] = { 0, 4 },
688 [ILO_GPE_GEN7_MEDIA_INTERFACE_DESCRIPTOR_LOAD] = { 0, 4 },
689 [ILO_GPE_GEN7_MEDIA_STATE_FLUSH] = { 0, 2 },
690 [ILO_GPE_GEN7_GPGPU_WALKER] = { 0, 11 },
691 [ILO_GPE_GEN7_3DSTATE_CLEAR_PARAMS] = { 0, 3 },
692 [ILO_GPE_GEN7_3DSTATE_DEPTH_BUFFER] = { 0, 7 },
693 [ILO_GPE_GEN7_3DSTATE_STENCIL_BUFFER] = { 0, 3 },
694 [ILO_GPE_GEN7_3DSTATE_HIER_DEPTH_BUFFER] = { 0, 3 },
695 [ILO_GPE_GEN7_3DSTATE_VERTEX_BUFFERS] = { 1, 4 },
696 [ILO_GPE_GEN7_3DSTATE_VERTEX_ELEMENTS] = { 1, 2 },
697 [ILO_GPE_GEN7_3DSTATE_INDEX_BUFFER] = { 0, 3 },
698 [ILO_GPE_GEN7_3DSTATE_VF] = { 0, 2 },
699 [ILO_GPE_GEN7_3DSTATE_CC_STATE_POINTERS] = { 0, 2 },
700 [ILO_GPE_GEN7_3DSTATE_SCISSOR_STATE_POINTERS] = { 0, 2 },
701 [ILO_GPE_GEN7_3DSTATE_VS] = { 0, 6 },
702 [ILO_GPE_GEN7_3DSTATE_GS] = { 0, 7 },
703 [ILO_GPE_GEN7_3DSTATE_CLIP] = { 0, 4 },
704 [ILO_GPE_GEN7_3DSTATE_SF] = { 0, 7 },
705 [ILO_GPE_GEN7_3DSTATE_WM] = { 0, 3 },
706 [ILO_GPE_GEN7_3DSTATE_CONSTANT_VS] = { 0, 7 },
707 [ILO_GPE_GEN7_3DSTATE_CONSTANT_GS] = { 0, 7 },
708 [ILO_GPE_GEN7_3DSTATE_CONSTANT_PS] = { 0, 7 },
709 [ILO_GPE_GEN7_3DSTATE_SAMPLE_MASK] = { 0, 2 },
710 [ILO_GPE_GEN7_3DSTATE_CONSTANT_HS] = { 0, 7 },
711 [ILO_GPE_GEN7_3DSTATE_CONSTANT_DS] = { 0, 7 },
712 [ILO_GPE_GEN7_3DSTATE_HS] = { 0, 7 },
713 [ILO_GPE_GEN7_3DSTATE_TE] = { 0, 4 },
714 [ILO_GPE_GEN7_3DSTATE_DS] = { 0, 6 },
715 [ILO_GPE_GEN7_3DSTATE_STREAMOUT] = { 0, 3 },
716 [ILO_GPE_GEN7_3DSTATE_SBE] = { 0, 14 },
717 [ILO_GPE_GEN7_3DSTATE_PS] = { 0, 8 },
718 [ILO_GPE_GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP] = { 0, 2 },
719 [ILO_GPE_GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC] = { 0, 2 },
720 [ILO_GPE_GEN7_3DSTATE_BLEND_STATE_POINTERS] = { 0, 2 },
721 [ILO_GPE_GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS] = { 0, 2 },
722 [ILO_GPE_GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS] = { 0, 2 },
723 [ILO_GPE_GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS] = { 0, 2 },
724 [ILO_GPE_GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS] = { 0, 2 },
725 [ILO_GPE_GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS] = { 0, 2 },
726 [ILO_GPE_GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS] = { 0, 2 },
727 [ILO_GPE_GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS] = { 0, 2 },
728 [ILO_GPE_GEN7_3DSTATE_SAMPLER_STATE_POINTERS_HS] = { 0, 2 },
729 [ILO_GPE_GEN7_3DSTATE_SAMPLER_STATE_POINTERS_DS] = { 0, 2 },
730 [ILO_GPE_GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS] = { 0, 2 },
731 [ILO_GPE_GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS] = { 0, 2 },
732 [ILO_GPE_GEN7_3DSTATE_URB_VS] = { 0, 2 },
733 [ILO_GPE_GEN7_3DSTATE_URB_HS] = { 0, 2 },
734 [ILO_GPE_GEN7_3DSTATE_URB_DS] = { 0, 2 },
735 [ILO_GPE_GEN7_3DSTATE_URB_GS] = { 0, 2 },
736 [ILO_GPE_GEN7_3DSTATE_DRAWING_RECTANGLE] = { 0, 4 },
737 [ILO_GPE_GEN7_3DSTATE_POLY_STIPPLE_OFFSET] = { 0, 2 },
738 [ILO_GPE_GEN7_3DSTATE_POLY_STIPPLE_PATTERN] = { 0, 33, },
739 [ILO_GPE_GEN7_3DSTATE_LINE_STIPPLE] = { 0, 3 },
740 [ILO_GPE_GEN7_3DSTATE_AA_LINE_PARAMETERS] = { 0, 3 },
741 [ILO_GPE_GEN7_3DSTATE_MULTISAMPLE] = { 0, 4 },
742 [ILO_GPE_GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS] = { 0, 2 },
743 [ILO_GPE_GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_HS] = { 0, 2 },
744 [ILO_GPE_GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_DS] = { 0, 2 },
745 [ILO_GPE_GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_GS] = { 0, 2 },
746 [ILO_GPE_GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS] = { 0, 2 },
747 [ILO_GPE_GEN7_3DSTATE_SO_DECL_LIST] = { 3, 2 },
748 [ILO_GPE_GEN7_3DSTATE_SO_BUFFER] = { 0, 4 },
749 [ILO_GPE_GEN7_PIPE_CONTROL] = { 0, 5 },
750 [ILO_GPE_GEN7_3DPRIMITIVE] = { 0, 7 },
751 };
752 const int header = gen7_command_size_table[cmd].header;
753 const int body = gen7_command_size_table[cmd].body;
754 const int count = arg;
755
756 ILO_GPE_VALID_GEN(dev, 7, 7.5);
757 assert(cmd < ILO_GPE_GEN7_COMMAND_COUNT);
758
759 return (likely(count)) ? header + body * count : 0;
760 }
761
762 int
763 ilo_gpe_gen7_estimate_state_size(const struct ilo_dev_info *dev,
764 enum ilo_gpe_gen7_state state,
765 int arg)
766 {
767 static const struct {
768 int alignment;
769 int body;
770 bool is_array;
771 } gen7_state_size_table[ILO_GPE_GEN7_STATE_COUNT] = {
772 [ILO_GPE_GEN7_INTERFACE_DESCRIPTOR_DATA] = { 8, 8, true },
773 [ILO_GPE_GEN7_SF_CLIP_VIEWPORT] = { 16, 16, true },
774 [ILO_GPE_GEN7_CC_VIEWPORT] = { 8, 2, true },
775 [ILO_GPE_GEN7_COLOR_CALC_STATE] = { 16, 6, false },
776 [ILO_GPE_GEN7_BLEND_STATE] = { 16, 2, true },
777 [ILO_GPE_GEN7_DEPTH_STENCIL_STATE] = { 16, 3, false },
778 [ILO_GPE_GEN7_SCISSOR_RECT] = { 8, 2, true },
779 [ILO_GPE_GEN7_BINDING_TABLE_STATE] = { 8, 1, true },
780 [ILO_GPE_GEN7_SURFACE_STATE] = { 8, 8, false },
781 [ILO_GPE_GEN7_SAMPLER_STATE] = { 8, 4, true },
782 [ILO_GPE_GEN7_SAMPLER_BORDER_COLOR_STATE] = { 8, 4, false },
783 [ILO_GPE_GEN7_PUSH_CONSTANT_BUFFER] = { 8, 1, true },
784 };
785 const int alignment = gen7_state_size_table[state].alignment;
786 const int body = gen7_state_size_table[state].body;
787 const bool is_array = gen7_state_size_table[state].is_array;
788 const int count = arg;
789 int estimate;
790
791 ILO_GPE_VALID_GEN(dev, 7, 7.5);
792 assert(state < ILO_GPE_GEN7_STATE_COUNT);
793
794 if (likely(count)) {
795 if (is_array) {
796 estimate = (alignment - 1) + body * count;
797 }
798 else {
799 estimate = (alignment - 1) + body;
800 /* all states are aligned */
801 if (count > 1)
802 estimate += util_align_npot(body, alignment) * (count - 1);
803 }
804 }
805 else {
806 estimate = 0;
807 }
808
809 return estimate;
810 }