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 "util/macros.h" /* Needed for MAX3 and MAX2 for format_rgb9e5 */
27 #include "util/format_rgb9e5.h"
28 #include "util/format_srgb.h"
29 #include "util/u_math.h"
30
31 #include "blorp_priv.h"
32 #include "dev/intel_debug.h"
33 #include "dev/intel_device_info.h"
34
35 #include "blorp_nir_builder.h"
36
37 #define FILE_DEBUG_FLAG DEBUG_BLORP
38
39 #pragma pack(push, 1)
40 struct blorp_const_color_prog_key
41 {
42 struct blorp_base_key base;
43 bool is_fast_clear;
44 bool use_simd16_replicated_data;
45 bool clear_rgb_as_red;
46 uint8_t local_y;
47 };
48 #pragma pack(pop)
49
50 static bool
blorp_params_get_clear_kernel_fs(struct blorp_batch * batch,struct blorp_params * params,bool is_fast_clear,bool want_replicated_data,bool clear_rgb_as_red)51 blorp_params_get_clear_kernel_fs(struct blorp_batch *batch,
52 struct blorp_params *params,
53 bool is_fast_clear,
54 bool want_replicated_data,
55 bool clear_rgb_as_red)
56 {
57 const bool use_replicated_data = want_replicated_data &&
58 batch->blorp->isl_dev->info->ver < 20;
59 struct blorp_context *blorp = batch->blorp;
60
61 const struct blorp_const_color_prog_key blorp_key = {
62 .base = BLORP_BASE_KEY_INIT(BLORP_SHADER_TYPE_CLEAR),
63 .base.shader_pipeline = BLORP_SHADER_PIPELINE_RENDER,
64 .is_fast_clear = is_fast_clear,
65 .use_simd16_replicated_data = use_replicated_data,
66 .clear_rgb_as_red = clear_rgb_as_red,
67 .local_y = 0,
68 };
69
70 params->shader_type = blorp_key.base.shader_type;
71 params->shader_pipeline = blorp_key.base.shader_pipeline;
72
73 if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
74 ¶ms->wm_prog_kernel, ¶ms->wm_prog_data))
75 return true;
76
77 void *mem_ctx = ralloc_context(NULL);
78
79 nir_builder b;
80 blorp_nir_init_shader(&b, blorp, mem_ctx, MESA_SHADER_FRAGMENT,
81 blorp_shader_type_to_name(blorp_key.base.shader_type));
82
83 nir_variable *v_color =
84 BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type());
85 nir_def *color = nir_load_var(&b, v_color);
86
87 if (clear_rgb_as_red) {
88 nir_def *pos = nir_f2i32(&b, nir_load_frag_coord(&b));
89 nir_def *comp = nir_umod_imm(&b, nir_channel(&b, pos, 0), 3);
90 color = nir_pad_vec4(&b, nir_vector_extract(&b, color, comp));
91 }
92
93 nir_variable *frag_color = nir_variable_create(b.shader, nir_var_shader_out,
94 glsl_vec4_type(),
95 "gl_FragColor");
96 frag_color->data.location = FRAG_RESULT_COLOR;
97 nir_store_var(&b, frag_color, color, 0xf);
98
99 const bool multisample_fbo = false;
100 struct blorp_program p =
101 blorp_compile_fs(blorp, mem_ctx, b.shader, multisample_fbo,
102 is_fast_clear, use_replicated_data);
103
104 bool result =
105 blorp->upload_shader(batch, MESA_SHADER_FRAGMENT,
106 &blorp_key, sizeof(blorp_key),
107 p.kernel, p.kernel_size,
108 p.prog_data, p.prog_data_size,
109 ¶ms->wm_prog_kernel, ¶ms->wm_prog_data);
110
111 ralloc_free(mem_ctx);
112 return result;
113 }
114
115 static bool
blorp_params_get_clear_kernel_cs(struct blorp_batch * batch,struct blorp_params * params,bool clear_rgb_as_red)116 blorp_params_get_clear_kernel_cs(struct blorp_batch *batch,
117 struct blorp_params *params,
118 bool clear_rgb_as_red)
119 {
120 struct blorp_context *blorp = batch->blorp;
121
122 const struct blorp_const_color_prog_key blorp_key = {
123 .base = BLORP_BASE_KEY_INIT(BLORP_SHADER_TYPE_CLEAR),
124 .base.shader_pipeline = BLORP_SHADER_PIPELINE_COMPUTE,
125 .use_simd16_replicated_data = false,
126 .clear_rgb_as_red = clear_rgb_as_red,
127 .local_y = blorp_get_cs_local_y(params),
128 };
129
130 params->shader_type = blorp_key.base.shader_type;
131 params->shader_pipeline = blorp_key.base.shader_pipeline;
132
133 if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
134 ¶ms->cs_prog_kernel, ¶ms->cs_prog_data))
135 return true;
136
137 void *mem_ctx = ralloc_context(NULL);
138
139 nir_builder b;
140 blorp_nir_init_shader(&b, blorp, mem_ctx, MESA_SHADER_COMPUTE,
141 "BLORP-gpgpu-clear");
142 blorp_set_cs_dims(b.shader, blorp_key.local_y);
143
144 nir_def *dst_pos = nir_load_global_invocation_id(&b, 32);
145
146 nir_variable *v_color =
147 BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type());
148 nir_def *color = nir_load_var(&b, v_color);
149
150 nir_variable *v_bounds_rect =
151 BLORP_CREATE_NIR_INPUT(b.shader, bounds_rect, glsl_vec4_type());
152 nir_def *bounds_rect = nir_load_var(&b, v_bounds_rect);
153 nir_def *in_bounds = blorp_check_in_bounds(&b, bounds_rect, dst_pos);
154
155 if (clear_rgb_as_red) {
156 nir_def *comp = nir_umod_imm(&b, nir_channel(&b, dst_pos, 0), 3);
157 color = nir_pad_vec4(&b, nir_vector_extract(&b, color, comp));
158 }
159
160 nir_push_if(&b, in_bounds);
161
162 nir_image_store(&b, nir_imm_int(&b, 0),
163 nir_pad_vector_imm_int(&b, dst_pos, 0, 4),
164 nir_imm_int(&b, 0),
165 nir_pad_vector_imm_int(&b, color, 0, 4),
166 nir_imm_int(&b, 0),
167 .image_dim = GLSL_SAMPLER_DIM_2D,
168 .image_array = true,
169 .access = ACCESS_NON_READABLE);
170
171 nir_pop_if(&b, NULL);
172
173 const struct blorp_program p =
174 blorp_compile_cs(blorp, mem_ctx, b.shader);
175
176 bool result =
177 blorp->upload_shader(batch, MESA_SHADER_COMPUTE,
178 &blorp_key, sizeof(blorp_key),
179 p.kernel, p.kernel_size,
180 p.prog_data, p.prog_data_size,
181 ¶ms->cs_prog_kernel, ¶ms->cs_prog_data);
182
183 ralloc_free(mem_ctx);
184 return result;
185 }
186
187 static bool
blorp_params_get_clear_kernel(struct blorp_batch * batch,struct blorp_params * params,bool is_fast_clear,bool use_replicated_data,bool clear_rgb_as_red)188 blorp_params_get_clear_kernel(struct blorp_batch *batch,
189 struct blorp_params *params,
190 bool is_fast_clear,
191 bool use_replicated_data,
192 bool clear_rgb_as_red)
193 {
194 if (batch->flags & BLORP_BATCH_USE_COMPUTE) {
195 assert(!use_replicated_data);
196 return blorp_params_get_clear_kernel_cs(batch, params, clear_rgb_as_red);
197 } else {
198 return blorp_params_get_clear_kernel_fs(batch, params, is_fast_clear,
199 use_replicated_data,
200 clear_rgb_as_red);
201 }
202 }
203
204 /* The x0, y0, x1, and y1 parameters must already be populated with the render
205 * area of the framebuffer to be cleared.
206 */
207 static void
get_fast_clear_rect(const struct isl_device * dev,const struct isl_surf * surf,const struct isl_surf * aux_surf,unsigned * x0,unsigned * y0,unsigned * x1,unsigned * y1)208 get_fast_clear_rect(const struct isl_device *dev,
209 const struct isl_surf *surf,
210 const struct isl_surf *aux_surf,
211 unsigned *x0, unsigned *y0,
212 unsigned *x1, unsigned *y1)
213 {
214 unsigned int x_align, y_align;
215 unsigned int x_scaledown, y_scaledown;
216
217 /* Only single sampled surfaces need to (and actually can) be resolved. */
218 if (surf->samples == 1) {
219 const uint32_t bs = isl_format_get_layout(surf->format)->bpb / 8;
220 if (dev->info->ver >= 20) {
221 /* From Bspec 57340, "MCS/CCS Buffers, Fast Clear for Render Target(s)":
222 *
223 * Table "Tile4/Tile64 2D/2D Array/Cube Surface"
224 * Table "Tile64 3D/Volumetric"
225 *
226 * The below calculation is derived from these tables.
227 */
228 assert(surf->tiling == ISL_TILING_4 ||
229 surf->tiling == ISL_TILING_64_XE2);
230 x_align = x_scaledown = 64 / bs;
231 y_align = y_scaledown = 4;
232 } else if (dev->info->verx10 >= 125) {
233 /* From Bspec 47709, "MCS/CCS Buffer for Render Target(s)":
234 *
235 * SW must ensure that clearing rectangle dimensions cover the
236 * entire area desired, to accomplish this task initial X/Y
237 * dimensions need to be rounded up to next multiple of scaledown
238 * factor before dividing by scale down factor:
239 *
240 * The X and Y scale down factors in the table that follows are used
241 * for both alignment and scaling down.
242 */
243 if (surf->tiling == ISL_TILING_4) {
244 x_align = x_scaledown = 1024 / bs;
245 y_align = y_scaledown = 16;
246 } else if (surf->tiling == ISL_TILING_64) {
247 switch (bs) {
248 case 1:
249 x_align = x_scaledown = 128;
250 y_align = y_scaledown = 128;
251 break;
252 case 2:
253 x_align = x_scaledown = 128;
254 y_align = y_scaledown = 64;
255 break;
256 case 4:
257 x_align = x_scaledown = 64;
258 y_align = y_scaledown = 64;
259 break;
260 case 8:
261 x_align = x_scaledown = 64;
262 y_align = y_scaledown = 32;
263 break;
264 case 16:
265 x_align = x_scaledown = 32;
266 y_align = y_scaledown = 32;
267 break;
268 default:
269 unreachable("unsupported bpp");
270 }
271 } else {
272 unreachable("Unsupported tiling format");
273 }
274 } else {
275 /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
276 * Target(s)", beneath the "Fast Color Clear" bullet (p327):
277 *
278 * Clear pass must have a clear rectangle that must follow
279 * alignment rules in terms of pixels and lines as shown in the
280 * table below. Further, the clear-rectangle height and width
281 * must be multiple of the following dimensions. If the height
282 * and width of the render target being cleared do not meet these
283 * requirements, an MCS buffer can be created such that it
284 * follows the requirement and covers the RT.
285 *
286 * The alignment size in the table that follows is a multiple of the
287 * alignment size that is baked into the CCS surface format.
288 */
289 enum isl_format ccs_format;
290 if (ISL_GFX_VERX10(dev) == 120) {
291 assert(surf->tiling == ISL_TILING_Y0);
292 switch (isl_format_get_layout(surf->format)->bpb) {
293 case 8: ccs_format = ISL_FORMAT_GFX12_CCS_8BPP_Y0; break;
294 case 16: ccs_format = ISL_FORMAT_GFX12_CCS_16BPP_Y0; break;
295 case 32: ccs_format = ISL_FORMAT_GFX12_CCS_32BPP_Y0; break;
296 case 64: ccs_format = ISL_FORMAT_GFX12_CCS_64BPP_Y0; break;
297 case 128: ccs_format = ISL_FORMAT_GFX12_CCS_128BPP_Y0; break;
298 default: unreachable("Invalid surface bpb for fast clearing");
299 }
300 } else {
301 assert(aux_surf->usage == ISL_SURF_USAGE_CCS_BIT);
302 ccs_format = aux_surf->format;
303 }
304
305 x_align = isl_format_get_layout(ccs_format)->bw * 16;
306 y_align = isl_format_get_layout(ccs_format)->bh * 32 /
307 isl_format_get_layout(ccs_format)->bpb;
308
309 /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
310 * Target(s)", beneath the "Fast Color Clear" bullet (p327):
311 *
312 * In order to optimize the performance MCS buffer (when bound to
313 * 1X RT) clear similarly to MCS buffer clear for MSRT case,
314 * clear rect is required to be scaled by the following factors
315 * in the horizontal and vertical directions:
316 *
317 * The X and Y scale down factors in the table that follows are each
318 * equal to half the alignment value computed above.
319 */
320 x_scaledown = x_align / 2;
321 y_scaledown = y_align / 2;
322 }
323
324 if (ISL_DEV_IS_HASWELL(dev)) {
325 /* From BSpec: 3D-Media-GPGPU Engine > 3D Pipeline > Pixel > Pixel
326 * Backend > MCS Buffer for Render Target(s) [DevIVB+] > Table "Color
327 * Clear of Non-MultiSampled Render Target Restrictions":
328 *
329 * Clear rectangle must be aligned to two times the number of
330 * pixels in the table shown below due to 16x16 hashing across the
331 * slice.
332 *
333 * This restriction is only documented to exist on HSW GT3 but
334 * empirical evidence suggests that it's also needed GT2.
335 */
336 x_align *= 2;
337 y_align *= 2;
338 }
339 } else {
340 assert(aux_surf->usage == ISL_SURF_USAGE_MCS_BIT);
341
342 /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
343 * Target(s)", beneath the "MSAA Compression" bullet (p326):
344 *
345 * Clear pass for this case requires that scaled down primitive
346 * is sent down with upper left coordinate to coincide with
347 * actual rectangle being cleared. For MSAA, clear rectangle’s
348 * height and width need to as show in the following table in
349 * terms of (width,height) of the RT.
350 *
351 * MSAA Width of Clear Rect Height of Clear Rect
352 * 2X Ceil(1/8*width) Ceil(1/2*height)
353 * 4X Ceil(1/8*width) Ceil(1/2*height)
354 * 8X Ceil(1/2*width) Ceil(1/2*height)
355 * 16X width Ceil(1/2*height)
356 *
357 * The text "with upper left coordinate to coincide with actual
358 * rectangle being cleared" is a little confusing--it seems to imply
359 * that to clear a rectangle from (x,y) to (x+w,y+h), one needs to
360 * feed the pipeline using the rectangle (x,y) to
361 * (x+Ceil(w/N),y+Ceil(h/2)), where N is either 2 or 8 depending on
362 * the number of samples. Experiments indicate that this is not
363 * quite correct; actually, what the hardware appears to do is to
364 * align whatever rectangle is sent down the pipeline to the nearest
365 * multiple of 2x2 blocks, and then scale it up by a factor of N
366 * horizontally and 2 vertically. So the resulting alignment is 4
367 * vertically and either 4 or 16 horizontally, and the scaledown
368 * factor is 2 vertically and either 2 or 8 horizontally.
369 *
370 * On Xe2+:
371 * Bspec 57340 (r59562):
372 *
373 * Fast Clear MCS Surface
374 * (Table)
375 *
376 * The scaled down values in the Xe2 table are different from what's in
377 * the previous platforms.
378 */
379 switch (aux_surf->format) {
380 case ISL_FORMAT_MCS_2X:
381 case ISL_FORMAT_MCS_4X:
382 x_scaledown = dev->info->ver >= 20 ? 64 : 8;
383 break;
384 case ISL_FORMAT_MCS_8X:
385 x_scaledown = dev->info->ver >= 20 ? 16 : 2;
386 break;
387 case ISL_FORMAT_MCS_16X:
388 x_scaledown = dev->info->ver >= 20 ? 8 : 1;
389 break;
390 default:
391 unreachable("Unexpected MCS format for fast clear");
392 }
393 y_scaledown = dev->info->ver >= 20 ? 4 : 2;
394 x_align = x_scaledown * 2;
395 y_align = y_scaledown * 2;
396 }
397
398 *x0 = ROUND_DOWN_TO(*x0, x_align) / x_scaledown;
399 *y0 = ROUND_DOWN_TO(*y0, y_align) / y_scaledown;
400 *x1 = ALIGN(*x1, x_align) / x_scaledown;
401 *y1 = ALIGN(*y1, y_align) / y_scaledown;
402 }
403
404 static void
convert_rt_from_3d_to_2d(const struct isl_device * isl_dev,struct blorp_surface_info * info)405 convert_rt_from_3d_to_2d(const struct isl_device *isl_dev,
406 struct blorp_surface_info *info)
407 {
408 assert(info->surf.dim == ISL_SURF_DIM_3D);
409 assert(info->surf.dim_layout == ISL_DIM_LAYOUT_GFX4_2D);
410
411 /* Some tilings have different swizzling between 2D/3D images. So,
412 * conversion would not be possible.
413 */
414 assert(!isl_tiling_is_std_y(info->surf.tiling));
415 assert(!isl_tiling_is_64(info->surf.tiling));
416
417 /* Convert from 3D to 2D-array. */
418 uint32_t array_pitch_el_rows = info->surf.array_pitch_el_rows;
419 uint64_t size_B = info->surf.size_B;
420 bool ok = isl_surf_init(isl_dev, &info->surf,
421 .dim = ISL_SURF_DIM_2D,
422 .format = info->surf.format,
423 .width = info->surf.logical_level0_px.w,
424 .height = info->surf.logical_level0_px.h,
425 .depth = 1,
426 .levels = info->surf.levels,
427 .array_len = info->surf.logical_level0_px.d,
428 .samples = 1,
429 .row_pitch_B = info->surf.row_pitch_B,
430 .usage = info->surf.usage,
431 .tiling_flags = (1 << info->surf.tiling));
432 assert(ok);
433
434 /* Fix up the array-pitch and size. */
435 info->surf.array_pitch_el_rows = array_pitch_el_rows;
436 info->surf.size_B = size_B;
437 }
438
439 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)440 blorp_fast_clear(struct blorp_batch *batch,
441 const struct blorp_surf *surf,
442 enum isl_format format, struct isl_swizzle swizzle,
443 uint32_t level, uint32_t start_layer, uint32_t num_layers,
444 uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
445 {
446 struct blorp_params params;
447 blorp_params_init(¶ms);
448 params.num_layers = num_layers;
449 assert((batch->flags & BLORP_BATCH_USE_COMPUTE) == 0);
450
451 params.x0 = x0;
452 params.y0 = y0;
453 params.x1 = x1;
454 params.y1 = y1;
455
456 if (batch->blorp->isl_dev->info->ver >= 20) {
457 union isl_color_value clear_color =
458 isl_color_value_swizzle_inv(surf->clear_color, swizzle);
459 if (format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) {
460 clear_color.u32[0] = float3_to_rgb9e5(clear_color.f32);
461 format = ISL_FORMAT_R32_UINT;
462 } else if (format == ISL_FORMAT_L8_UNORM_SRGB) {
463 clear_color.f32[0] = util_format_linear_to_srgb_float(clear_color.f32[0]);
464 format = ISL_FORMAT_R8_UNORM;
465 }
466
467 /* Bspec 57340 (r59562):
468 *
469 * Overview of Fast Clear:
470 * Pixel shader's color output is treated as Clear Value, value
471 * should be a constant.
472 */
473 memcpy(¶ms.wm_inputs.clear_color, &clear_color, 4 * sizeof(float));
474 } else {
475 /* BSpec: 2423 (r153658):
476 *
477 * The pixel shader kernel requires no attributes, and delivers a
478 * value of 0xFFFFFFFF in all channels of the render target write
479 * message The replicated color message should be used.
480 */
481 memset(¶ms.wm_inputs.clear_color, 0xff, 4 * sizeof(float));
482 }
483
484 params.fast_clear_op = ISL_AUX_OP_FAST_CLEAR;
485
486 get_fast_clear_rect(batch->blorp->isl_dev, surf->surf, surf->aux_surf,
487 ¶ms.x0, ¶ms.y0, ¶ms.x1, ¶ms.y1);
488
489 if (!blorp_params_get_clear_kernel(batch, ¶ms, true, true, false))
490 return;
491
492 blorp_surface_info_init(batch, ¶ms.dst, surf, level,
493 start_layer, format, true);
494
495 /* BSpec: 46969 (r45602):
496 *
497 * 3D/Volumetric surfaces do not support Fast Clear operation.
498 */
499 if (ISL_GFX_VERX10(batch->blorp->isl_dev) == 120 &&
500 params.dst.surf.dim == ISL_SURF_DIM_3D) {
501 convert_rt_from_3d_to_2d(batch->blorp->isl_dev, ¶ms.dst);
502 }
503
504 params.num_samples = params.dst.surf.samples;
505
506 assert(params.num_samples != 0);
507 if (params.num_samples == 1)
508 params.op = BLORP_OP_CCS_COLOR_CLEAR;
509 else
510 params.op = BLORP_OP_MCS_COLOR_CLEAR;
511
512 /* If a swizzle was provided, we need to swizzle the clear color so that
513 * the hardware color format conversion will work properly.
514 */
515 params.dst.clear_color =
516 isl_color_value_swizzle_inv(params.dst.clear_color, swizzle);
517
518 batch->blorp->exec(batch, ¶ms);
519 }
520
521 bool
blorp_clear_supports_blitter(struct blorp_context * blorp,const struct blorp_surf * surf,uint8_t color_write_disable,bool blend_enabled)522 blorp_clear_supports_blitter(struct blorp_context *blorp,
523 const struct blorp_surf *surf,
524 uint8_t color_write_disable,
525 bool blend_enabled)
526 {
527 const struct intel_device_info *devinfo = blorp->isl_dev->info;
528
529 if (devinfo->ver < 12)
530 return false;
531
532 if (surf->surf->samples > 1)
533 return false;
534
535 if (color_write_disable != 0 || blend_enabled)
536 return false;
537
538 if (!blorp_blitter_supports_aux(devinfo, surf->aux_usage))
539 return false;
540
541 const struct isl_format_layout *fmtl =
542 isl_format_get_layout(surf->surf->format);
543
544 /* We can only support linear mode for 96bpp. */
545 if (fmtl->bpb == 96 && surf->surf->tiling != ISL_TILING_LINEAR)
546 return false;
547
548 return true;
549 }
550
551 bool
blorp_clear_supports_compute(struct blorp_context * blorp,uint8_t color_write_disable,bool blend_enabled,enum isl_aux_usage aux_usage)552 blorp_clear_supports_compute(struct blorp_context *blorp,
553 uint8_t color_write_disable, bool blend_enabled,
554 enum isl_aux_usage aux_usage)
555 {
556 if (blorp->isl_dev->info->ver < 7)
557 return false;
558 if (color_write_disable != 0 || blend_enabled)
559 return false;
560 if (blorp->isl_dev->info->ver >= 12) {
561 return aux_usage == ISL_AUX_USAGE_FCV_CCS_E ||
562 aux_usage == ISL_AUX_USAGE_CCS_E ||
563 aux_usage == ISL_AUX_USAGE_NONE;
564 } else {
565 return aux_usage == ISL_AUX_USAGE_NONE;
566 }
567 }
568
569 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,uint8_t color_write_disable)570 blorp_clear(struct blorp_batch *batch,
571 const struct blorp_surf *surf,
572 enum isl_format format, struct isl_swizzle swizzle,
573 uint32_t level, uint32_t start_layer, uint32_t num_layers,
574 uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
575 union isl_color_value clear_color,
576 uint8_t color_write_disable)
577 {
578 struct blorp_params params;
579 blorp_params_init(¶ms);
580 params.op = BLORP_OP_SLOW_COLOR_CLEAR;
581
582 const bool compute = batch->flags & BLORP_BATCH_USE_COMPUTE;
583 if (compute) {
584 assert(blorp_clear_supports_compute(batch->blorp, color_write_disable,
585 false, surf->aux_usage));
586 } else if (batch->flags & BLORP_BATCH_USE_BLITTER) {
587 assert(blorp_clear_supports_blitter(batch->blorp, surf,
588 color_write_disable, false));
589 }
590
591 /* Manually apply the clear destination swizzle. This way swizzled clears
592 * will work for swizzles which we can't normally use for rendering and it
593 * also ensures that they work on pre-Haswell hardware which can't swizlle
594 * at all.
595 */
596 clear_color = isl_color_value_swizzle_inv(clear_color, swizzle);
597 swizzle = ISL_SWIZZLE_IDENTITY;
598
599 bool clear_rgb_as_red = false;
600 if (format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) {
601 clear_color.u32[0] = float3_to_rgb9e5(clear_color.f32);
602 format = ISL_FORMAT_R32_UINT;
603 } else if (format == ISL_FORMAT_L8_UNORM_SRGB) {
604 clear_color.f32[0] = util_format_linear_to_srgb_float(clear_color.f32[0]);
605 format = ISL_FORMAT_R8_UNORM;
606 } else if (format == ISL_FORMAT_A4B4G4R4_UNORM) {
607 /* Broadwell and earlier cannot render to this format so we need to work
608 * around it by swapping the colors around and using B4G4R4A4 instead.
609 */
610 const struct isl_swizzle ARGB = ISL_SWIZZLE(ALPHA, RED, GREEN, BLUE);
611 clear_color = isl_color_value_swizzle_inv(clear_color, ARGB);
612 format = ISL_FORMAT_B4G4R4A4_UNORM;
613 } else if (isl_format_get_layout(format)->bpb % 3 == 0) {
614 clear_rgb_as_red = true;
615 if (format == ISL_FORMAT_R8G8B8_UNORM_SRGB) {
616 clear_color.f32[0] = util_format_linear_to_srgb_float(clear_color.f32[0]);
617 clear_color.f32[1] = util_format_linear_to_srgb_float(clear_color.f32[1]);
618 clear_color.f32[2] = util_format_linear_to_srgb_float(clear_color.f32[2]);
619 }
620 }
621
622 memcpy(¶ms.wm_inputs.clear_color, clear_color.f32, sizeof(float) * 4);
623
624 bool use_simd16_replicated_data = true;
625
626 /* From the SNB PRM (Vol4_Part1):
627 *
628 * "Replicated data (Message Type = 111) is only supported when
629 * accessing tiled memory. Using this Message Type to access linear
630 * (untiled) memory is UNDEFINED."
631 */
632 if (surf->surf->tiling == ISL_TILING_LINEAR)
633 use_simd16_replicated_data = false;
634
635 /* Replicated clears don't work before gfx6 */
636 if (batch->blorp->isl_dev->info->ver < 6)
637 use_simd16_replicated_data = false;
638
639 /* From the BSpec: 47719 (TGL/DG2/MTL) Replicate Data:
640 *
641 * "Replicate Data Render Target Write message should not be used
642 * on all projects TGL+."
643 *
644 * Xe2 spec (57350) does not mention this restriction.
645 *
646 * See 14017879046, 14017880152 for additional information.
647 */
648 if (batch->blorp->isl_dev->info->ver >= 12 &&
649 batch->blorp->isl_dev->info->ver < 20)
650 use_simd16_replicated_data = false;
651
652 if (compute)
653 use_simd16_replicated_data = false;
654
655 /* Constant color writes ignore everything in blend and color calculator
656 * state. This is not documented.
657 */
658 params.color_write_disable = color_write_disable & BITFIELD_MASK(4);
659 if (color_write_disable)
660 use_simd16_replicated_data = false;
661
662 if (!blorp_params_get_clear_kernel(batch, ¶ms, false,
663 use_simd16_replicated_data,
664 clear_rgb_as_red))
665 return;
666
667 if (!compute && !blorp_ensure_sf_program(batch, ¶ms))
668 return;
669
670 assert(num_layers > 0);
671 while (num_layers > 0) {
672 blorp_surface_info_init(batch, ¶ms.dst, surf, level,
673 start_layer, format, true);
674 params.dst.view.swizzle = swizzle;
675
676 params.x0 = x0;
677 params.y0 = y0;
678 params.x1 = x1;
679 params.y1 = y1;
680
681 if (compute) {
682 params.wm_inputs.bounds_rect.x0 = x0;
683 params.wm_inputs.bounds_rect.y0 = y0;
684 params.wm_inputs.bounds_rect.x1 = x1;
685 params.wm_inputs.bounds_rect.y1 = y1;
686 }
687
688 if (params.dst.tile_x_sa || params.dst.tile_y_sa) {
689 assert(params.dst.surf.samples == 1);
690 assert(num_layers == 1);
691 params.x0 += params.dst.tile_x_sa;
692 params.y0 += params.dst.tile_y_sa;
693 params.x1 += params.dst.tile_x_sa;
694 params.y1 += params.dst.tile_y_sa;
695 }
696
697 /* The MinLOD and MinimumArrayElement don't work properly for cube maps.
698 * Convert them to a single slice on gfx4.
699 */
700 if (batch->blorp->isl_dev->info->ver == 4 &&
701 (params.dst.surf.usage & ISL_SURF_USAGE_CUBE_BIT)) {
702 blorp_surf_convert_to_single_slice(batch->blorp->isl_dev, ¶ms.dst);
703 }
704
705 if (clear_rgb_as_red) {
706 surf_fake_rgb_with_red(batch->blorp->isl_dev, ¶ms.dst);
707 params.x0 *= 3;
708 params.x1 *= 3;
709 }
710
711 if (isl_format_is_compressed(params.dst.surf.format)) {
712 blorp_surf_convert_to_uncompressed(batch->blorp->isl_dev, ¶ms.dst,
713 NULL, NULL, NULL, NULL);
714 //&dst_x, &dst_y, &dst_w, &dst_h);
715 }
716
717 if (params.dst.tile_x_sa || params.dst.tile_y_sa) {
718 /* Either we're on gfx4 where there is no multisampling or the
719 * surface is compressed which also implies no multisampling.
720 * Therefore, sa == px and we don't need to do a conversion.
721 */
722 assert(params.dst.surf.samples == 1);
723 params.x0 += params.dst.tile_x_sa;
724 params.y0 += params.dst.tile_y_sa;
725 params.x1 += params.dst.tile_x_sa;
726 params.y1 += params.dst.tile_y_sa;
727 }
728
729 params.num_samples = params.dst.surf.samples;
730
731 /* We may be restricted on the number of layers we can bind at any one
732 * time. In particular, Sandy Bridge has a maximum number of layers of
733 * 512 but a maximum 3D texture size is much larger.
734 */
735 params.num_layers = MIN2(params.dst.view.array_len, num_layers);
736
737 const unsigned max_image_width = 16 * 1024;
738 if (params.dst.surf.logical_level0_px.width > max_image_width) {
739 /* Clearing an RGB image as red multiplies the surface width by 3
740 * so it may now be too wide for the hardware surface limits. We
741 * have to break the clear up into pieces in order to clear wide
742 * images.
743 */
744 assert(clear_rgb_as_red);
745 assert(params.dst.surf.dim == ISL_SURF_DIM_2D);
746 assert(params.dst.surf.tiling == ISL_TILING_LINEAR);
747 assert(params.dst.surf.logical_level0_px.depth == 1);
748 assert(params.dst.surf.logical_level0_px.array_len == 1);
749 assert(params.dst.surf.levels == 1);
750 assert(params.dst.surf.samples == 1);
751 assert(params.dst.tile_x_sa == 0 || params.dst.tile_y_sa == 0);
752 assert(params.dst.aux_usage == ISL_AUX_USAGE_NONE);
753
754 /* max_image_width rounded down to a multiple of 3 */
755 const unsigned max_fake_rgb_width = (max_image_width / 3) * 3;
756 const unsigned cpp =
757 isl_format_get_layout(params.dst.surf.format)->bpb / 8;
758
759 params.dst.surf.logical_level0_px.width = max_fake_rgb_width;
760 params.dst.surf.phys_level0_sa.width = max_fake_rgb_width;
761
762 uint32_t orig_x0 = params.x0, orig_x1 = params.x1;
763 uint64_t orig_offset = params.dst.addr.offset;
764 for (uint32_t x = orig_x0; x < orig_x1; x += max_fake_rgb_width) {
765 /* Offset to the surface. It's easy because we're linear */
766 params.dst.addr.offset = orig_offset + x * cpp;
767
768 params.x0 = 0;
769 params.x1 = MIN2(orig_x1 - x, max_image_width);
770
771 batch->blorp->exec(batch, ¶ms);
772 }
773 } else {
774 batch->blorp->exec(batch, ¶ms);
775 }
776
777 start_layer += params.num_layers;
778 num_layers -= params.num_layers;
779 }
780 }
781
782 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)783 blorp_clear_stencil_as_rgba(struct blorp_batch *batch,
784 const struct blorp_surf *surf,
785 uint32_t level, uint32_t start_layer,
786 uint32_t num_layers,
787 uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
788 uint8_t stencil_mask, uint8_t stencil_value)
789 {
790 assert((batch->flags & BLORP_BATCH_USE_COMPUTE) == 0);
791
792 /* Stencil mask support would require piles of shader magic */
793 if (stencil_mask != 0xff)
794 return false;
795
796 /* We only support separate W-tiled stencil for now */
797 if (surf->surf->format != ISL_FORMAT_R8_UINT ||
798 surf->surf->tiling != ISL_TILING_W)
799 return false;
800
801 if (surf->surf->samples > 1) {
802 /* Adjust x0, y0, x1, and y1 to be in units of samples */
803 assert(surf->surf->msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED);
804 struct isl_extent2d msaa_px_size_sa =
805 isl_get_interleaved_msaa_px_size_sa(surf->surf->samples);
806
807 x0 *= msaa_px_size_sa.w;
808 y0 *= msaa_px_size_sa.h;
809 x1 *= msaa_px_size_sa.w;
810 y1 *= msaa_px_size_sa.h;
811 }
812
813 /* W-tiles and Y-tiles have the same layout as far as cache lines are
814 * concerned: both are 8x8 cache lines laid out Y-major. The difference is
815 * entirely in how the data is arranged within the cache line. W-tiling
816 * is 8x8 pixels in a swizzled pattern while Y-tiling is 16B by 4 rows
817 * regardless of image format size. As long as everything is aligned to 8,
818 * we can just treat the W-tiled image as Y-tiled, ignore the layout
819 * difference within a cache line, and blast out data.
820 */
821 if (x0 % 8 != 0 || y0 % 8 != 0 || x1 % 8 != 0 || y1 % 8 != 0)
822 return false;
823
824 struct blorp_params params;
825 blorp_params_init(¶ms);
826 params.op = BLORP_OP_SLOW_DEPTH_CLEAR;
827
828 if (!blorp_params_get_clear_kernel(batch, ¶ms, false, true, false))
829 return false;
830
831 memset(¶ms.wm_inputs.clear_color, stencil_value,
832 sizeof(params.wm_inputs.clear_color));
833
834 /* The Sandy Bridge PRM Vol. 4 Pt. 2, section 2.11.2.1.1 has the
835 * following footnote to the format table:
836 *
837 * 128 BPE Formats cannot be Tiled Y when used as render targets
838 *
839 * We have to use RGBA16_UINT on SNB.
840 */
841 enum isl_format wide_format;
842 if (ISL_GFX_VER(batch->blorp->isl_dev) <= 6) {
843 wide_format = ISL_FORMAT_R16G16B16A16_UINT;
844
845 /* For RGBA16_UINT, we need to mask the stencil value otherwise, we risk
846 * clamping giving us the wrong values
847 */
848 for (unsigned i = 0; i < 4; i++)
849 params.wm_inputs.clear_color[i] &= 0xffff;
850 } else {
851 wide_format = ISL_FORMAT_R32G32B32A32_UINT;
852 }
853
854 for (uint32_t a = 0; a < num_layers; a++) {
855 uint32_t layer = start_layer + a;
856
857 blorp_surface_info_init(batch, ¶ms.dst, surf, level,
858 layer, ISL_FORMAT_UNSUPPORTED, true);
859
860 if (surf->surf->samples > 1)
861 blorp_surf_fake_interleaved_msaa(batch->blorp->isl_dev, ¶ms.dst);
862
863 /* Make it Y-tiled */
864 blorp_surf_retile_w_to_y(batch->blorp->isl_dev, ¶ms.dst);
865
866 unsigned wide_Bpp =
867 isl_format_get_layout(wide_format)->bpb / 8;
868
869 params.dst.view.format = params.dst.surf.format = wide_format;
870 assert(params.dst.surf.logical_level0_px.width % wide_Bpp == 0);
871 params.dst.surf.logical_level0_px.width /= wide_Bpp;
872 assert(params.dst.tile_x_sa % wide_Bpp == 0);
873 params.dst.tile_x_sa /= wide_Bpp;
874
875 params.x0 = params.dst.tile_x_sa + x0 / (wide_Bpp / 2);
876 params.y0 = params.dst.tile_y_sa + y0 / 2;
877 params.x1 = params.dst.tile_x_sa + x1 / (wide_Bpp / 2);
878 params.y1 = params.dst.tile_y_sa + y1 / 2;
879
880 batch->blorp->exec(batch, ¶ms);
881 }
882
883 return true;
884 }
885
886 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)887 blorp_clear_depth_stencil(struct blorp_batch *batch,
888 const struct blorp_surf *depth,
889 const struct blorp_surf *stencil,
890 uint32_t level, uint32_t start_layer,
891 uint32_t num_layers,
892 uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
893 bool clear_depth, float depth_value,
894 uint8_t stencil_mask, uint8_t stencil_value)
895 {
896 assert((batch->flags & BLORP_BATCH_USE_COMPUTE) == 0);
897 assert(num_layers > 0);
898
899 if (!clear_depth && blorp_clear_stencil_as_rgba(batch, stencil, level,
900 start_layer, num_layers,
901 x0, y0, x1, y1,
902 stencil_mask,
903 stencil_value))
904 return;
905
906 struct blorp_params params;
907 blorp_params_init(¶ms);
908 params.op = BLORP_OP_SLOW_DEPTH_CLEAR;
909
910 params.x0 = x0;
911 params.y0 = y0;
912 params.x1 = x1;
913 params.y1 = y1;
914
915 if (ISL_GFX_VER(batch->blorp->isl_dev) == 6) {
916 /* For some reason, Sandy Bridge gets occlusion queries wrong if we
917 * don't have a shader. In particular, it records samples even though
918 * we disable statistics in 3DSTATE_WM. Give it the usual clear shader
919 * to work around the issue.
920 */
921 if (!blorp_params_get_clear_kernel(batch, ¶ms, false, false, false))
922 return;
923 }
924
925 while (num_layers > 0) {
926 params.num_layers = num_layers;
927
928 if (stencil_mask) {
929 blorp_surface_info_init(batch, ¶ms.stencil, stencil,
930 level, start_layer,
931 ISL_FORMAT_UNSUPPORTED, true);
932 params.stencil_mask = stencil_mask;
933 params.stencil_ref = stencil_value;
934
935 params.dst.surf.samples = params.stencil.surf.samples;
936 params.dst.surf.logical_level0_px =
937 params.stencil.surf.logical_level0_px;
938 params.dst.view = params.stencil.view;
939
940 params.num_samples = params.stencil.surf.samples;
941
942 /* We may be restricted on the number of layers we can bind at any
943 * one time. In particular, Sandy Bridge has a maximum number of
944 * layers of 512 but a maximum 3D texture size is much larger.
945 */
946 if (params.stencil.view.array_len < params.num_layers)
947 params.num_layers = params.stencil.view.array_len;
948 }
949
950 if (clear_depth) {
951 blorp_surface_info_init(batch, ¶ms.depth, depth,
952 level, start_layer,
953 ISL_FORMAT_UNSUPPORTED, true);
954 params.z = depth_value;
955 params.depth_format =
956 isl_format_get_depth_format(depth->surf->format, false);
957
958 params.dst.surf.samples = params.depth.surf.samples;
959 params.dst.surf.logical_level0_px =
960 params.depth.surf.logical_level0_px;
961 params.dst.view = params.depth.view;
962
963 params.num_samples = params.depth.surf.samples;
964
965 /* We may be restricted on the number of layers we can bind at any
966 * one time. In particular, Sandy Bridge has a maximum number of
967 * layers of 512 but a maximum 3D texture size is much larger.
968 */
969 if (params.depth.view.array_len < params.num_layers)
970 params.num_layers = params.depth.view.array_len;
971 }
972
973 batch->blorp->exec(batch, ¶ms);
974
975 start_layer += params.num_layers;
976 num_layers -= params.num_layers;
977 }
978 }
979
980 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)981 blorp_can_clear_full_surface(const struct blorp_surf *depth,
982 const struct blorp_surf *stencil,
983 uint32_t level,
984 uint32_t x0, uint32_t y0,
985 uint32_t x1, uint32_t y1,
986 bool clear_depth,
987 bool clear_stencil)
988 {
989 uint32_t width = 0, height = 0;
990 if (clear_stencil) {
991 width = u_minify(stencil->surf->logical_level0_px.width, level);
992 height = u_minify(stencil->surf->logical_level0_px.height, level);
993 }
994
995 if (clear_depth && !(width || height)) {
996 width = u_minify(depth->surf->logical_level0_px.width, level);
997 height = u_minify(depth->surf->logical_level0_px.height, level);
998 }
999
1000 return x0 == 0 && y0 == 0 && width == x1 && height == y1;
1001 }
1002
1003 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)1004 blorp_hiz_clear_depth_stencil(struct blorp_batch *batch,
1005 const struct blorp_surf *depth,
1006 const struct blorp_surf *stencil,
1007 uint32_t level,
1008 uint32_t start_layer, uint32_t num_layers,
1009 uint32_t x0, uint32_t y0,
1010 uint32_t x1, uint32_t y1,
1011 bool clear_depth, float depth_value,
1012 bool clear_stencil, uint8_t stencil_value)
1013 {
1014 struct blorp_params params;
1015 blorp_params_init(¶ms);
1016 params.op = BLORP_OP_HIZ_CLEAR;
1017
1018 /* This requires WM_HZ_OP which only exists on gfx8+ */
1019 assert(ISL_GFX_VER(batch->blorp->isl_dev) >= 8);
1020
1021 params.hiz_op = ISL_AUX_OP_FAST_CLEAR;
1022 /* From BSpec: 3DSTATE_WM_HZ_OP_BODY >> Full Surface Depth and Stencil Clear
1023 *
1024 * "Software must set this only when the APP requires the entire Depth
1025 * surface to be cleared."
1026 */
1027 params.full_surface_hiz_op =
1028 blorp_can_clear_full_surface(depth, stencil, level, x0, y0, x1, y1,
1029 clear_depth, clear_stencil);
1030 params.num_layers = 1;
1031
1032 params.x0 = x0;
1033 params.y0 = y0;
1034 params.x1 = x1;
1035 params.y1 = y1;
1036
1037 for (uint32_t l = 0; l < num_layers; l++) {
1038 const uint32_t layer = start_layer + l;
1039 if (clear_stencil) {
1040 blorp_surface_info_init(batch, ¶ms.stencil, stencil,
1041 level, layer,
1042 ISL_FORMAT_UNSUPPORTED, true);
1043 params.stencil_mask = 0xff;
1044 params.stencil_ref = stencil_value;
1045 params.num_samples = params.stencil.surf.samples;
1046 }
1047
1048 if (clear_depth) {
1049 /* If we're clearing depth, we must have HiZ */
1050 assert(depth && isl_aux_usage_has_hiz(depth->aux_usage));
1051
1052 blorp_surface_info_init(batch, ¶ms.depth, depth,
1053 level, layer,
1054 ISL_FORMAT_UNSUPPORTED, true);
1055 params.depth.clear_color.f32[0] = depth_value;
1056 params.depth_format =
1057 isl_format_get_depth_format(depth->surf->format, false);
1058 params.num_samples = params.depth.surf.samples;
1059 }
1060
1061 batch->blorp->exec(batch, ¶ms);
1062 }
1063 }
1064
1065 /* Given a depth stencil attachment, this function performs a fast depth clear
1066 * on a depth portion and a regular clear on the stencil portion. When
1067 * performing a fast depth clear on the depth portion, the HiZ buffer is simply
1068 * tagged as cleared so the depth clear value is not actually needed.
1069 */
1070 void
blorp_gfx8_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)1071 blorp_gfx8_hiz_clear_attachments(struct blorp_batch *batch,
1072 uint32_t num_samples,
1073 uint32_t x0, uint32_t y0,
1074 uint32_t x1, uint32_t y1,
1075 bool clear_depth, bool clear_stencil,
1076 uint8_t stencil_value)
1077 {
1078 assert(batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
1079
1080 struct blorp_params params;
1081 blorp_params_init(¶ms);
1082 params.op = BLORP_OP_HIZ_CLEAR;
1083 params.num_layers = 1;
1084 params.hiz_op = ISL_AUX_OP_FAST_CLEAR;
1085 params.x0 = x0;
1086 params.y0 = y0;
1087 params.x1 = x1;
1088 params.y1 = y1;
1089 params.num_samples = num_samples;
1090 params.depth.enabled = clear_depth;
1091 params.stencil.enabled = clear_stencil;
1092 params.stencil_ref = stencil_value;
1093 batch->blorp->exec(batch, ¶ms);
1094 }
1095
1096 /** Clear active color/depth/stencili attachments
1097 *
1098 * This function performs a clear operation on the currently bound
1099 * color/depth/stencil attachments. It is assumed that any information passed
1100 * in here is valid, consistent, and in-bounds relative to the currently
1101 * attached depth/stencil. The binding_table_offset parameter is the 32-bit
1102 * offset relative to surface state base address where pre-baked binding table
1103 * that we are to use lives. If clear_color is false, binding_table_offset
1104 * must point to a binding table with one entry which is a valid null surface
1105 * that matches the currently bound depth and stencil.
1106 */
1107 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)1108 blorp_clear_attachments(struct blorp_batch *batch,
1109 uint32_t binding_table_offset,
1110 enum isl_format depth_format,
1111 uint32_t num_samples,
1112 uint32_t start_layer, uint32_t num_layers,
1113 uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
1114 bool clear_color, union isl_color_value color_value,
1115 bool clear_depth, float depth_value,
1116 uint8_t stencil_mask, uint8_t stencil_value)
1117 {
1118 struct blorp_params params;
1119 blorp_params_init(¶ms);
1120
1121 assert((batch->flags & BLORP_BATCH_USE_COMPUTE) == 0);
1122 assert(batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
1123
1124 params.x0 = x0;
1125 params.y0 = y0;
1126 params.x1 = x1;
1127 params.y1 = y1;
1128
1129 params.use_pre_baked_binding_table = true;
1130 params.pre_baked_binding_table_offset = binding_table_offset;
1131
1132 params.num_layers = num_layers;
1133 params.num_samples = num_samples;
1134
1135 if (clear_color) {
1136 params.dst.enabled = true;
1137 params.op = BLORP_OP_SLOW_COLOR_CLEAR;
1138
1139 memcpy(¶ms.wm_inputs.clear_color, color_value.f32, sizeof(float) * 4);
1140
1141 /* Unfortunately, without knowing whether or not our destination surface
1142 * is tiled or not, we have to assume it may be linear. This means no
1143 * SIMD16_REPDATA for us. :-(
1144 */
1145 if (!blorp_params_get_clear_kernel(batch, ¶ms, false, false, false))
1146 return;
1147 }
1148
1149 if (clear_depth) {
1150 params.depth.enabled = true;
1151 params.op = BLORP_OP_SLOW_DEPTH_CLEAR;
1152
1153 params.z = depth_value;
1154 params.depth_format = isl_format_get_depth_format(depth_format, false);
1155 }
1156
1157 if (stencil_mask) {
1158 params.stencil.enabled = true;
1159 params.op = BLORP_OP_SLOW_DEPTH_CLEAR;
1160
1161 params.stencil_mask = stencil_mask;
1162 params.stencil_ref = stencil_value;
1163 }
1164
1165 if (!blorp_params_get_layer_offset_vs(batch, ¶ms))
1166 return;
1167
1168 params.vs_inputs.base_layer = start_layer;
1169
1170 batch->blorp->exec(batch, ¶ms);
1171 }
1172
1173 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)1174 blorp_ccs_resolve(struct blorp_batch *batch,
1175 struct blorp_surf *surf, uint32_t level,
1176 uint32_t start_layer, uint32_t num_layers,
1177 enum isl_format format,
1178 enum isl_aux_op resolve_op)
1179 {
1180 assert((batch->flags & BLORP_BATCH_USE_COMPUTE) == 0);
1181 struct blorp_params params;
1182
1183 blorp_params_init(¶ms);
1184 switch(resolve_op) {
1185 case ISL_AUX_OP_AMBIGUATE:
1186 params.op = BLORP_OP_CCS_AMBIGUATE;
1187 break;
1188 case ISL_AUX_OP_FULL_RESOLVE:
1189 params.op = BLORP_OP_CCS_RESOLVE;
1190 break;
1191 case ISL_AUX_OP_PARTIAL_RESOLVE:
1192 params.op = BLORP_OP_CCS_PARTIAL_RESOLVE;
1193 break;
1194 default:
1195 assert(false);
1196 }
1197 blorp_surface_info_init(batch, ¶ms.dst, surf,
1198 level, start_layer, format, true);
1199
1200 /* From the TGL PRM, Volume 2d: 3DSTATE_PS_BODY,
1201 *
1202 * 3D/Volumetric surfaces do not support Fast Clear operation.
1203 *
1204 * [...]
1205 *
1206 * 3D/Volumetric surfaces do not support in-place resolve pass
1207 * operation.
1208 *
1209 * HSD 1406738321 suggests a more limited scope of restrictions, but
1210 * there should be no harm in complying with the Bspec restrictions.
1211 */
1212 if (ISL_GFX_VERX10(batch->blorp->isl_dev) == 120 &&
1213 params.dst.surf.dim == ISL_SURF_DIM_3D) {
1214 convert_rt_from_3d_to_2d(batch->blorp->isl_dev, ¶ms.dst);
1215 }
1216
1217 params.x0 = params.y0 = 0;
1218 params.x1 = u_minify(params.dst.surf.logical_level0_px.width, level);
1219 params.y1 = u_minify(params.dst.surf.logical_level0_px.height, level);
1220 if (ISL_GFX_VER(batch->blorp->isl_dev) >= 9) {
1221 /* From Bspec 2424, "Render Target Resolve":
1222 *
1223 * The Resolve Rectangle size is same as Clear Rectangle size from
1224 * SKL+.
1225 *
1226 * Note that this differs from Vol7 of the Sky Lake PRM, which only
1227 * specifies aligning by the scaledown factors.
1228 */
1229 get_fast_clear_rect(batch->blorp->isl_dev, surf->surf, surf->aux_surf,
1230 ¶ms.x0, ¶ms.y0, ¶ms.x1, ¶ms.y1);
1231 } else {
1232 /* From the Ivy Bridge PRM, Vol2 Part1 11.9 "Render Target Resolve":
1233 *
1234 * A rectangle primitive must be scaled down by the following factors
1235 * with respect to render target being resolved.
1236 *
1237 * The scaledown factors in the table that follows are related to the
1238 * block size of the CCS format. For IVB and HSW, we divide by two, for
1239 * BDW we multiply by 8 and 16.
1240 */
1241 const struct isl_format_layout *aux_fmtl =
1242 isl_format_get_layout(params.dst.aux_surf.format);
1243 assert(aux_fmtl->txc == ISL_TXC_CCS);
1244
1245 unsigned x_scaledown, y_scaledown;
1246 if (ISL_GFX_VER(batch->blorp->isl_dev) >= 8) {
1247 x_scaledown = aux_fmtl->bw * 8;
1248 y_scaledown = aux_fmtl->bh * 16;
1249 } else {
1250 x_scaledown = aux_fmtl->bw / 2;
1251 y_scaledown = aux_fmtl->bh / 2;
1252 }
1253 params.x1 = ALIGN(params.x1, x_scaledown) / x_scaledown;
1254 params.y1 = ALIGN(params.y1, y_scaledown) / y_scaledown;
1255 }
1256
1257 if (batch->blorp->isl_dev->info->ver >= 10) {
1258 assert(resolve_op == ISL_AUX_OP_FULL_RESOLVE ||
1259 resolve_op == ISL_AUX_OP_PARTIAL_RESOLVE ||
1260 resolve_op == ISL_AUX_OP_AMBIGUATE);
1261 } else if (batch->blorp->isl_dev->info->ver >= 9) {
1262 assert(resolve_op == ISL_AUX_OP_FULL_RESOLVE ||
1263 resolve_op == ISL_AUX_OP_PARTIAL_RESOLVE);
1264 } else {
1265 /* Broadwell and earlier do not have a partial resolve */
1266 assert(resolve_op == ISL_AUX_OP_FULL_RESOLVE);
1267 }
1268 params.fast_clear_op = resolve_op;
1269 params.num_layers = num_layers;
1270
1271 /* Note: there is no need to initialize push constants because it doesn't
1272 * matter what data gets dispatched to the render target. However, we must
1273 * ensure that the fragment shader delivers the data using the "replicated
1274 * color" message.
1275 */
1276
1277 if (!blorp_params_get_clear_kernel(batch, ¶ms, false, true, false))
1278 return;
1279
1280 batch->blorp->exec(batch, ¶ms);
1281
1282 if (batch->blorp->isl_dev->info->ver <= 8) {
1283 assert(surf->aux_usage == ISL_AUX_USAGE_CCS_D);
1284 assert(resolve_op == ISL_AUX_OP_FULL_RESOLVE);
1285 /* ISL's state-machine of CCS_D describes full resolves as leaving the
1286 * aux buffer in the pass-through state. Hardware doesn't behave this
1287 * way on Broadwell however. On that platform, full resolves transition
1288 * the aux buffer to the resolved state. We assume that gfx7 behaves the
1289 * same. Use an ambiguate to match driver expectations.
1290 */
1291 for (int l = 0; l < num_layers; l++)
1292 blorp_ccs_ambiguate(batch, surf, level, start_layer + l);
1293 }
1294 }
1295
1296 static nir_def *
blorp_nir_bit(nir_builder * b,nir_def * src,unsigned bit)1297 blorp_nir_bit(nir_builder *b, nir_def *src, unsigned bit)
1298 {
1299 return nir_iand_imm(b, nir_ushr_imm(b, src, bit), 1);
1300 }
1301
1302 #pragma pack(push, 1)
1303 struct blorp_mcs_partial_resolve_key
1304 {
1305 struct blorp_base_key base;
1306 bool indirect_clear_color;
1307 bool int_format;
1308 uint32_t num_samples;
1309 };
1310 #pragma pack(pop)
1311
1312 static bool
blorp_params_get_mcs_partial_resolve_kernel(struct blorp_batch * batch,struct blorp_params * params)1313 blorp_params_get_mcs_partial_resolve_kernel(struct blorp_batch *batch,
1314 struct blorp_params *params)
1315 {
1316 struct blorp_context *blorp = batch->blorp;
1317 const struct blorp_mcs_partial_resolve_key blorp_key = {
1318 .base = BLORP_BASE_KEY_INIT(BLORP_SHADER_TYPE_MCS_PARTIAL_RESOLVE),
1319 .indirect_clear_color = params->dst.clear_color_addr.buffer != NULL,
1320 .int_format = isl_format_has_int_channel(params->dst.view.format),
1321 .num_samples = params->num_samples,
1322 };
1323
1324 if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
1325 ¶ms->wm_prog_kernel, ¶ms->wm_prog_data))
1326 return true;
1327
1328 void *mem_ctx = ralloc_context(NULL);
1329
1330 nir_builder b;
1331 blorp_nir_init_shader(&b, blorp, mem_ctx, MESA_SHADER_FRAGMENT,
1332 blorp_shader_type_to_name(blorp_key.base.shader_type));
1333
1334 nir_variable *v_color =
1335 BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type());
1336
1337 nir_variable *frag_color =
1338 nir_variable_create(b.shader, nir_var_shader_out,
1339 glsl_vec4_type(), "gl_FragColor");
1340 frag_color->data.location = FRAG_RESULT_COLOR;
1341
1342 /* Do an MCS fetch and check if it is equal to the magic clear value */
1343 nir_def *mcs =
1344 blorp_nir_txf_ms_mcs(&b, nir_f2i32(&b, nir_load_frag_coord(&b)),
1345 nir_load_layer_id(&b));
1346 nir_def *is_clear =
1347 blorp_nir_mcs_is_clear_color(&b, mcs, blorp_key.num_samples);
1348
1349 /* If we aren't the clear value, discard. */
1350 nir_discard_if(&b, nir_inot(&b, is_clear));
1351
1352 nir_def *clear_color = nir_load_var(&b, v_color);
1353 if (blorp_key.indirect_clear_color && blorp->isl_dev->info->ver <= 8) {
1354 /* Gfx7-8 clear colors are stored as single 0/1 bits */
1355 clear_color = nir_vec4(&b, blorp_nir_bit(&b, clear_color, 31),
1356 blorp_nir_bit(&b, clear_color, 30),
1357 blorp_nir_bit(&b, clear_color, 29),
1358 blorp_nir_bit(&b, clear_color, 28));
1359
1360 if (!blorp_key.int_format)
1361 clear_color = nir_i2f32(&b, clear_color);
1362 }
1363 nir_store_var(&b, frag_color, clear_color, 0xf);
1364
1365 const bool multisample_fbo = true;
1366 const struct blorp_program p =
1367 blorp_compile_fs(blorp, mem_ctx, b.shader, multisample_fbo, false, false);
1368
1369 bool result =
1370 blorp->upload_shader(batch, MESA_SHADER_FRAGMENT,
1371 &blorp_key, sizeof(blorp_key),
1372 p.kernel, p.kernel_size,
1373 p.prog_data, p.prog_data_size,
1374 ¶ms->wm_prog_kernel, ¶ms->wm_prog_data);
1375
1376 ralloc_free(mem_ctx);
1377 return result;
1378 }
1379
1380 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)1381 blorp_mcs_partial_resolve(struct blorp_batch *batch,
1382 struct blorp_surf *surf,
1383 enum isl_format format,
1384 uint32_t start_layer, uint32_t num_layers)
1385 {
1386 struct blorp_params params;
1387 blorp_params_init(¶ms);
1388 params.op = BLORP_OP_MCS_PARTIAL_RESOLVE;
1389
1390 assert(batch->blorp->isl_dev->info->ver >= 7);
1391
1392 params.x0 = 0;
1393 params.y0 = 0;
1394 params.x1 = surf->surf->logical_level0_px.width;
1395 params.y1 = surf->surf->logical_level0_px.height;
1396
1397 blorp_surface_info_init(batch, ¶ms.src, surf, 0,
1398 start_layer, format, false);
1399 blorp_surface_info_init(batch, ¶ms.dst, surf, 0,
1400 start_layer, format, true);
1401
1402 params.num_samples = params.dst.surf.samples;
1403 params.num_layers = num_layers;
1404 params.dst_clear_color_as_input = surf->clear_color_addr.buffer != NULL;
1405
1406 memcpy(¶ms.wm_inputs.clear_color,
1407 surf->clear_color.f32, sizeof(float) * 4);
1408
1409 if (!blorp_params_get_mcs_partial_resolve_kernel(batch, ¶ms))
1410 return;
1411
1412 batch->blorp->exec(batch, ¶ms);
1413 }
1414
1415 static uint64_t
get_mcs_ambiguate_pixel(int sample_count)1416 get_mcs_ambiguate_pixel(int sample_count)
1417 {
1418 /* See the Broadwell PRM, Volume 5 "Memory Views", Section "Compressed
1419 * Multisample Surfaces".
1420 */
1421 assert(sample_count >= 2);
1422 assert(sample_count <= 16);
1423
1424 /* Each MCS element contains an array of sample slice (SS) elements. The
1425 * size of this array matches the sample count.
1426 */
1427 const int num_ss_entries = sample_count;
1428
1429 /* The width of each SS entry is just large enough to index every slice. */
1430 const int ss_entry_size_b = util_logbase2(num_ss_entries);
1431
1432 /* The encoding for "ambiguated" has each sample slice value storing its
1433 * index (e.g., SS[0] = 0, SS[1] = 1, etc.). The values are stored in
1434 * little endian order. The unused bits are defined as either Reserved or
1435 * Reserved (MBZ). We choose to interpret both as MBZ.
1436 */
1437 uint64_t ambiguate_pixel = 0;
1438 for (uint64_t entry = 0; entry < num_ss_entries; entry++)
1439 ambiguate_pixel |= entry << (entry * ss_entry_size_b);
1440
1441 return ambiguate_pixel;
1442 }
1443
1444 /** Clear an MCS to the "uncompressed" state
1445 *
1446 * This pass is the MCS equivalent of a "HiZ resolve". It sets the MCS values
1447 * for a given layer of a surface to a sample-count dependent value which is
1448 * the "uncompressed" state which tells the sampler to go look at the main
1449 * surface.
1450 */
1451 void
blorp_mcs_ambiguate(struct blorp_batch * batch,struct blorp_surf * surf,uint32_t start_layer,uint32_t num_layers)1452 blorp_mcs_ambiguate(struct blorp_batch *batch,
1453 struct blorp_surf *surf,
1454 uint32_t start_layer, uint32_t num_layers)
1455 {
1456 assert((batch->flags & BLORP_BATCH_USE_COMPUTE) == 0);
1457
1458 struct blorp_params params;
1459 blorp_params_init(¶ms);
1460 params.op = BLORP_OP_MCS_AMBIGUATE;
1461
1462 assert(ISL_GFX_VER(batch->blorp->isl_dev) >= 7);
1463
1464 enum isl_format renderable_format;
1465 switch (isl_format_get_layout(surf->aux_surf->format)->bpb) {
1466 case 8: renderable_format = ISL_FORMAT_R8_UINT; break;
1467 case 32: renderable_format = ISL_FORMAT_R32_UINT; break;
1468 case 64: renderable_format = ISL_FORMAT_R32G32_UINT; break;
1469 default: unreachable("Unexpected MCS format size for ambiguate");
1470 }
1471
1472 /* From Bspec 57340 (r59562):
1473 *
1474 * To the calculated MCS size we add 4kb page to be used as clear value
1475 * storage.
1476 *
1477 * and
1478 *
1479 * When allocating memory, MCS buffer size is extended by 4KB over its
1480 * original calculated size. First 4KB page of the MCS is reserved for
1481 * internal HW usage.
1482 *
1483 * We shift aux buffer's start address by 4KB, accordingly.
1484 */
1485 struct blorp_address aux_addr = surf->aux_addr;
1486 if (ISL_GFX_VER(batch->blorp->isl_dev) >= 20)
1487 aux_addr.offset += 4096;
1488
1489 params.dst = (struct blorp_surface_info) {
1490 .enabled = true,
1491 .surf = *surf->aux_surf,
1492 .addr = aux_addr,
1493 .view = {
1494 .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT,
1495 .format = renderable_format,
1496 .base_level = 0,
1497 .base_array_layer = start_layer,
1498 .levels = 1,
1499 .array_len = num_layers,
1500 .swizzle = ISL_SWIZZLE_IDENTITY,
1501 },
1502 };
1503
1504 params.x0 = 0;
1505 params.y0 = 0;
1506 params.x1 = params.dst.surf.logical_level0_px.width;
1507 params.y1 = params.dst.surf.logical_level0_px.height;
1508 params.num_layers = params.dst.view.array_len;
1509
1510 const uint64_t pixel = get_mcs_ambiguate_pixel(surf->surf->samples);
1511 params.wm_inputs.clear_color[0] = pixel & 0xFFFFFFFF;
1512 params.wm_inputs.clear_color[1] = pixel >> 32;
1513
1514 if (!blorp_params_get_clear_kernel(batch, ¶ms, false, true, false))
1515 return;
1516
1517 batch->blorp->exec(batch, ¶ms);
1518 }
1519
1520 /** Clear a CCS to the "uncompressed" state
1521 *
1522 * This pass is the CCS equivalent of a "HiZ resolve". It sets the CCS values
1523 * for a given layer/level of a surface to 0x0 which is the "uncompressed"
1524 * state which tells the sampler to go look at the main surface.
1525 */
1526 void
blorp_ccs_ambiguate(struct blorp_batch * batch,struct blorp_surf * surf,uint32_t level,uint32_t layer)1527 blorp_ccs_ambiguate(struct blorp_batch *batch,
1528 struct blorp_surf *surf,
1529 uint32_t level, uint32_t layer)
1530 {
1531 assert((batch->flags & BLORP_BATCH_USE_COMPUTE) == 0);
1532
1533 if (ISL_GFX_VER(batch->blorp->isl_dev) >= 10) {
1534 /* On gfx10 and above, we have a hardware resolve op for this */
1535 return blorp_ccs_resolve(batch, surf, level, layer, 1,
1536 surf->surf->format, ISL_AUX_OP_AMBIGUATE);
1537 }
1538
1539 struct blorp_params params;
1540 blorp_params_init(¶ms);
1541 params.op = BLORP_OP_CCS_AMBIGUATE;
1542
1543 assert(ISL_GFX_VER(batch->blorp->isl_dev) >= 7);
1544
1545 const struct isl_format_layout *aux_fmtl =
1546 isl_format_get_layout(surf->aux_surf->format);
1547 assert(aux_fmtl->txc == ISL_TXC_CCS);
1548
1549 params.dst = (struct blorp_surface_info) {
1550 .enabled = true,
1551 .addr = surf->aux_addr,
1552 .view = {
1553 .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT,
1554 .format = ISL_FORMAT_R32G32B32A32_UINT,
1555 .base_level = 0,
1556 .base_array_layer = 0,
1557 .levels = 1,
1558 .array_len = 1,
1559 .swizzle = ISL_SWIZZLE_IDENTITY,
1560 },
1561 };
1562
1563 uint32_t z = 0;
1564 if (surf->surf->dim == ISL_SURF_DIM_3D) {
1565 z = layer;
1566 layer = 0;
1567 }
1568
1569 uint64_t offset_B;
1570 uint32_t x_offset_el, y_offset_el;
1571 isl_surf_get_image_offset_B_tile_el(surf->aux_surf, level, layer, z,
1572 &offset_B, &x_offset_el, &y_offset_el);
1573 params.dst.addr.offset += offset_B;
1574
1575 const uint32_t width_px =
1576 u_minify(surf->aux_surf->logical_level0_px.width, level);
1577 const uint32_t height_px =
1578 u_minify(surf->aux_surf->logical_level0_px.height, level);
1579 const uint32_t width_el = DIV_ROUND_UP(width_px, aux_fmtl->bw);
1580 const uint32_t height_el = DIV_ROUND_UP(height_px, aux_fmtl->bh);
1581
1582 struct isl_tile_info ccs_tile_info;
1583 isl_surf_get_tile_info(surf->aux_surf, &ccs_tile_info);
1584
1585 /* We're going to map it as a regular RGBA32_UINT surface. We need to
1586 * downscale a good deal. We start by computing the area on the CCS to
1587 * clear in units of Y-tiled cache lines.
1588 */
1589 uint32_t x_offset_cl, y_offset_cl, width_cl, height_cl;
1590 if (ISL_GFX_VER(batch->blorp->isl_dev) >= 8) {
1591 /* From the Sky Lake PRM Vol. 12 in the section on planes:
1592 *
1593 * "The Color Control Surface (CCS) contains the compression status
1594 * of the cache-line pairs. The compression state of the cache-line
1595 * pair is specified by 2 bits in the CCS. Each CCS cache-line
1596 * represents an area on the main surface of 16x16 sets of 128 byte
1597 * Y-tiled cache-line-pairs. CCS is always Y tiled."
1598 *
1599 * Each 2-bit surface element in the CCS corresponds to a single
1600 * cache-line pair in the main surface. This means that 16x16 el block
1601 * in the CCS maps to a Y-tiled cache line. Fortunately, CCS layouts
1602 * are calculated with a very large alignment so we can round up to a
1603 * whole cache line without worrying about overdraw.
1604 */
1605
1606 /* On Broadwell and above, a CCS tile is the same as a Y tile when
1607 * viewed at the cache-line granularity. Fortunately, the horizontal
1608 * and vertical alignment requirements of the CCS are such that we can
1609 * align to an entire cache line without worrying about crossing over
1610 * from one LOD to another.
1611 */
1612 const uint32_t x_el_per_cl = ccs_tile_info.logical_extent_el.w / 8;
1613 const uint32_t y_el_per_cl = ccs_tile_info.logical_extent_el.h / 8;
1614 assert(surf->aux_surf->image_alignment_el.w % x_el_per_cl == 0);
1615 assert(surf->aux_surf->image_alignment_el.h % y_el_per_cl == 0);
1616
1617 assert(x_offset_el % x_el_per_cl == 0);
1618 assert(y_offset_el % y_el_per_cl == 0);
1619 x_offset_cl = x_offset_el / x_el_per_cl;
1620 y_offset_cl = y_offset_el / y_el_per_cl;
1621 width_cl = DIV_ROUND_UP(width_el, x_el_per_cl);
1622 height_cl = DIV_ROUND_UP(height_el, y_el_per_cl);
1623 } else {
1624 /* On gfx7, the CCS tiling is not so nice. However, there we are
1625 * guaranteed that we only have a single level and slice so we don't
1626 * have to worry about it and can just align to a whole tile.
1627 */
1628 assert(surf->aux_surf->logical_level0_px.depth == 1);
1629 assert(surf->aux_surf->logical_level0_px.array_len == 1);
1630 assert(x_offset_el == 0 && y_offset_el == 0);
1631 const uint32_t width_tl =
1632 DIV_ROUND_UP(width_el, ccs_tile_info.logical_extent_el.w);
1633 const uint32_t height_tl =
1634 DIV_ROUND_UP(height_el, ccs_tile_info.logical_extent_el.h);
1635 x_offset_cl = 0;
1636 y_offset_cl = 0;
1637 width_cl = width_tl * 8;
1638 height_cl = height_tl * 8;
1639 }
1640
1641 /* We're going to use a RGBA32 format so as to write data as quickly as
1642 * possible. A y-tiled cache line will then be 1x4 px.
1643 */
1644 const uint32_t x_offset_rgba_px = x_offset_cl;
1645 const uint32_t y_offset_rgba_px = y_offset_cl * 4;
1646 const uint32_t width_rgba_px = width_cl;
1647 const uint32_t height_rgba_px = height_cl * 4;
1648
1649 ASSERTED bool ok =
1650 isl_surf_init(batch->blorp->isl_dev, ¶ms.dst.surf,
1651 .dim = ISL_SURF_DIM_2D,
1652 .format = ISL_FORMAT_R32G32B32A32_UINT,
1653 .width = width_rgba_px + x_offset_rgba_px,
1654 .height = height_rgba_px + y_offset_rgba_px,
1655 .depth = 1,
1656 .levels = 1,
1657 .array_len = 1,
1658 .samples = 1,
1659 .row_pitch_B = surf->aux_surf->row_pitch_B,
1660 .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT,
1661 .tiling_flags = ISL_TILING_Y0_BIT);
1662 assert(ok);
1663
1664 params.x0 = x_offset_rgba_px;
1665 params.y0 = y_offset_rgba_px;
1666 params.x1 = x_offset_rgba_px + width_rgba_px;
1667 params.y1 = y_offset_rgba_px + height_rgba_px;
1668
1669 /* A CCS value of 0 means "uncompressed." */
1670 memset(¶ms.wm_inputs.clear_color, 0,
1671 sizeof(params.wm_inputs.clear_color));
1672
1673 if (!blorp_params_get_clear_kernel(batch, ¶ms, false, true, false))
1674 return;
1675
1676 batch->blorp->exec(batch, ¶ms);
1677 }
1678