blob: 53e17c04125c6d2f969f0b9e3459dcbd2459dd60 [file] [log] [blame]
Chia-I Wu5a323262014-08-11 10:31:53 +08001/*
2 * XGL
3 *
4 * Copyright (C) 2014 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.
Chia-I Wu44e42362014-09-02 08:32:09 +080023 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
Chia-I Wu5a323262014-08-11 10:31:53 +080026 */
27
Chia-I Wu9269d1c2014-08-16 12:47:47 +080028#include "genhw/genhw.h"
29#include "kmd/winsys.h"
Chia-I Wu714df452015-01-01 07:55:04 +080030#include "buf.h"
Chia-I Wu5a323262014-08-11 10:31:53 +080031#include "dev.h"
Chia-I Wu9269d1c2014-08-16 12:47:47 +080032#include "format.h"
Chia-I Wu5a323262014-08-11 10:31:53 +080033#include "gpu.h"
34#include "img.h"
35#include "mem.h"
36#include "view.h"
37
Chia-I Wu06bed192014-08-20 13:57:18 +080038static void surface_state_null_gen7(const struct intel_gpu *gpu,
39 uint32_t dw[8])
Chia-I Wu9269d1c2014-08-16 12:47:47 +080040{
41 INTEL_GPU_ASSERT(gpu, 7, 7.5);
42
43 /*
44 * From the Ivy Bridge PRM, volume 4 part 1, page 62:
45 *
46 * "A null surface is used in instances where an actual surface is not
47 * bound. When a write message is generated to a null surface, no
48 * actual surface is written to. When a read message (including any
49 * sampling engine message) is generated to a null surface, the result
50 * is all zeros. Note that a null surface type is allowed to be used
51 * with all messages, even if it is not specificially indicated as
52 * supported. All of the remaining fields in surface state are ignored
53 * for null surfaces, with the following exceptions:
54 *
55 * * Width, Height, Depth, LOD, and Render Target View Extent fields
56 * must match the depth buffer's corresponding state for all render
57 * target surfaces, including null.
58 * * All sampling engine and data port messages support null surfaces
59 * with the above behavior, even if not mentioned as specifically
60 * supported, except for the following:
61 * * Data Port Media Block Read/Write messages.
62 * * The Surface Type of a surface used as a render target (accessed
63 * via the Data Port's Render Target Write message) must be the same
64 * as the Surface Type of all other render targets and of the depth
65 * buffer (defined in 3DSTATE_DEPTH_BUFFER), unless either the depth
66 * buffer or render targets are SURFTYPE_NULL."
67 *
68 * From the Ivy Bridge PRM, volume 4 part 1, page 65:
69 *
70 * "If Surface Type is SURFTYPE_NULL, this field (Tiled Surface) must be
71 * true"
72 */
73
74 dw[0] = GEN6_SURFTYPE_NULL << GEN7_SURFACE_DW0_TYPE__SHIFT |
75 GEN6_FORMAT_B8G8R8A8_UNORM << GEN7_SURFACE_DW0_FORMAT__SHIFT |
76 GEN6_TILING_X << 13;
77
78 dw[1] = 0;
79 dw[2] = 0;
80 dw[3] = 0;
81 dw[4] = 0;
82 dw[5] = 0;
83 dw[6] = 0;
84 dw[7] = 0;
85}
86
Chia-I Wu06bed192014-08-20 13:57:18 +080087static void surface_state_buf_gen7(const struct intel_gpu *gpu,
88 unsigned offset, unsigned size,
89 unsigned struct_size,
90 XGL_FORMAT elem_format,
91 bool is_rt, bool render_cache_rw,
92 uint32_t dw[8])
Chia-I Wu9269d1c2014-08-16 12:47:47 +080093{
94 const bool typed = !icd_format_is_undef(elem_format);
95 const bool structured = (!typed && struct_size > 1);
96 const int elem_size = (typed) ?
97 icd_format_get_size(elem_format) : 1;
98 int width, height, depth, pitch;
99 int surface_type, surface_format, num_entries;
100
101 INTEL_GPU_ASSERT(gpu, 7, 7.5);
102
103 surface_type = (structured) ? GEN7_SURFTYPE_STRBUF : GEN6_SURFTYPE_BUFFER;
104
105 surface_format = (typed) ?
106 intel_format_translate_color(gpu, elem_format) : GEN6_FORMAT_RAW;
107
108 num_entries = size / struct_size;
109 /* see if there is enough space to fit another element */
110 if (size % struct_size >= elem_size && !structured)
111 num_entries++;
112
113 /*
114 * From the Ivy Bridge PRM, volume 4 part 1, page 67:
115 *
116 * "For SURFTYPE_BUFFER render targets, this field (Surface Base
117 * Address) specifies the base address of first element of the
118 * surface. The surface is interpreted as a simple array of that
119 * single element type. The address must be naturally-aligned to the
120 * element size (e.g., a buffer containing R32G32B32A32_FLOAT elements
121 * must be 16-byte aligned)
122 *
123 * For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
124 * the base address of the first element of the surface, computed in
125 * software by adding the surface base address to the byte offset of
126 * the element in the buffer."
127 */
128 if (is_rt)
129 assert(offset % elem_size == 0);
130
131 /*
132 * From the Ivy Bridge PRM, volume 4 part 1, page 68:
133 *
134 * "For typed buffer and structured buffer surfaces, the number of
135 * entries in the buffer ranges from 1 to 2^27. For raw buffer
136 * surfaces, the number of entries in the buffer is the number of
137 * bytes which can range from 1 to 2^30."
138 */
139 assert(num_entries >= 1 &&
140 num_entries <= 1 << ((typed || structured) ? 27 : 30));
141
142 /*
143 * From the Ivy Bridge PRM, volume 4 part 1, page 69:
144 *
145 * "For SURFTYPE_BUFFER: The low two bits of this field (Width) must be
146 * 11 if the Surface Format is RAW (the size of the buffer must be a
147 * multiple of 4 bytes)."
148 *
149 * From the Ivy Bridge PRM, volume 4 part 1, page 70:
150 *
151 * "For surfaces of type SURFTYPE_BUFFER and SURFTYPE_STRBUF, this
152 * field (Surface Pitch) indicates the size of the structure."
153 *
154 * "For linear surfaces with Surface Type of SURFTYPE_STRBUF, the pitch
155 * must be a multiple of 4 bytes."
156 */
157 if (structured)
158 assert(struct_size % 4 == 0);
159 else if (!typed)
160 assert(num_entries % 4 == 0);
161
162 pitch = struct_size;
163
164 pitch--;
165 num_entries--;
166 /* bits [6:0] */
167 width = (num_entries & 0x0000007f);
168 /* bits [20:7] */
169 height = (num_entries & 0x001fff80) >> 7;
170 /* bits [30:21] */
171 depth = (num_entries & 0x7fe00000) >> 21;
172 /* limit to [26:21] */
173 if (typed || structured)
174 depth &= 0x3f;
175
176 dw[0] = surface_type << GEN7_SURFACE_DW0_TYPE__SHIFT |
177 surface_format << GEN7_SURFACE_DW0_FORMAT__SHIFT;
178 if (render_cache_rw)
179 dw[0] |= GEN7_SURFACE_DW0_RENDER_CACHE_RW;
180
181 dw[1] = offset;
182
183 dw[2] = height << GEN7_SURFACE_DW2_HEIGHT__SHIFT |
184 width << GEN7_SURFACE_DW2_WIDTH__SHIFT;
185
186 dw[3] = depth << GEN7_SURFACE_DW3_DEPTH__SHIFT |
187 pitch;
188
189 dw[4] = 0;
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700190 dw[5] = GEN7_MOCS_L3_WB << GEN7_SURFACE_DW5_MOCS__SHIFT;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800191
192 dw[6] = 0;
193 dw[7] = 0;
194
195 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
196 dw[7] |= GEN75_SCS_RED << GEN75_SURFACE_DW7_SCS_R__SHIFT |
197 GEN75_SCS_GREEN << GEN75_SURFACE_DW7_SCS_G__SHIFT |
198 GEN75_SCS_BLUE << GEN75_SURFACE_DW7_SCS_B__SHIFT |
199 GEN75_SCS_ALPHA << GEN75_SURFACE_DW7_SCS_A__SHIFT;
200 }
201}
202
Chia-I Wueac0acf2015-02-17 09:51:00 -0700203static int img_type_to_view_type(XGL_IMAGE_TYPE type)
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800204{
205 switch (type) {
206 case XGL_IMAGE_1D: return XGL_IMAGE_VIEW_1D;
207 case XGL_IMAGE_2D: return XGL_IMAGE_VIEW_2D;
208 case XGL_IMAGE_3D: return XGL_IMAGE_VIEW_3D;
209 default: assert(!"unknown img type"); return XGL_IMAGE_VIEW_1D;
210 }
211}
212
213static int view_type_to_surface_type(XGL_IMAGE_VIEW_TYPE type)
214{
215 switch (type) {
216 case XGL_IMAGE_VIEW_1D: return GEN6_SURFTYPE_1D;
217 case XGL_IMAGE_VIEW_2D: return GEN6_SURFTYPE_2D;
218 case XGL_IMAGE_VIEW_3D: return GEN6_SURFTYPE_3D;
219 case XGL_IMAGE_VIEW_CUBE: return GEN6_SURFTYPE_CUBE;
220 default: assert(!"unknown view type"); return GEN6_SURFTYPE_NULL;
221 }
222}
223
Chia-I Wuf57758c2014-12-02 14:15:50 +0800224static int channel_swizzle_to_scs(XGL_CHANNEL_SWIZZLE swizzle)
225{
226 switch (swizzle) {
227 case XGL_CHANNEL_SWIZZLE_ZERO: return GEN75_SCS_ZERO;
228 case XGL_CHANNEL_SWIZZLE_ONE: return GEN75_SCS_ONE;
229 case XGL_CHANNEL_SWIZZLE_R: return GEN75_SCS_RED;
230 case XGL_CHANNEL_SWIZZLE_G: return GEN75_SCS_GREEN;
231 case XGL_CHANNEL_SWIZZLE_B: return GEN75_SCS_BLUE;
232 case XGL_CHANNEL_SWIZZLE_A: return GEN75_SCS_ALPHA;
233 default: assert(!"unknown swizzle"); return GEN75_SCS_ZERO;
234 }
235}
236
Chia-I Wu06bed192014-08-20 13:57:18 +0800237static void surface_state_tex_gen7(const struct intel_gpu *gpu,
238 const struct intel_img *img,
239 XGL_IMAGE_VIEW_TYPE type,
240 XGL_FORMAT format,
241 unsigned first_level,
242 unsigned num_levels,
243 unsigned first_layer,
244 unsigned num_layers,
Chia-I Wuf57758c2014-12-02 14:15:50 +0800245 XGL_CHANNEL_MAPPING swizzles,
Chia-I Wu06bed192014-08-20 13:57:18 +0800246 bool is_rt,
247 uint32_t dw[8])
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800248{
249 int surface_type, surface_format;
250 int width, height, depth, pitch, lod;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800251
252 INTEL_GPU_ASSERT(gpu, 7, 7.5);
253
254 surface_type = view_type_to_surface_type(type);
255 assert(surface_type != GEN6_SURFTYPE_BUFFER);
256
257 surface_format = intel_format_translate_color(gpu, format);
258 assert(surface_format >= 0);
259
Chia-I Wu73e326f2014-08-21 11:07:57 +0800260 width = img->layout.width0;
261 height = img->layout.height0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800262 depth = (type == XGL_IMAGE_VIEW_3D) ?
Chia-I Wu73e326f2014-08-21 11:07:57 +0800263 img->depth : num_layers;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800264 pitch = img->layout.bo_stride;
265
266 if (surface_type == GEN6_SURFTYPE_CUBE) {
267 /*
268 * From the Ivy Bridge PRM, volume 4 part 1, page 70:
269 *
270 * "For SURFTYPE_CUBE:For Sampling Engine Surfaces, the range of
271 * this field is [0,340], indicating the number of cube array
272 * elements (equal to the number of underlying 2D array elements
273 * divided by 6). For other surfaces, this field must be zero."
274 *
275 * When is_rt is true, we treat the texture as a 2D one to avoid the
276 * restriction.
277 */
278 if (is_rt) {
279 surface_type = GEN6_SURFTYPE_2D;
280 }
281 else {
282 assert(num_layers % 6 == 0);
283 depth = num_layers / 6;
284 }
285 }
286
287 /* sanity check the size */
288 assert(width >= 1 && height >= 1 && depth >= 1 && pitch >= 1);
289 assert(first_layer < 2048 && num_layers <= 2048);
290 switch (surface_type) {
291 case GEN6_SURFTYPE_1D:
292 assert(width <= 16384 && height == 1 && depth <= 2048);
293 break;
294 case GEN6_SURFTYPE_2D:
295 assert(width <= 16384 && height <= 16384 && depth <= 2048);
296 break;
297 case GEN6_SURFTYPE_3D:
298 assert(width <= 2048 && height <= 2048 && depth <= 2048);
299 if (!is_rt)
300 assert(first_layer == 0);
301 break;
302 case GEN6_SURFTYPE_CUBE:
303 assert(width <= 16384 && height <= 16384 && depth <= 86);
304 assert(width == height);
305 if (is_rt)
306 assert(first_layer == 0);
307 break;
308 default:
309 assert(!"unexpected surface type");
310 break;
311 }
312
313 if (is_rt) {
314 assert(num_levels == 1);
315 lod = first_level;
316 }
317 else {
318 lod = num_levels - 1;
319 }
320
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800321 /*
322 * From the Ivy Bridge PRM, volume 4 part 1, page 68:
323 *
324 * "The Base Address for linear render target surfaces and surfaces
325 * accessed with the typed surface read/write data port messages must
326 * be element-size aligned, for non-YUV surface formats, or a multiple
327 * of 2 element-sizes for YUV surface formats. Other linear surfaces
328 * have no alignment requirements (byte alignment is sufficient)."
329 *
330 * From the Ivy Bridge PRM, volume 4 part 1, page 70:
331 *
332 * "For linear render target surfaces and surfaces accessed with the
333 * typed data port messages, the pitch must be a multiple of the
334 * element size for non-YUV surface formats. Pitch must be a multiple
335 * of 2 * element size for YUV surface formats. For linear surfaces
336 * with Surface Type of SURFTYPE_STRBUF, the pitch must be a multiple
337 * of 4 bytes.For other linear surfaces, the pitch can be any multiple
338 * of bytes."
339 *
340 * From the Ivy Bridge PRM, volume 4 part 1, page 74:
341 *
342 * "For linear surfaces, this field (X Offset) must be zero."
343 */
Chia-I Wud1eb90c2015-03-07 06:01:45 +0800344 if (img->layout.tiling == GEN6_TILING_NONE) {
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800345 if (is_rt) {
Chia-I Wu08cd6e92015-02-11 13:44:50 -0700346 const int elem_size U_ASSERT_ONLY = icd_format_get_size(format);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800347 assert(pitch % elem_size == 0);
348 }
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800349 }
350
Chia-I Wud1eb90c2015-03-07 06:01:45 +0800351 assert(img->layout.tiling != GEN8_TILING_W);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800352 dw[0] = surface_type << GEN7_SURFACE_DW0_TYPE__SHIFT |
353 surface_format << GEN7_SURFACE_DW0_FORMAT__SHIFT |
Chia-I Wud1eb90c2015-03-07 06:01:45 +0800354 img->layout.tiling << 13;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800355
356 /*
357 * From the Ivy Bridge PRM, volume 4 part 1, page 63:
358 *
359 * "If this field (Surface Array) is enabled, the Surface Type must be
360 * SURFTYPE_1D, SURFTYPE_2D, or SURFTYPE_CUBE. If this field is
361 * disabled and Surface Type is SURFTYPE_1D, SURFTYPE_2D, or
362 * SURFTYPE_CUBE, the Depth field must be set to zero."
363 *
364 * For non-3D sampler surfaces, resinfo (the sampler message) always
365 * returns zero for the number of layers when this field is not set.
366 */
367 if (surface_type != GEN6_SURFTYPE_3D) {
368 if (num_layers > 1)
369 dw[0] |= GEN7_SURFACE_DW0_IS_ARRAY;
370 else
371 assert(depth == 1);
372 }
373
374 assert(img->layout.align_i == 4 || img->layout.align_i == 8);
375 assert(img->layout.align_j == 2 || img->layout.align_j == 4);
376
377 if (img->layout.align_j == 4)
378 dw[0] |= GEN7_SURFACE_DW0_VALIGN_4;
379
380 if (img->layout.align_i == 8)
381 dw[0] |= GEN7_SURFACE_DW0_HALIGN_8;
382
Chia-I Wu457d0a62014-08-18 13:02:26 +0800383 if (img->layout.walk == INTEL_LAYOUT_WALK_LOD)
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800384 dw[0] |= GEN7_SURFACE_DW0_ARYSPC_LOD0;
Chia-I Wu457d0a62014-08-18 13:02:26 +0800385 else
386 dw[0] |= GEN7_SURFACE_DW0_ARYSPC_FULL;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800387
388 if (is_rt)
389 dw[0] |= GEN7_SURFACE_DW0_RENDER_CACHE_RW;
390
391 if (surface_type == GEN6_SURFTYPE_CUBE && !is_rt)
392 dw[0] |= GEN7_SURFACE_DW0_CUBE_FACE_ENABLES__MASK;
393
Chia-I Wu457d0a62014-08-18 13:02:26 +0800394 dw[1] = 0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800395
396 dw[2] = (height - 1) << GEN7_SURFACE_DW2_HEIGHT__SHIFT |
397 (width - 1) << GEN7_SURFACE_DW2_WIDTH__SHIFT;
398
399 dw[3] = (depth - 1) << GEN7_SURFACE_DW3_DEPTH__SHIFT |
400 (pitch - 1);
401
402 dw[4] = first_layer << 18 |
403 (num_layers - 1) << 7;
404
405 /*
406 * MSFMT_MSS means the samples are not interleaved and MSFMT_DEPTH_STENCIL
407 * means the samples are interleaved. The layouts are the same when the
408 * number of samples is 1.
409 */
410 if (img->layout.interleaved_samples && img->samples > 1) {
411 assert(!is_rt);
412 dw[4] |= GEN7_SURFACE_DW4_MSFMT_DEPTH_STENCIL;
413 }
414 else {
415 dw[4] |= GEN7_SURFACE_DW4_MSFMT_MSS;
416 }
417
418 if (img->samples > 4)
419 dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_8;
420 else if (img->samples > 2)
421 dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_4;
422 else
423 dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_1;
424
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700425 dw[5] = GEN7_MOCS_L3_WB << GEN7_SURFACE_DW5_MOCS__SHIFT |
Chia-I Wub3686982015-02-27 09:51:16 -0700426 (first_level) << GEN7_SURFACE_DW5_MIN_LOD__SHIFT |
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800427 lod;
428
429 dw[6] = 0;
430 dw[7] = 0;
431
432 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
Chia-I Wuf57758c2014-12-02 14:15:50 +0800433 dw[7] |=
434 channel_swizzle_to_scs(swizzles.r) << GEN75_SURFACE_DW7_SCS_R__SHIFT |
435 channel_swizzle_to_scs(swizzles.g) << GEN75_SURFACE_DW7_SCS_G__SHIFT |
436 channel_swizzle_to_scs(swizzles.b) << GEN75_SURFACE_DW7_SCS_B__SHIFT |
437 channel_swizzle_to_scs(swizzles.a) << GEN75_SURFACE_DW7_SCS_A__SHIFT;
438 } else {
439 assert(swizzles.r == XGL_CHANNEL_SWIZZLE_R &&
440 swizzles.g == XGL_CHANNEL_SWIZZLE_G &&
441 swizzles.b == XGL_CHANNEL_SWIZZLE_B &&
442 swizzles.a == XGL_CHANNEL_SWIZZLE_A);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800443 }
444}
445
Chia-I Wu06bed192014-08-20 13:57:18 +0800446static void surface_state_null_gen6(const struct intel_gpu *gpu,
447 uint32_t dw[6])
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800448{
449 INTEL_GPU_ASSERT(gpu, 6, 6);
450
451 /*
452 * From the Sandy Bridge PRM, volume 4 part 1, page 71:
453 *
454 * "A null surface will be used in instances where an actual surface is
455 * not bound. When a write message is generated to a null surface, no
456 * actual surface is written to. When a read message (including any
457 * sampling engine message) is generated to a null surface, the result
458 * is all zeros. Note that a null surface type is allowed to be used
459 * with all messages, even if it is not specificially indicated as
460 * supported. All of the remaining fields in surface state are ignored
461 * for null surfaces, with the following exceptions:
462 *
463 * * [DevSNB+]: Width, Height, Depth, and LOD fields must match the
464 * depth buffer's corresponding state for all render target
465 * surfaces, including null.
466 * * Surface Format must be R8G8B8A8_UNORM."
467 *
468 * From the Sandy Bridge PRM, volume 4 part 1, page 82:
469 *
470 * "If Surface Type is SURFTYPE_NULL, this field (Tiled Surface) must be
471 * true"
472 */
473
474 dw[0] = GEN6_SURFTYPE_NULL << GEN6_SURFACE_DW0_TYPE__SHIFT |
475 GEN6_FORMAT_B8G8R8A8_UNORM << GEN6_SURFACE_DW0_FORMAT__SHIFT;
476
477 dw[1] = 0;
478 dw[2] = 0;
479 dw[3] = GEN6_TILING_X;
480 dw[4] = 0;
481 dw[5] = 0;
482}
483
Chia-I Wu06bed192014-08-20 13:57:18 +0800484static void surface_state_buf_gen6(const struct intel_gpu *gpu,
485 unsigned offset, unsigned size,
486 unsigned struct_size,
487 XGL_FORMAT elem_format,
488 bool is_rt, bool render_cache_rw,
489 uint32_t dw[6])
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800490{
Chia-I Wu4619ed22014-10-08 12:24:37 +0800491 const bool typed = !icd_format_is_undef(elem_format);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800492 const int elem_size = icd_format_get_size(elem_format);
493 int width, height, depth, pitch;
494 int surface_format, num_entries;
495
496 INTEL_GPU_ASSERT(gpu, 6, 6);
497
498 /*
499 * For SURFTYPE_BUFFER, a SURFACE_STATE specifies an element of a
500 * structure in a buffer.
501 */
502
Chia-I Wu4619ed22014-10-08 12:24:37 +0800503 surface_format = (typed) ?
504 intel_format_translate_color(gpu, elem_format) : GEN6_FORMAT_RAW;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800505
506 num_entries = size / struct_size;
507 /* see if there is enough space to fit another element */
508 if (size % struct_size >= elem_size)
509 num_entries++;
510
511 /*
512 * From the Sandy Bridge PRM, volume 4 part 1, page 76:
513 *
514 * "For SURFTYPE_BUFFER render targets, this field (Surface Base
515 * Address) specifies the base address of first element of the
516 * surface. The surface is interpreted as a simple array of that
517 * single element type. The address must be naturally-aligned to the
518 * element size (e.g., a buffer containing R32G32B32A32_FLOAT elements
519 * must be 16-byte aligned).
520 *
521 * For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
522 * the base address of the first element of the surface, computed in
523 * software by adding the surface base address to the byte offset of
524 * the element in the buffer."
525 */
526 if (is_rt)
527 assert(offset % elem_size == 0);
528
529 /*
530 * From the Sandy Bridge PRM, volume 4 part 1, page 77:
531 *
532 * "For buffer surfaces, the number of entries in the buffer ranges
533 * from 1 to 2^27."
534 */
535 assert(num_entries >= 1 && num_entries <= 1 << 27);
536
537 /*
538 * From the Sandy Bridge PRM, volume 4 part 1, page 81:
539 *
540 * "For surfaces of type SURFTYPE_BUFFER, this field (Surface Pitch)
541 * indicates the size of the structure."
542 */
543 pitch = struct_size;
544
545 pitch--;
546 num_entries--;
547 /* bits [6:0] */
548 width = (num_entries & 0x0000007f);
549 /* bits [19:7] */
550 height = (num_entries & 0x000fff80) >> 7;
551 /* bits [26:20] */
552 depth = (num_entries & 0x07f00000) >> 20;
553
554 dw[0] = GEN6_SURFTYPE_BUFFER << GEN6_SURFACE_DW0_TYPE__SHIFT |
555 surface_format << GEN6_SURFACE_DW0_FORMAT__SHIFT;
556 if (render_cache_rw)
557 dw[0] |= GEN6_SURFACE_DW0_RENDER_CACHE_RW;
558
559 dw[1] = offset;
560
561 dw[2] = height << GEN6_SURFACE_DW2_HEIGHT__SHIFT |
562 width << GEN6_SURFACE_DW2_WIDTH__SHIFT;
563
564 dw[3] = depth << GEN6_SURFACE_DW3_DEPTH__SHIFT |
565 pitch << GEN6_SURFACE_DW3_PITCH__SHIFT;
566
567 dw[4] = 0;
568 dw[5] = 0;
569}
570
Chia-I Wu06bed192014-08-20 13:57:18 +0800571static void surface_state_tex_gen6(const struct intel_gpu *gpu,
572 const struct intel_img *img,
573 XGL_IMAGE_VIEW_TYPE type,
574 XGL_FORMAT format,
575 unsigned first_level,
576 unsigned num_levels,
577 unsigned first_layer,
578 unsigned num_layers,
579 bool is_rt,
580 uint32_t dw[6])
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800581{
582 int surface_type, surface_format;
583 int width, height, depth, pitch, lod;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800584
585 INTEL_GPU_ASSERT(gpu, 6, 6);
586
587 surface_type = view_type_to_surface_type(type);
588 assert(surface_type != GEN6_SURFTYPE_BUFFER);
589
590 surface_format = intel_format_translate_color(gpu, format);
591 assert(surface_format >= 0);
592
Chia-I Wu73e326f2014-08-21 11:07:57 +0800593 width = img->layout.width0;
594 height = img->layout.height0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800595 depth = (type == XGL_IMAGE_VIEW_3D) ?
Chia-I Wu73e326f2014-08-21 11:07:57 +0800596 img->depth : num_layers;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800597 pitch = img->layout.bo_stride;
598
599 if (surface_type == GEN6_SURFTYPE_CUBE) {
600 /*
601 * From the Sandy Bridge PRM, volume 4 part 1, page 81:
602 *
603 * "For SURFTYPE_CUBE: [DevSNB+]: for Sampling Engine Surfaces, the
604 * range of this field (Depth) is [0,84], indicating the number of
605 * cube array elements (equal to the number of underlying 2D array
606 * elements divided by 6). For other surfaces, this field must be
607 * zero."
608 *
609 * When is_rt is true, we treat the texture as a 2D one to avoid the
610 * restriction.
611 */
612 if (is_rt) {
613 surface_type = GEN6_SURFTYPE_2D;
614 }
615 else {
616 assert(num_layers % 6 == 0);
617 depth = num_layers / 6;
618 }
619 }
620
621 /* sanity check the size */
622 assert(width >= 1 && height >= 1 && depth >= 1 && pitch >= 1);
623 switch (surface_type) {
624 case GEN6_SURFTYPE_1D:
625 assert(width <= 8192 && height == 1 && depth <= 512);
626 assert(first_layer < 512 && num_layers <= 512);
627 break;
628 case GEN6_SURFTYPE_2D:
629 assert(width <= 8192 && height <= 8192 && depth <= 512);
630 assert(first_layer < 512 && num_layers <= 512);
631 break;
632 case GEN6_SURFTYPE_3D:
633 assert(width <= 2048 && height <= 2048 && depth <= 2048);
634 assert(first_layer < 2048 && num_layers <= 512);
635 if (!is_rt)
636 assert(first_layer == 0);
637 break;
638 case GEN6_SURFTYPE_CUBE:
639 assert(width <= 8192 && height <= 8192 && depth <= 85);
640 assert(width == height);
641 assert(first_layer < 512 && num_layers <= 512);
642 if (is_rt)
643 assert(first_layer == 0);
644 break;
645 default:
646 assert(!"unexpected surface type");
647 break;
648 }
649
650 /* non-full array spacing is supported only on GEN7+ */
Chia-I Wu457d0a62014-08-18 13:02:26 +0800651 assert(img->layout.walk != INTEL_LAYOUT_WALK_LOD);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800652 /* non-interleaved samples are supported only on GEN7+ */
653 if (img->samples > 1)
654 assert(img->layout.interleaved_samples);
655
656 if (is_rt) {
657 assert(num_levels == 1);
658 lod = first_level;
659 }
660 else {
661 lod = num_levels - 1;
662 }
663
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800664 /*
665 * From the Sandy Bridge PRM, volume 4 part 1, page 76:
666 *
667 * "Linear render target surface base addresses must be element-size
668 * aligned, for non-YUV surface formats, or a multiple of 2
669 * element-sizes for YUV surface formats. Other linear surfaces have
670 * no alignment requirements (byte alignment is sufficient.)"
671 *
672 * From the Sandy Bridge PRM, volume 4 part 1, page 81:
673 *
674 * "For linear render target surfaces, the pitch must be a multiple
675 * of the element size for non-YUV surface formats. Pitch must be a
676 * multiple of 2 * element size for YUV surface formats."
677 *
678 * From the Sandy Bridge PRM, volume 4 part 1, page 86:
679 *
680 * "For linear surfaces, this field (X Offset) must be zero"
681 */
Chia-I Wud1eb90c2015-03-07 06:01:45 +0800682 if (img->layout.tiling == GEN6_TILING_NONE) {
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800683 if (is_rt) {
Chia-I Wu08cd6e92015-02-11 13:44:50 -0700684 const int elem_size U_ASSERT_ONLY = icd_format_get_size(format);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800685 assert(pitch % elem_size == 0);
686 }
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800687 }
688
689 dw[0] = surface_type << GEN6_SURFACE_DW0_TYPE__SHIFT |
690 surface_format << GEN6_SURFACE_DW0_FORMAT__SHIFT |
691 GEN6_SURFACE_DW0_MIPLAYOUT_BELOW;
692
693 if (surface_type == GEN6_SURFTYPE_CUBE && !is_rt) {
694 dw[0] |= 1 << 9 |
695 GEN6_SURFACE_DW0_CUBE_FACE_ENABLES__MASK;
696 }
697
698 if (is_rt)
699 dw[0] |= GEN6_SURFACE_DW0_RENDER_CACHE_RW;
700
Chia-I Wu457d0a62014-08-18 13:02:26 +0800701 dw[1] = 0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800702
703 dw[2] = (height - 1) << GEN6_SURFACE_DW2_HEIGHT__SHIFT |
704 (width - 1) << GEN6_SURFACE_DW2_WIDTH__SHIFT |
705 lod << GEN6_SURFACE_DW2_MIP_COUNT_LOD__SHIFT;
706
Chia-I Wud1eb90c2015-03-07 06:01:45 +0800707 assert(img->layout.tiling != GEN8_TILING_W);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800708 dw[3] = (depth - 1) << GEN6_SURFACE_DW3_DEPTH__SHIFT |
709 (pitch - 1) << GEN6_SURFACE_DW3_PITCH__SHIFT |
Chia-I Wud1eb90c2015-03-07 06:01:45 +0800710 img->layout.tiling;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800711
712 dw[4] = first_level << GEN6_SURFACE_DW4_MIN_LOD__SHIFT |
713 first_layer << 17 |
714 (num_layers - 1) << 8 |
715 ((img->samples > 1) ? GEN6_SURFACE_DW4_MULTISAMPLECOUNT_4 :
716 GEN6_SURFACE_DW4_MULTISAMPLECOUNT_1);
717
Chia-I Wu457d0a62014-08-18 13:02:26 +0800718 dw[5] = 0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800719
720 assert(img->layout.align_j == 2 || img->layout.align_j == 4);
721 if (img->layout.align_j == 4)
722 dw[5] |= GEN6_SURFACE_DW5_VALIGN_4;
723}
724
725struct ds_surface_info {
726 int surface_type;
727 int format;
728
729 struct {
730 unsigned stride;
Chia-I Wu457d0a62014-08-18 13:02:26 +0800731 unsigned offset;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800732 } zs, stencil, hiz;
733
734 unsigned width, height, depth;
735 unsigned lod, first_layer, num_layers;
736};
737
738static void
739ds_init_info_null(const struct intel_gpu *gpu,
740 struct ds_surface_info *info)
741{
742 INTEL_GPU_ASSERT(gpu, 6, 7.5);
743
744 memset(info, 0, sizeof(*info));
745
746 info->surface_type = GEN6_SURFTYPE_NULL;
747 info->format = GEN6_ZFORMAT_D32_FLOAT;
748 info->width = 1;
749 info->height = 1;
750 info->depth = 1;
751 info->num_layers = 1;
752}
753
754static void
755ds_init_info(const struct intel_gpu *gpu,
756 const struct intel_img *img,
757 XGL_FORMAT format, unsigned level,
758 unsigned first_layer, unsigned num_layers,
759 struct ds_surface_info *info)
760{
761 bool separate_stencil;
762
763 INTEL_GPU_ASSERT(gpu, 6, 7.5);
764
765 memset(info, 0, sizeof(*info));
766
767 info->surface_type =
768 view_type_to_surface_type(img_type_to_view_type(img->type));
769
770 if (info->surface_type == GEN6_SURFTYPE_CUBE) {
771 /*
772 * From the Sandy Bridge PRM, volume 2 part 1, page 325-326:
773 *
774 * "For Other Surfaces (Cube Surfaces):
775 * This field (Minimum Array Element) is ignored."
776 *
777 * "For Other Surfaces (Cube Surfaces):
778 * This field (Render Target View Extent) is ignored."
779 *
780 * As such, we cannot set first_layer and num_layers on cube surfaces.
781 * To work around that, treat it as a 2D surface.
782 */
783 info->surface_type = GEN6_SURFTYPE_2D;
784 }
785
786 if (intel_gpu_gen(gpu) >= INTEL_GEN(7)) {
787 separate_stencil = true;
788 }
789 else {
790 /*
791 * From the Sandy Bridge PRM, volume 2 part 1, page 317:
792 *
793 * "This field (Separate Stencil Buffer Enable) must be set to the
794 * same value (enabled or disabled) as Hierarchical Depth Buffer
795 * Enable."
796 */
Chia-I Wu3defd1f2015-02-18 12:21:22 -0700797 separate_stencil = intel_img_can_enable_hiz(img, level);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800798 }
799
800 /*
801 * From the Sandy Bridge PRM, volume 2 part 1, page 317:
802 *
803 * "If this field (Hierarchical Depth Buffer Enable) is enabled, the
804 * Surface Format of the depth buffer cannot be
805 * D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT. Use of stencil
806 * requires the separate stencil buffer."
807 *
808 * From the Ironlake PRM, volume 2 part 1, page 330:
809 *
810 * "If this field (Separate Stencil Buffer Enable) is disabled, the
811 * Surface Format of the depth buffer cannot be D24_UNORM_X8_UINT."
812 *
813 * There is no similar restriction for GEN6. But when D24_UNORM_X8_UINT
814 * is indeed used, the depth values output by the fragment shaders will
815 * be different when read back.
816 *
817 * As for GEN7+, separate_stencil is always true.
818 */
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700819 switch (format) {
820 case XGL_FMT_D16_UNORM:
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800821 info->format = GEN6_ZFORMAT_D16_UNORM;
822 break;
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700823 case XGL_FMT_D32_SFLOAT:
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800824 info->format = GEN6_ZFORMAT_D32_FLOAT;
825 break;
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700826 case XGL_FMT_D32_SFLOAT_S8_UINT:
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800827 info->format = (separate_stencil) ?
828 GEN6_ZFORMAT_D32_FLOAT :
829 GEN6_ZFORMAT_D32_FLOAT_S8X24_UINT;
830 break;
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700831 case XGL_FMT_S8_UINT:
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800832 if (separate_stencil) {
833 info->format = GEN6_ZFORMAT_D32_FLOAT;
834 break;
835 }
836 /* fall through */
837 default:
838 assert(!"unsupported depth/stencil format");
839 ds_init_info_null(gpu, info);
840 return;
841 break;
842 }
843
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700844 if (format != XGL_FMT_S8_UINT)
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800845 info->zs.stride = img->layout.bo_stride;
846
847 if (img->s8_layout) {
848 /*
849 * From the Sandy Bridge PRM, volume 2 part 1, page 329:
850 *
851 * "The pitch must be set to 2x the value computed based on width,
852 * as the stencil buffer is stored with two rows interleaved."
853 *
854 * According to the classic driver, we need to do the same for GEN7+
855 * even though the Ivy Bridge PRM does not say anything about it.
856 */
857 info->stencil.stride = img->s8_layout->bo_stride * 2;
Chia-I Wu457d0a62014-08-18 13:02:26 +0800858
859 if (intel_gpu_gen(gpu) == INTEL_GEN(6)) {
860 unsigned x, y;
861
862 assert(img->s8_layout->walk == INTEL_LAYOUT_WALK_LOD);
863
864 /* offset to the level */
865 intel_layout_get_slice_pos(img->s8_layout, level, 0, &x, &y);
866 intel_layout_pos_to_mem(img->s8_layout, x, y, &x, &y);
867 info->stencil.offset = intel_layout_mem_to_raw(img->s8_layout, x, y);
868 }
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700869 } else if (format == XGL_FMT_S8_UINT) {
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800870 info->stencil.stride = img->layout.bo_stride * 2;
871 }
872
Chia-I Wu3defd1f2015-02-18 12:21:22 -0700873 if (intel_img_can_enable_hiz(img, level)) {
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800874 info->hiz.stride = img->layout.aux_stride;
875
Chia-I Wu457d0a62014-08-18 13:02:26 +0800876 /* offset to the level */
877 if (intel_gpu_gen(gpu) == INTEL_GEN(6))
878 info->hiz.offset = img->layout.aux_offsets[level];
879 }
880
Chia-I Wu73e326f2014-08-21 11:07:57 +0800881 info->width = img->layout.width0;
882 info->height = img->layout.height0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800883 info->depth = (img->type == XGL_IMAGE_3D) ?
Chia-I Wu73e326f2014-08-21 11:07:57 +0800884 img->depth : num_layers;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800885
886 info->lod = level;
887 info->first_layer = first_layer;
888 info->num_layers = num_layers;
889}
890
Chia-I Wu06bed192014-08-20 13:57:18 +0800891static void ds_view_init(struct intel_ds_view *view,
892 const struct intel_gpu *gpu,
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800893 const struct intel_img *img,
894 XGL_FORMAT format, unsigned level,
Chia-I Wu06bed192014-08-20 13:57:18 +0800895 unsigned first_layer, unsigned num_layers)
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800896{
Chia-I Wu08cd6e92015-02-11 13:44:50 -0700897 const int max_2d_size U_ASSERT_ONLY =
898 (intel_gpu_gen(gpu) >= INTEL_GEN(7)) ? 16384 : 8192;
899 const int max_array_size U_ASSERT_ONLY =
900 (intel_gpu_gen(gpu) >= INTEL_GEN(7)) ? 2048 : 512;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800901 struct ds_surface_info info;
902 uint32_t dw1, dw2, dw3, dw4, dw5, dw6;
Chia-I Wu06bed192014-08-20 13:57:18 +0800903 uint32_t *dw;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800904
905 INTEL_GPU_ASSERT(gpu, 6, 7.5);
906
907 if (img) {
908 ds_init_info(gpu, img, format, level, first_layer, num_layers, &info);
909 }
910 else {
911 ds_init_info_null(gpu, &info);
912 }
913
914 switch (info.surface_type) {
915 case GEN6_SURFTYPE_NULL:
916 break;
917 case GEN6_SURFTYPE_1D:
918 assert(info.width <= max_2d_size && info.height == 1 &&
919 info.depth <= max_array_size);
920 assert(info.first_layer < max_array_size - 1 &&
921 info.num_layers <= max_array_size);
922 break;
923 case GEN6_SURFTYPE_2D:
924 assert(info.width <= max_2d_size && info.height <= max_2d_size &&
925 info.depth <= max_array_size);
926 assert(info.first_layer < max_array_size - 1 &&
927 info.num_layers <= max_array_size);
928 break;
929 case GEN6_SURFTYPE_3D:
930 assert(info.width <= 2048 && info.height <= 2048 && info.depth <= 2048);
931 assert(info.first_layer < 2048 && info.num_layers <= max_array_size);
932 break;
933 case GEN6_SURFTYPE_CUBE:
934 assert(info.width <= max_2d_size && info.height <= max_2d_size &&
935 info.depth == 1);
936 assert(info.first_layer == 0 && info.num_layers == 1);
937 assert(info.width == info.height);
938 break;
939 default:
940 assert(!"unexpected depth surface type");
941 break;
942 }
943
944 dw1 = info.surface_type << 29 |
945 info.format << 18;
946
947 if (info.zs.stride) {
948 /* required for GEN6+ */
949 assert(info.zs.stride > 0 && info.zs.stride < 128 * 1024 &&
950 info.zs.stride % 128 == 0);
951 assert(info.width <= info.zs.stride);
952
953 dw1 |= (info.zs.stride - 1);
954 }
955
956 dw2 = 0;
957
958 if (intel_gpu_gen(gpu) >= INTEL_GEN(7)) {
959 if (info.zs.stride)
960 dw1 |= 1 << 28;
961
962 if (info.stencil.stride)
963 dw1 |= 1 << 27;
964
965 if (info.hiz.stride)
966 dw1 |= 1 << 22;
967
968 dw3 = (info.height - 1) << 18 |
969 (info.width - 1) << 4 |
970 info.lod;
971
972 dw4 = (info.depth - 1) << 21 |
Chia-I Wub3686982015-02-27 09:51:16 -0700973 info.first_layer << 10 |
Chia-I Wu97aa4de2015-03-05 15:43:16 -0700974 GEN7_MOCS_L3_WB;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800975
976 dw5 = 0;
977
978 dw6 = (info.num_layers - 1) << 21;
979 }
980 else {
981 /* always Y-tiled */
982 dw1 |= 1 << 27 |
983 1 << 26;
984
985 if (info.hiz.stride) {
986 dw1 |= 1 << 22 |
987 1 << 21;
988 }
989
990 dw3 = (info.height - 1) << 19 |
991 (info.width - 1) << 6 |
992 info.lod << 2 |
993 GEN6_DEPTH_DW3_MIPLAYOUT_BELOW;
994
995 dw4 = (info.depth - 1) << 21 |
996 info.first_layer << 10 |
997 (info.num_layers - 1) << 1;
998
999 dw5 = 0;
1000
1001 dw6 = 0;
1002 }
1003
Chia-I Wu06bed192014-08-20 13:57:18 +08001004 STATIC_ASSERT(ARRAY_SIZE(view->cmd) >= 10);
1005 dw = view->cmd;
1006
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001007 dw[0] = dw1;
1008 dw[1] = dw2;
1009 dw[2] = dw3;
1010 dw[3] = dw4;
1011 dw[4] = dw5;
1012 dw[5] = dw6;
1013
1014 /* separate stencil */
1015 if (info.stencil.stride) {
1016 assert(info.stencil.stride > 0 && info.stencil.stride < 128 * 1024 &&
1017 info.stencil.stride % 128 == 0);
1018
1019 dw[6] = info.stencil.stride - 1;
1020 dw[7] = img->s8_offset;
1021
Chia-I Wub3686982015-02-27 09:51:16 -07001022 if (intel_gpu_gen(gpu) >= INTEL_GEN(7))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001023 dw[6] |= GEN7_MOCS_L3_WB << GEN6_STENCIL_DW1_MOCS__SHIFT;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001024 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5))
1025 dw[6] |= GEN75_STENCIL_DW1_STENCIL_BUFFER_ENABLE;
1026 }
1027 else {
1028 dw[6] = 0;
1029 dw[7] = 0;
1030 }
1031
1032 /* hiz */
1033 if (info.hiz.stride) {
1034 dw[8] = info.hiz.stride - 1;
1035 dw[9] = img->aux_offset;
Chia-I Wub3686982015-02-27 09:51:16 -07001036
1037 if (intel_gpu_gen(gpu) >= INTEL_GEN(7))
Chia-I Wu97aa4de2015-03-05 15:43:16 -07001038 dw[8] |= GEN7_MOCS_L3_WB << GEN6_HIZ_DW1_MOCS__SHIFT;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001039 }
1040 else {
1041 dw[8] = 0;
1042 dw[9] = 0;
1043 }
Chia-I Wu3defd1f2015-02-18 12:21:22 -07001044
1045 view->has_stencil = info.stencil.stride;
1046 view->has_hiz = info.hiz.stride;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001047}
1048
Chia-I Wu5a323262014-08-11 10:31:53 +08001049void intel_null_view_init(struct intel_null_view *view,
1050 struct intel_dev *dev)
1051{
Chia-I Wucd83cf12014-08-23 17:26:08 +08001052 if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wu06bed192014-08-20 13:57:18 +08001053 surface_state_null_gen7(dev->gpu, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001054 view->cmd_len = 8;
1055 } else {
Chia-I Wu06bed192014-08-20 13:57:18 +08001056 surface_state_null_gen6(dev->gpu, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001057 view->cmd_len = 6;
1058 }
Chia-I Wu5a323262014-08-11 10:31:53 +08001059}
1060
Chia-I Wu714df452015-01-01 07:55:04 +08001061static void buf_view_destroy(struct intel_obj *obj)
Chia-I Wu5a323262014-08-11 10:31:53 +08001062{
Chia-I Wu714df452015-01-01 07:55:04 +08001063 struct intel_buf_view *view = intel_buf_view_from_obj(obj);
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001064
Chia-I Wu714df452015-01-01 07:55:04 +08001065 intel_buf_view_destroy(view);
1066}
Chia-I Wu5a323262014-08-11 10:31:53 +08001067
Chia-I Wu714df452015-01-01 07:55:04 +08001068XGL_RESULT intel_buf_view_create(struct intel_dev *dev,
1069 const XGL_BUFFER_VIEW_CREATE_INFO *info,
1070 struct intel_buf_view **view_ret)
1071{
1072 struct intel_buf *buf = intel_buf(info->buffer);
1073 const bool will_write = (buf->usage |
1074 (XGL_BUFFER_USAGE_SHADER_ACCESS_WRITE_BIT &
1075 XGL_BUFFER_USAGE_SHADER_ACCESS_ATOMIC_BIT));
Chia-I Wu34341ba2015-01-16 17:38:37 +08001076 XGL_FORMAT format;
1077 XGL_GPU_SIZE stride;
1078 uint32_t *cmd;
Chia-I Wu714df452015-01-01 07:55:04 +08001079 struct intel_buf_view *view;
Chia-I Wu34341ba2015-01-16 17:38:37 +08001080 int i;
Chia-I Wu714df452015-01-01 07:55:04 +08001081
Chia-I Wu545c2e12015-02-22 13:19:54 +08001082 view = (struct intel_buf_view *) intel_base_create(&dev->base.handle,
1083 sizeof(*view), dev->base.dbg, XGL_DBG_OBJECT_BUFFER_VIEW,
1084 info, 0);
Chia-I Wu714df452015-01-01 07:55:04 +08001085 if (!view)
1086 return XGL_ERROR_OUT_OF_MEMORY;
1087
1088 view->obj.destroy = buf_view_destroy;
1089
1090 view->buf = buf;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001091
Chia-I Wu34341ba2015-01-16 17:38:37 +08001092 /*
1093 * The compiler expects uniform buffers to have pitch of
1094 * 4 for fragment shaders, but 16 for other stages. The format
1095 * must be XGL_FMT_R32G32B32A32_SFLOAT.
1096 */
1097 if (info->viewType == XGL_BUFFER_VIEW_RAW) {
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -07001098 format = XGL_FMT_R32G32B32A32_SFLOAT;
Chia-I Wu34341ba2015-01-16 17:38:37 +08001099 stride = 16;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001100 } else {
Chia-I Wu34341ba2015-01-16 17:38:37 +08001101 format = info->format;
Courtney Goeltzenleuchterba093032015-03-25 16:31:58 -06001102 stride = icd_format_get_size(format);
Chia-I Wu34341ba2015-01-16 17:38:37 +08001103 }
1104 cmd = view->cmd;
1105
1106 for (i = 0; i < 2; i++) {
1107 if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7)) {
1108 surface_state_buf_gen7(dev->gpu, info->offset,
1109 info->range, stride, format,
1110 will_write, will_write, cmd);
1111 view->cmd_len = 8;
1112 } else {
1113 surface_state_buf_gen6(dev->gpu, info->offset,
1114 info->range, stride, format,
1115 will_write, will_write, cmd);
1116 view->cmd_len = 6;
1117 }
1118
1119 /* switch to view->fs_cmd */
1120 if (info->viewType == XGL_BUFFER_VIEW_RAW) {
1121 cmd = view->fs_cmd;
1122 stride = 4;
1123 } else {
1124 memcpy(view->fs_cmd, view->cmd, sizeof(uint32_t) * view->cmd_len);
1125 break;
1126 }
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001127 }
Chia-I Wu714df452015-01-01 07:55:04 +08001128
1129 *view_ret = view;
1130
1131 return XGL_SUCCESS;
1132}
1133
1134void intel_buf_view_destroy(struct intel_buf_view *view)
1135{
1136 intel_base_destroy(&view->obj.base);
Chia-I Wu5a323262014-08-11 10:31:53 +08001137}
1138
1139static void img_view_destroy(struct intel_obj *obj)
1140{
1141 struct intel_img_view *view = intel_img_view_from_obj(obj);
1142
1143 intel_img_view_destroy(view);
1144}
1145
1146XGL_RESULT intel_img_view_create(struct intel_dev *dev,
1147 const XGL_IMAGE_VIEW_CREATE_INFO *info,
1148 struct intel_img_view **view_ret)
1149{
1150 struct intel_img *img = intel_img(info->image);
1151 struct intel_img_view *view;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001152 uint32_t mip_levels, array_size;
Chia-I Wuf57758c2014-12-02 14:15:50 +08001153 XGL_CHANNEL_MAPPING state_swizzles;
Chia-I Wuaa759372014-10-18 12:47:35 +08001154
1155 if (info->subresourceRange.baseMipLevel >= img->mip_levels ||
1156 info->subresourceRange.baseArraySlice >= img->array_size ||
1157 !info->subresourceRange.mipLevels ||
1158 !info->subresourceRange.arraySize)
1159 return XGL_ERROR_INVALID_VALUE;
1160
1161 mip_levels = info->subresourceRange.mipLevels;
1162 if (mip_levels > img->mip_levels - info->subresourceRange.baseMipLevel)
1163 mip_levels = img->mip_levels - info->subresourceRange.baseMipLevel;
1164
1165 array_size = info->subresourceRange.arraySize;
1166 if (array_size > img->array_size - info->subresourceRange.baseArraySlice)
1167 array_size = img->array_size - info->subresourceRange.baseArraySlice;
Chia-I Wu5a323262014-08-11 10:31:53 +08001168
Chia-I Wu545c2e12015-02-22 13:19:54 +08001169 view = (struct intel_img_view *) intel_base_create(&dev->base.handle,
1170 sizeof(*view), dev->base.dbg, XGL_DBG_OBJECT_IMAGE_VIEW, info, 0);
Chia-I Wu5a323262014-08-11 10:31:53 +08001171 if (!view)
1172 return XGL_ERROR_OUT_OF_MEMORY;
1173
1174 view->obj.destroy = img_view_destroy;
1175
1176 view->img = img;
Chia-I Wu5a323262014-08-11 10:31:53 +08001177 view->min_lod = info->minLod;
1178
Chia-I Wuf57758c2014-12-02 14:15:50 +08001179 if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7.5)) {
1180 state_swizzles = info->channels;
1181 view->shader_swizzles.r = XGL_CHANNEL_SWIZZLE_R;
1182 view->shader_swizzles.g = XGL_CHANNEL_SWIZZLE_G;
1183 view->shader_swizzles.b = XGL_CHANNEL_SWIZZLE_B;
1184 view->shader_swizzles.a = XGL_CHANNEL_SWIZZLE_A;
1185 } else {
1186 state_swizzles.r = XGL_CHANNEL_SWIZZLE_R;
1187 state_swizzles.g = XGL_CHANNEL_SWIZZLE_G;
1188 state_swizzles.b = XGL_CHANNEL_SWIZZLE_B;
1189 state_swizzles.a = XGL_CHANNEL_SWIZZLE_A;
1190 view->shader_swizzles = info->channels;
1191 }
1192
1193 /* shader_swizzles is ignored by the compiler */
1194 if (view->shader_swizzles.r != XGL_CHANNEL_SWIZZLE_R ||
1195 view->shader_swizzles.g != XGL_CHANNEL_SWIZZLE_G ||
1196 view->shader_swizzles.b != XGL_CHANNEL_SWIZZLE_B ||
1197 view->shader_swizzles.a != XGL_CHANNEL_SWIZZLE_A) {
1198 intel_dev_log(dev, XGL_DBG_MSG_WARNING,
1199 XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0, 0,
1200 "image data swizzling is ignored");
1201 }
1202
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001203 if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wu06bed192014-08-20 13:57:18 +08001204 surface_state_tex_gen7(dev->gpu, img, info->viewType, info->format,
Chia-I Wuaa759372014-10-18 12:47:35 +08001205 info->subresourceRange.baseMipLevel, mip_levels,
1206 info->subresourceRange.baseArraySlice, array_size,
Chia-I Wuf57758c2014-12-02 14:15:50 +08001207 state_swizzles, false, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001208 view->cmd_len = 8;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001209 } else {
Chia-I Wu06bed192014-08-20 13:57:18 +08001210 surface_state_tex_gen6(dev->gpu, img, info->viewType, info->format,
Chia-I Wuaa759372014-10-18 12:47:35 +08001211 info->subresourceRange.baseMipLevel, mip_levels,
1212 info->subresourceRange.baseArraySlice, array_size,
1213 false, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001214 view->cmd_len = 6;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001215 }
1216
Chia-I Wu5a323262014-08-11 10:31:53 +08001217 *view_ret = view;
1218
1219 return XGL_SUCCESS;
1220}
1221
1222void intel_img_view_destroy(struct intel_img_view *view)
1223{
1224 intel_base_destroy(&view->obj.base);
1225}
1226
1227static void rt_view_destroy(struct intel_obj *obj)
1228{
1229 struct intel_rt_view *view = intel_rt_view_from_obj(obj);
1230
1231 intel_rt_view_destroy(view);
1232}
1233
1234XGL_RESULT intel_rt_view_create(struct intel_dev *dev,
1235 const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO *info,
1236 struct intel_rt_view **view_ret)
1237{
Chia-I Wuf57758c2014-12-02 14:15:50 +08001238 static const XGL_CHANNEL_MAPPING identity_channel_mapping = {
1239 .r = XGL_CHANNEL_SWIZZLE_R,
1240 .g = XGL_CHANNEL_SWIZZLE_G,
1241 .b = XGL_CHANNEL_SWIZZLE_B,
1242 .a = XGL_CHANNEL_SWIZZLE_A,
1243 };
Chia-I Wu5a323262014-08-11 10:31:53 +08001244 struct intel_img *img = intel_img(info->image);
1245 struct intel_rt_view *view;
1246
Chia-I Wu545c2e12015-02-22 13:19:54 +08001247 view = (struct intel_rt_view *) intel_base_create(&dev->base.handle,
1248 sizeof(*view), dev->base.dbg, XGL_DBG_OBJECT_COLOR_TARGET_VIEW,
1249 info, 0);
Chia-I Wu5a323262014-08-11 10:31:53 +08001250 if (!view)
1251 return XGL_ERROR_OUT_OF_MEMORY;
1252
1253 view->obj.destroy = rt_view_destroy;
1254
1255 view->img = img;
1256
Mark Lobodzinski71fcc2d2015-01-27 13:24:03 -06001257 view->array_size = info->arraySize;
1258
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001259 if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wu06bed192014-08-20 13:57:18 +08001260 surface_state_tex_gen7(dev->gpu, img,
1261 img_type_to_view_type(img->type),
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001262 info->format, info->mipLevel, 1,
1263 info->baseArraySlice, info->arraySize,
Chia-I Wuf57758c2014-12-02 14:15:50 +08001264 identity_channel_mapping, true, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001265 view->cmd_len = 8;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001266 } else {
Chia-I Wu06bed192014-08-20 13:57:18 +08001267 surface_state_tex_gen6(dev->gpu, img,
1268 img_type_to_view_type(img->type),
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001269 info->format, info->mipLevel, 1,
1270 info->baseArraySlice, info->arraySize,
1271 true, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001272 view->cmd_len = 6;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001273 }
1274
Chia-I Wu5a323262014-08-11 10:31:53 +08001275 *view_ret = view;
1276
1277 return XGL_SUCCESS;
1278}
1279
1280void intel_rt_view_destroy(struct intel_rt_view *view)
1281{
1282 intel_base_destroy(&view->obj.base);
1283}
1284
1285static void ds_view_destroy(struct intel_obj *obj)
1286{
1287 struct intel_ds_view *view = intel_ds_view_from_obj(obj);
1288
1289 intel_ds_view_destroy(view);
1290}
1291
1292XGL_RESULT intel_ds_view_create(struct intel_dev *dev,
1293 const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO *info,
1294 struct intel_ds_view **view_ret)
1295{
1296 struct intel_img *img = intel_img(info->image);
1297 struct intel_ds_view *view;
1298
Chia-I Wu545c2e12015-02-22 13:19:54 +08001299 view = (struct intel_ds_view *) intel_base_create(&dev->base.handle,
1300 sizeof(*view), dev->base.dbg, XGL_DBG_OBJECT_DEPTH_STENCIL_VIEW,
1301 info, 0);
Chia-I Wu5a323262014-08-11 10:31:53 +08001302 if (!view)
1303 return XGL_ERROR_OUT_OF_MEMORY;
1304
1305 view->obj.destroy = ds_view_destroy;
1306
1307 view->img = img;
1308
Mark Lobodzinski71fcc2d2015-01-27 13:24:03 -06001309 view->array_size = info->arraySize;
1310
Chia-I Wu06bed192014-08-20 13:57:18 +08001311 ds_view_init(view, dev->gpu, img, img->layout.format, info->mipLevel,
1312 info->baseArraySlice, info->arraySize);
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001313
Chia-I Wu5a323262014-08-11 10:31:53 +08001314 *view_ret = view;
1315
1316 return XGL_SUCCESS;
1317}
1318
1319void intel_ds_view_destroy(struct intel_ds_view *view)
1320{
1321 intel_base_destroy(&view->obj.base);
1322}
1323
Chia-I Wu714df452015-01-01 07:55:04 +08001324ICD_EXPORT XGL_RESULT XGLAPI xglCreateBufferView(
1325 XGL_DEVICE device,
1326 const XGL_BUFFER_VIEW_CREATE_INFO* pCreateInfo,
1327 XGL_BUFFER_VIEW* pView)
1328{
1329 struct intel_dev *dev = intel_dev(device);
1330
1331 return intel_buf_view_create(dev, pCreateInfo,
1332 (struct intel_buf_view **) pView);
1333}
1334
Chia-I Wu96177272015-01-03 15:27:41 +08001335ICD_EXPORT XGL_RESULT XGLAPI xglCreateImageView(
Chia-I Wu5a323262014-08-11 10:31:53 +08001336 XGL_DEVICE device,
1337 const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo,
1338 XGL_IMAGE_VIEW* pView)
1339{
1340 struct intel_dev *dev = intel_dev(device);
1341
1342 return intel_img_view_create(dev, pCreateInfo,
1343 (struct intel_img_view **) pView);
1344}
1345
Chia-I Wu96177272015-01-03 15:27:41 +08001346ICD_EXPORT XGL_RESULT XGLAPI xglCreateColorAttachmentView(
Chia-I Wu5a323262014-08-11 10:31:53 +08001347 XGL_DEVICE device,
1348 const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo,
1349 XGL_COLOR_ATTACHMENT_VIEW* pView)
1350{
1351 struct intel_dev *dev = intel_dev(device);
1352
1353 return intel_rt_view_create(dev, pCreateInfo,
1354 (struct intel_rt_view **) pView);
1355}
1356
Chia-I Wu96177272015-01-03 15:27:41 +08001357ICD_EXPORT XGL_RESULT XGLAPI xglCreateDepthStencilView(
Chia-I Wu5a323262014-08-11 10:31:53 +08001358 XGL_DEVICE device,
1359 const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo,
1360 XGL_DEPTH_STENCIL_VIEW* pView)
1361{
1362 struct intel_dev *dev = intel_dev(device);
1363
1364 return intel_ds_view_create(dev, pCreateInfo,
1365 (struct intel_ds_view **) pView);
1366}