1 /*
2 * Copyright © 2017 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 shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23 #include <stdio.h>
24 #include <errno.h>
25 #include "pipe/p_defines.h"
26 #include "pipe/p_state.h"
27 #include "pipe/p_context.h"
28 #include "pipe/p_screen.h"
29 #include "util/u_inlines.h"
30 #include "util/format/u_format.h"
31 #include "util/u_upload_mgr.h"
32 #include "util/ralloc.h"
33 #include "iris_context.h"
34 #include "iris_resource.h"
35 #include "iris_screen.h"
36 #include "intel/compiler/brw_compiler.h"
37
38 static bool
iris_is_color_fast_clear_compatible(struct iris_context * ice,enum isl_format format,const union isl_color_value color)39 iris_is_color_fast_clear_compatible(struct iris_context *ice,
40 enum isl_format format,
41 const union isl_color_value color)
42 {
43 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
44 const struct intel_device_info *devinfo = &batch->screen->devinfo;
45
46 if (isl_format_has_int_channel(format)) {
47 perf_debug(&ice->dbg, "Integer fast clear not enabled for %s\n",
48 isl_format_get_name(format));
49 return false;
50 }
51
52 for (int i = 0; i < 4; i++) {
53 if (!isl_format_has_color_component(format, i)) {
54 continue;
55 }
56
57 if (devinfo->ver < 9 &&
58 color.f32[i] != 0.0f && color.f32[i] != 1.0f) {
59 return false;
60 }
61 }
62
63 return true;
64 }
65
66 static bool
can_fast_clear_color(struct iris_context * ice,struct pipe_resource * p_res,unsigned level,const struct pipe_box * box,bool render_condition_enabled,enum isl_format render_format,union isl_color_value color)67 can_fast_clear_color(struct iris_context *ice,
68 struct pipe_resource *p_res,
69 unsigned level,
70 const struct pipe_box *box,
71 bool render_condition_enabled,
72 enum isl_format render_format,
73 union isl_color_value color)
74 {
75 struct iris_resource *res = (void *) p_res;
76
77 if (INTEL_DEBUG(DEBUG_NO_FAST_CLEAR))
78 return false;
79
80 if (!isl_aux_usage_has_fast_clears(res->aux.usage))
81 return false;
82
83 /* Check for partial clear */
84 if (box->x > 0 || box->y > 0 ||
85 box->width < minify(p_res->width0, level) ||
86 box->height < minify(p_res->height0, level)) {
87 return false;
88 }
89
90 /* Avoid conditional fast clears to maintain correct tracking of the aux
91 * state (see iris_resource_finish_write for more info). Note that partial
92 * fast clears (if they existed) would not pose a problem with conditional
93 * rendering.
94 */
95 if (render_condition_enabled &&
96 ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) {
97 return false;
98 }
99
100 /* Disable sRGB fast-clears for non-0/1 color values. For texturing and
101 * draw calls, HW expects the clear color to be in two different color
102 * spaces after sRGB fast-clears - sRGB in the former and linear in the
103 * latter. By limiting the allowable values to 0/1, both color space
104 * requirements are satisfied.
105 */
106 if (isl_format_is_srgb(render_format) &&
107 !isl_color_value_is_zero_one(color, render_format)) {
108 return false;
109 }
110
111 /* We store clear colors as floats or uints as needed. If there are
112 * texture views in play, the formats will not properly be respected
113 * during resolves because the resolve operations only know about the
114 * resource and not the renderbuffer.
115 */
116 if (!iris_render_formats_color_compatible(render_format, res->surf.format,
117 color, false)) {
118 return false;
119 }
120
121 if (!iris_is_color_fast_clear_compatible(ice, res->surf.format, color))
122 return false;
123
124 /* The RENDER_SURFACE_STATE page for TGL says:
125 *
126 * For an 8 bpp surface with NUM_MULTISAMPLES = 1, Surface Width not
127 * multiple of 64 pixels and more than 1 mip level in the view, Fast Clear
128 * is not supported when AUX_CCS_E is set in this field.
129 *
130 * The granularity of a fast-clear is one CCS element. For an 8 bpp primary
131 * surface, this maps to 32px x 4rows. Due to the surface layout parameters,
132 * if LOD0's width isn't a multiple of 64px, LOD1 and LOD2+ will share CCS
133 * elements. Assuming LOD2 exists, don't fast-clear any level above LOD0
134 * to avoid stomping on other LODs.
135 */
136 if (level > 0 && util_format_get_blocksizebits(p_res->format) == 8 &&
137 res->aux.usage == ISL_AUX_USAGE_GFX12_CCS_E && p_res->width0 % 64) {
138 return false;
139 }
140
141 return true;
142 }
143
144 static union isl_color_value
convert_clear_color(enum pipe_format format,const union pipe_color_union * color)145 convert_clear_color(enum pipe_format format,
146 const union pipe_color_union *color)
147 {
148 /* pipe_color_union and isl_color_value are interchangeable */
149 union isl_color_value override_color = *(union isl_color_value *)color;
150
151 const struct util_format_description *desc =
152 util_format_description(format);
153 unsigned colormask = util_format_colormask(desc);
154
155 if (util_format_is_intensity(format) ||
156 util_format_is_luminance(format)) {
157 override_color.u32[1] = override_color.u32[0];
158 override_color.u32[2] = override_color.u32[0];
159 if (util_format_is_intensity(format))
160 override_color.u32[3] = override_color.u32[0];
161 } else {
162 for (int chan = 0; chan < 3; chan++) {
163 if (!(colormask & (1 << chan)))
164 override_color.u32[chan] = 0;
165 }
166 }
167
168 if (util_format_is_unorm(format)) {
169 for (int i = 0; i < 4; i++)
170 override_color.f32[i] = SATURATE(override_color.f32[i]);
171 } else if (util_format_is_snorm(format)) {
172 for (int i = 0; i < 4; i++)
173 override_color.f32[i] = CLAMP(override_color.f32[i], -1.0f, 1.0f);
174 } else if (util_format_is_pure_uint(format)) {
175 for (int i = 0; i < 4; i++) {
176 unsigned bits = util_format_get_component_bits(
177 format, UTIL_FORMAT_COLORSPACE_RGB, i);
178 if (bits < 32) {
179 uint32_t max = (1u << bits) - 1;
180 override_color.u32[i] = MIN2(override_color.u32[i], max);
181 }
182 }
183 } else if (util_format_is_pure_sint(format)) {
184 for (int i = 0; i < 4; i++) {
185 unsigned bits = util_format_get_component_bits(
186 format, UTIL_FORMAT_COLORSPACE_RGB, i);
187 if (bits > 0 && bits < 32) {
188 int32_t max = u_intN_max(bits);
189 int32_t min = u_intN_min(bits);
190 override_color.i32[i] = CLAMP(override_color.i32[i], min, max);
191 }
192 }
193 } else if (format == PIPE_FORMAT_R11G11B10_FLOAT ||
194 format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
195 /* these packed float formats only store unsigned values */
196 for (int i = 0; i < 4; i++)
197 override_color.f32[i] = MAX2(override_color.f32[i], 0.0f);
198 }
199
200 if (!(colormask & 1 << 3)) {
201 if (util_format_is_pure_integer(format))
202 override_color.u32[3] = 1;
203 else
204 override_color.f32[3] = 1.0f;
205 }
206
207 return override_color;
208 }
209
210 static void
fast_clear_color(struct iris_context * ice,struct iris_resource * res,unsigned level,const struct pipe_box * box,enum isl_format format,union isl_color_value color)211 fast_clear_color(struct iris_context *ice,
212 struct iris_resource *res,
213 unsigned level,
214 const struct pipe_box *box,
215 enum isl_format format,
216 union isl_color_value color)
217 {
218 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
219 struct pipe_resource *p_res = (void *) res;
220
221 bool color_changed = res->aux.clear_color_unknown ||
222 memcmp(&res->aux.clear_color, &color, sizeof(color)) != 0;
223
224 if (color_changed) {
225 /* If we are clearing to a new clear value, we need to resolve fast
226 * clears from other levels/layers first, since we can't have different
227 * levels/layers with different fast clear colors.
228 */
229 for (unsigned res_lvl = 0; res_lvl < res->surf.levels; res_lvl++) {
230 const unsigned level_layers =
231 iris_get_num_logical_layers(res, res_lvl);
232 for (unsigned layer = 0; layer < level_layers; layer++) {
233 if (res_lvl == level &&
234 layer >= box->z &&
235 layer < box->z + box->depth) {
236 /* We're going to clear this layer anyway. Leave it alone. */
237 continue;
238 }
239
240 enum isl_aux_state aux_state =
241 iris_resource_get_aux_state(res, res_lvl, layer);
242
243 if (aux_state != ISL_AUX_STATE_CLEAR &&
244 aux_state != ISL_AUX_STATE_PARTIAL_CLEAR &&
245 aux_state != ISL_AUX_STATE_COMPRESSED_CLEAR) {
246 /* This slice doesn't have any fast-cleared bits. */
247 continue;
248 }
249
250 /* If we got here, then the level may have fast-clear bits that use
251 * the old clear value. We need to do a color resolve to get rid
252 * of their use of the clear color before we can change it.
253 * Fortunately, few applications ever change their clear color at
254 * different levels/layers, so this shouldn't happen often.
255 */
256 iris_resource_prepare_access(ice, res,
257 res_lvl, 1, layer, 1,
258 res->aux.usage,
259 false);
260 if (res->aux.clear_color_unknown) {
261 perf_debug(&ice->dbg,
262 "Resolving resource (%p) level %d, layer %d: color changing from "
263 "(unknown) to (%0.2f, %0.2f, %0.2f, %0.2f)\n",
264 res, res_lvl, layer,
265 color.f32[0], color.f32[1], color.f32[2], color.f32[3]);
266 } else {
267 perf_debug(&ice->dbg,
268 "Resolving resource (%p) level %d, layer %d: color changing from "
269 "(%0.2f, %0.2f, %0.2f, %0.2f) to "
270 "(%0.2f, %0.2f, %0.2f, %0.2f)\n",
271 res, res_lvl, layer,
272 res->aux.clear_color.f32[0],
273 res->aux.clear_color.f32[1],
274 res->aux.clear_color.f32[2],
275 res->aux.clear_color.f32[3],
276 color.f32[0], color.f32[1], color.f32[2], color.f32[3]);
277 }
278 }
279 }
280 }
281
282 iris_resource_set_clear_color(ice, res, color);
283
284 /* If the buffer is already in ISL_AUX_STATE_CLEAR, and the color hasn't
285 * changed, the clear is redundant and can be skipped.
286 */
287 const enum isl_aux_state aux_state =
288 iris_resource_get_aux_state(res, level, box->z);
289 if (!color_changed && box->depth == 1 && aux_state == ISL_AUX_STATE_CLEAR)
290 return;
291
292 /* Ivybridge PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)":
293 *
294 * "Any transition from any value in {Clear, Render, Resolve} to a
295 * different value in {Clear, Render, Resolve} requires end of pipe
296 * synchronization."
297 *
298 * In other words, fast clear ops are not properly synchronized with
299 * other drawing. We need to use a PIPE_CONTROL to ensure that the
300 * contents of the previous draw hit the render target before we resolve
301 * and again afterwards to ensure that the resolve is complete before we
302 * do any more regular drawing.
303 */
304 iris_emit_end_of_pipe_sync(batch,
305 "fast clear: pre-flush",
306 PIPE_CONTROL_RENDER_TARGET_FLUSH |
307 PIPE_CONTROL_TILE_CACHE_FLUSH);
308
309 iris_batch_sync_region_start(batch);
310
311 /* If we reach this point, we need to fast clear to change the state to
312 * ISL_AUX_STATE_CLEAR, or to update the fast clear color (or both).
313 */
314 enum blorp_batch_flags blorp_flags = 0;
315 blorp_flags |= color_changed ? 0 : BLORP_BATCH_NO_UPDATE_CLEAR_COLOR;
316
317 struct blorp_batch blorp_batch;
318 blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
319
320 struct blorp_surf surf;
321 iris_blorp_surf_for_resource(&batch->screen->isl_dev, &surf,
322 p_res, res->aux.usage, level, true);
323
324 blorp_fast_clear(&blorp_batch, &surf, format, ISL_SWIZZLE_IDENTITY,
325 level, box->z, box->depth,
326 box->x, box->y, box->x + box->width,
327 box->y + box->height);
328 blorp_batch_finish(&blorp_batch);
329 iris_emit_end_of_pipe_sync(batch,
330 "fast clear: post flush",
331 PIPE_CONTROL_RENDER_TARGET_FLUSH);
332 iris_batch_sync_region_end(batch);
333
334 iris_resource_set_aux_state(ice, res, level, box->z,
335 box->depth, ISL_AUX_STATE_CLEAR);
336 ice->state.dirty |= IRIS_DIRTY_RENDER_BUFFER;
337 ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_BINDINGS;
338 return;
339 }
340
341 static void
clear_color(struct iris_context * ice,struct pipe_resource * p_res,unsigned level,const struct pipe_box * box,bool render_condition_enabled,enum isl_format format,struct isl_swizzle swizzle,union isl_color_value color)342 clear_color(struct iris_context *ice,
343 struct pipe_resource *p_res,
344 unsigned level,
345 const struct pipe_box *box,
346 bool render_condition_enabled,
347 enum isl_format format,
348 struct isl_swizzle swizzle,
349 union isl_color_value color)
350 {
351 struct iris_resource *res = (void *) p_res;
352
353 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
354 const struct intel_device_info *devinfo = &batch->screen->devinfo;
355 enum blorp_batch_flags blorp_flags = 0;
356
357 if (render_condition_enabled) {
358 if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
359 return;
360
361 if (ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT)
362 blorp_flags |= BLORP_BATCH_PREDICATE_ENABLE;
363 }
364
365 if (p_res->target == PIPE_BUFFER)
366 util_range_add(&res->base.b, &res->valid_buffer_range, box->x, box->x + box->width);
367
368 iris_batch_maybe_flush(batch, 1500);
369
370 bool can_fast_clear = can_fast_clear_color(ice, p_res, level, box,
371 render_condition_enabled,
372 format, color);
373 if (can_fast_clear) {
374 fast_clear_color(ice, res, level, box, format, color);
375 return;
376 }
377
378 enum isl_aux_usage aux_usage =
379 iris_resource_render_aux_usage(ice, res, level, format, false);
380
381 iris_resource_prepare_render(ice, res, level, box->z, box->depth,
382 aux_usage);
383 iris_emit_buffer_barrier_for(batch, res->bo, IRIS_DOMAIN_RENDER_WRITE);
384
385 struct blorp_surf surf;
386 iris_blorp_surf_for_resource(&batch->screen->isl_dev, &surf,
387 p_res, aux_usage, level, true);
388
389 iris_batch_sync_region_start(batch);
390
391 struct blorp_batch blorp_batch;
392 blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
393
394 if (!isl_format_supports_rendering(devinfo, format) &&
395 isl_format_is_rgbx(format))
396 format = isl_format_rgbx_to_rgba(format);
397
398 blorp_clear(&blorp_batch, &surf, format, swizzle,
399 level, box->z, box->depth, box->x, box->y,
400 box->x + box->width, box->y + box->height,
401 color, 0 /* color_write_disable */);
402
403 blorp_batch_finish(&blorp_batch);
404 iris_batch_sync_region_end(batch);
405
406 iris_flush_and_dirty_for_history(ice, batch, res,
407 PIPE_CONTROL_RENDER_TARGET_FLUSH,
408 "cache history: post color clear");
409
410 iris_resource_finish_render(ice, res, level,
411 box->z, box->depth, aux_usage);
412 }
413
414 static bool
can_fast_clear_depth(struct iris_context * ice,struct iris_resource * res,unsigned level,const struct pipe_box * box,bool render_condition_enabled,float depth)415 can_fast_clear_depth(struct iris_context *ice,
416 struct iris_resource *res,
417 unsigned level,
418 const struct pipe_box *box,
419 bool render_condition_enabled,
420 float depth)
421 {
422 struct pipe_resource *p_res = (void *) res;
423 struct pipe_context *ctx = (void *) ice;
424 struct iris_screen *screen = (void *) ctx->screen;
425 const struct intel_device_info *devinfo = &screen->devinfo;
426
427 if (INTEL_DEBUG(DEBUG_NO_FAST_CLEAR))
428 return false;
429
430 /* Check for partial clears */
431 if (box->x > 0 || box->y > 0 ||
432 box->width < u_minify(p_res->width0, level) ||
433 box->height < u_minify(p_res->height0, level)) {
434 return false;
435 }
436
437 /* Avoid conditional fast clears to maintain correct tracking of the aux
438 * state (see iris_resource_finish_write for more info). Note that partial
439 * fast clears would not pose a problem with conditional rendering.
440 */
441 if (render_condition_enabled &&
442 ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) {
443 return false;
444 }
445
446 if (!iris_resource_level_has_hiz(res, level))
447 return false;
448
449 if (!blorp_can_hiz_clear_depth(devinfo, &res->surf, res->aux.usage,
450 level, box->z, box->x, box->y,
451 box->x + box->width,
452 box->y + box->height)) {
453 return false;
454 }
455
456 return true;
457 }
458
459 static void
fast_clear_depth(struct iris_context * ice,struct iris_resource * res,unsigned level,const struct pipe_box * box,float depth)460 fast_clear_depth(struct iris_context *ice,
461 struct iris_resource *res,
462 unsigned level,
463 const struct pipe_box *box,
464 float depth)
465 {
466 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
467
468 bool update_clear_depth = false;
469
470 /* If we're clearing to a new clear value, then we need to resolve any clear
471 * flags out of the HiZ buffer into the real depth buffer.
472 */
473 if (res->aux.clear_color_unknown || res->aux.clear_color.f32[0] != depth) {
474 for (unsigned res_level = 0; res_level < res->surf.levels; res_level++) {
475 const unsigned level_layers =
476 iris_get_num_logical_layers(res, res_level);
477 for (unsigned layer = 0; layer < level_layers; layer++) {
478 if (res_level == level &&
479 layer >= box->z &&
480 layer < box->z + box->depth) {
481 /* We're going to clear this layer anyway. Leave it alone. */
482 continue;
483 }
484
485 enum isl_aux_state aux_state =
486 iris_resource_get_aux_state(res, res_level, layer);
487
488 if (aux_state != ISL_AUX_STATE_CLEAR &&
489 aux_state != ISL_AUX_STATE_COMPRESSED_CLEAR) {
490 /* This slice doesn't have any fast-cleared bits. */
491 continue;
492 }
493
494 /* If we got here, then the level may have fast-clear bits that
495 * use the old clear value. We need to do a depth resolve to get
496 * rid of their use of the clear value before we can change it.
497 * Fortunately, few applications ever change their depth clear
498 * value so this shouldn't happen often.
499 */
500 iris_hiz_exec(ice, batch, res, res_level, layer, 1,
501 ISL_AUX_OP_FULL_RESOLVE, false);
502 iris_resource_set_aux_state(ice, res, res_level, layer, 1,
503 ISL_AUX_STATE_RESOLVED);
504 }
505 }
506 const union isl_color_value clear_value = { .f32 = {depth, } };
507 iris_resource_set_clear_color(ice, res, clear_value);
508 update_clear_depth = true;
509 }
510
511 if (res->aux.usage == ISL_AUX_USAGE_HIZ_CCS_WT) {
512 /* From Bspec 47010 (Depth Buffer Clear):
513 *
514 * Since the fast clear cycles to CCS are not cached in TileCache,
515 * any previous depth buffer writes to overlapping pixels must be
516 * flushed out of TileCache before a succeeding Depth Buffer Clear.
517 * This restriction only applies to Depth Buffer with write-thru
518 * enabled, since fast clears to CCS only occur for write-thru mode.
519 *
520 * There may have been a write to this depth buffer. Flush it from the
521 * tile cache just in case.
522 */
523 iris_emit_pipe_control_flush(batch, "hiz_ccs_wt: before fast clear",
524 PIPE_CONTROL_DEPTH_CACHE_FLUSH |
525 PIPE_CONTROL_TILE_CACHE_FLUSH);
526 }
527
528 for (unsigned l = 0; l < box->depth; l++) {
529 enum isl_aux_state aux_state =
530 iris_resource_get_aux_state(res, level, box->z + l);
531 if (update_clear_depth || aux_state != ISL_AUX_STATE_CLEAR) {
532 if (aux_state == ISL_AUX_STATE_CLEAR) {
533 perf_debug(&ice->dbg, "Performing HiZ clear just to update the "
534 "depth clear value\n");
535 }
536 iris_hiz_exec(ice, batch, res, level,
537 box->z + l, 1, ISL_AUX_OP_FAST_CLEAR,
538 update_clear_depth);
539 }
540 }
541
542 iris_resource_set_aux_state(ice, res, level, box->z, box->depth,
543 ISL_AUX_STATE_CLEAR);
544 ice->state.dirty |= IRIS_DIRTY_DEPTH_BUFFER;
545 ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_BINDINGS;
546 }
547
548 static void
clear_depth_stencil(struct iris_context * ice,struct pipe_resource * p_res,unsigned level,const struct pipe_box * box,bool render_condition_enabled,bool clear_depth,bool clear_stencil,float depth,uint8_t stencil)549 clear_depth_stencil(struct iris_context *ice,
550 struct pipe_resource *p_res,
551 unsigned level,
552 const struct pipe_box *box,
553 bool render_condition_enabled,
554 bool clear_depth,
555 bool clear_stencil,
556 float depth,
557 uint8_t stencil)
558 {
559 struct iris_resource *res = (void *) p_res;
560
561 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
562 enum blorp_batch_flags blorp_flags = 0;
563
564 if (render_condition_enabled) {
565 if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
566 return;
567
568 if (ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT)
569 blorp_flags |= BLORP_BATCH_PREDICATE_ENABLE;
570 }
571
572 iris_batch_maybe_flush(batch, 1500);
573
574 struct iris_resource *z_res;
575 struct iris_resource *stencil_res;
576 struct blorp_surf z_surf;
577 struct blorp_surf stencil_surf;
578
579 iris_get_depth_stencil_resources(p_res, &z_res, &stencil_res);
580 if (z_res && clear_depth &&
581 can_fast_clear_depth(ice, z_res, level, box, render_condition_enabled,
582 depth)) {
583 fast_clear_depth(ice, z_res, level, box, depth);
584 iris_flush_and_dirty_for_history(ice, batch, res, 0,
585 "cache history: post fast Z clear");
586 clear_depth = false;
587 z_res = false;
588 }
589
590 /* At this point, we might have fast cleared the depth buffer. So if there's
591 * no stencil clear pending, return early.
592 */
593 if (!(clear_depth || (clear_stencil && stencil_res))) {
594 return;
595 }
596
597 if (clear_depth && z_res) {
598 const enum isl_aux_usage aux_usage =
599 iris_resource_render_aux_usage(ice, z_res, level, z_res->surf.format,
600 false);
601 iris_resource_prepare_render(ice, z_res, level, box->z, box->depth,
602 aux_usage);
603 iris_emit_buffer_barrier_for(batch, z_res->bo, IRIS_DOMAIN_DEPTH_WRITE);
604 iris_blorp_surf_for_resource(&batch->screen->isl_dev, &z_surf,
605 &z_res->base.b, aux_usage, level, true);
606 }
607
608 uint8_t stencil_mask = clear_stencil && stencil_res ? 0xff : 0;
609 if (stencil_mask) {
610 iris_resource_prepare_access(ice, stencil_res, level, 1, box->z,
611 box->depth, stencil_res->aux.usage, false);
612 iris_emit_buffer_barrier_for(batch, stencil_res->bo,
613 IRIS_DOMAIN_DEPTH_WRITE);
614 iris_blorp_surf_for_resource(&batch->screen->isl_dev,
615 &stencil_surf, &stencil_res->base.b,
616 stencil_res->aux.usage, level, true);
617 }
618
619 iris_batch_sync_region_start(batch);
620
621 struct blorp_batch blorp_batch;
622 blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
623
624 blorp_clear_depth_stencil(&blorp_batch, &z_surf, &stencil_surf,
625 level, box->z, box->depth,
626 box->x, box->y,
627 box->x + box->width,
628 box->y + box->height,
629 clear_depth && z_res, depth,
630 stencil_mask, stencil);
631
632 blorp_batch_finish(&blorp_batch);
633 iris_batch_sync_region_end(batch);
634
635 iris_flush_and_dirty_for_history(ice, batch, res, 0,
636 "cache history: post slow ZS clear");
637
638 if (clear_depth && z_res) {
639 iris_resource_finish_render(ice, z_res, level, box->z, box->depth,
640 z_surf.aux_usage);
641 }
642
643 if (stencil_mask) {
644 iris_resource_finish_write(ice, stencil_res, level, box->z, box->depth,
645 stencil_res->aux.usage);
646 }
647 }
648
649 /**
650 * The pipe->clear() driver hook.
651 *
652 * This clears buffers attached to the current draw framebuffer.
653 */
654 static void
iris_clear(struct pipe_context * ctx,unsigned buffers,const struct pipe_scissor_state * scissor_state,const union pipe_color_union * p_color,double depth,unsigned stencil)655 iris_clear(struct pipe_context *ctx,
656 unsigned buffers,
657 const struct pipe_scissor_state *scissor_state,
658 const union pipe_color_union *p_color,
659 double depth,
660 unsigned stencil)
661 {
662 struct iris_context *ice = (void *) ctx;
663 struct pipe_framebuffer_state *cso_fb = &ice->state.framebuffer;
664
665 assert(buffers != 0);
666
667 struct pipe_box box = {
668 .width = cso_fb->width,
669 .height = cso_fb->height,
670 };
671
672 if (scissor_state) {
673 box.x = scissor_state->minx;
674 box.y = scissor_state->miny;
675 box.width = MIN2(box.width, scissor_state->maxx - scissor_state->minx);
676 box.height = MIN2(box.height, scissor_state->maxy - scissor_state->miny);
677 }
678
679 if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
680 struct pipe_surface *psurf = cso_fb->zsbuf;
681
682 box.depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1;
683 box.z = psurf->u.tex.first_layer,
684 clear_depth_stencil(ice, psurf->texture, psurf->u.tex.level, &box, true,
685 buffers & PIPE_CLEAR_DEPTH,
686 buffers & PIPE_CLEAR_STENCIL,
687 depth, stencil);
688 }
689
690 if (buffers & PIPE_CLEAR_COLOR) {
691 for (unsigned i = 0; i < cso_fb->nr_cbufs; i++) {
692 if (buffers & (PIPE_CLEAR_COLOR0 << i)) {
693 struct pipe_surface *psurf = cso_fb->cbufs[i];
694 struct iris_surface *isurf = (void *) psurf;
695 box.depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1,
696 box.z = psurf->u.tex.first_layer,
697
698 clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
699 true, isurf->view.format, isurf->view.swizzle,
700 convert_clear_color(psurf->format, p_color));
701 }
702 }
703 }
704 }
705
706 /**
707 * The pipe->clear_texture() driver hook.
708 *
709 * This clears the given texture resource.
710 */
711 static void
iris_clear_texture(struct pipe_context * ctx,struct pipe_resource * p_res,unsigned level,const struct pipe_box * box,const void * data)712 iris_clear_texture(struct pipe_context *ctx,
713 struct pipe_resource *p_res,
714 unsigned level,
715 const struct pipe_box *box,
716 const void *data)
717 {
718 struct iris_context *ice = (void *) ctx;
719 struct iris_screen *screen = (void *) ctx->screen;
720 const struct intel_device_info *devinfo = &screen->devinfo;
721
722 if (util_format_is_depth_or_stencil(p_res->format)) {
723 const struct util_format_unpack_description *unpack =
724 util_format_unpack_description(p_res->format);
725
726 float depth = 0.0;
727 uint8_t stencil = 0;
728
729 if (unpack->unpack_z_float)
730 util_format_unpack_z_float(p_res->format, &depth, data, 1);
731
732 if (unpack->unpack_s_8uint)
733 util_format_unpack_s_8uint(p_res->format, &stencil, data, 1);
734
735 clear_depth_stencil(ice, p_res, level, box, true, true, true,
736 depth, stencil);
737 } else {
738 union isl_color_value color;
739 struct iris_resource *res = (void *) p_res;
740 enum isl_format format = res->surf.format;
741
742 if (!isl_format_supports_rendering(devinfo, format)) {
743 const struct isl_format_layout *fmtl = isl_format_get_layout(format);
744 // XXX: actually just get_copy_format_for_bpb from BLORP
745 // XXX: don't cut and paste this
746 switch (fmtl->bpb) {
747 case 8: format = ISL_FORMAT_R8_UINT; break;
748 case 16: format = ISL_FORMAT_R8G8_UINT; break;
749 case 24: format = ISL_FORMAT_R8G8B8_UINT; break;
750 case 32: format = ISL_FORMAT_R8G8B8A8_UINT; break;
751 case 48: format = ISL_FORMAT_R16G16B16_UINT; break;
752 case 64: format = ISL_FORMAT_R16G16B16A16_UINT; break;
753 case 96: format = ISL_FORMAT_R32G32B32_UINT; break;
754 case 128: format = ISL_FORMAT_R32G32B32A32_UINT; break;
755 default:
756 unreachable("Unknown format bpb");
757 }
758
759 /* No aux surfaces for non-renderable surfaces */
760 assert(res->aux.usage == ISL_AUX_USAGE_NONE);
761 }
762
763 isl_color_value_unpack(&color, format, data);
764
765 clear_color(ice, p_res, level, box, true, format,
766 ISL_SWIZZLE_IDENTITY, color);
767 }
768 }
769
770 /**
771 * The pipe->clear_render_target() driver hook.
772 *
773 * This clears the given render target surface.
774 */
775 static void
iris_clear_render_target(struct pipe_context * ctx,struct pipe_surface * psurf,const union pipe_color_union * p_color,unsigned dst_x,unsigned dst_y,unsigned width,unsigned height,bool render_condition_enabled)776 iris_clear_render_target(struct pipe_context *ctx,
777 struct pipe_surface *psurf,
778 const union pipe_color_union *p_color,
779 unsigned dst_x, unsigned dst_y,
780 unsigned width, unsigned height,
781 bool render_condition_enabled)
782 {
783 struct iris_context *ice = (void *) ctx;
784 struct iris_surface *isurf = (void *) psurf;
785 struct pipe_box box = {
786 .x = dst_x,
787 .y = dst_y,
788 .z = psurf->u.tex.first_layer,
789 .width = width,
790 .height = height,
791 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1
792 };
793
794 clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
795 render_condition_enabled,
796 isurf->view.format, isurf->view.swizzle,
797 convert_clear_color(psurf->format, p_color));
798 }
799
800 /**
801 * The pipe->clear_depth_stencil() driver hook.
802 *
803 * This clears the given depth/stencil surface.
804 */
805 static void
iris_clear_depth_stencil(struct pipe_context * ctx,struct pipe_surface * psurf,unsigned flags,double depth,unsigned stencil,unsigned dst_x,unsigned dst_y,unsigned width,unsigned height,bool render_condition_enabled)806 iris_clear_depth_stencil(struct pipe_context *ctx,
807 struct pipe_surface *psurf,
808 unsigned flags,
809 double depth,
810 unsigned stencil,
811 unsigned dst_x, unsigned dst_y,
812 unsigned width, unsigned height,
813 bool render_condition_enabled)
814 {
815 struct iris_context *ice = (void *) ctx;
816 struct pipe_box box = {
817 .x = dst_x,
818 .y = dst_y,
819 .z = psurf->u.tex.first_layer,
820 .width = width,
821 .height = height,
822 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1
823 };
824
825 assert(util_format_is_depth_or_stencil(psurf->texture->format));
826
827 clear_depth_stencil(ice, psurf->texture, psurf->u.tex.level, &box,
828 render_condition_enabled,
829 flags & PIPE_CLEAR_DEPTH, flags & PIPE_CLEAR_STENCIL,
830 depth, stencil);
831 }
832
833 void
iris_init_clear_functions(struct pipe_context * ctx)834 iris_init_clear_functions(struct pipe_context *ctx)
835 {
836 ctx->clear = iris_clear;
837 ctx->clear_texture = iris_clear_texture;
838 ctx->clear_render_target = iris_clear_render_target;
839 ctx->clear_depth_stencil = iris_clear_depth_stencil;
840 }
841