blob: 5d2f08f9dd24a9050505bbd930faead433ed88d7 [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 Wu5a323262014-08-11 10:31:53 +080030#include "dev.h"
Chia-I Wu9269d1c2014-08-16 12:47:47 +080031#include "format.h"
Chia-I Wu5a323262014-08-11 10:31:53 +080032#include "gpu.h"
33#include "img.h"
34#include "mem.h"
35#include "view.h"
36
Chia-I Wu06bed192014-08-20 13:57:18 +080037static void surface_state_null_gen7(const struct intel_gpu *gpu,
38 uint32_t dw[8])
Chia-I Wu9269d1c2014-08-16 12:47:47 +080039{
40 INTEL_GPU_ASSERT(gpu, 7, 7.5);
41
42 /*
43 * From the Ivy Bridge PRM, volume 4 part 1, page 62:
44 *
45 * "A null surface is used in instances where an actual surface is not
46 * bound. When a write message is generated to a null surface, no
47 * actual surface is written to. When a read message (including any
48 * sampling engine message) is generated to a null surface, the result
49 * is all zeros. Note that a null surface type is allowed to be used
50 * with all messages, even if it is not specificially indicated as
51 * supported. All of the remaining fields in surface state are ignored
52 * for null surfaces, with the following exceptions:
53 *
54 * * Width, Height, Depth, LOD, and Render Target View Extent fields
55 * must match the depth buffer's corresponding state for all render
56 * target surfaces, including null.
57 * * All sampling engine and data port messages support null surfaces
58 * with the above behavior, even if not mentioned as specifically
59 * supported, except for the following:
60 * * Data Port Media Block Read/Write messages.
61 * * The Surface Type of a surface used as a render target (accessed
62 * via the Data Port's Render Target Write message) must be the same
63 * as the Surface Type of all other render targets and of the depth
64 * buffer (defined in 3DSTATE_DEPTH_BUFFER), unless either the depth
65 * buffer or render targets are SURFTYPE_NULL."
66 *
67 * From the Ivy Bridge PRM, volume 4 part 1, page 65:
68 *
69 * "If Surface Type is SURFTYPE_NULL, this field (Tiled Surface) must be
70 * true"
71 */
72
73 dw[0] = GEN6_SURFTYPE_NULL << GEN7_SURFACE_DW0_TYPE__SHIFT |
74 GEN6_FORMAT_B8G8R8A8_UNORM << GEN7_SURFACE_DW0_FORMAT__SHIFT |
75 GEN6_TILING_X << 13;
76
77 dw[1] = 0;
78 dw[2] = 0;
79 dw[3] = 0;
80 dw[4] = 0;
81 dw[5] = 0;
82 dw[6] = 0;
83 dw[7] = 0;
84}
85
Chia-I Wu06bed192014-08-20 13:57:18 +080086static void surface_state_buf_gen7(const struct intel_gpu *gpu,
87 unsigned offset, unsigned size,
88 unsigned struct_size,
89 XGL_FORMAT elem_format,
90 bool is_rt, bool render_cache_rw,
91 uint32_t dw[8])
Chia-I Wu9269d1c2014-08-16 12:47:47 +080092{
93 const bool typed = !icd_format_is_undef(elem_format);
94 const bool structured = (!typed && struct_size > 1);
95 const int elem_size = (typed) ?
96 icd_format_get_size(elem_format) : 1;
97 int width, height, depth, pitch;
98 int surface_type, surface_format, num_entries;
99
100 INTEL_GPU_ASSERT(gpu, 7, 7.5);
101
102 surface_type = (structured) ? GEN7_SURFTYPE_STRBUF : GEN6_SURFTYPE_BUFFER;
103
104 surface_format = (typed) ?
105 intel_format_translate_color(gpu, elem_format) : GEN6_FORMAT_RAW;
106
107 num_entries = size / struct_size;
108 /* see if there is enough space to fit another element */
109 if (size % struct_size >= elem_size && !structured)
110 num_entries++;
111
112 /*
113 * From the Ivy Bridge PRM, volume 4 part 1, page 67:
114 *
115 * "For SURFTYPE_BUFFER render targets, this field (Surface Base
116 * Address) specifies the base address of first element of the
117 * surface. The surface is interpreted as a simple array of that
118 * single element type. The address must be naturally-aligned to the
119 * element size (e.g., a buffer containing R32G32B32A32_FLOAT elements
120 * must be 16-byte aligned)
121 *
122 * For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
123 * the base address of the first element of the surface, computed in
124 * software by adding the surface base address to the byte offset of
125 * the element in the buffer."
126 */
127 if (is_rt)
128 assert(offset % elem_size == 0);
129
130 /*
131 * From the Ivy Bridge PRM, volume 4 part 1, page 68:
132 *
133 * "For typed buffer and structured buffer surfaces, the number of
134 * entries in the buffer ranges from 1 to 2^27. For raw buffer
135 * surfaces, the number of entries in the buffer is the number of
136 * bytes which can range from 1 to 2^30."
137 */
138 assert(num_entries >= 1 &&
139 num_entries <= 1 << ((typed || structured) ? 27 : 30));
140
141 /*
142 * From the Ivy Bridge PRM, volume 4 part 1, page 69:
143 *
144 * "For SURFTYPE_BUFFER: The low two bits of this field (Width) must be
145 * 11 if the Surface Format is RAW (the size of the buffer must be a
146 * multiple of 4 bytes)."
147 *
148 * From the Ivy Bridge PRM, volume 4 part 1, page 70:
149 *
150 * "For surfaces of type SURFTYPE_BUFFER and SURFTYPE_STRBUF, this
151 * field (Surface Pitch) indicates the size of the structure."
152 *
153 * "For linear surfaces with Surface Type of SURFTYPE_STRBUF, the pitch
154 * must be a multiple of 4 bytes."
155 */
156 if (structured)
157 assert(struct_size % 4 == 0);
158 else if (!typed)
159 assert(num_entries % 4 == 0);
160
161 pitch = struct_size;
162
163 pitch--;
164 num_entries--;
165 /* bits [6:0] */
166 width = (num_entries & 0x0000007f);
167 /* bits [20:7] */
168 height = (num_entries & 0x001fff80) >> 7;
169 /* bits [30:21] */
170 depth = (num_entries & 0x7fe00000) >> 21;
171 /* limit to [26:21] */
172 if (typed || structured)
173 depth &= 0x3f;
174
175 dw[0] = surface_type << GEN7_SURFACE_DW0_TYPE__SHIFT |
176 surface_format << GEN7_SURFACE_DW0_FORMAT__SHIFT;
177 if (render_cache_rw)
178 dw[0] |= GEN7_SURFACE_DW0_RENDER_CACHE_RW;
179
180 dw[1] = offset;
181
182 dw[2] = height << GEN7_SURFACE_DW2_HEIGHT__SHIFT |
183 width << GEN7_SURFACE_DW2_WIDTH__SHIFT;
184
185 dw[3] = depth << GEN7_SURFACE_DW3_DEPTH__SHIFT |
186 pitch;
187
188 dw[4] = 0;
189 dw[5] = 0;
190
191 dw[6] = 0;
192 dw[7] = 0;
193
194 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
195 dw[7] |= GEN75_SCS_RED << GEN75_SURFACE_DW7_SCS_R__SHIFT |
196 GEN75_SCS_GREEN << GEN75_SURFACE_DW7_SCS_G__SHIFT |
197 GEN75_SCS_BLUE << GEN75_SURFACE_DW7_SCS_B__SHIFT |
198 GEN75_SCS_ALPHA << GEN75_SURFACE_DW7_SCS_A__SHIFT;
199 }
200}
201
202static int img_type_to_view_type(XGL_IMAGE_VIEW_TYPE type)
203{
204 switch (type) {
205 case XGL_IMAGE_1D: return XGL_IMAGE_VIEW_1D;
206 case XGL_IMAGE_2D: return XGL_IMAGE_VIEW_2D;
207 case XGL_IMAGE_3D: return XGL_IMAGE_VIEW_3D;
208 default: assert(!"unknown img type"); return XGL_IMAGE_VIEW_1D;
209 }
210}
211
212static int view_type_to_surface_type(XGL_IMAGE_VIEW_TYPE type)
213{
214 switch (type) {
215 case XGL_IMAGE_VIEW_1D: return GEN6_SURFTYPE_1D;
216 case XGL_IMAGE_VIEW_2D: return GEN6_SURFTYPE_2D;
217 case XGL_IMAGE_VIEW_3D: return GEN6_SURFTYPE_3D;
218 case XGL_IMAGE_VIEW_CUBE: return GEN6_SURFTYPE_CUBE;
219 default: assert(!"unknown view type"); return GEN6_SURFTYPE_NULL;
220 }
221}
222
223static int winsys_tiling_to_surface_tiling(enum intel_tiling_mode tiling)
224{
225 switch (tiling) {
226 case INTEL_TILING_NONE: return GEN6_TILING_NONE;
227 case INTEL_TILING_X: return GEN6_TILING_X;
228 case INTEL_TILING_Y: return GEN6_TILING_Y;
229 default: assert(!"unknown tiling"); return GEN6_TILING_NONE;
230 }
231}
232
Chia-I Wuf57758c2014-12-02 14:15:50 +0800233static int channel_swizzle_to_scs(XGL_CHANNEL_SWIZZLE swizzle)
234{
235 switch (swizzle) {
236 case XGL_CHANNEL_SWIZZLE_ZERO: return GEN75_SCS_ZERO;
237 case XGL_CHANNEL_SWIZZLE_ONE: return GEN75_SCS_ONE;
238 case XGL_CHANNEL_SWIZZLE_R: return GEN75_SCS_RED;
239 case XGL_CHANNEL_SWIZZLE_G: return GEN75_SCS_GREEN;
240 case XGL_CHANNEL_SWIZZLE_B: return GEN75_SCS_BLUE;
241 case XGL_CHANNEL_SWIZZLE_A: return GEN75_SCS_ALPHA;
242 default: assert(!"unknown swizzle"); return GEN75_SCS_ZERO;
243 }
244}
245
Chia-I Wu06bed192014-08-20 13:57:18 +0800246static void surface_state_tex_gen7(const struct intel_gpu *gpu,
247 const struct intel_img *img,
248 XGL_IMAGE_VIEW_TYPE type,
249 XGL_FORMAT format,
250 unsigned first_level,
251 unsigned num_levels,
252 unsigned first_layer,
253 unsigned num_layers,
Chia-I Wuf57758c2014-12-02 14:15:50 +0800254 XGL_CHANNEL_MAPPING swizzles,
Chia-I Wu06bed192014-08-20 13:57:18 +0800255 bool is_rt,
256 uint32_t dw[8])
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800257{
258 int surface_type, surface_format;
259 int width, height, depth, pitch, lod;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800260
261 INTEL_GPU_ASSERT(gpu, 7, 7.5);
262
263 surface_type = view_type_to_surface_type(type);
264 assert(surface_type != GEN6_SURFTYPE_BUFFER);
265
266 surface_format = intel_format_translate_color(gpu, format);
267 assert(surface_format >= 0);
268
Chia-I Wu73e326f2014-08-21 11:07:57 +0800269 width = img->layout.width0;
270 height = img->layout.height0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800271 depth = (type == XGL_IMAGE_VIEW_3D) ?
Chia-I Wu73e326f2014-08-21 11:07:57 +0800272 img->depth : num_layers;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800273 pitch = img->layout.bo_stride;
274
275 if (surface_type == GEN6_SURFTYPE_CUBE) {
276 /*
277 * From the Ivy Bridge PRM, volume 4 part 1, page 70:
278 *
279 * "For SURFTYPE_CUBE:For Sampling Engine Surfaces, the range of
280 * this field is [0,340], indicating the number of cube array
281 * elements (equal to the number of underlying 2D array elements
282 * divided by 6). For other surfaces, this field must be zero."
283 *
284 * When is_rt is true, we treat the texture as a 2D one to avoid the
285 * restriction.
286 */
287 if (is_rt) {
288 surface_type = GEN6_SURFTYPE_2D;
289 }
290 else {
291 assert(num_layers % 6 == 0);
292 depth = num_layers / 6;
293 }
294 }
295
296 /* sanity check the size */
297 assert(width >= 1 && height >= 1 && depth >= 1 && pitch >= 1);
298 assert(first_layer < 2048 && num_layers <= 2048);
299 switch (surface_type) {
300 case GEN6_SURFTYPE_1D:
301 assert(width <= 16384 && height == 1 && depth <= 2048);
302 break;
303 case GEN6_SURFTYPE_2D:
304 assert(width <= 16384 && height <= 16384 && depth <= 2048);
305 break;
306 case GEN6_SURFTYPE_3D:
307 assert(width <= 2048 && height <= 2048 && depth <= 2048);
308 if (!is_rt)
309 assert(first_layer == 0);
310 break;
311 case GEN6_SURFTYPE_CUBE:
312 assert(width <= 16384 && height <= 16384 && depth <= 86);
313 assert(width == height);
314 if (is_rt)
315 assert(first_layer == 0);
316 break;
317 default:
318 assert(!"unexpected surface type");
319 break;
320 }
321
322 if (is_rt) {
323 assert(num_levels == 1);
324 lod = first_level;
325 }
326 else {
327 lod = num_levels - 1;
328 }
329
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800330 /*
331 * From the Ivy Bridge PRM, volume 4 part 1, page 68:
332 *
333 * "The Base Address for linear render target surfaces and surfaces
334 * accessed with the typed surface read/write data port messages must
335 * be element-size aligned, for non-YUV surface formats, or a multiple
336 * of 2 element-sizes for YUV surface formats. Other linear surfaces
337 * have no alignment requirements (byte alignment is sufficient)."
338 *
339 * From the Ivy Bridge PRM, volume 4 part 1, page 70:
340 *
341 * "For linear render target surfaces and surfaces accessed with the
342 * typed data port messages, the pitch must be a multiple of the
343 * element size for non-YUV surface formats. Pitch must be a multiple
344 * of 2 * element size for YUV surface formats. For linear surfaces
345 * with Surface Type of SURFTYPE_STRBUF, the pitch must be a multiple
346 * of 4 bytes.For other linear surfaces, the pitch can be any multiple
347 * of bytes."
348 *
349 * From the Ivy Bridge PRM, volume 4 part 1, page 74:
350 *
351 * "For linear surfaces, this field (X Offset) must be zero."
352 */
353 if (img->layout.tiling == INTEL_TILING_NONE) {
354 if (is_rt) {
355 const int elem_size = icd_format_get_size(format);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800356 assert(pitch % elem_size == 0);
357 }
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800358 }
359
360 dw[0] = surface_type << GEN7_SURFACE_DW0_TYPE__SHIFT |
361 surface_format << GEN7_SURFACE_DW0_FORMAT__SHIFT |
362 winsys_tiling_to_surface_tiling(img->layout.tiling) << 13;
363
364 /*
365 * From the Ivy Bridge PRM, volume 4 part 1, page 63:
366 *
367 * "If this field (Surface Array) is enabled, the Surface Type must be
368 * SURFTYPE_1D, SURFTYPE_2D, or SURFTYPE_CUBE. If this field is
369 * disabled and Surface Type is SURFTYPE_1D, SURFTYPE_2D, or
370 * SURFTYPE_CUBE, the Depth field must be set to zero."
371 *
372 * For non-3D sampler surfaces, resinfo (the sampler message) always
373 * returns zero for the number of layers when this field is not set.
374 */
375 if (surface_type != GEN6_SURFTYPE_3D) {
376 if (num_layers > 1)
377 dw[0] |= GEN7_SURFACE_DW0_IS_ARRAY;
378 else
379 assert(depth == 1);
380 }
381
382 assert(img->layout.align_i == 4 || img->layout.align_i == 8);
383 assert(img->layout.align_j == 2 || img->layout.align_j == 4);
384
385 if (img->layout.align_j == 4)
386 dw[0] |= GEN7_SURFACE_DW0_VALIGN_4;
387
388 if (img->layout.align_i == 8)
389 dw[0] |= GEN7_SURFACE_DW0_HALIGN_8;
390
Chia-I Wu457d0a62014-08-18 13:02:26 +0800391 if (img->layout.walk == INTEL_LAYOUT_WALK_LOD)
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800392 dw[0] |= GEN7_SURFACE_DW0_ARYSPC_LOD0;
Chia-I Wu457d0a62014-08-18 13:02:26 +0800393 else
394 dw[0] |= GEN7_SURFACE_DW0_ARYSPC_FULL;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800395
396 if (is_rt)
397 dw[0] |= GEN7_SURFACE_DW0_RENDER_CACHE_RW;
398
399 if (surface_type == GEN6_SURFTYPE_CUBE && !is_rt)
400 dw[0] |= GEN7_SURFACE_DW0_CUBE_FACE_ENABLES__MASK;
401
Chia-I Wu457d0a62014-08-18 13:02:26 +0800402 dw[1] = 0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800403
404 dw[2] = (height - 1) << GEN7_SURFACE_DW2_HEIGHT__SHIFT |
405 (width - 1) << GEN7_SURFACE_DW2_WIDTH__SHIFT;
406
407 dw[3] = (depth - 1) << GEN7_SURFACE_DW3_DEPTH__SHIFT |
408 (pitch - 1);
409
410 dw[4] = first_layer << 18 |
411 (num_layers - 1) << 7;
412
413 /*
414 * MSFMT_MSS means the samples are not interleaved and MSFMT_DEPTH_STENCIL
415 * means the samples are interleaved. The layouts are the same when the
416 * number of samples is 1.
417 */
418 if (img->layout.interleaved_samples && img->samples > 1) {
419 assert(!is_rt);
420 dw[4] |= GEN7_SURFACE_DW4_MSFMT_DEPTH_STENCIL;
421 }
422 else {
423 dw[4] |= GEN7_SURFACE_DW4_MSFMT_MSS;
424 }
425
426 if (img->samples > 4)
427 dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_8;
428 else if (img->samples > 2)
429 dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_4;
430 else
431 dw[4] |= GEN7_SURFACE_DW4_MULTISAMPLECOUNT_1;
432
Chia-I Wu457d0a62014-08-18 13:02:26 +0800433 dw[5] = (first_level) << GEN7_SURFACE_DW5_MIN_LOD__SHIFT |
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800434 lod;
435
436 dw[6] = 0;
437 dw[7] = 0;
438
439 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5)) {
Chia-I Wuf57758c2014-12-02 14:15:50 +0800440 dw[7] |=
441 channel_swizzle_to_scs(swizzles.r) << GEN75_SURFACE_DW7_SCS_R__SHIFT |
442 channel_swizzle_to_scs(swizzles.g) << GEN75_SURFACE_DW7_SCS_G__SHIFT |
443 channel_swizzle_to_scs(swizzles.b) << GEN75_SURFACE_DW7_SCS_B__SHIFT |
444 channel_swizzle_to_scs(swizzles.a) << GEN75_SURFACE_DW7_SCS_A__SHIFT;
445 } else {
446 assert(swizzles.r == XGL_CHANNEL_SWIZZLE_R &&
447 swizzles.g == XGL_CHANNEL_SWIZZLE_G &&
448 swizzles.b == XGL_CHANNEL_SWIZZLE_B &&
449 swizzles.a == XGL_CHANNEL_SWIZZLE_A);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800450 }
451}
452
Chia-I Wu06bed192014-08-20 13:57:18 +0800453static void surface_state_null_gen6(const struct intel_gpu *gpu,
454 uint32_t dw[6])
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800455{
456 INTEL_GPU_ASSERT(gpu, 6, 6);
457
458 /*
459 * From the Sandy Bridge PRM, volume 4 part 1, page 71:
460 *
461 * "A null surface will be used in instances where an actual surface is
462 * not bound. When a write message is generated to a null surface, no
463 * actual surface is written to. When a read message (including any
464 * sampling engine message) is generated to a null surface, the result
465 * is all zeros. Note that a null surface type is allowed to be used
466 * with all messages, even if it is not specificially indicated as
467 * supported. All of the remaining fields in surface state are ignored
468 * for null surfaces, with the following exceptions:
469 *
470 * * [DevSNB+]: Width, Height, Depth, and LOD fields must match the
471 * depth buffer's corresponding state for all render target
472 * surfaces, including null.
473 * * Surface Format must be R8G8B8A8_UNORM."
474 *
475 * From the Sandy Bridge PRM, volume 4 part 1, page 82:
476 *
477 * "If Surface Type is SURFTYPE_NULL, this field (Tiled Surface) must be
478 * true"
479 */
480
481 dw[0] = GEN6_SURFTYPE_NULL << GEN6_SURFACE_DW0_TYPE__SHIFT |
482 GEN6_FORMAT_B8G8R8A8_UNORM << GEN6_SURFACE_DW0_FORMAT__SHIFT;
483
484 dw[1] = 0;
485 dw[2] = 0;
486 dw[3] = GEN6_TILING_X;
487 dw[4] = 0;
488 dw[5] = 0;
489}
490
Chia-I Wu06bed192014-08-20 13:57:18 +0800491static void surface_state_buf_gen6(const struct intel_gpu *gpu,
492 unsigned offset, unsigned size,
493 unsigned struct_size,
494 XGL_FORMAT elem_format,
495 bool is_rt, bool render_cache_rw,
496 uint32_t dw[6])
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800497{
Chia-I Wu4619ed22014-10-08 12:24:37 +0800498 const bool typed = !icd_format_is_undef(elem_format);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800499 const int elem_size = icd_format_get_size(elem_format);
500 int width, height, depth, pitch;
501 int surface_format, num_entries;
502
503 INTEL_GPU_ASSERT(gpu, 6, 6);
504
505 /*
506 * For SURFTYPE_BUFFER, a SURFACE_STATE specifies an element of a
507 * structure in a buffer.
508 */
509
Chia-I Wu4619ed22014-10-08 12:24:37 +0800510 surface_format = (typed) ?
511 intel_format_translate_color(gpu, elem_format) : GEN6_FORMAT_RAW;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800512
513 num_entries = size / struct_size;
514 /* see if there is enough space to fit another element */
515 if (size % struct_size >= elem_size)
516 num_entries++;
517
518 /*
519 * From the Sandy Bridge PRM, volume 4 part 1, page 76:
520 *
521 * "For SURFTYPE_BUFFER render targets, this field (Surface Base
522 * Address) specifies the base address of first element of the
523 * surface. The surface is interpreted as a simple array of that
524 * single element type. The address must be naturally-aligned to the
525 * element size (e.g., a buffer containing R32G32B32A32_FLOAT elements
526 * must be 16-byte aligned).
527 *
528 * For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
529 * the base address of the first element of the surface, computed in
530 * software by adding the surface base address to the byte offset of
531 * the element in the buffer."
532 */
533 if (is_rt)
534 assert(offset % elem_size == 0);
535
536 /*
537 * From the Sandy Bridge PRM, volume 4 part 1, page 77:
538 *
539 * "For buffer surfaces, the number of entries in the buffer ranges
540 * from 1 to 2^27."
541 */
542 assert(num_entries >= 1 && num_entries <= 1 << 27);
543
544 /*
545 * From the Sandy Bridge PRM, volume 4 part 1, page 81:
546 *
547 * "For surfaces of type SURFTYPE_BUFFER, this field (Surface Pitch)
548 * indicates the size of the structure."
549 */
550 pitch = struct_size;
551
552 pitch--;
553 num_entries--;
554 /* bits [6:0] */
555 width = (num_entries & 0x0000007f);
556 /* bits [19:7] */
557 height = (num_entries & 0x000fff80) >> 7;
558 /* bits [26:20] */
559 depth = (num_entries & 0x07f00000) >> 20;
560
561 dw[0] = GEN6_SURFTYPE_BUFFER << GEN6_SURFACE_DW0_TYPE__SHIFT |
562 surface_format << GEN6_SURFACE_DW0_FORMAT__SHIFT;
563 if (render_cache_rw)
564 dw[0] |= GEN6_SURFACE_DW0_RENDER_CACHE_RW;
565
566 dw[1] = offset;
567
568 dw[2] = height << GEN6_SURFACE_DW2_HEIGHT__SHIFT |
569 width << GEN6_SURFACE_DW2_WIDTH__SHIFT;
570
571 dw[3] = depth << GEN6_SURFACE_DW3_DEPTH__SHIFT |
572 pitch << GEN6_SURFACE_DW3_PITCH__SHIFT;
573
574 dw[4] = 0;
575 dw[5] = 0;
576}
577
Chia-I Wu06bed192014-08-20 13:57:18 +0800578static void surface_state_tex_gen6(const struct intel_gpu *gpu,
579 const struct intel_img *img,
580 XGL_IMAGE_VIEW_TYPE type,
581 XGL_FORMAT format,
582 unsigned first_level,
583 unsigned num_levels,
584 unsigned first_layer,
585 unsigned num_layers,
586 bool is_rt,
587 uint32_t dw[6])
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800588{
589 int surface_type, surface_format;
590 int width, height, depth, pitch, lod;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800591
592 INTEL_GPU_ASSERT(gpu, 6, 6);
593
594 surface_type = view_type_to_surface_type(type);
595 assert(surface_type != GEN6_SURFTYPE_BUFFER);
596
597 surface_format = intel_format_translate_color(gpu, format);
598 assert(surface_format >= 0);
599
Chia-I Wu73e326f2014-08-21 11:07:57 +0800600 width = img->layout.width0;
601 height = img->layout.height0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800602 depth = (type == XGL_IMAGE_VIEW_3D) ?
Chia-I Wu73e326f2014-08-21 11:07:57 +0800603 img->depth : num_layers;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800604 pitch = img->layout.bo_stride;
605
606 if (surface_type == GEN6_SURFTYPE_CUBE) {
607 /*
608 * From the Sandy Bridge PRM, volume 4 part 1, page 81:
609 *
610 * "For SURFTYPE_CUBE: [DevSNB+]: for Sampling Engine Surfaces, the
611 * range of this field (Depth) is [0,84], indicating the number of
612 * cube array elements (equal to the number of underlying 2D array
613 * elements divided by 6). For other surfaces, this field must be
614 * zero."
615 *
616 * When is_rt is true, we treat the texture as a 2D one to avoid the
617 * restriction.
618 */
619 if (is_rt) {
620 surface_type = GEN6_SURFTYPE_2D;
621 }
622 else {
623 assert(num_layers % 6 == 0);
624 depth = num_layers / 6;
625 }
626 }
627
628 /* sanity check the size */
629 assert(width >= 1 && height >= 1 && depth >= 1 && pitch >= 1);
630 switch (surface_type) {
631 case GEN6_SURFTYPE_1D:
632 assert(width <= 8192 && height == 1 && depth <= 512);
633 assert(first_layer < 512 && num_layers <= 512);
634 break;
635 case GEN6_SURFTYPE_2D:
636 assert(width <= 8192 && height <= 8192 && depth <= 512);
637 assert(first_layer < 512 && num_layers <= 512);
638 break;
639 case GEN6_SURFTYPE_3D:
640 assert(width <= 2048 && height <= 2048 && depth <= 2048);
641 assert(first_layer < 2048 && num_layers <= 512);
642 if (!is_rt)
643 assert(first_layer == 0);
644 break;
645 case GEN6_SURFTYPE_CUBE:
646 assert(width <= 8192 && height <= 8192 && depth <= 85);
647 assert(width == height);
648 assert(first_layer < 512 && num_layers <= 512);
649 if (is_rt)
650 assert(first_layer == 0);
651 break;
652 default:
653 assert(!"unexpected surface type");
654 break;
655 }
656
657 /* non-full array spacing is supported only on GEN7+ */
Chia-I Wu457d0a62014-08-18 13:02:26 +0800658 assert(img->layout.walk != INTEL_LAYOUT_WALK_LOD);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800659 /* non-interleaved samples are supported only on GEN7+ */
660 if (img->samples > 1)
661 assert(img->layout.interleaved_samples);
662
663 if (is_rt) {
664 assert(num_levels == 1);
665 lod = first_level;
666 }
667 else {
668 lod = num_levels - 1;
669 }
670
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800671 /*
672 * From the Sandy Bridge PRM, volume 4 part 1, page 76:
673 *
674 * "Linear render target surface base addresses must be element-size
675 * aligned, for non-YUV surface formats, or a multiple of 2
676 * element-sizes for YUV surface formats. Other linear surfaces have
677 * no alignment requirements (byte alignment is sufficient.)"
678 *
679 * From the Sandy Bridge PRM, volume 4 part 1, page 81:
680 *
681 * "For linear render target surfaces, the pitch must be a multiple
682 * of the element size for non-YUV surface formats. Pitch must be a
683 * multiple of 2 * element size for YUV surface formats."
684 *
685 * From the Sandy Bridge PRM, volume 4 part 1, page 86:
686 *
687 * "For linear surfaces, this field (X Offset) must be zero"
688 */
689 if (img->layout.tiling == INTEL_TILING_NONE) {
690 if (is_rt) {
691 const int elem_size = icd_format_get_size(format);
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800692 assert(pitch % elem_size == 0);
693 }
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800694 }
695
696 dw[0] = surface_type << GEN6_SURFACE_DW0_TYPE__SHIFT |
697 surface_format << GEN6_SURFACE_DW0_FORMAT__SHIFT |
698 GEN6_SURFACE_DW0_MIPLAYOUT_BELOW;
699
700 if (surface_type == GEN6_SURFTYPE_CUBE && !is_rt) {
701 dw[0] |= 1 << 9 |
702 GEN6_SURFACE_DW0_CUBE_FACE_ENABLES__MASK;
703 }
704
705 if (is_rt)
706 dw[0] |= GEN6_SURFACE_DW0_RENDER_CACHE_RW;
707
Chia-I Wu457d0a62014-08-18 13:02:26 +0800708 dw[1] = 0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800709
710 dw[2] = (height - 1) << GEN6_SURFACE_DW2_HEIGHT__SHIFT |
711 (width - 1) << GEN6_SURFACE_DW2_WIDTH__SHIFT |
712 lod << GEN6_SURFACE_DW2_MIP_COUNT_LOD__SHIFT;
713
714 dw[3] = (depth - 1) << GEN6_SURFACE_DW3_DEPTH__SHIFT |
715 (pitch - 1) << GEN6_SURFACE_DW3_PITCH__SHIFT |
716 winsys_tiling_to_surface_tiling(img->layout.tiling);
717
718 dw[4] = first_level << GEN6_SURFACE_DW4_MIN_LOD__SHIFT |
719 first_layer << 17 |
720 (num_layers - 1) << 8 |
721 ((img->samples > 1) ? GEN6_SURFACE_DW4_MULTISAMPLECOUNT_4 :
722 GEN6_SURFACE_DW4_MULTISAMPLECOUNT_1);
723
Chia-I Wu457d0a62014-08-18 13:02:26 +0800724 dw[5] = 0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800725
726 assert(img->layout.align_j == 2 || img->layout.align_j == 4);
727 if (img->layout.align_j == 4)
728 dw[5] |= GEN6_SURFACE_DW5_VALIGN_4;
729}
730
731struct ds_surface_info {
732 int surface_type;
733 int format;
734
735 struct {
736 unsigned stride;
Chia-I Wu457d0a62014-08-18 13:02:26 +0800737 unsigned offset;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800738 } zs, stencil, hiz;
739
740 unsigned width, height, depth;
741 unsigned lod, first_layer, num_layers;
742};
743
744static void
745ds_init_info_null(const struct intel_gpu *gpu,
746 struct ds_surface_info *info)
747{
748 INTEL_GPU_ASSERT(gpu, 6, 7.5);
749
750 memset(info, 0, sizeof(*info));
751
752 info->surface_type = GEN6_SURFTYPE_NULL;
753 info->format = GEN6_ZFORMAT_D32_FLOAT;
754 info->width = 1;
755 info->height = 1;
756 info->depth = 1;
757 info->num_layers = 1;
758}
759
760static void
761ds_init_info(const struct intel_gpu *gpu,
762 const struct intel_img *img,
763 XGL_FORMAT format, unsigned level,
764 unsigned first_layer, unsigned num_layers,
765 struct ds_surface_info *info)
766{
767 bool separate_stencil;
768
769 INTEL_GPU_ASSERT(gpu, 6, 7.5);
770
771 memset(info, 0, sizeof(*info));
772
773 info->surface_type =
774 view_type_to_surface_type(img_type_to_view_type(img->type));
775
776 if (info->surface_type == GEN6_SURFTYPE_CUBE) {
777 /*
778 * From the Sandy Bridge PRM, volume 2 part 1, page 325-326:
779 *
780 * "For Other Surfaces (Cube Surfaces):
781 * This field (Minimum Array Element) is ignored."
782 *
783 * "For Other Surfaces (Cube Surfaces):
784 * This field (Render Target View Extent) is ignored."
785 *
786 * As such, we cannot set first_layer and num_layers on cube surfaces.
787 * To work around that, treat it as a 2D surface.
788 */
789 info->surface_type = GEN6_SURFTYPE_2D;
790 }
791
792 if (intel_gpu_gen(gpu) >= INTEL_GEN(7)) {
793 separate_stencil = true;
794 }
795 else {
796 /*
797 * From the Sandy Bridge PRM, volume 2 part 1, page 317:
798 *
799 * "This field (Separate Stencil Buffer Enable) must be set to the
800 * same value (enabled or disabled) as Hierarchical Depth Buffer
801 * Enable."
802 */
803 separate_stencil = img->aux_offset;
804 }
805
806 /*
807 * From the Sandy Bridge PRM, volume 2 part 1, page 317:
808 *
809 * "If this field (Hierarchical Depth Buffer Enable) is enabled, the
810 * Surface Format of the depth buffer cannot be
811 * D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT. Use of stencil
812 * requires the separate stencil buffer."
813 *
814 * From the Ironlake PRM, volume 2 part 1, page 330:
815 *
816 * "If this field (Separate Stencil Buffer Enable) is disabled, the
817 * Surface Format of the depth buffer cannot be D24_UNORM_X8_UINT."
818 *
819 * There is no similar restriction for GEN6. But when D24_UNORM_X8_UINT
820 * is indeed used, the depth values output by the fragment shaders will
821 * be different when read back.
822 *
823 * As for GEN7+, separate_stencil is always true.
824 */
825 switch (format.channelFormat) {
826 case XGL_CH_FMT_R16:
827 info->format = GEN6_ZFORMAT_D16_UNORM;
828 break;
829 case XGL_CH_FMT_R32:
830 info->format = GEN6_ZFORMAT_D32_FLOAT;
831 break;
832 case XGL_CH_FMT_R32G8:
833 info->format = (separate_stencil) ?
834 GEN6_ZFORMAT_D32_FLOAT :
835 GEN6_ZFORMAT_D32_FLOAT_S8X24_UINT;
836 break;
837 case XGL_CH_FMT_R8:
838 if (separate_stencil) {
839 info->format = GEN6_ZFORMAT_D32_FLOAT;
840 break;
841 }
842 /* fall through */
843 default:
844 assert(!"unsupported depth/stencil format");
845 ds_init_info_null(gpu, info);
846 return;
847 break;
848 }
849
850 if (format.channelFormat != XGL_CH_FMT_R8)
851 info->zs.stride = img->layout.bo_stride;
852
853 if (img->s8_layout) {
854 /*
855 * From the Sandy Bridge PRM, volume 2 part 1, page 329:
856 *
857 * "The pitch must be set to 2x the value computed based on width,
858 * as the stencil buffer is stored with two rows interleaved."
859 *
860 * According to the classic driver, we need to do the same for GEN7+
861 * even though the Ivy Bridge PRM does not say anything about it.
862 */
863 info->stencil.stride = img->s8_layout->bo_stride * 2;
Chia-I Wu457d0a62014-08-18 13:02:26 +0800864
865 if (intel_gpu_gen(gpu) == INTEL_GEN(6)) {
866 unsigned x, y;
867
868 assert(img->s8_layout->walk == INTEL_LAYOUT_WALK_LOD);
869
870 /* offset to the level */
871 intel_layout_get_slice_pos(img->s8_layout, level, 0, &x, &y);
872 intel_layout_pos_to_mem(img->s8_layout, x, y, &x, &y);
873 info->stencil.offset = intel_layout_mem_to_raw(img->s8_layout, x, y);
874 }
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800875 } else if (format.channelFormat == XGL_CH_FMT_R8) {
876 info->stencil.stride = img->layout.bo_stride * 2;
877 }
878
Chia-I Wu457d0a62014-08-18 13:02:26 +0800879 if (img->aux_offset) {
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800880 info->hiz.stride = img->layout.aux_stride;
881
Chia-I Wu457d0a62014-08-18 13:02:26 +0800882 /* offset to the level */
883 if (intel_gpu_gen(gpu) == INTEL_GEN(6))
884 info->hiz.offset = img->layout.aux_offsets[level];
885 }
886
887
Chia-I Wu73e326f2014-08-21 11:07:57 +0800888 info->width = img->layout.width0;
889 info->height = img->layout.height0;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800890 info->depth = (img->type == XGL_IMAGE_3D) ?
Chia-I Wu73e326f2014-08-21 11:07:57 +0800891 img->depth : num_layers;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800892
893 info->lod = level;
894 info->first_layer = first_layer;
895 info->num_layers = num_layers;
896}
897
Chia-I Wu06bed192014-08-20 13:57:18 +0800898static void ds_view_init(struct intel_ds_view *view,
899 const struct intel_gpu *gpu,
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800900 const struct intel_img *img,
901 XGL_FORMAT format, unsigned level,
Chia-I Wu06bed192014-08-20 13:57:18 +0800902 unsigned first_layer, unsigned num_layers)
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800903{
904 const int max_2d_size = (intel_gpu_gen(gpu) >= INTEL_GEN(7)) ? 16384 : 8192;
905 const int max_array_size = (intel_gpu_gen(gpu) >= INTEL_GEN(7)) ? 2048 : 512;
906 struct ds_surface_info info;
907 uint32_t dw1, dw2, dw3, dw4, dw5, dw6;
Chia-I Wu06bed192014-08-20 13:57:18 +0800908 uint32_t *dw;
Chia-I Wu9269d1c2014-08-16 12:47:47 +0800909
910 INTEL_GPU_ASSERT(gpu, 6, 7.5);
911
912 if (img) {
913 ds_init_info(gpu, img, format, level, first_layer, num_layers, &info);
914 }
915 else {
916 ds_init_info_null(gpu, &info);
917 }
918
919 switch (info.surface_type) {
920 case GEN6_SURFTYPE_NULL:
921 break;
922 case GEN6_SURFTYPE_1D:
923 assert(info.width <= max_2d_size && info.height == 1 &&
924 info.depth <= max_array_size);
925 assert(info.first_layer < max_array_size - 1 &&
926 info.num_layers <= max_array_size);
927 break;
928 case GEN6_SURFTYPE_2D:
929 assert(info.width <= max_2d_size && info.height <= max_2d_size &&
930 info.depth <= max_array_size);
931 assert(info.first_layer < max_array_size - 1 &&
932 info.num_layers <= max_array_size);
933 break;
934 case GEN6_SURFTYPE_3D:
935 assert(info.width <= 2048 && info.height <= 2048 && info.depth <= 2048);
936 assert(info.first_layer < 2048 && info.num_layers <= max_array_size);
937 break;
938 case GEN6_SURFTYPE_CUBE:
939 assert(info.width <= max_2d_size && info.height <= max_2d_size &&
940 info.depth == 1);
941 assert(info.first_layer == 0 && info.num_layers == 1);
942 assert(info.width == info.height);
943 break;
944 default:
945 assert(!"unexpected depth surface type");
946 break;
947 }
948
949 dw1 = info.surface_type << 29 |
950 info.format << 18;
951
952 if (info.zs.stride) {
953 /* required for GEN6+ */
954 assert(info.zs.stride > 0 && info.zs.stride < 128 * 1024 &&
955 info.zs.stride % 128 == 0);
956 assert(info.width <= info.zs.stride);
957
958 dw1 |= (info.zs.stride - 1);
959 }
960
961 dw2 = 0;
962
963 if (intel_gpu_gen(gpu) >= INTEL_GEN(7)) {
964 if (info.zs.stride)
965 dw1 |= 1 << 28;
966
967 if (info.stencil.stride)
968 dw1 |= 1 << 27;
969
970 if (info.hiz.stride)
971 dw1 |= 1 << 22;
972
973 dw3 = (info.height - 1) << 18 |
974 (info.width - 1) << 4 |
975 info.lod;
976
977 dw4 = (info.depth - 1) << 21 |
978 info.first_layer << 10;
979
980 dw5 = 0;
981
982 dw6 = (info.num_layers - 1) << 21;
983 }
984 else {
985 /* always Y-tiled */
986 dw1 |= 1 << 27 |
987 1 << 26;
988
989 if (info.hiz.stride) {
990 dw1 |= 1 << 22 |
991 1 << 21;
992 }
993
994 dw3 = (info.height - 1) << 19 |
995 (info.width - 1) << 6 |
996 info.lod << 2 |
997 GEN6_DEPTH_DW3_MIPLAYOUT_BELOW;
998
999 dw4 = (info.depth - 1) << 21 |
1000 info.first_layer << 10 |
1001 (info.num_layers - 1) << 1;
1002
1003 dw5 = 0;
1004
1005 dw6 = 0;
1006 }
1007
Chia-I Wu06bed192014-08-20 13:57:18 +08001008 STATIC_ASSERT(ARRAY_SIZE(view->cmd) >= 10);
1009 dw = view->cmd;
1010
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001011 dw[0] = dw1;
1012 dw[1] = dw2;
1013 dw[2] = dw3;
1014 dw[3] = dw4;
1015 dw[4] = dw5;
1016 dw[5] = dw6;
1017
1018 /* separate stencil */
1019 if (info.stencil.stride) {
1020 assert(info.stencil.stride > 0 && info.stencil.stride < 128 * 1024 &&
1021 info.stencil.stride % 128 == 0);
1022
1023 dw[6] = info.stencil.stride - 1;
1024 dw[7] = img->s8_offset;
1025
1026 if (intel_gpu_gen(gpu) >= INTEL_GEN(7.5))
1027 dw[6] |= GEN75_STENCIL_DW1_STENCIL_BUFFER_ENABLE;
1028 }
1029 else {
1030 dw[6] = 0;
1031 dw[7] = 0;
1032 }
1033
1034 /* hiz */
1035 if (info.hiz.stride) {
1036 dw[8] = info.hiz.stride - 1;
1037 dw[9] = img->aux_offset;
1038 }
1039 else {
1040 dw[8] = 0;
1041 dw[9] = 0;
1042 }
1043}
1044
Chia-I Wu5a323262014-08-11 10:31:53 +08001045void intel_null_view_init(struct intel_null_view *view,
1046 struct intel_dev *dev)
1047{
Chia-I Wucd83cf12014-08-23 17:26:08 +08001048 if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wu06bed192014-08-20 13:57:18 +08001049 surface_state_null_gen7(dev->gpu, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001050 view->cmd_len = 8;
1051 } else {
Chia-I Wu06bed192014-08-20 13:57:18 +08001052 surface_state_null_gen6(dev->gpu, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001053 view->cmd_len = 6;
1054 }
Chia-I Wu5a323262014-08-11 10:31:53 +08001055}
1056
1057void intel_mem_view_init(struct intel_mem_view *view,
1058 struct intel_dev *dev,
1059 const XGL_MEMORY_VIEW_ATTACH_INFO *info)
1060{
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001061 bool will_write;
1062
1063 switch (info->state) {
1064 case XGL_MEMORY_STATE_GRAPHICS_SHADER_WRITE_ONLY:
1065 case XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_WRITE:
1066 case XGL_MEMORY_STATE_COMPUTE_SHADER_WRITE_ONLY:
1067 case XGL_MEMORY_STATE_COMPUTE_SHADER_READ_WRITE:
1068 will_write = true;
1069 break;
1070 default:
1071 will_write = false;
1072 break;
1073 }
Chia-I Wu5a323262014-08-11 10:31:53 +08001074
1075 view->mem = intel_mem(info->mem);
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001076
1077 if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wu06bed192014-08-20 13:57:18 +08001078 surface_state_buf_gen7(dev->gpu, info->offset,
1079 info->range, info->stride, info->format,
1080 will_write, will_write, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001081 view->cmd_len = 8;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001082 } else {
Chia-I Wu06bed192014-08-20 13:57:18 +08001083 surface_state_buf_gen6(dev->gpu, info->offset,
1084 info->range, info->stride, info->format,
1085 will_write, will_write, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001086 view->cmd_len = 6;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001087 }
Chia-I Wu5a323262014-08-11 10:31:53 +08001088}
1089
1090static void img_view_destroy(struct intel_obj *obj)
1091{
1092 struct intel_img_view *view = intel_img_view_from_obj(obj);
1093
1094 intel_img_view_destroy(view);
1095}
1096
1097XGL_RESULT intel_img_view_create(struct intel_dev *dev,
1098 const XGL_IMAGE_VIEW_CREATE_INFO *info,
1099 struct intel_img_view **view_ret)
1100{
1101 struct intel_img *img = intel_img(info->image);
1102 struct intel_img_view *view;
Chia-I Wuaa759372014-10-18 12:47:35 +08001103 XGL_UINT mip_levels, array_size;
Chia-I Wuf57758c2014-12-02 14:15:50 +08001104 XGL_CHANNEL_MAPPING state_swizzles;
Chia-I Wuaa759372014-10-18 12:47:35 +08001105
1106 if (info->subresourceRange.baseMipLevel >= img->mip_levels ||
1107 info->subresourceRange.baseArraySlice >= img->array_size ||
1108 !info->subresourceRange.mipLevels ||
1109 !info->subresourceRange.arraySize)
1110 return XGL_ERROR_INVALID_VALUE;
1111
1112 mip_levels = info->subresourceRange.mipLevels;
1113 if (mip_levels > img->mip_levels - info->subresourceRange.baseMipLevel)
1114 mip_levels = img->mip_levels - info->subresourceRange.baseMipLevel;
1115
1116 array_size = info->subresourceRange.arraySize;
1117 if (array_size > img->array_size - info->subresourceRange.baseArraySlice)
1118 array_size = img->array_size - info->subresourceRange.baseArraySlice;
Chia-I Wu5a323262014-08-11 10:31:53 +08001119
1120 view = (struct intel_img_view *) intel_base_create(dev, sizeof(*view),
1121 dev->base.dbg, XGL_DBG_OBJECT_IMAGE_VIEW, info, 0);
1122 if (!view)
1123 return XGL_ERROR_OUT_OF_MEMORY;
1124
1125 view->obj.destroy = img_view_destroy;
1126
1127 view->img = img;
Chia-I Wu5a323262014-08-11 10:31:53 +08001128 view->min_lod = info->minLod;
1129
Chia-I Wuf57758c2014-12-02 14:15:50 +08001130 if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7.5)) {
1131 state_swizzles = info->channels;
1132 view->shader_swizzles.r = XGL_CHANNEL_SWIZZLE_R;
1133 view->shader_swizzles.g = XGL_CHANNEL_SWIZZLE_G;
1134 view->shader_swizzles.b = XGL_CHANNEL_SWIZZLE_B;
1135 view->shader_swizzles.a = XGL_CHANNEL_SWIZZLE_A;
1136 } else {
1137 state_swizzles.r = XGL_CHANNEL_SWIZZLE_R;
1138 state_swizzles.g = XGL_CHANNEL_SWIZZLE_G;
1139 state_swizzles.b = XGL_CHANNEL_SWIZZLE_B;
1140 state_swizzles.a = XGL_CHANNEL_SWIZZLE_A;
1141 view->shader_swizzles = info->channels;
1142 }
1143
1144 /* shader_swizzles is ignored by the compiler */
1145 if (view->shader_swizzles.r != XGL_CHANNEL_SWIZZLE_R ||
1146 view->shader_swizzles.g != XGL_CHANNEL_SWIZZLE_G ||
1147 view->shader_swizzles.b != XGL_CHANNEL_SWIZZLE_B ||
1148 view->shader_swizzles.a != XGL_CHANNEL_SWIZZLE_A) {
1149 intel_dev_log(dev, XGL_DBG_MSG_WARNING,
1150 XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0, 0,
1151 "image data swizzling is ignored");
1152 }
1153
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001154 if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wu06bed192014-08-20 13:57:18 +08001155 surface_state_tex_gen7(dev->gpu, img, info->viewType, info->format,
Chia-I Wuaa759372014-10-18 12:47:35 +08001156 info->subresourceRange.baseMipLevel, mip_levels,
1157 info->subresourceRange.baseArraySlice, array_size,
Chia-I Wuf57758c2014-12-02 14:15:50 +08001158 state_swizzles, false, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001159 view->cmd_len = 8;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001160 } else {
Chia-I Wu06bed192014-08-20 13:57:18 +08001161 surface_state_tex_gen6(dev->gpu, img, info->viewType, info->format,
Chia-I Wuaa759372014-10-18 12:47:35 +08001162 info->subresourceRange.baseMipLevel, mip_levels,
1163 info->subresourceRange.baseArraySlice, array_size,
1164 false, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001165 view->cmd_len = 6;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001166 }
1167
Chia-I Wu5a323262014-08-11 10:31:53 +08001168 *view_ret = view;
1169
1170 return XGL_SUCCESS;
1171}
1172
1173void intel_img_view_destroy(struct intel_img_view *view)
1174{
1175 intel_base_destroy(&view->obj.base);
1176}
1177
1178static void rt_view_destroy(struct intel_obj *obj)
1179{
1180 struct intel_rt_view *view = intel_rt_view_from_obj(obj);
1181
1182 intel_rt_view_destroy(view);
1183}
1184
1185XGL_RESULT intel_rt_view_create(struct intel_dev *dev,
1186 const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO *info,
1187 struct intel_rt_view **view_ret)
1188{
Chia-I Wuf57758c2014-12-02 14:15:50 +08001189 static const XGL_CHANNEL_MAPPING identity_channel_mapping = {
1190 .r = XGL_CHANNEL_SWIZZLE_R,
1191 .g = XGL_CHANNEL_SWIZZLE_G,
1192 .b = XGL_CHANNEL_SWIZZLE_B,
1193 .a = XGL_CHANNEL_SWIZZLE_A,
1194 };
Chia-I Wu5a323262014-08-11 10:31:53 +08001195 struct intel_img *img = intel_img(info->image);
1196 struct intel_rt_view *view;
1197
1198 view = (struct intel_rt_view *) intel_base_create(dev, sizeof(*view),
1199 dev->base.dbg, XGL_DBG_OBJECT_COLOR_TARGET_VIEW, info, 0);
1200 if (!view)
1201 return XGL_ERROR_OUT_OF_MEMORY;
1202
1203 view->obj.destroy = rt_view_destroy;
1204
1205 view->img = img;
1206
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001207 if (intel_gpu_gen(dev->gpu) >= INTEL_GEN(7)) {
Chia-I Wu06bed192014-08-20 13:57:18 +08001208 surface_state_tex_gen7(dev->gpu, img,
1209 img_type_to_view_type(img->type),
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001210 info->format, info->mipLevel, 1,
1211 info->baseArraySlice, info->arraySize,
Chia-I Wuf57758c2014-12-02 14:15:50 +08001212 identity_channel_mapping, true, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001213 view->cmd_len = 8;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001214 } else {
Chia-I Wu06bed192014-08-20 13:57:18 +08001215 surface_state_tex_gen6(dev->gpu, img,
1216 img_type_to_view_type(img->type),
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001217 info->format, info->mipLevel, 1,
1218 info->baseArraySlice, info->arraySize,
1219 true, view->cmd);
Chia-I Wucd83cf12014-08-23 17:26:08 +08001220 view->cmd_len = 6;
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001221 }
1222
Chia-I Wu5a323262014-08-11 10:31:53 +08001223 *view_ret = view;
1224
1225 return XGL_SUCCESS;
1226}
1227
1228void intel_rt_view_destroy(struct intel_rt_view *view)
1229{
1230 intel_base_destroy(&view->obj.base);
1231}
1232
1233static void ds_view_destroy(struct intel_obj *obj)
1234{
1235 struct intel_ds_view *view = intel_ds_view_from_obj(obj);
1236
1237 intel_ds_view_destroy(view);
1238}
1239
1240XGL_RESULT intel_ds_view_create(struct intel_dev *dev,
1241 const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO *info,
1242 struct intel_ds_view **view_ret)
1243{
1244 struct intel_img *img = intel_img(info->image);
1245 struct intel_ds_view *view;
1246
1247 view = (struct intel_ds_view *) intel_base_create(dev, sizeof(*view),
1248 dev->base.dbg, XGL_DBG_OBJECT_DEPTH_STENCIL_VIEW, info, 0);
1249 if (!view)
1250 return XGL_ERROR_OUT_OF_MEMORY;
1251
1252 view->obj.destroy = ds_view_destroy;
1253
1254 view->img = img;
1255
Chia-I Wu06bed192014-08-20 13:57:18 +08001256 ds_view_init(view, dev->gpu, img, img->layout.format, info->mipLevel,
1257 info->baseArraySlice, info->arraySize);
Chia-I Wu9269d1c2014-08-16 12:47:47 +08001258
Chia-I Wu5a323262014-08-11 10:31:53 +08001259 *view_ret = view;
1260
1261 return XGL_SUCCESS;
1262}
1263
1264void intel_ds_view_destroy(struct intel_ds_view *view)
1265{
1266 intel_base_destroy(&view->obj.base);
1267}
1268
1269XGL_RESULT XGLAPI intelCreateImageView(
1270 XGL_DEVICE device,
1271 const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo,
1272 XGL_IMAGE_VIEW* pView)
1273{
1274 struct intel_dev *dev = intel_dev(device);
1275
1276 return intel_img_view_create(dev, pCreateInfo,
1277 (struct intel_img_view **) pView);
1278}
1279
1280XGL_RESULT XGLAPI intelCreateColorAttachmentView(
1281 XGL_DEVICE device,
1282 const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo,
1283 XGL_COLOR_ATTACHMENT_VIEW* pView)
1284{
1285 struct intel_dev *dev = intel_dev(device);
1286
1287 return intel_rt_view_create(dev, pCreateInfo,
1288 (struct intel_rt_view **) pView);
1289}
1290
1291XGL_RESULT XGLAPI intelCreateDepthStencilView(
1292 XGL_DEVICE device,
1293 const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo,
1294 XGL_DEPTH_STENCIL_VIEW* pView)
1295{
1296 struct intel_dev *dev = intel_dev(device);
1297
1298 return intel_ds_view_create(dev, pCreateInfo,
1299 (struct intel_ds_view **) pView);
1300}