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