1 /*
2 * Copyright © 2013 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "util/ralloc.h"
25
26 #include "main/macros.h" /* Needed for MAX3 and MAX2 for format_rgb9e5 */
27 #include "util/format_rgb9e5.h"
28 #include "util/format_srgb.h"
29
30 #include "blorp_priv.h"
31 #include "compiler/brw_eu_defines.h"
32
33 #include "blorp_nir_builder.h"
34
35 #define FILE_DEBUG_FLAG DEBUG_BLORP
36
37 #pragma pack(push, 1)
38 struct brw_blorp_const_color_prog_key
39 {
40 enum blorp_shader_type shader_type; /* Must be BLORP_SHADER_TYPE_CLEAR */
41 bool use_simd16_replicated_data;
42 bool clear_rgb_as_red;
43 };
44 #pragma pack(pop)
45
46 static bool
blorp_params_get_clear_kernel(struct blorp_batch * batch,struct blorp_params * params,bool use_replicated_data,bool clear_rgb_as_red)47 blorp_params_get_clear_kernel(struct blorp_batch *batch,
48 struct blorp_params *params,
49 bool use_replicated_data,
50 bool clear_rgb_as_red)
51 {
52 struct blorp_context *blorp = batch->blorp;
53
54 const struct brw_blorp_const_color_prog_key blorp_key = {
55 .shader_type = BLORP_SHADER_TYPE_CLEAR,
56 .use_simd16_replicated_data = use_replicated_data,
57 .clear_rgb_as_red = clear_rgb_as_red,
58 };
59
60 if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
61 ¶ms->wm_prog_kernel, ¶ms->wm_prog_data))
62 return true;
63
64 void *mem_ctx = ralloc_context(NULL);
65
66 nir_builder b;
67 blorp_nir_init_shader(&b, mem_ctx, MESA_SHADER_FRAGMENT,
68 blorp_shader_type_to_name(blorp_key.shader_type));
69
70 nir_variable *v_color =
71 BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type());
72 nir_ssa_def *color = nir_load_var(&b, v_color);
73
74 if (clear_rgb_as_red) {
75 nir_ssa_def *pos = nir_f2i32(&b, nir_load_frag_coord(&b));
76 nir_ssa_def *comp = nir_umod(&b, nir_channel(&b, pos, 0),
77 nir_imm_int(&b, 3));
78 nir_ssa_def *color_component =
79 nir_bcsel(&b, nir_ieq_imm(&b, comp, 0),
80 nir_channel(&b, color, 0),
81 nir_bcsel(&b, nir_ieq_imm(&b, comp, 1),
82 nir_channel(&b, color, 1),
83 nir_channel(&b, color, 2)));
84
85 nir_ssa_def *u = nir_ssa_undef(&b, 1, 32);
86 color = nir_vec4(&b, color_component, u, u, u);
87 }
88
89 nir_variable *frag_color = nir_variable_create(b.shader, nir_var_shader_out,
90 glsl_vec4_type(),
91 "gl_FragColor");
92 frag_color->data.location = FRAG_RESULT_COLOR;
93 nir_store_var(&b, frag_color, color, 0xf);
94
95 struct brw_wm_prog_key wm_key;
96 brw_blorp_init_wm_prog_key(&wm_key);
97
98 struct brw_wm_prog_data prog_data;
99 const unsigned *program =
100 blorp_compile_fs(blorp, mem_ctx, b.shader, &wm_key, use_replicated_data,
101 &prog_data);
102
103 bool result =
104 blorp->upload_shader(batch, MESA_SHADER_FRAGMENT,
105 &blorp_key, sizeof(blorp_key),
106 program, prog_data.base.program_size,
107 &prog_data.base, sizeof(prog_data),
108 ¶ms->wm_prog_kernel, ¶ms->wm_prog_data);
109
110 ralloc_free(mem_ctx);
111 return result;
112 }
113
114 #pragma pack(push, 1)
115 struct layer_offset_vs_key {
116 enum blorp_shader_type shader_type;
117 unsigned num_inputs;
118 };
119 #pragma pack(pop)
120
121 /* In the case of doing attachment clears, we are using a surface state that
122 * is handed to us so we can't set (and don't even know) the base array layer.
123 * In order to do a layered clear in this scenario, we need some way of adding
124 * the base array layer to the instance id. Unfortunately, our hardware has
125 * no real concept of "base instance", so we have to do it manually in a
126 * vertex shader.
127 */
128 static bool
blorp_params_get_layer_offset_vs(struct blorp_batch * batch,struct blorp_params * params)129 blorp_params_get_layer_offset_vs(struct blorp_batch *batch,
130 struct blorp_params *params)
131 {
132 struct blorp_context *blorp = batch->blorp;
133 struct layer_offset_vs_key blorp_key = {
134 .shader_type = BLORP_SHADER_TYPE_LAYER_OFFSET_VS,
135 };
136
137 if (params->wm_prog_data)
138 blorp_key.num_inputs = params->wm_prog_data->num_varying_inputs;
139
140 if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
141 ¶ms->vs_prog_kernel, ¶ms->vs_prog_data))
142 return true;
143
144 void *mem_ctx = ralloc_context(NULL);
145
146 nir_builder b;
147 blorp_nir_init_shader(&b, mem_ctx, MESA_SHADER_VERTEX,
148 blorp_shader_type_to_name(blorp_key.shader_type));
149
150 const struct glsl_type *uvec4_type = glsl_vector_type(GLSL_TYPE_UINT, 4);
151
152 /* First we deal with the header which has instance and base instance */
153 nir_variable *a_header = nir_variable_create(b.shader, nir_var_shader_in,
154 uvec4_type, "header");
155 a_header->data.location = VERT_ATTRIB_GENERIC0;
156
157 nir_variable *v_layer = nir_variable_create(b.shader, nir_var_shader_out,
158 glsl_int_type(), "layer_id");
159 v_layer->data.location = VARYING_SLOT_LAYER;
160
161 /* Compute the layer id */
162 nir_ssa_def *header = nir_load_var(&b, a_header);
163 nir_ssa_def *base_layer = nir_channel(&b, header, 0);
164 nir_ssa_def *instance = nir_channel(&b, header, 1);
165 nir_store_var(&b, v_layer, nir_iadd(&b, instance, base_layer), 0x1);
166
167 /* Then we copy the vertex from the next slot to VARYING_SLOT_POS */
168 nir_variable *a_vertex = nir_variable_create(b.shader, nir_var_shader_in,
169 glsl_vec4_type(), "a_vertex");
170 a_vertex->data.location = VERT_ATTRIB_GENERIC1;
171
172 nir_variable *v_pos = nir_variable_create(b.shader, nir_var_shader_out,
173 glsl_vec4_type(), "v_pos");
174 v_pos->data.location = VARYING_SLOT_POS;
175
176 nir_copy_var(&b, v_pos, a_vertex);
177
178 /* Then we copy everything else */
179 for (unsigned i = 0; i < blorp_key.num_inputs; i++) {
180 nir_variable *a_in = nir_variable_create(b.shader, nir_var_shader_in,
181 uvec4_type, "input");
182 a_in->data.location = VERT_ATTRIB_GENERIC2 + i;
183
184 nir_variable *v_out = nir_variable_create(b.shader, nir_var_shader_out,
185 uvec4_type, "output");
186 v_out->data.location = VARYING_SLOT_VAR0 + i;
187
188 nir_copy_var(&b, v_out, a_in);
189 }
190
191 struct brw_vs_prog_data vs_prog_data;
192 memset(&vs_prog_data, 0, sizeof(vs_prog_data));
193
194 const unsigned *program =
195 blorp_compile_vs(blorp, mem_ctx, b.shader, &vs_prog_data);
196
197 bool result =
198 blorp->upload_shader(batch, MESA_SHADER_VERTEX,
199 &blorp_key, sizeof(blorp_key),
200 program, vs_prog_data.base.base.program_size,
201 &vs_prog_data.base.base, sizeof(vs_prog_data),
202 ¶ms->vs_prog_kernel, ¶ms->vs_prog_data);
203
204 ralloc_free(mem_ctx);
205 return result;
206 }
207
208 /* The x0, y0, x1, and y1 parameters must already be populated with the render
209 * area of the framebuffer to be cleared.
210 */
211 static void
get_fast_clear_rect(const struct isl_device * dev,const struct isl_surf * aux_surf,unsigned * x0,unsigned * y0,unsigned * x1,unsigned * y1)212 get_fast_clear_rect(const struct isl_device *dev,
213 const struct isl_surf *aux_surf,
214 unsigned *x0, unsigned *y0,
215 unsigned *x1, unsigned *y1)
216 {
217 unsigned int x_align, y_align;
218 unsigned int x_scaledown, y_scaledown;
219
220 /* Only single sampled surfaces need to (and actually can) be resolved. */
221 if (aux_surf->usage == ISL_SURF_USAGE_CCS_BIT) {
222 /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
223 * Target(s)", beneath the "Fast Color Clear" bullet (p327):
224 *
225 * Clear pass must have a clear rectangle that must follow
226 * alignment rules in terms of pixels and lines as shown in the
227 * table below. Further, the clear-rectangle height and width
228 * must be multiple of the following dimensions. If the height
229 * and width of the render target being cleared do not meet these
230 * requirements, an MCS buffer can be created such that it
231 * follows the requirement and covers the RT.
232 *
233 * The alignment size in the table that follows is related to the
234 * alignment size that is baked into the CCS surface format but with X
235 * alignment multiplied by 16 and Y alignment multiplied by 32.
236 */
237 x_align = isl_format_get_layout(aux_surf->format)->bw;
238 y_align = isl_format_get_layout(aux_surf->format)->bh;
239
240 x_align *= 16;
241
242 /* The line alignment requirement for Y-tiled is halved at SKL and again
243 * at TGL.
244 */
245 if (dev->info->gen >= 12)
246 y_align *= 8;
247 else if (dev->info->gen >= 9)
248 y_align *= 16;
249 else
250 y_align *= 32;
251
252 /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
253 * Target(s)", beneath the "Fast Color Clear" bullet (p327):
254 *
255 * In order to optimize the performance MCS buffer (when bound to
256 * 1X RT) clear similarly to MCS buffer clear for MSRT case,
257 * clear rect is required to be scaled by the following factors
258 * in the horizontal and vertical directions:
259 *
260 * The X and Y scale down factors in the table that follows are each
261 * equal to half the alignment value computed above.
262 */
263 x_scaledown = x_align / 2;
264 y_scaledown = y_align / 2;
265
266 if (ISL_DEV_IS_HASWELL(dev)) {
267 /* From BSpec: 3D-Media-GPGPU Engine > 3D Pipeline > Pixel > Pixel
268 * Backend > MCS Buffer for Render Target(s) [DevIVB+] > Table "Color
269 * Clear of Non-MultiSampled Render Target Restrictions":
270 *
271 * Clear rectangle must be aligned to two times the number of
272 * pixels in the table shown below due to 16x16 hashing across the
273 * slice.
274 *
275 * This restriction is only documented to exist on HSW GT3 but
276 * empirical evidence suggests that it's also needed GT2.
277 */
278 x_align *= 2;
279 y_align *= 2;
280 }
281 } else {
282 assert(aux_surf->usage == ISL_SURF_USAGE_MCS_BIT);
283
284 /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
285 * Target(s)", beneath the "MSAA Compression" bullet (p326):
286 *
287 * Clear pass for this case requires that scaled down primitive
288 * is sent down with upper left co-ordinate to coincide with
289 * actual rectangle being cleared. For MSAA, clear rectangle’s
290 * height and width need to as show in the following table in
291 * terms of (width,height) of the RT.
292 *
293 * MSAA Width of Clear Rect Height of Clear Rect
294 * 2X Ceil(1/8*width) Ceil(1/2*height)
295 * 4X Ceil(1/8*width) Ceil(1/2*height)
296 * 8X Ceil(1/2*width) Ceil(1/2*height)
297 * 16X width Ceil(1/2*height)
298 *
299 * The text "with upper left co-ordinate to coincide with actual
300 * rectangle being cleared" is a little confusing--it seems to imply
301 * that to clear a rectangle from (x,y) to (x+w,y+h), one needs to
302 * feed the pipeline using the rectangle (x,y) to
303 * (x+Ceil(w/N),y+Ceil(h/2)), where N is either 2 or 8 depending on
304 * the number of samples. Experiments indicate that this is not
305 * quite correct; actually, what the hardware appears to do is to
306 * align whatever rectangle is sent down the pipeline to the nearest
307 * multiple of 2x2 blocks, and then scale it up by a factor of N
308 * horizontally and 2 vertically. So the resulting alignment is 4
309 * vertically and either 4 or 16 horizontally, and the scaledown
310 * factor is 2 vertically and either 2 or 8 horizontally.
311 */
312 switch (aux_surf->format) {
313 case ISL_FORMAT_MCS_2X:
314 case ISL_FORMAT_MCS_4X:
315 x_scaledown = 8;
316 break;
317 case ISL_FORMAT_MCS_8X:
318 x_scaledown = 2;
319 break;
320 case ISL_FORMAT_MCS_16X:
321 x_scaledown = 1;
322 break;
323 default:
324 unreachable("Unexpected MCS format for fast clear");
325 }
326 y_scaledown = 2;
327 x_align = x_scaledown * 2;
328 y_align = y_scaledown * 2;
329 }
330
331 *x0 = ROUND_DOWN_TO(*x0, x_align) / x_scaledown;
332 *y0 = ROUND_DOWN_TO(*y0, y_align) / y_scaledown;
333 *x1 = ALIGN(*x1, x_align) / x_scaledown;
334 *y1 = ALIGN(*y1, y_align) / y_scaledown;
335 }
336
337 void
blorp_fast_clear(struct blorp_batch * batch,const struct blorp_surf * surf,enum isl_format format,struct isl_swizzle swizzle,uint32_t level,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1)338 blorp_fast_clear(struct blorp_batch *batch,
339 const struct blorp_surf *surf,
340 enum isl_format format, struct isl_swizzle swizzle,
341 uint32_t level, uint32_t start_layer, uint32_t num_layers,
342 uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
343 {
344 struct blorp_params params;
345 blorp_params_init(¶ms);
346 params.num_layers = num_layers;
347
348 params.x0 = x0;
349 params.y0 = y0;
350 params.x1 = x1;
351 params.y1 = y1;
352
353 memset(¶ms.wm_inputs.clear_color, 0xff, 4*sizeof(float));
354 params.fast_clear_op = ISL_AUX_OP_FAST_CLEAR;
355
356 get_fast_clear_rect(batch->blorp->isl_dev, surf->aux_surf,
357 ¶ms.x0, ¶ms.y0, ¶ms.x1, ¶ms.y1);
358
359 if (!blorp_params_get_clear_kernel(batch, ¶ms, true, false))
360 return;
361
362 brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, surf, level,
363 start_layer, format, true);
364 params.num_samples = params.dst.surf.samples;
365
366 /* If a swizzle was provided, we need to swizzle the clear color so that
367 * the hardware color format conversion will work properly.
368 */
369 params.dst.clear_color =
370 isl_color_value_swizzle_inv(params.dst.clear_color, swizzle);
371
372 batch->blorp->exec(batch, ¶ms);
373 }
374
375 void
blorp_clear(struct blorp_batch * batch,const struct blorp_surf * surf,enum isl_format format,struct isl_swizzle swizzle,uint32_t level,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,union isl_color_value clear_color,const bool color_write_disable[4])376 blorp_clear(struct blorp_batch *batch,
377 const struct blorp_surf *surf,
378 enum isl_format format, struct isl_swizzle swizzle,
379 uint32_t level, uint32_t start_layer, uint32_t num_layers,
380 uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
381 union isl_color_value clear_color,
382 const bool color_write_disable[4])
383 {
384 struct blorp_params params;
385 blorp_params_init(¶ms);
386
387 /* Manually apply the clear destination swizzle. This way swizzled clears
388 * will work for swizzles which we can't normally use for rendering and it
389 * also ensures that they work on pre-Haswell hardware which can't swizlle
390 * at all.
391 */
392 clear_color = isl_color_value_swizzle_inv(clear_color, swizzle);
393 swizzle = ISL_SWIZZLE_IDENTITY;
394
395 bool clear_rgb_as_red = false;
396 if (format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) {
397 clear_color.u32[0] = float3_to_rgb9e5(clear_color.f32);
398 format = ISL_FORMAT_R32_UINT;
399 } else if (format == ISL_FORMAT_L8_UNORM_SRGB) {
400 clear_color.f32[0] = util_format_linear_to_srgb_float(clear_color.f32[0]);
401 format = ISL_FORMAT_R8_UNORM;
402 } else if (format == ISL_FORMAT_A4B4G4R4_UNORM) {
403 /* Broadwell and earlier cannot render to this format so we need to work
404 * around it by swapping the colors around and using B4G4R4A4 instead.
405 */
406 const struct isl_swizzle ARGB = ISL_SWIZZLE(ALPHA, RED, GREEN, BLUE);
407 clear_color = isl_color_value_swizzle_inv(clear_color, ARGB);
408 format = ISL_FORMAT_B4G4R4A4_UNORM;
409 } else if (isl_format_get_layout(format)->bpb % 3 == 0) {
410 clear_rgb_as_red = true;
411 if (format == ISL_FORMAT_R8G8B8_UNORM_SRGB) {
412 clear_color.f32[0] = util_format_linear_to_srgb_float(clear_color.f32[0]);
413 clear_color.f32[1] = util_format_linear_to_srgb_float(clear_color.f32[1]);
414 clear_color.f32[2] = util_format_linear_to_srgb_float(clear_color.f32[2]);
415 }
416 }
417
418 memcpy(¶ms.wm_inputs.clear_color, clear_color.f32, sizeof(float) * 4);
419
420 bool use_simd16_replicated_data = true;
421
422 /* From the SNB PRM (Vol4_Part1):
423 *
424 * "Replicated data (Message Type = 111) is only supported when
425 * accessing tiled memory. Using this Message Type to access linear
426 * (untiled) memory is UNDEFINED."
427 */
428 if (surf->surf->tiling == ISL_TILING_LINEAR)
429 use_simd16_replicated_data = false;
430
431 /* Replicated clears don't work yet before gen6 */
432 if (batch->blorp->isl_dev->info->gen < 6)
433 use_simd16_replicated_data = false;
434
435 /* Constant color writes ignore everyting in blend and color calculator
436 * state. This is not documented.
437 */
438 if (color_write_disable) {
439 for (unsigned i = 0; i < 4; i++) {
440 params.color_write_disable[i] = color_write_disable[i];
441 if (color_write_disable[i])
442 use_simd16_replicated_data = false;
443 }
444 }
445
446 if (!blorp_params_get_clear_kernel(batch, ¶ms,
447 use_simd16_replicated_data,
448 clear_rgb_as_red))
449 return;
450
451 if (!blorp_ensure_sf_program(batch, ¶ms))
452 return;
453
454 while (num_layers > 0) {
455 brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, surf, level,
456 start_layer, format, true);
457 params.dst.view.swizzle = swizzle;
458
459 params.x0 = x0;
460 params.y0 = y0;
461 params.x1 = x1;
462 params.y1 = y1;
463
464 if (params.dst.tile_x_sa || params.dst.tile_y_sa) {
465 assert(params.dst.surf.samples == 1);
466 assert(num_layers == 1);
467 params.x0 += params.dst.tile_x_sa;
468 params.y0 += params.dst.tile_y_sa;
469 params.x1 += params.dst.tile_x_sa;
470 params.y1 += params.dst.tile_y_sa;
471 }
472
473 /* The MinLOD and MinimumArrayElement don't work properly for cube maps.
474 * Convert them to a single slice on gen4.
475 */
476 if (batch->blorp->isl_dev->info->gen == 4 &&
477 (params.dst.surf.usage & ISL_SURF_USAGE_CUBE_BIT)) {
478 blorp_surf_convert_to_single_slice(batch->blorp->isl_dev, ¶ms.dst);
479 }
480
481 if (clear_rgb_as_red) {
482 surf_fake_rgb_with_red(batch->blorp->isl_dev, ¶ms.dst);
483 params.x0 *= 3;
484 params.x1 *= 3;
485 }
486
487 if (isl_format_is_compressed(params.dst.surf.format)) {
488 blorp_surf_convert_to_uncompressed(batch->blorp->isl_dev, ¶ms.dst,
489 NULL, NULL, NULL, NULL);
490 //&dst_x, &dst_y, &dst_w, &dst_h);
491 }
492
493 if (params.dst.tile_x_sa || params.dst.tile_y_sa) {
494 /* Either we're on gen4 where there is no multisampling or the
495 * surface is compressed which also implies no multisampling.
496 * Therefore, sa == px and we don't need to do a conversion.
497 */
498 assert(params.dst.surf.samples == 1);
499 params.x0 += params.dst.tile_x_sa;
500 params.y0 += params.dst.tile_y_sa;
501 params.x1 += params.dst.tile_x_sa;
502 params.y1 += params.dst.tile_y_sa;
503 }
504
505 params.num_samples = params.dst.surf.samples;
506
507 /* We may be restricted on the number of layers we can bind at any one
508 * time. In particular, Sandy Bridge has a maximum number of layers of
509 * 512 but a maximum 3D texture size is much larger.
510 */
511 params.num_layers = MIN2(params.dst.view.array_len, num_layers);
512
513 const unsigned max_image_width = 16 * 1024;
514 if (params.dst.surf.logical_level0_px.width > max_image_width) {
515 /* Clearing an RGB image as red multiplies the surface width by 3
516 * so it may now be too wide for the hardware surface limits. We
517 * have to break the clear up into pieces in order to clear wide
518 * images.
519 */
520 assert(clear_rgb_as_red);
521 assert(params.dst.surf.dim == ISL_SURF_DIM_2D);
522 assert(params.dst.surf.tiling == ISL_TILING_LINEAR);
523 assert(params.dst.surf.logical_level0_px.depth == 1);
524 assert(params.dst.surf.logical_level0_px.array_len == 1);
525 assert(params.dst.surf.levels == 1);
526 assert(params.dst.surf.samples == 1);
527 assert(params.dst.tile_x_sa == 0 || params.dst.tile_y_sa == 0);
528 assert(params.dst.aux_usage == ISL_AUX_USAGE_NONE);
529
530 /* max_image_width rounded down to a multiple of 3 */
531 const unsigned max_fake_rgb_width = (max_image_width / 3) * 3;
532 const unsigned cpp =
533 isl_format_get_layout(params.dst.surf.format)->bpb / 8;
534
535 params.dst.surf.logical_level0_px.width = max_fake_rgb_width;
536 params.dst.surf.phys_level0_sa.width = max_fake_rgb_width;
537
538 uint32_t orig_x0 = params.x0, orig_x1 = params.x1;
539 uint64_t orig_offset = params.dst.addr.offset;
540 for (uint32_t x = orig_x0; x < orig_x1; x += max_fake_rgb_width) {
541 /* Offset to the surface. It's easy because we're linear */
542 params.dst.addr.offset = orig_offset + x * cpp;
543
544 params.x0 = 0;
545 params.x1 = MIN2(orig_x1 - x, max_image_width);
546
547 batch->blorp->exec(batch, ¶ms);
548 }
549 } else {
550 batch->blorp->exec(batch, ¶ms);
551 }
552
553 start_layer += params.num_layers;
554 num_layers -= params.num_layers;
555 }
556 }
557
558 static bool
blorp_clear_stencil_as_rgba(struct blorp_batch * batch,const struct blorp_surf * surf,uint32_t level,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,uint8_t stencil_mask,uint8_t stencil_value)559 blorp_clear_stencil_as_rgba(struct blorp_batch *batch,
560 const struct blorp_surf *surf,
561 uint32_t level, uint32_t start_layer,
562 uint32_t num_layers,
563 uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
564 uint8_t stencil_mask, uint8_t stencil_value)
565 {
566 /* We only support separate W-tiled stencil for now */
567 if (surf->surf->format != ISL_FORMAT_R8_UINT ||
568 surf->surf->tiling != ISL_TILING_W)
569 return false;
570
571 /* Stencil mask support would require piles of shader magic */
572 if (stencil_mask != 0xff)
573 return false;
574
575 if (surf->surf->samples > 1) {
576 /* Adjust x0, y0, x1, and y1 to be in units of samples */
577 assert(surf->surf->msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED);
578 struct isl_extent2d msaa_px_size_sa =
579 isl_get_interleaved_msaa_px_size_sa(surf->surf->samples);
580
581 x0 *= msaa_px_size_sa.w;
582 y0 *= msaa_px_size_sa.h;
583 x1 *= msaa_px_size_sa.w;
584 y1 *= msaa_px_size_sa.h;
585 }
586
587 /* W-tiles and Y-tiles have the same layout as far as cache lines are
588 * concerned: both are 8x8 cache lines laid out Y-major. The difference is
589 * entirely in how the data is arranged withing the cache line. W-tiling
590 * is 8x8 pixels in a swizzled pattern while Y-tiling is 16B by 4 rows
591 * regardless of image format size. As long as everything is aligned to 8,
592 * we can just treat the W-tiled image as Y-tiled, ignore the layout
593 * difference within a cache line, and blast out data.
594 */
595 if (x0 % 8 != 0 || y0 % 8 != 0 || x1 % 8 != 0 || y1 % 8 != 0)
596 return false;
597
598 struct blorp_params params;
599 blorp_params_init(¶ms);
600
601 if (!blorp_params_get_clear_kernel(batch, ¶ms, true, false))
602 return false;
603
604 memset(¶ms.wm_inputs.clear_color, stencil_value,
605 sizeof(params.wm_inputs.clear_color));
606
607 /* The Sandy Bridge PRM Vol. 4 Pt. 2, section 2.11.2.1.1 has the
608 * following footnote to the format table:
609 *
610 * 128 BPE Formats cannot be Tiled Y when used as render targets
611 *
612 * We have to use RGBA16_UINT on SNB.
613 */
614 enum isl_format wide_format;
615 if (ISL_DEV_GEN(batch->blorp->isl_dev) <= 6) {
616 wide_format = ISL_FORMAT_R16G16B16A16_UINT;
617
618 /* For RGBA16_UINT, we need to mask the stencil value otherwise, we risk
619 * clamping giving us the wrong values
620 */
621 for (unsigned i = 0; i < 4; i++)
622 params.wm_inputs.clear_color[i] &= 0xffff;
623 } else {
624 wide_format = ISL_FORMAT_R32G32B32A32_UINT;
625 }
626
627 for (uint32_t a = 0; a < num_layers; a++) {
628 uint32_t layer = start_layer + a;
629
630 brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, surf, level,
631 layer, ISL_FORMAT_UNSUPPORTED, true);
632
633 if (surf->surf->samples > 1)
634 blorp_surf_fake_interleaved_msaa(batch->blorp->isl_dev, ¶ms.dst);
635
636 /* Make it Y-tiled */
637 blorp_surf_retile_w_to_y(batch->blorp->isl_dev, ¶ms.dst);
638
639 unsigned wide_Bpp =
640 isl_format_get_layout(wide_format)->bpb / 8;
641
642 params.dst.view.format = params.dst.surf.format = wide_format;
643 assert(params.dst.surf.logical_level0_px.width % wide_Bpp == 0);
644 params.dst.surf.logical_level0_px.width /= wide_Bpp;
645 assert(params.dst.tile_x_sa % wide_Bpp == 0);
646 params.dst.tile_x_sa /= wide_Bpp;
647
648 params.x0 = params.dst.tile_x_sa + x0 / (wide_Bpp / 2);
649 params.y0 = params.dst.tile_y_sa + y0 / 2;
650 params.x1 = params.dst.tile_x_sa + x1 / (wide_Bpp / 2);
651 params.y1 = params.dst.tile_y_sa + y1 / 2;
652
653 batch->blorp->exec(batch, ¶ms);
654 }
655
656 return true;
657 }
658
659 void
blorp_clear_depth_stencil(struct blorp_batch * batch,const struct blorp_surf * depth,const struct blorp_surf * stencil,uint32_t level,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,bool clear_depth,float depth_value,uint8_t stencil_mask,uint8_t stencil_value)660 blorp_clear_depth_stencil(struct blorp_batch *batch,
661 const struct blorp_surf *depth,
662 const struct blorp_surf *stencil,
663 uint32_t level, uint32_t start_layer,
664 uint32_t num_layers,
665 uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
666 bool clear_depth, float depth_value,
667 uint8_t stencil_mask, uint8_t stencil_value)
668 {
669 if (!clear_depth && blorp_clear_stencil_as_rgba(batch, stencil, level,
670 start_layer, num_layers,
671 x0, y0, x1, y1,
672 stencil_mask,
673 stencil_value))
674 return;
675
676 struct blorp_params params;
677 blorp_params_init(¶ms);
678
679 params.x0 = x0;
680 params.y0 = y0;
681 params.x1 = x1;
682 params.y1 = y1;
683
684 if (ISL_DEV_GEN(batch->blorp->isl_dev) == 6) {
685 /* For some reason, Sandy Bridge gets occlusion queries wrong if we
686 * don't have a shader. In particular, it records samples even though
687 * we disable statistics in 3DSTATE_WM. Give it the usual clear shader
688 * to work around the issue.
689 */
690 if (!blorp_params_get_clear_kernel(batch, ¶ms, false, false))
691 return;
692 }
693
694 while (num_layers > 0) {
695 params.num_layers = num_layers;
696
697 if (stencil_mask) {
698 brw_blorp_surface_info_init(batch->blorp, ¶ms.stencil, stencil,
699 level, start_layer,
700 ISL_FORMAT_UNSUPPORTED, true);
701 params.stencil_mask = stencil_mask;
702 params.stencil_ref = stencil_value;
703
704 params.dst.surf.samples = params.stencil.surf.samples;
705 params.dst.surf.logical_level0_px =
706 params.stencil.surf.logical_level0_px;
707 params.dst.view = params.stencil.view;
708
709 params.num_samples = params.stencil.surf.samples;
710
711 /* We may be restricted on the number of layers we can bind at any
712 * one time. In particular, Sandy Bridge has a maximum number of
713 * layers of 512 but a maximum 3D texture size is much larger.
714 */
715 if (params.stencil.view.array_len < params.num_layers)
716 params.num_layers = params.stencil.view.array_len;
717 }
718
719 if (clear_depth) {
720 brw_blorp_surface_info_init(batch->blorp, ¶ms.depth, depth,
721 level, start_layer,
722 ISL_FORMAT_UNSUPPORTED, true);
723 params.z = depth_value;
724 params.depth_format =
725 isl_format_get_depth_format(depth->surf->format, false);
726
727 params.dst.surf.samples = params.depth.surf.samples;
728 params.dst.surf.logical_level0_px =
729 params.depth.surf.logical_level0_px;
730 params.dst.view = params.depth.view;
731
732 params.num_samples = params.depth.surf.samples;
733
734 /* We may be restricted on the number of layers we can bind at any
735 * one time. In particular, Sandy Bridge has a maximum number of
736 * layers of 512 but a maximum 3D texture size is much larger.
737 */
738 if (params.depth.view.array_len < params.num_layers)
739 params.num_layers = params.depth.view.array_len;
740 }
741
742 batch->blorp->exec(batch, ¶ms);
743
744 start_layer += params.num_layers;
745 num_layers -= params.num_layers;
746 }
747 }
748
749 bool
blorp_can_hiz_clear_depth(const struct gen_device_info * devinfo,const struct isl_surf * surf,enum isl_aux_usage aux_usage,uint32_t level,uint32_t layer,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1)750 blorp_can_hiz_clear_depth(const struct gen_device_info *devinfo,
751 const struct isl_surf *surf,
752 enum isl_aux_usage aux_usage,
753 uint32_t level, uint32_t layer,
754 uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
755 {
756 /* This function currently doesn't support any gen prior to gen8 */
757 assert(devinfo->gen >= 8);
758
759 if (devinfo->gen == 8 && surf->format == ISL_FORMAT_R16_UNORM) {
760 /* Apply the D16 alignment restrictions. On BDW, HiZ has an 8x4 sample
761 * block with the following property: as the number of samples increases,
762 * the number of pixels representable by this block decreases by a factor
763 * of the sample dimensions. Sample dimensions scale following the MSAA
764 * interleaved pattern.
765 *
766 * Sample|Sample|Pixel
767 * Count |Dim |Dim
768 * ===================
769 * 1 | 1x1 | 8x4
770 * 2 | 2x1 | 4x4
771 * 4 | 2x2 | 4x2
772 * 8 | 4x2 | 2x2
773 * 16 | 4x4 | 2x1
774 *
775 * Table: Pixel Dimensions in a HiZ Sample Block Pre-SKL
776 */
777 const struct isl_extent2d sa_block_dim =
778 isl_get_interleaved_msaa_px_size_sa(surf->samples);
779 const uint8_t align_px_w = 8 / sa_block_dim.w;
780 const uint8_t align_px_h = 4 / sa_block_dim.h;
781
782 /* Fast depth clears clear an entire sample block at a time. As a result,
783 * the rectangle must be aligned to the dimensions of the encompassing
784 * pixel block for a successful operation.
785 *
786 * Fast clears can still work if the upper-left corner is aligned and the
787 * bottom-rigtht corner touches the edge of a depth buffer whose extent
788 * is unaligned. This is because each miplevel in the depth buffer is
789 * padded by the Pixel Dim (similar to a standard compressed texture).
790 * In this case, the clear rectangle could be padded by to match the full
791 * depth buffer extent but to support multiple clearing techniques, we
792 * chose to be unaware of the depth buffer's extent and thus don't handle
793 * this case.
794 */
795 if (x0 % align_px_w || y0 % align_px_h ||
796 x1 % align_px_w || y1 % align_px_h)
797 return false;
798 } else if (aux_usage == ISL_AUX_USAGE_HIZ_CCS_WT) {
799 /* We have to set the WM_HZ_OP::FullSurfaceDepthandStencilClear bit
800 * whenever we clear an uninitialized HIZ buffer (as some drivers
801 * currently do). However, this bit seems liable to clear 16x8 pixels in
802 * the ZCS on Gen12 - greater than the slice alignments for depth
803 * buffers.
804 */
805 assert(surf->image_alignment_el.w % 16 != 0 ||
806 surf->image_alignment_el.h % 8 != 0);
807
808 /* This is the hypothesis behind some corruption that was seen with the
809 * amd_vertex_shader_layer-layered-depth-texture-render piglit test.
810 *
811 * From the Compressed Depth Buffers section of the Bspec, under the
812 * Gen12 texture performant and ZCS columns:
813 *
814 * Update with clear at either 16x8 or 8x4 granularity, based on
815 * fs_clr or otherwise.
816 *
817 * There are a number of ways to avoid full surface CCS clears that
818 * overlap other slices, but for now we choose to disable fast-clears
819 * when an initializing clear could hit another miplevel.
820 *
821 * NOTE: Because the CCS compresses the depth buffer and not a version
822 * of it that has been rearranged with different alignments (like Gen8+
823 * HIZ), we have to make sure that the x0 and y0 are at least 16x8
824 * aligned in the context of the entire surface.
825 */
826 uint32_t slice_x0, slice_y0;
827 isl_surf_get_image_offset_el(surf, level,
828 surf->dim == ISL_SURF_DIM_3D ? 0 : layer,
829 surf->dim == ISL_SURF_DIM_3D ? layer: 0,
830 &slice_x0, &slice_y0);
831 const bool max_x1_y1 =
832 x1 == minify(surf->logical_level0_px.width, level) &&
833 y1 == minify(surf->logical_level0_px.height, level);
834 const uint32_t haligned_x1 = ALIGN(x1, surf->image_alignment_el.w);
835 const uint32_t valigned_y1 = ALIGN(y1, surf->image_alignment_el.h);
836 const bool unaligned = (slice_x0 + x0) % 16 || (slice_y0 + y0) % 8 ||
837 (max_x1_y1 ? haligned_x1 % 16 || valigned_y1 % 8 :
838 x1 % 16 || y1 % 8);
839 const bool partial_clear = x0 > 0 || y0 > 0 || !max_x1_y1;
840 const bool multislice_surf = surf->levels > 1 ||
841 surf->logical_level0_px.depth > 1 ||
842 surf->logical_level0_px.array_len > 1;
843
844 if (unaligned && (partial_clear || multislice_surf))
845 return false;
846 }
847
848 return isl_aux_usage_has_hiz(aux_usage);
849 }
850
851 static bool
blorp_can_clear_full_surface(const struct blorp_surf * depth,const struct blorp_surf * stencil,uint32_t level,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,bool clear_depth,bool clear_stencil)852 blorp_can_clear_full_surface(const struct blorp_surf *depth,
853 const struct blorp_surf *stencil,
854 uint32_t level,
855 uint32_t x0, uint32_t y0,
856 uint32_t x1, uint32_t y1,
857 bool clear_depth,
858 bool clear_stencil)
859 {
860 uint32_t width = 0, height = 0;
861 if (clear_stencil) {
862 width = minify(stencil->surf->logical_level0_px.width, level);
863 height = minify(stencil->surf->logical_level0_px.height, level);
864 }
865
866 if (clear_depth && !(width || height)) {
867 width = minify(depth->surf->logical_level0_px.width, level);
868 height = minify(depth->surf->logical_level0_px.height, level);
869 }
870
871 return x0 == 0 && y0 == 0 && width == x1 && height == y1;
872 }
873
874 void
blorp_hiz_clear_depth_stencil(struct blorp_batch * batch,const struct blorp_surf * depth,const struct blorp_surf * stencil,uint32_t level,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,bool clear_depth,float depth_value,bool clear_stencil,uint8_t stencil_value)875 blorp_hiz_clear_depth_stencil(struct blorp_batch *batch,
876 const struct blorp_surf *depth,
877 const struct blorp_surf *stencil,
878 uint32_t level,
879 uint32_t start_layer, uint32_t num_layers,
880 uint32_t x0, uint32_t y0,
881 uint32_t x1, uint32_t y1,
882 bool clear_depth, float depth_value,
883 bool clear_stencil, uint8_t stencil_value)
884 {
885 struct blorp_params params;
886 blorp_params_init(¶ms);
887
888 /* This requires WM_HZ_OP which only exists on gen8+ */
889 assert(ISL_DEV_GEN(batch->blorp->isl_dev) >= 8);
890
891 params.hiz_op = ISL_AUX_OP_FAST_CLEAR;
892 /* From BSpec: 3DSTATE_WM_HZ_OP_BODY >> Full Surface Depth and Stencil Clear
893 *
894 * "Software must set this only when the APP requires the entire Depth
895 * surface to be cleared."
896 */
897 params.full_surface_hiz_op =
898 blorp_can_clear_full_surface(depth, stencil, level, x0, y0, x1, y1,
899 clear_depth, clear_stencil);
900 params.num_layers = 1;
901
902 params.x0 = x0;
903 params.y0 = y0;
904 params.x1 = x1;
905 params.y1 = y1;
906
907 for (uint32_t l = 0; l < num_layers; l++) {
908 const uint32_t layer = start_layer + l;
909 if (clear_stencil) {
910 brw_blorp_surface_info_init(batch->blorp, ¶ms.stencil, stencil,
911 level, layer,
912 ISL_FORMAT_UNSUPPORTED, true);
913 params.stencil_mask = 0xff;
914 params.stencil_ref = stencil_value;
915 params.num_samples = params.stencil.surf.samples;
916 }
917
918 if (clear_depth) {
919 /* If we're clearing depth, we must have HiZ */
920 assert(depth && isl_aux_usage_has_hiz(depth->aux_usage));
921
922 brw_blorp_surface_info_init(batch->blorp, ¶ms.depth, depth,
923 level, layer,
924 ISL_FORMAT_UNSUPPORTED, true);
925 params.depth.clear_color.f32[0] = depth_value;
926 params.depth_format =
927 isl_format_get_depth_format(depth->surf->format, false);
928 params.num_samples = params.depth.surf.samples;
929 }
930
931 batch->blorp->exec(batch, ¶ms);
932 }
933 }
934
935 /* Given a depth stencil attachment, this function performs a fast depth clear
936 * on a depth portion and a regular clear on the stencil portion. When
937 * performing a fast depth clear on the depth portion, the HiZ buffer is simply
938 * tagged as cleared so the depth clear value is not actually needed.
939 */
940 void
blorp_gen8_hiz_clear_attachments(struct blorp_batch * batch,uint32_t num_samples,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,bool clear_depth,bool clear_stencil,uint8_t stencil_value)941 blorp_gen8_hiz_clear_attachments(struct blorp_batch *batch,
942 uint32_t num_samples,
943 uint32_t x0, uint32_t y0,
944 uint32_t x1, uint32_t y1,
945 bool clear_depth, bool clear_stencil,
946 uint8_t stencil_value)
947 {
948 assert(batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
949
950 struct blorp_params params;
951 blorp_params_init(¶ms);
952 params.num_layers = 1;
953 params.hiz_op = ISL_AUX_OP_FAST_CLEAR;
954 params.x0 = x0;
955 params.y0 = y0;
956 params.x1 = x1;
957 params.y1 = y1;
958 params.num_samples = num_samples;
959 params.depth.enabled = clear_depth;
960 params.stencil.enabled = clear_stencil;
961 params.stencil_ref = stencil_value;
962 batch->blorp->exec(batch, ¶ms);
963 }
964
965 /** Clear active color/depth/stencili attachments
966 *
967 * This function performs a clear operation on the currently bound
968 * color/depth/stencil attachments. It is assumed that any information passed
969 * in here is valid, consistent, and in-bounds relative to the currently
970 * attached depth/stencil. The binding_table_offset parameter is the 32-bit
971 * offset relative to surface state base address where pre-baked binding table
972 * that we are to use lives. If clear_color is false, binding_table_offset
973 * must point to a binding table with one entry which is a valid null surface
974 * that matches the currently bound depth and stencil.
975 */
976 void
blorp_clear_attachments(struct blorp_batch * batch,uint32_t binding_table_offset,enum isl_format depth_format,uint32_t num_samples,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,bool clear_color,union isl_color_value color_value,bool clear_depth,float depth_value,uint8_t stencil_mask,uint8_t stencil_value)977 blorp_clear_attachments(struct blorp_batch *batch,
978 uint32_t binding_table_offset,
979 enum isl_format depth_format,
980 uint32_t num_samples,
981 uint32_t start_layer, uint32_t num_layers,
982 uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
983 bool clear_color, union isl_color_value color_value,
984 bool clear_depth, float depth_value,
985 uint8_t stencil_mask, uint8_t stencil_value)
986 {
987 struct blorp_params params;
988 blorp_params_init(¶ms);
989
990 assert(batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
991
992 params.x0 = x0;
993 params.y0 = y0;
994 params.x1 = x1;
995 params.y1 = y1;
996
997 params.use_pre_baked_binding_table = true;
998 params.pre_baked_binding_table_offset = binding_table_offset;
999
1000 params.num_layers = num_layers;
1001 params.num_samples = num_samples;
1002
1003 if (clear_color) {
1004 params.dst.enabled = true;
1005
1006 memcpy(¶ms.wm_inputs.clear_color, color_value.f32, sizeof(float) * 4);
1007
1008 /* Unfortunately, without knowing whether or not our destination surface
1009 * is tiled or not, we have to assume it may be linear. This means no
1010 * SIMD16_REPDATA for us. :-(
1011 */
1012 if (!blorp_params_get_clear_kernel(batch, ¶ms, false, false))
1013 return;
1014 }
1015
1016 if (clear_depth) {
1017 params.depth.enabled = true;
1018
1019 params.z = depth_value;
1020 params.depth_format = isl_format_get_depth_format(depth_format, false);
1021 }
1022
1023 if (stencil_mask) {
1024 params.stencil.enabled = true;
1025
1026 params.stencil_mask = stencil_mask;
1027 params.stencil_ref = stencil_value;
1028 }
1029
1030 if (!blorp_params_get_layer_offset_vs(batch, ¶ms))
1031 return;
1032
1033 params.vs_inputs.base_layer = start_layer;
1034
1035 batch->blorp->exec(batch, ¶ms);
1036 }
1037
1038 void
blorp_ccs_resolve(struct blorp_batch * batch,struct blorp_surf * surf,uint32_t level,uint32_t start_layer,uint32_t num_layers,enum isl_format format,enum isl_aux_op resolve_op)1039 blorp_ccs_resolve(struct blorp_batch *batch,
1040 struct blorp_surf *surf, uint32_t level,
1041 uint32_t start_layer, uint32_t num_layers,
1042 enum isl_format format,
1043 enum isl_aux_op resolve_op)
1044 {
1045 struct blorp_params params;
1046
1047 blorp_params_init(¶ms);
1048 brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, surf,
1049 level, start_layer, format, true);
1050
1051 /* From the Ivy Bridge PRM, Vol2 Part1 11.9 "Render Target Resolve":
1052 *
1053 * A rectangle primitive must be scaled down by the following factors
1054 * with respect to render target being resolved.
1055 *
1056 * The scaledown factors in the table that follows are related to the block
1057 * size of the CCS format. For IVB and HSW, we divide by two, for BDW we
1058 * multiply by 8 and 16. On Sky Lake, we multiply by 8.
1059 */
1060 const struct isl_format_layout *aux_fmtl =
1061 isl_format_get_layout(params.dst.aux_surf.format);
1062 assert(aux_fmtl->txc == ISL_TXC_CCS);
1063
1064 unsigned x_scaledown, y_scaledown;
1065 if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 12) {
1066 x_scaledown = aux_fmtl->bw * 8;
1067 y_scaledown = aux_fmtl->bh * 4;
1068 } else if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 9) {
1069 x_scaledown = aux_fmtl->bw * 8;
1070 y_scaledown = aux_fmtl->bh * 8;
1071 } else if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 8) {
1072 x_scaledown = aux_fmtl->bw * 8;
1073 y_scaledown = aux_fmtl->bh * 16;
1074 } else {
1075 x_scaledown = aux_fmtl->bw / 2;
1076 y_scaledown = aux_fmtl->bh / 2;
1077 }
1078 params.x0 = params.y0 = 0;
1079 params.x1 = minify(params.dst.surf.logical_level0_px.width, level);
1080 params.y1 = minify(params.dst.surf.logical_level0_px.height, level);
1081 params.x1 = ALIGN(params.x1, x_scaledown) / x_scaledown;
1082 params.y1 = ALIGN(params.y1, y_scaledown) / y_scaledown;
1083
1084 if (batch->blorp->isl_dev->info->gen >= 10) {
1085 assert(resolve_op == ISL_AUX_OP_FULL_RESOLVE ||
1086 resolve_op == ISL_AUX_OP_PARTIAL_RESOLVE ||
1087 resolve_op == ISL_AUX_OP_AMBIGUATE);
1088 } else if (batch->blorp->isl_dev->info->gen >= 9) {
1089 assert(resolve_op == ISL_AUX_OP_FULL_RESOLVE ||
1090 resolve_op == ISL_AUX_OP_PARTIAL_RESOLVE);
1091 } else {
1092 /* Broadwell and earlier do not have a partial resolve */
1093 assert(resolve_op == ISL_AUX_OP_FULL_RESOLVE);
1094 }
1095 params.fast_clear_op = resolve_op;
1096 params.num_layers = num_layers;
1097
1098 /* Note: there is no need to initialize push constants because it doesn't
1099 * matter what data gets dispatched to the render target. However, we must
1100 * ensure that the fragment shader delivers the data using the "replicated
1101 * color" message.
1102 */
1103
1104 if (!blorp_params_get_clear_kernel(batch, ¶ms, true, false))
1105 return;
1106
1107 batch->blorp->exec(batch, ¶ms);
1108 }
1109
1110 static nir_ssa_def *
blorp_nir_bit(nir_builder * b,nir_ssa_def * src,unsigned bit)1111 blorp_nir_bit(nir_builder *b, nir_ssa_def *src, unsigned bit)
1112 {
1113 return nir_iand(b, nir_ushr(b, src, nir_imm_int(b, bit)),
1114 nir_imm_int(b, 1));
1115 }
1116
1117 #pragma pack(push, 1)
1118 struct blorp_mcs_partial_resolve_key
1119 {
1120 enum blorp_shader_type shader_type;
1121 bool indirect_clear_color;
1122 bool int_format;
1123 uint32_t num_samples;
1124 };
1125 #pragma pack(pop)
1126
1127 static bool
blorp_params_get_mcs_partial_resolve_kernel(struct blorp_batch * batch,struct blorp_params * params)1128 blorp_params_get_mcs_partial_resolve_kernel(struct blorp_batch *batch,
1129 struct blorp_params *params)
1130 {
1131 struct blorp_context *blorp = batch->blorp;
1132 const struct blorp_mcs_partial_resolve_key blorp_key = {
1133 .shader_type = BLORP_SHADER_TYPE_MCS_PARTIAL_RESOLVE,
1134 .indirect_clear_color = params->dst.clear_color_addr.buffer != NULL,
1135 .int_format = isl_format_has_int_channel(params->dst.view.format),
1136 .num_samples = params->num_samples,
1137 };
1138
1139 if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
1140 ¶ms->wm_prog_kernel, ¶ms->wm_prog_data))
1141 return true;
1142
1143 void *mem_ctx = ralloc_context(NULL);
1144
1145 nir_builder b;
1146 blorp_nir_init_shader(&b, mem_ctx, MESA_SHADER_FRAGMENT,
1147 blorp_shader_type_to_name(blorp_key.shader_type));
1148
1149 nir_variable *v_color =
1150 BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type());
1151
1152 nir_variable *frag_color =
1153 nir_variable_create(b.shader, nir_var_shader_out,
1154 glsl_vec4_type(), "gl_FragColor");
1155 frag_color->data.location = FRAG_RESULT_COLOR;
1156
1157 /* Do an MCS fetch and check if it is equal to the magic clear value */
1158 nir_ssa_def *mcs =
1159 blorp_nir_txf_ms_mcs(&b, nir_f2i32(&b, nir_load_frag_coord(&b)),
1160 nir_load_layer_id(&b));
1161 nir_ssa_def *is_clear =
1162 blorp_nir_mcs_is_clear_color(&b, mcs, blorp_key.num_samples);
1163
1164 /* If we aren't the clear value, discard. */
1165 nir_intrinsic_instr *discard =
1166 nir_intrinsic_instr_create(b.shader, nir_intrinsic_discard_if);
1167 discard->src[0] = nir_src_for_ssa(nir_inot(&b, is_clear));
1168 nir_builder_instr_insert(&b, &discard->instr);
1169
1170 nir_ssa_def *clear_color = nir_load_var(&b, v_color);
1171 if (blorp_key.indirect_clear_color && blorp->isl_dev->info->gen <= 8) {
1172 /* Gen7-8 clear colors are stored as single 0/1 bits */
1173 clear_color = nir_vec4(&b, blorp_nir_bit(&b, clear_color, 31),
1174 blorp_nir_bit(&b, clear_color, 30),
1175 blorp_nir_bit(&b, clear_color, 29),
1176 blorp_nir_bit(&b, clear_color, 28));
1177
1178 if (!blorp_key.int_format)
1179 clear_color = nir_i2f32(&b, clear_color);
1180 }
1181 nir_store_var(&b, frag_color, clear_color, 0xf);
1182
1183 struct brw_wm_prog_key wm_key;
1184 brw_blorp_init_wm_prog_key(&wm_key);
1185 wm_key.base.tex.compressed_multisample_layout_mask = 1;
1186 wm_key.base.tex.msaa_16 = blorp_key.num_samples == 16;
1187 wm_key.multisample_fbo = true;
1188
1189 struct brw_wm_prog_data prog_data;
1190 const unsigned *program =
1191 blorp_compile_fs(blorp, mem_ctx, b.shader, &wm_key, false,
1192 &prog_data);
1193
1194 bool result =
1195 blorp->upload_shader(batch, MESA_SHADER_FRAGMENT,
1196 &blorp_key, sizeof(blorp_key),
1197 program, prog_data.base.program_size,
1198 &prog_data.base, sizeof(prog_data),
1199 ¶ms->wm_prog_kernel, ¶ms->wm_prog_data);
1200
1201 ralloc_free(mem_ctx);
1202 return result;
1203 }
1204
1205 void
blorp_mcs_partial_resolve(struct blorp_batch * batch,struct blorp_surf * surf,enum isl_format format,uint32_t start_layer,uint32_t num_layers)1206 blorp_mcs_partial_resolve(struct blorp_batch *batch,
1207 struct blorp_surf *surf,
1208 enum isl_format format,
1209 uint32_t start_layer, uint32_t num_layers)
1210 {
1211 struct blorp_params params;
1212 blorp_params_init(¶ms);
1213
1214 assert(batch->blorp->isl_dev->info->gen >= 7);
1215
1216 params.x0 = 0;
1217 params.y0 = 0;
1218 params.x1 = surf->surf->logical_level0_px.width;
1219 params.y1 = surf->surf->logical_level0_px.height;
1220
1221 brw_blorp_surface_info_init(batch->blorp, ¶ms.src, surf, 0,
1222 start_layer, format, false);
1223 brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, surf, 0,
1224 start_layer, format, true);
1225
1226 params.num_samples = params.dst.surf.samples;
1227 params.num_layers = num_layers;
1228 params.dst_clear_color_as_input = surf->clear_color_addr.buffer != NULL;
1229
1230 memcpy(¶ms.wm_inputs.clear_color,
1231 surf->clear_color.f32, sizeof(float) * 4);
1232
1233 if (!blorp_params_get_mcs_partial_resolve_kernel(batch, ¶ms))
1234 return;
1235
1236 batch->blorp->exec(batch, ¶ms);
1237 }
1238
1239 /** Clear a CCS to the "uncompressed" state
1240 *
1241 * This pass is the CCS equivalent of a "HiZ resolve". It sets the CCS values
1242 * for a given layer/level of a surface to 0x0 which is the "uncompressed"
1243 * state which tells the sampler to go look at the main surface.
1244 */
1245 void
blorp_ccs_ambiguate(struct blorp_batch * batch,struct blorp_surf * surf,uint32_t level,uint32_t layer)1246 blorp_ccs_ambiguate(struct blorp_batch *batch,
1247 struct blorp_surf *surf,
1248 uint32_t level, uint32_t layer)
1249 {
1250 if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 10) {
1251 /* On gen10 and above, we have a hardware resolve op for this */
1252 return blorp_ccs_resolve(batch, surf, level, layer, 1,
1253 surf->surf->format, ISL_AUX_OP_AMBIGUATE);
1254 }
1255
1256 struct blorp_params params;
1257 blorp_params_init(¶ms);
1258
1259 assert(ISL_DEV_GEN(batch->blorp->isl_dev) >= 7);
1260
1261 const struct isl_format_layout *aux_fmtl =
1262 isl_format_get_layout(surf->aux_surf->format);
1263 assert(aux_fmtl->txc == ISL_TXC_CCS);
1264
1265 params.dst = (struct brw_blorp_surface_info) {
1266 .enabled = true,
1267 .addr = surf->aux_addr,
1268 .view = {
1269 .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT,
1270 .format = ISL_FORMAT_R32G32B32A32_UINT,
1271 .base_level = 0,
1272 .base_array_layer = 0,
1273 .levels = 1,
1274 .array_len = 1,
1275 .swizzle = ISL_SWIZZLE_IDENTITY,
1276 },
1277 };
1278
1279 uint32_t z = 0;
1280 if (surf->surf->dim == ISL_SURF_DIM_3D) {
1281 z = layer;
1282 layer = 0;
1283 }
1284
1285 uint32_t offset_B, x_offset_el, y_offset_el;
1286 isl_surf_get_image_offset_el(surf->aux_surf, level, layer, z,
1287 &x_offset_el, &y_offset_el);
1288 isl_tiling_get_intratile_offset_el(surf->aux_surf->tiling, aux_fmtl->bpb,
1289 surf->aux_surf->row_pitch_B,
1290 x_offset_el, y_offset_el,
1291 &offset_B, &x_offset_el, &y_offset_el);
1292 params.dst.addr.offset += offset_B;
1293
1294 const uint32_t width_px =
1295 minify(surf->aux_surf->logical_level0_px.width, level);
1296 const uint32_t height_px =
1297 minify(surf->aux_surf->logical_level0_px.height, level);
1298 const uint32_t width_el = DIV_ROUND_UP(width_px, aux_fmtl->bw);
1299 const uint32_t height_el = DIV_ROUND_UP(height_px, aux_fmtl->bh);
1300
1301 struct isl_tile_info ccs_tile_info;
1302 isl_surf_get_tile_info(surf->aux_surf, &ccs_tile_info);
1303
1304 /* We're going to map it as a regular RGBA32_UINT surface. We need to
1305 * downscale a good deal. We start by computing the area on the CCS to
1306 * clear in units of Y-tiled cache lines.
1307 */
1308 uint32_t x_offset_cl, y_offset_cl, width_cl, height_cl;
1309 if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 8) {
1310 /* From the Sky Lake PRM Vol. 12 in the section on planes:
1311 *
1312 * "The Color Control Surface (CCS) contains the compression status
1313 * of the cache-line pairs. The compression state of the cache-line
1314 * pair is specified by 2 bits in the CCS. Each CCS cache-line
1315 * represents an area on the main surface of 16x16 sets of 128 byte
1316 * Y-tiled cache-line-pairs. CCS is always Y tiled."
1317 *
1318 * Each 2-bit surface element in the CCS corresponds to a single
1319 * cache-line pair in the main surface. This means that 16x16 el block
1320 * in the CCS maps to a Y-tiled cache line. Fortunately, CCS layouts
1321 * are calculated with a very large alignment so we can round up to a
1322 * whole cache line without worrying about overdraw.
1323 */
1324
1325 /* On Broadwell and above, a CCS tile is the same as a Y tile when
1326 * viewed at the cache-line granularity. Fortunately, the horizontal
1327 * and vertical alignment requirements of the CCS are such that we can
1328 * align to an entire cache line without worrying about crossing over
1329 * from one LOD to another.
1330 */
1331 const uint32_t x_el_per_cl = ccs_tile_info.logical_extent_el.w / 8;
1332 const uint32_t y_el_per_cl = ccs_tile_info.logical_extent_el.h / 8;
1333 assert(surf->aux_surf->image_alignment_el.w % x_el_per_cl == 0);
1334 assert(surf->aux_surf->image_alignment_el.h % y_el_per_cl == 0);
1335
1336 assert(x_offset_el % x_el_per_cl == 0);
1337 assert(y_offset_el % y_el_per_cl == 0);
1338 x_offset_cl = x_offset_el / x_el_per_cl;
1339 y_offset_cl = y_offset_el / y_el_per_cl;
1340 width_cl = DIV_ROUND_UP(width_el, x_el_per_cl);
1341 height_cl = DIV_ROUND_UP(height_el, y_el_per_cl);
1342 } else {
1343 /* On gen7, the CCS tiling is not so nice. However, there we are
1344 * guaranteed that we only have a single level and slice so we don't
1345 * have to worry about it and can just align to a whole tile.
1346 */
1347 assert(surf->aux_surf->logical_level0_px.depth == 1);
1348 assert(surf->aux_surf->logical_level0_px.array_len == 1);
1349 assert(x_offset_el == 0 && y_offset_el == 0);
1350 const uint32_t width_tl =
1351 DIV_ROUND_UP(width_el, ccs_tile_info.logical_extent_el.w);
1352 const uint32_t height_tl =
1353 DIV_ROUND_UP(height_el, ccs_tile_info.logical_extent_el.h);
1354 x_offset_cl = 0;
1355 y_offset_cl = 0;
1356 width_cl = width_tl * 8;
1357 height_cl = height_tl * 8;
1358 }
1359
1360 /* We're going to use a RGBA32 format so as to write data as quickly as
1361 * possible. A y-tiled cache line will then be 1x4 px.
1362 */
1363 const uint32_t x_offset_rgba_px = x_offset_cl;
1364 const uint32_t y_offset_rgba_px = y_offset_cl * 4;
1365 const uint32_t width_rgba_px = width_cl;
1366 const uint32_t height_rgba_px = height_cl * 4;
1367
1368 ASSERTED bool ok =
1369 isl_surf_init(batch->blorp->isl_dev, ¶ms.dst.surf,
1370 .dim = ISL_SURF_DIM_2D,
1371 .format = ISL_FORMAT_R32G32B32A32_UINT,
1372 .width = width_rgba_px + x_offset_rgba_px,
1373 .height = height_rgba_px + y_offset_rgba_px,
1374 .depth = 1,
1375 .levels = 1,
1376 .array_len = 1,
1377 .samples = 1,
1378 .row_pitch_B = surf->aux_surf->row_pitch_B,
1379 .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT,
1380 .tiling_flags = ISL_TILING_Y0_BIT);
1381 assert(ok);
1382
1383 params.x0 = x_offset_rgba_px;
1384 params.y0 = y_offset_rgba_px;
1385 params.x1 = x_offset_rgba_px + width_rgba_px;
1386 params.y1 = y_offset_rgba_px + height_rgba_px;
1387
1388 /* A CCS value of 0 means "uncompressed." */
1389 memset(¶ms.wm_inputs.clear_color, 0,
1390 sizeof(params.wm_inputs.clear_color));
1391
1392 if (!blorp_params_get_clear_kernel(batch, ¶ms, true, false))
1393 return;
1394
1395 batch->blorp->exec(batch, ¶ms);
1396 }
1397