intel/blorp: Add support for swizzling fast-clear colors
[mesa.git] / src / gallium / drivers / iris / iris_clear.c
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 #include "util/format_srgb.h"
38
39 static bool
40 iris_is_color_fast_clear_compatible(struct iris_context *ice,
41 enum isl_format format,
42 const union isl_color_value color)
43 {
44 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
45 const struct gen_device_info *devinfo = &batch->screen->devinfo;
46
47 if (isl_format_has_int_channel(format)) {
48 perf_debug(&ice->dbg, "Integer fast clear not enabled for %s",
49 isl_format_get_name(format));
50 return false;
51 }
52
53 for (int i = 0; i < 4; i++) {
54 if (!isl_format_has_color_component(format, i)) {
55 continue;
56 }
57
58 if (devinfo->gen < 9 &&
59 color.f32[i] != 0.0f && color.f32[i] != 1.0f) {
60 return false;
61 }
62 }
63
64 return true;
65 }
66
67 static bool
68 can_fast_clear_color(struct iris_context *ice,
69 struct pipe_resource *p_res,
70 unsigned level,
71 const struct pipe_box *box,
72 enum isl_format format,
73 enum isl_format render_format,
74 union isl_color_value color)
75 {
76 struct iris_resource *res = (void *) p_res;
77
78 if (INTEL_DEBUG & DEBUG_NO_FAST_CLEAR)
79 return false;
80
81 if (!isl_aux_usage_has_fast_clears(res->aux.usage))
82 return false;
83
84 /* Check for partial clear */
85 if (box->x > 0 || box->y > 0 ||
86 box->width < minify(p_res->width0, level) ||
87 box->height < minify(p_res->height0, level)) {
88 return false;
89 }
90
91 /* We store clear colors as floats or uints as needed. If there are
92 * texture views in play, the formats will not properly be respected
93 * during resolves because the resolve operations only know about the
94 * resource and not the renderbuffer.
95 */
96 if (isl_format_srgb_to_linear(render_format) !=
97 isl_format_srgb_to_linear(format)) {
98 return false;
99 }
100
101 /* XXX: if (irb->mt->supports_fast_clear)
102 * see intel_miptree_create_for_dri_image()
103 */
104
105 if (!iris_is_color_fast_clear_compatible(ice, format, color))
106 return false;
107
108 return true;
109 }
110
111 static union isl_color_value
112 convert_fast_clear_color(struct iris_context *ice,
113 struct iris_resource *res,
114 enum isl_format render_format,
115 const union isl_color_value color)
116 {
117 union isl_color_value override_color = color;
118 struct pipe_resource *p_res = (void *) res;
119
120 const enum pipe_format format = p_res->format;
121 const struct util_format_description *desc =
122 util_format_description(format);
123 unsigned colormask = util_format_colormask(desc);
124
125 if (util_format_is_intensity(format) ||
126 util_format_is_luminance(format) ||
127 util_format_is_luminance_alpha(format)) {
128 override_color.u32[1] = override_color.u32[0];
129 override_color.u32[2] = override_color.u32[0];
130 if (util_format_is_intensity(format))
131 override_color.u32[3] = override_color.u32[0];
132 } else {
133 for (int chan = 0; chan < 3; chan++) {
134 if (!(colormask & (1 << chan)))
135 override_color.u32[chan] = 0;
136 }
137 }
138
139 if (util_format_is_unorm(format)) {
140 for (int i = 0; i < 4; i++)
141 override_color.f32[i] = CLAMP(override_color.f32[i], 0.0f, 1.0f);
142 } else if (util_format_is_snorm(format)) {
143 for (int i = 0; i < 4; i++)
144 override_color.f32[i] = CLAMP(override_color.f32[i], -1.0f, 1.0f);
145 } else if (util_format_is_pure_uint(format)) {
146 for (int i = 0; i < 4; i++) {
147 unsigned bits = util_format_get_component_bits(
148 format, UTIL_FORMAT_COLORSPACE_RGB, i);
149 if (bits < 32) {
150 uint32_t max = (1u << bits) - 1;
151 override_color.u32[i] = MIN2(override_color.u32[i], max);
152 }
153 }
154 } else if (util_format_is_pure_sint(format)) {
155 for (int i = 0; i < 4; i++) {
156 unsigned bits = util_format_get_component_bits(
157 format, UTIL_FORMAT_COLORSPACE_RGB, i);
158 if (bits < 32) {
159 int32_t max = (1 << (bits - 1)) - 1;
160 int32_t min = -(1 << (bits - 1));
161 override_color.i32[i] = CLAMP(override_color.i32[i], min, max);
162 }
163 }
164 } else if (format == PIPE_FORMAT_R11G11B10_FLOAT ||
165 format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
166 /* these packed float formats only store unsigned values */
167 for (int i = 0; i < 4; i++)
168 override_color.f32[i] = MAX2(override_color.f32[i], 0.0f);
169 }
170
171 if (!(colormask & 1 << 3)) {
172 if (util_format_is_pure_integer(format))
173 override_color.u32[3] = 1;
174 else
175 override_color.f32[3] = 1.0f;
176 }
177
178 /* Handle linear to SRGB conversion */
179 if (isl_format_is_srgb(render_format)) {
180 for (int i = 0; i < 3; i++) {
181 override_color.f32[i] =
182 util_format_linear_to_srgb_float(override_color.f32[i]);
183 }
184 }
185
186 return override_color;
187 }
188
189 static void
190 fast_clear_color(struct iris_context *ice,
191 struct iris_resource *res,
192 unsigned level,
193 const struct pipe_box *box,
194 enum isl_format format,
195 union isl_color_value color,
196 enum blorp_batch_flags blorp_flags)
197 {
198 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
199 struct pipe_resource *p_res = (void *) res;
200 const enum isl_aux_state aux_state =
201 iris_resource_get_aux_state(res, level, box->z);
202
203 color = convert_fast_clear_color(ice, res, format, color);
204
205 bool color_changed = !!memcmp(&res->aux.clear_color, &color,
206 sizeof(color));
207
208 if (color_changed) {
209 /* We decided that we are going to fast clear, and the color is
210 * changing. But if we have a predicate bit set, the predication
211 * affects whether we should clear or not, and if we shouldn't, we
212 * also shouldn't update the clear color.
213 *
214 * However, we can't simply predicate-update the clear color (the
215 * commands don't support that). And we would lose track of the
216 * color, preventing us from doing some optimizations later.
217 *
218 * Since changing the clear color when the predication bit is enabled
219 * is not something that should happen often, we stall on the CPU here
220 * to resolve the predication, and then proceed.
221 */
222 ice->vtbl.resolve_conditional_render(ice);
223 if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
224 return;
225
226 /* If we are clearing to a new clear value, we need to resolve fast
227 * clears from other levels/layers first, since we can't have different
228 * levels/layers with different fast clear colors.
229 */
230 for (unsigned res_lvl = 0; res_lvl < res->surf.levels; res_lvl++) {
231 const unsigned level_layers =
232 iris_get_num_logical_layers(res, res_lvl);
233 for (unsigned layer = 0; layer < level_layers; layer++) {
234 if (res_lvl == level &&
235 layer >= box->z &&
236 layer < box->z + box->depth) {
237 /* We're going to clear this layer anyway. Leave it alone. */
238 continue;
239 }
240
241 enum isl_aux_state aux_state =
242 iris_resource_get_aux_state(res, res_lvl, layer);
243
244 if (aux_state != ISL_AUX_STATE_CLEAR &&
245 aux_state != ISL_AUX_STATE_PARTIAL_CLEAR &&
246 aux_state != ISL_AUX_STATE_COMPRESSED_CLEAR) {
247 /* This slice doesn't have any fast-cleared bits. */
248 continue;
249 }
250
251 /* If we got here, then the level may have fast-clear bits that use
252 * the old clear value. We need to do a color resolve to get rid
253 * of their use of the clear color before we can change it.
254 * Fortunately, few applications ever change their clear color at
255 * different levels/layers, so this shouldn't happen often.
256 */
257 iris_resource_prepare_access(ice, batch, res,
258 res_lvl, 1, layer, 1,
259 res->aux.usage,
260 false);
261 perf_debug(&ice->dbg,
262 "Resolving resource (%p) level %d, layer %d: color changing from "
263 "(%0.2f, %0.2f, %0.2f, %0.2f) to "
264 "(%0.2f, %0.2f, %0.2f, %0.2f)\n",
265 res, res_lvl, layer,
266 res->aux.clear_color.f32[0],
267 res->aux.clear_color.f32[1],
268 res->aux.clear_color.f32[2],
269 res->aux.clear_color.f32[3],
270 color.f32[0], color.f32[1], color.f32[2], color.f32[3]);
271 }
272 }
273 }
274
275 iris_resource_set_clear_color(ice, res, color);
276
277 /* If the buffer is already in ISL_AUX_STATE_CLEAR, and the color hasn't
278 * changed, the clear is redundant and can be skipped.
279 */
280 if (!color_changed && aux_state == ISL_AUX_STATE_CLEAR)
281 return;
282
283 /* Ivybrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)":
284 *
285 * "Any transition from any value in {Clear, Render, Resolve} to a
286 * different value in {Clear, Render, Resolve} requires end of pipe
287 * synchronization."
288 *
289 * In other words, fast clear ops are not properly synchronized with
290 * other drawing. We need to use a PIPE_CONTROL to ensure that the
291 * contents of the previous draw hit the render target before we resolve
292 * and again afterwards to ensure that the resolve is complete before we
293 * do any more regular drawing.
294 */
295 iris_emit_end_of_pipe_sync(batch,
296 "fast clear: pre-flush",
297 PIPE_CONTROL_RENDER_TARGET_FLUSH);
298
299 /* If we reach this point, we need to fast clear to change the state to
300 * ISL_AUX_STATE_CLEAR, or to update the fast clear color (or both).
301 */
302 blorp_flags |= color_changed ? 0 : BLORP_BATCH_NO_UPDATE_CLEAR_COLOR;
303
304 struct blorp_batch blorp_batch;
305 blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
306
307 struct blorp_surf surf;
308 iris_blorp_surf_for_resource(&ice->vtbl, &batch->screen->isl_dev, &surf,
309 p_res, res->aux.usage, level, true);
310
311 /* In newer gens (> 9), the hardware will do a linear -> sRGB conversion of
312 * the clear color during the fast clear, if the surface format is of sRGB
313 * type. We use the linear version of the surface format here to prevent
314 * that from happening, since we already do our own linear -> sRGB
315 * conversion in convert_fast_clear_color().
316 */
317 blorp_fast_clear(&blorp_batch, &surf, isl_format_srgb_to_linear(format),
318 ISL_SWIZZLE_IDENTITY,
319 level, box->z, box->depth,
320 box->x, box->y, box->x + box->width,
321 box->y + box->height);
322 blorp_batch_finish(&blorp_batch);
323 iris_emit_end_of_pipe_sync(batch,
324 "fast clear: post flush",
325 PIPE_CONTROL_RENDER_TARGET_FLUSH);
326
327 iris_resource_set_aux_state(ice, res, level, box->z,
328 box->depth, ISL_AUX_STATE_CLEAR);
329 ice->state.dirty |= IRIS_ALL_DIRTY_BINDINGS;
330 return;
331 }
332
333 static void
334 clear_color(struct iris_context *ice,
335 struct pipe_resource *p_res,
336 unsigned level,
337 const struct pipe_box *box,
338 bool render_condition_enabled,
339 enum isl_format format,
340 struct isl_swizzle swizzle,
341 union isl_color_value color)
342 {
343 struct iris_resource *res = (void *) p_res;
344
345 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
346 const struct gen_device_info *devinfo = &batch->screen->devinfo;
347 enum blorp_batch_flags blorp_flags = 0;
348
349 if (render_condition_enabled) {
350 if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
351 return;
352
353 if (ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT)
354 blorp_flags |= BLORP_BATCH_PREDICATE_ENABLE;
355 }
356
357 if (p_res->target == PIPE_BUFFER)
358 util_range_add(&res->base, &res->valid_buffer_range, box->x, box->x + box->width);
359
360 iris_batch_maybe_flush(batch, 1500);
361
362 bool can_fast_clear = can_fast_clear_color(ice, p_res, level, box,
363 res->surf.format, format, color);
364 if (can_fast_clear) {
365 fast_clear_color(ice, res, level, box, format, color,
366 blorp_flags);
367 return;
368 }
369
370 bool color_write_disable[4] = { false, false, false, false };
371 enum isl_aux_usage aux_usage =
372 iris_resource_render_aux_usage(ice, res, format,
373 false, false);
374
375 iris_resource_prepare_render(ice, batch, res, level,
376 box->z, box->depth, aux_usage);
377
378 struct blorp_surf surf;
379 iris_blorp_surf_for_resource(&ice->vtbl, &batch->screen->isl_dev, &surf,
380 p_res, aux_usage, level, true);
381
382 struct blorp_batch blorp_batch;
383 blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
384
385 if (!isl_format_supports_rendering(devinfo, format) &&
386 isl_format_is_rgbx(format))
387 format = isl_format_rgbx_to_rgba(format);
388
389 blorp_clear(&blorp_batch, &surf, format, swizzle,
390 level, box->z, box->depth, box->x, box->y,
391 box->x + box->width, box->y + box->height,
392 color, color_write_disable);
393
394 blorp_batch_finish(&blorp_batch);
395 iris_flush_and_dirty_for_history(ice, batch, res,
396 PIPE_CONTROL_RENDER_TARGET_FLUSH,
397 "cache history: post color clear");
398
399 iris_resource_finish_render(ice, res, level,
400 box->z, box->depth, aux_usage);
401 }
402
403 static bool
404 can_fast_clear_depth(struct iris_context *ice,
405 struct iris_resource *res,
406 unsigned level,
407 const struct pipe_box *box,
408 float depth)
409 {
410 struct pipe_resource *p_res = (void *) res;
411 struct pipe_context *ctx = (void *) ice;
412 struct iris_screen *screen = (void *) ctx->screen;
413 const struct gen_device_info *devinfo = &screen->devinfo;
414
415 if (INTEL_DEBUG & DEBUG_NO_FAST_CLEAR)
416 return false;
417
418 /* Check for partial clears */
419 if (box->x > 0 || box->y > 0 ||
420 box->width < u_minify(p_res->width0, level) ||
421 box->height < u_minify(p_res->height0, level)) {
422 return false;
423 }
424
425 if (!(res->aux.has_hiz & (1 << level)))
426 return false;
427
428 return blorp_can_hiz_clear_depth(devinfo, &res->surf, res->aux.usage,
429 level, box->z, box->x, box->y,
430 box->x + box->width,
431 box->y + box->height);
432 }
433
434 static void
435 fast_clear_depth(struct iris_context *ice,
436 struct iris_resource *res,
437 unsigned level,
438 const struct pipe_box *box,
439 float depth)
440 {
441 struct pipe_resource *p_res = (void *) res;
442 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
443
444 /* Quantize the clear value to what can be stored in the actual depth
445 * buffer. This makes the following check more accurate because it now
446 * checks if the actual depth bits will match. It also prevents us from
447 * getting a too-accurate depth value during depth testing or when sampling
448 * with HiZ enabled.
449 */
450 const unsigned nbits = p_res->format == PIPE_FORMAT_Z16_UNORM ? 16 : 24;
451 const uint32_t depth_max = (1 << nbits) - 1;
452 depth = p_res->format == PIPE_FORMAT_Z32_FLOAT ? depth :
453 (unsigned)(depth * depth_max) / (float)depth_max;
454
455 bool update_clear_depth = false;
456
457 /* If we're clearing to a new clear value, then we need to resolve any clear
458 * flags out of the HiZ buffer into the real depth buffer.
459 */
460 if (res->aux.clear_color.f32[0] != depth) {
461 /* We decided that we are going to fast clear, and the color is
462 * changing. But if we have a predicate bit set, the predication
463 * affects whether we should clear or not, and if we shouldn't, we
464 * also shouldn't update the clear color.
465 *
466 * However, we can't simply predicate-update the clear color (the
467 * commands don't support that). And we would lose track of the
468 * color, preventing us from doing some optimizations later.
469 *
470 * For depth clears, things are even more complicated, because here we
471 * resolve the other levels/layers if they have a different color than
472 * the current one. That resolve can be predicated, but we also set those
473 * layers as ISL_AUX_STATE_RESOLVED, and this can't be predicated.
474 * Keeping track of the aux state when predication is involved is just
475 * even more complex, so the easiest thing to do when the fast clear
476 * depth is changing is to stall on the CPU and resolve the predication.
477 */
478 ice->vtbl.resolve_conditional_render(ice);
479 if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
480 return;
481
482 for (unsigned res_level = 0; res_level < res->surf.levels; res_level++) {
483 if (!(res->aux.has_hiz & (1 << res_level)))
484 continue;
485
486 const unsigned level_layers =
487 iris_get_num_logical_layers(res, res_level);
488 for (unsigned layer = 0; layer < level_layers; layer++) {
489 if (res_level == level &&
490 layer >= box->z &&
491 layer < box->z + box->depth) {
492 /* We're going to clear this layer anyway. Leave it alone. */
493 continue;
494 }
495
496 enum isl_aux_state aux_state =
497 iris_resource_get_aux_state(res, res_level, layer);
498
499 if (aux_state != ISL_AUX_STATE_CLEAR &&
500 aux_state != ISL_AUX_STATE_COMPRESSED_CLEAR) {
501 /* This slice doesn't have any fast-cleared bits. */
502 continue;
503 }
504
505 /* If we got here, then the level may have fast-clear bits that
506 * use the old clear value. We need to do a depth resolve to get
507 * rid of their use of the clear value before we can change it.
508 * Fortunately, few applications ever change their depth clear
509 * value so this shouldn't happen often.
510 */
511 iris_hiz_exec(ice, batch, res, res_level, layer, 1,
512 ISL_AUX_OP_FULL_RESOLVE, false);
513 iris_resource_set_aux_state(ice, res, res_level, layer, 1,
514 ISL_AUX_STATE_RESOLVED);
515 }
516 }
517 const union isl_color_value clear_value = { .f32 = {depth, } };
518 iris_resource_set_clear_color(ice, res, clear_value);
519 update_clear_depth = true;
520 }
521
522 for (unsigned l = 0; l < box->depth; l++) {
523 enum isl_aux_state aux_state =
524 iris_resource_get_aux_state(res, level, box->z + l);
525 if (update_clear_depth || aux_state != ISL_AUX_STATE_CLEAR) {
526 if (aux_state == ISL_AUX_STATE_CLEAR) {
527 perf_debug(&ice->dbg, "Performing HiZ clear just to update the "
528 "depth clear value\n");
529 }
530 iris_hiz_exec(ice, batch, res, level,
531 box->z + l, 1, ISL_AUX_OP_FAST_CLEAR,
532 update_clear_depth);
533 }
534 }
535
536 iris_resource_set_aux_state(ice, res, level, box->z, box->depth,
537 ISL_AUX_STATE_CLEAR);
538 ice->state.dirty |= IRIS_DIRTY_DEPTH_BUFFER;
539 }
540
541 static void
542 clear_depth_stencil(struct iris_context *ice,
543 struct pipe_resource *p_res,
544 unsigned level,
545 const struct pipe_box *box,
546 bool render_condition_enabled,
547 bool clear_depth,
548 bool clear_stencil,
549 float depth,
550 uint8_t stencil)
551 {
552 struct iris_resource *res = (void *) p_res;
553
554 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
555 enum blorp_batch_flags blorp_flags = 0;
556
557 if (render_condition_enabled) {
558 if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
559 return;
560
561 if (ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT)
562 blorp_flags |= BLORP_BATCH_PREDICATE_ENABLE;
563 }
564
565 iris_batch_maybe_flush(batch, 1500);
566
567 struct iris_resource *z_res;
568 struct iris_resource *stencil_res;
569 struct blorp_surf z_surf;
570 struct blorp_surf stencil_surf;
571
572 iris_get_depth_stencil_resources(p_res, &z_res, &stencil_res);
573 if (z_res && clear_depth &&
574 can_fast_clear_depth(ice, z_res, level, box, depth)) {
575 fast_clear_depth(ice, z_res, level, box, depth);
576 iris_flush_and_dirty_for_history(ice, batch, res, 0,
577 "cache history: post fast Z clear");
578 clear_depth = false;
579 z_res = false;
580 }
581
582 /* At this point, we might have fast cleared the depth buffer. So if there's
583 * no stencil clear pending, return early.
584 */
585 if (!(clear_depth || clear_stencil)) {
586 return;
587 }
588
589 if (clear_depth && z_res) {
590 iris_resource_prepare_depth(ice, batch, z_res, level, box->z, box->depth);
591 iris_blorp_surf_for_resource(&ice->vtbl, &batch->screen->isl_dev,
592 &z_surf, &z_res->base, z_res->aux.usage,
593 level, true);
594 }
595
596 struct blorp_batch blorp_batch;
597 blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
598
599 uint8_t stencil_mask = clear_stencil && stencil_res ? 0xff : 0;
600 if (stencil_mask) {
601 iris_resource_prepare_access(ice, batch, stencil_res, level, 1, box->z,
602 box->depth, stencil_res->aux.usage, false);
603 iris_blorp_surf_for_resource(&ice->vtbl, &batch->screen->isl_dev,
604 &stencil_surf, &stencil_res->base,
605 stencil_res->aux.usage, level, true);
606 }
607
608 blorp_clear_depth_stencil(&blorp_batch, &z_surf, &stencil_surf,
609 level, box->z, box->depth,
610 box->x, box->y,
611 box->x + box->width,
612 box->y + box->height,
613 clear_depth && z_res, depth,
614 stencil_mask, stencil);
615
616 blorp_batch_finish(&blorp_batch);
617 iris_flush_and_dirty_for_history(ice, batch, res, 0,
618 "cache history: post slow ZS clear");
619
620 if (clear_depth && z_res) {
621 iris_resource_finish_depth(ice, z_res, level,
622 box->z, box->depth, true);
623 }
624
625 if (stencil_mask) {
626 iris_resource_finish_write(ice, stencil_res, level, box->z, box->depth,
627 stencil_res->aux.usage);
628 }
629 }
630
631 /**
632 * The pipe->clear() driver hook.
633 *
634 * This clears buffers attached to the current draw framebuffer.
635 */
636 static void
637 iris_clear(struct pipe_context *ctx,
638 unsigned buffers,
639 const union pipe_color_union *p_color,
640 double depth,
641 unsigned stencil)
642 {
643 struct iris_context *ice = (void *) ctx;
644 struct pipe_framebuffer_state *cso_fb = &ice->state.framebuffer;
645
646 assert(buffers != 0);
647
648 if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
649 struct pipe_surface *psurf = cso_fb->zsbuf;
650 struct pipe_box box = {
651 .width = cso_fb->width,
652 .height = cso_fb->height,
653 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1,
654 .z = psurf->u.tex.first_layer,
655 };
656
657 clear_depth_stencil(ice, psurf->texture, psurf->u.tex.level, &box, true,
658 buffers & PIPE_CLEAR_DEPTH,
659 buffers & PIPE_CLEAR_STENCIL,
660 depth, stencil);
661 }
662
663 if (buffers & PIPE_CLEAR_COLOR) {
664 /* pipe_color_union and isl_color_value are interchangeable */
665 union isl_color_value *color = (void *) p_color;
666
667 for (unsigned i = 0; i < cso_fb->nr_cbufs; i++) {
668 if (buffers & (PIPE_CLEAR_COLOR0 << i)) {
669 struct pipe_surface *psurf = cso_fb->cbufs[i];
670 struct iris_surface *isurf = (void *) psurf;
671 struct pipe_box box = {
672 .width = cso_fb->width,
673 .height = cso_fb->height,
674 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1,
675 .z = psurf->u.tex.first_layer,
676 };
677
678 clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
679 true, isurf->view.format, isurf->view.swizzle,
680 *color);
681 }
682 }
683 }
684 }
685
686 /**
687 * The pipe->clear_texture() driver hook.
688 *
689 * This clears the given texture resource.
690 */
691 static void
692 iris_clear_texture(struct pipe_context *ctx,
693 struct pipe_resource *p_res,
694 unsigned level,
695 const struct pipe_box *box,
696 const void *data)
697 {
698 struct iris_context *ice = (void *) ctx;
699 struct iris_screen *screen = (void *) ctx->screen;
700 const struct gen_device_info *devinfo = &screen->devinfo;
701
702 if (util_format_is_depth_or_stencil(p_res->format)) {
703 const struct util_format_description *fmt_desc =
704 util_format_description(p_res->format);
705
706 float depth = 0.0;
707 uint8_t stencil = 0;
708
709 if (fmt_desc->unpack_z_float)
710 util_format_unpack_z_float(p_res->format, &depth, data, 1);
711
712 if (fmt_desc->unpack_s_8uint)
713 util_format_unpack_s_8uint(p_res->format, &stencil, data, 1);
714
715 clear_depth_stencil(ice, p_res, level, box, true, true, true,
716 depth, stencil);
717 } else {
718 union isl_color_value color;
719 struct iris_resource *res = (void *) p_res;
720 enum isl_format format = res->surf.format;
721
722 if (!isl_format_supports_rendering(devinfo, format)) {
723 const struct isl_format_layout *fmtl = isl_format_get_layout(format);
724 // XXX: actually just get_copy_format_for_bpb from BLORP
725 // XXX: don't cut and paste this
726 switch (fmtl->bpb) {
727 case 8: format = ISL_FORMAT_R8_UINT; break;
728 case 16: format = ISL_FORMAT_R8G8_UINT; break;
729 case 24: format = ISL_FORMAT_R8G8B8_UINT; break;
730 case 32: format = ISL_FORMAT_R8G8B8A8_UINT; break;
731 case 48: format = ISL_FORMAT_R16G16B16_UINT; break;
732 case 64: format = ISL_FORMAT_R16G16B16A16_UINT; break;
733 case 96: format = ISL_FORMAT_R32G32B32_UINT; break;
734 case 128: format = ISL_FORMAT_R32G32B32A32_UINT; break;
735 default:
736 unreachable("Unknown format bpb");
737 }
738
739 /* No aux surfaces for non-renderable surfaces */
740 assert(res->aux.usage == ISL_AUX_USAGE_NONE);
741 }
742
743 isl_color_value_unpack(&color, format, data);
744
745 clear_color(ice, p_res, level, box, true, format,
746 ISL_SWIZZLE_IDENTITY, color);
747 }
748 }
749
750 /**
751 * The pipe->clear_render_target() driver hook.
752 *
753 * This clears the given render target surface.
754 */
755 static void
756 iris_clear_render_target(struct pipe_context *ctx,
757 struct pipe_surface *psurf,
758 const union pipe_color_union *p_color,
759 unsigned dst_x, unsigned dst_y,
760 unsigned width, unsigned height,
761 bool render_condition_enabled)
762 {
763 struct iris_context *ice = (void *) ctx;
764 struct iris_surface *isurf = (void *) psurf;
765 struct pipe_box box = {
766 .x = dst_x,
767 .y = dst_y,
768 .z = psurf->u.tex.first_layer,
769 .width = width,
770 .height = height,
771 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1
772 };
773
774 /* pipe_color_union and isl_color_value are interchangeable */
775 union isl_color_value *color = (void *) p_color;
776
777 clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
778 render_condition_enabled,
779 isurf->view.format, isurf->view.swizzle, *color);
780 }
781
782 /**
783 * The pipe->clear_depth_stencil() driver hook.
784 *
785 * This clears the given depth/stencil surface.
786 */
787 static void
788 iris_clear_depth_stencil(struct pipe_context *ctx,
789 struct pipe_surface *psurf,
790 unsigned flags,
791 double depth,
792 unsigned stencil,
793 unsigned dst_x, unsigned dst_y,
794 unsigned width, unsigned height,
795 bool render_condition_enabled)
796 {
797 struct iris_context *ice = (void *) ctx;
798 struct pipe_box box = {
799 .x = dst_x,
800 .y = dst_y,
801 .z = psurf->u.tex.first_layer,
802 .width = width,
803 .height = height,
804 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1
805 };
806
807 assert(util_format_is_depth_or_stencil(psurf->texture->format));
808
809 clear_depth_stencil(ice, psurf->texture, psurf->u.tex.level, &box,
810 render_condition_enabled,
811 flags & PIPE_CLEAR_DEPTH, flags & PIPE_CLEAR_STENCIL,
812 depth, stencil);
813 }
814
815 void
816 iris_init_clear_functions(struct pipe_context *ctx)
817 {
818 ctx->clear = iris_clear;
819 ctx->clear_texture = iris_clear_texture;
820 ctx->clear_render_target = iris_clear_render_target;
821 ctx->clear_depth_stencil = iris_clear_depth_stencil;
822 }