iris: Prepare depth resource if clear_depth enable
[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/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 (res->aux.usage == ISL_AUX_USAGE_NONE)
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, &surf, p_res, res->aux.usage,
309 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 level, box->z, box->depth,
319 box->x, box->y, box->x + box->width,
320 box->y + box->height);
321 blorp_batch_finish(&blorp_batch);
322 iris_emit_end_of_pipe_sync(batch,
323 "fast clear: post flush",
324 PIPE_CONTROL_RENDER_TARGET_FLUSH);
325
326 iris_resource_set_aux_state(ice, res, level, box->z,
327 box->depth, ISL_AUX_STATE_CLEAR);
328 ice->state.dirty |= IRIS_ALL_DIRTY_BINDINGS;
329 return;
330 }
331
332 static void
333 clear_color(struct iris_context *ice,
334 struct pipe_resource *p_res,
335 unsigned level,
336 const struct pipe_box *box,
337 bool render_condition_enabled,
338 enum isl_format format,
339 struct isl_swizzle swizzle,
340 union isl_color_value color)
341 {
342 struct iris_resource *res = (void *) p_res;
343
344 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
345 const struct gen_device_info *devinfo = &batch->screen->devinfo;
346 enum blorp_batch_flags blorp_flags = 0;
347
348 if (render_condition_enabled) {
349 if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
350 return;
351
352 if (ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT)
353 blorp_flags |= BLORP_BATCH_PREDICATE_ENABLE;
354 }
355
356 if (p_res->target == PIPE_BUFFER)
357 util_range_add(&res->base, &res->valid_buffer_range, box->x, box->x + box->width);
358
359 iris_batch_maybe_flush(batch, 1500);
360
361 bool can_fast_clear = can_fast_clear_color(ice, p_res, level, box,
362 res->surf.format, format, color);
363 if (can_fast_clear) {
364 fast_clear_color(ice, res, level, box, format, color,
365 blorp_flags);
366 return;
367 }
368
369 bool color_write_disable[4] = { false, false, false, false };
370 enum isl_aux_usage aux_usage =
371 iris_resource_render_aux_usage(ice, res, format,
372 false, false);
373
374 iris_resource_prepare_render(ice, batch, res, level,
375 box->z, box->depth, aux_usage);
376
377 struct blorp_surf surf;
378 iris_blorp_surf_for_resource(&ice->vtbl, &surf, p_res, aux_usage, level,
379 true);
380
381 struct blorp_batch blorp_batch;
382 blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
383
384 if (!isl_format_supports_rendering(devinfo, format) &&
385 isl_format_is_rgbx(format))
386 format = isl_format_rgbx_to_rgba(format);
387
388 blorp_clear(&blorp_batch, &surf, format, swizzle,
389 level, box->z, box->depth, box->x, box->y,
390 box->x + box->width, box->y + box->height,
391 color, color_write_disable);
392
393 blorp_batch_finish(&blorp_batch);
394 iris_flush_and_dirty_for_history(ice, batch, res,
395 PIPE_CONTROL_RENDER_TARGET_FLUSH,
396 "cache history: post color clear");
397
398 iris_resource_finish_render(ice, res, level,
399 box->z, box->depth, aux_usage);
400 }
401
402 static bool
403 can_fast_clear_depth(struct iris_context *ice,
404 struct iris_resource *res,
405 unsigned level,
406 const struct pipe_box *box,
407 float depth)
408 {
409 struct pipe_resource *p_res = (void *) res;
410 struct pipe_context *ctx = (void *) ice;
411 struct iris_screen *screen = (void *) ctx->screen;
412 const struct gen_device_info *devinfo = &screen->devinfo;
413
414 if (INTEL_DEBUG & DEBUG_NO_FAST_CLEAR)
415 return false;
416
417 /* Check for partial clears */
418 if (box->x > 0 || box->y > 0 ||
419 box->width < u_minify(p_res->width0, level) ||
420 box->height < u_minify(p_res->height0, level)) {
421 return false;
422 }
423
424 if (!(res->aux.has_hiz & (1 << level)))
425 return false;
426
427 return blorp_can_hiz_clear_depth(devinfo, &res->surf, res->aux.usage,
428 level, box->z, box->x, box->y,
429 box->x + box->width,
430 box->y + box->height);
431 }
432
433 static void
434 fast_clear_depth(struct iris_context *ice,
435 struct iris_resource *res,
436 unsigned level,
437 const struct pipe_box *box,
438 float depth)
439 {
440 struct pipe_resource *p_res = (void *) res;
441 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
442
443 /* Quantize the clear value to what can be stored in the actual depth
444 * buffer. This makes the following check more accurate because it now
445 * checks if the actual depth bits will match. It also prevents us from
446 * getting a too-accurate depth value during depth testing or when sampling
447 * with HiZ enabled.
448 */
449 const unsigned nbits = p_res->format == PIPE_FORMAT_Z16_UNORM ? 16 : 24;
450 const uint32_t depth_max = (1 << nbits) - 1;
451 depth = p_res->format == PIPE_FORMAT_Z32_FLOAT ? depth :
452 (unsigned)(depth * depth_max) / (float)depth_max;
453
454 bool update_clear_depth = false;
455
456 /* If we're clearing to a new clear value, then we need to resolve any clear
457 * flags out of the HiZ buffer into the real depth buffer.
458 */
459 if (res->aux.clear_color.f32[0] != depth) {
460 /* We decided that we are going to fast clear, and the color is
461 * changing. But if we have a predicate bit set, the predication
462 * affects whether we should clear or not, and if we shouldn't, we
463 * also shouldn't update the clear color.
464 *
465 * However, we can't simply predicate-update the clear color (the
466 * commands don't support that). And we would lose track of the
467 * color, preventing us from doing some optimizations later.
468 *
469 * For depth clears, things are even more complicated, because here we
470 * resolve the other levels/layers if they have a different color than
471 * the current one. That resolve can be predicated, but we also set those
472 * layers as ISL_AUX_STATE_RESOLVED, and this can't be predicated.
473 * Keeping track of the aux state when predication is involved is just
474 * even more complex, so the easiest thing to do when the fast clear
475 * depth is changing is to stall on the CPU and resolve the predication.
476 */
477 ice->vtbl.resolve_conditional_render(ice);
478 if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
479 return;
480
481 for (unsigned res_level = 0; res_level < res->surf.levels; res_level++) {
482 if (!(res->aux.has_hiz & (1 << res_level)))
483 continue;
484
485 const unsigned level_layers =
486 iris_get_num_logical_layers(res, res_level);
487 for (unsigned layer = 0; layer < level_layers; layer++) {
488 if (res_level == level &&
489 layer >= box->z &&
490 layer < box->z + box->depth) {
491 /* We're going to clear this layer anyway. Leave it alone. */
492 continue;
493 }
494
495 enum isl_aux_state aux_state =
496 iris_resource_get_aux_state(res, res_level, layer);
497
498 if (aux_state != ISL_AUX_STATE_CLEAR &&
499 aux_state != ISL_AUX_STATE_COMPRESSED_CLEAR) {
500 /* This slice doesn't have any fast-cleared bits. */
501 continue;
502 }
503
504 /* If we got here, then the level may have fast-clear bits that
505 * use the old clear value. We need to do a depth resolve to get
506 * rid of their use of the clear value before we can change it.
507 * Fortunately, few applications ever change their depth clear
508 * value so this shouldn't happen often.
509 */
510 iris_hiz_exec(ice, batch, res, res_level, layer, 1,
511 ISL_AUX_OP_FULL_RESOLVE, false);
512 iris_resource_set_aux_state(ice, res, res_level, layer, 1,
513 ISL_AUX_STATE_RESOLVED);
514 }
515 }
516 const union isl_color_value clear_value = { .f32 = {depth, } };
517 iris_resource_set_clear_color(ice, res, clear_value);
518 update_clear_depth = true;
519 }
520
521 for (unsigned l = 0; l < box->depth; l++) {
522 enum isl_aux_state aux_state =
523 iris_resource_get_aux_state(res, level, box->z + l);
524 if (aux_state != ISL_AUX_STATE_CLEAR) {
525 iris_hiz_exec(ice, batch, res, level,
526 box->z + l, 1, ISL_AUX_OP_FAST_CLEAR,
527 update_clear_depth);
528 }
529 }
530
531 iris_resource_set_aux_state(ice, res, level, box->z, box->depth,
532 ISL_AUX_STATE_CLEAR);
533 ice->state.dirty |= IRIS_DIRTY_DEPTH_BUFFER;
534 }
535
536 static void
537 clear_depth_stencil(struct iris_context *ice,
538 struct pipe_resource *p_res,
539 unsigned level,
540 const struct pipe_box *box,
541 bool render_condition_enabled,
542 bool clear_depth,
543 bool clear_stencil,
544 float depth,
545 uint8_t stencil)
546 {
547 struct iris_resource *res = (void *) p_res;
548
549 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
550 enum blorp_batch_flags blorp_flags = 0;
551
552 if (render_condition_enabled) {
553 if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
554 return;
555
556 if (ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT)
557 blorp_flags |= BLORP_BATCH_PREDICATE_ENABLE;
558 }
559
560 iris_batch_maybe_flush(batch, 1500);
561
562 struct iris_resource *z_res;
563 struct iris_resource *stencil_res;
564 struct blorp_surf z_surf;
565 struct blorp_surf stencil_surf;
566
567 iris_get_depth_stencil_resources(p_res, &z_res, &stencil_res);
568 if (z_res && clear_depth &&
569 can_fast_clear_depth(ice, z_res, level, box, depth)) {
570 fast_clear_depth(ice, z_res, level, box, depth);
571 iris_flush_and_dirty_for_history(ice, batch, res, 0,
572 "cache history: post fast Z clear");
573 clear_depth = false;
574 z_res = false;
575 }
576
577 /* At this point, we might have fast cleared the depth buffer. So if there's
578 * no stencil clear pending, return early.
579 */
580 if (!(clear_depth || clear_stencil)) {
581 return;
582 }
583
584 if (clear_depth && z_res) {
585 iris_resource_prepare_depth(ice, batch, z_res, level, box->z, box->depth);
586 iris_blorp_surf_for_resource(&ice->vtbl, &z_surf, &z_res->base,
587 z_res->aux.usage, level, true);
588 }
589
590 struct blorp_batch blorp_batch;
591 blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
592
593 uint8_t stencil_mask = clear_stencil && stencil_res ? 0xff : 0;
594 if (stencil_mask) {
595 iris_resource_prepare_access(ice, batch, stencil_res, level, 1, box->z,
596 box->depth, stencil_res->aux.usage, false);
597 iris_blorp_surf_for_resource(&ice->vtbl, &stencil_surf,
598 &stencil_res->base, stencil_res->aux.usage,
599 level, true);
600 }
601
602 blorp_clear_depth_stencil(&blorp_batch, &z_surf, &stencil_surf,
603 level, box->z, box->depth,
604 box->x, box->y,
605 box->x + box->width,
606 box->y + box->height,
607 clear_depth && z_res, depth,
608 stencil_mask, stencil);
609
610 blorp_batch_finish(&blorp_batch);
611 iris_flush_and_dirty_for_history(ice, batch, res, 0,
612 "cache history: post slow ZS clear");
613
614 if (clear_depth && z_res) {
615 iris_resource_finish_depth(ice, z_res, level,
616 box->z, box->depth, true);
617 }
618
619 if (stencil_mask) {
620 iris_resource_finish_write(ice, stencil_res, level, box->z, box->depth,
621 stencil_res->aux.usage);
622 }
623 }
624
625 /**
626 * The pipe->clear() driver hook.
627 *
628 * This clears buffers attached to the current draw framebuffer.
629 */
630 static void
631 iris_clear(struct pipe_context *ctx,
632 unsigned buffers,
633 const union pipe_color_union *p_color,
634 double depth,
635 unsigned stencil)
636 {
637 struct iris_context *ice = (void *) ctx;
638 struct pipe_framebuffer_state *cso_fb = &ice->state.framebuffer;
639
640 assert(buffers != 0);
641
642 if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
643 struct pipe_surface *psurf = cso_fb->zsbuf;
644 struct pipe_box box = {
645 .width = cso_fb->width,
646 .height = cso_fb->height,
647 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1,
648 .z = psurf->u.tex.first_layer,
649 };
650
651 clear_depth_stencil(ice, psurf->texture, psurf->u.tex.level, &box, true,
652 buffers & PIPE_CLEAR_DEPTH,
653 buffers & PIPE_CLEAR_STENCIL,
654 depth, stencil);
655 }
656
657 if (buffers & PIPE_CLEAR_COLOR) {
658 /* pipe_color_union and isl_color_value are interchangeable */
659 union isl_color_value *color = (void *) p_color;
660
661 for (unsigned i = 0; i < cso_fb->nr_cbufs; i++) {
662 if (buffers & (PIPE_CLEAR_COLOR0 << i)) {
663 struct pipe_surface *psurf = cso_fb->cbufs[i];
664 struct iris_surface *isurf = (void *) psurf;
665 struct pipe_box box = {
666 .width = cso_fb->width,
667 .height = cso_fb->height,
668 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1,
669 .z = psurf->u.tex.first_layer,
670 };
671
672 clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
673 true, isurf->view.format, isurf->view.swizzle,
674 *color);
675 }
676 }
677 }
678 }
679
680 /**
681 * The pipe->clear_texture() driver hook.
682 *
683 * This clears the given texture resource.
684 */
685 static void
686 iris_clear_texture(struct pipe_context *ctx,
687 struct pipe_resource *p_res,
688 unsigned level,
689 const struct pipe_box *box,
690 const void *data)
691 {
692 struct iris_context *ice = (void *) ctx;
693 struct iris_screen *screen = (void *) ctx->screen;
694 const struct gen_device_info *devinfo = &screen->devinfo;
695
696 if (util_format_is_depth_or_stencil(p_res->format)) {
697 const struct util_format_description *fmt_desc =
698 util_format_description(p_res->format);
699
700 float depth = 0.0;
701 uint8_t stencil = 0;
702
703 if (fmt_desc->unpack_z_float)
704 fmt_desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
705
706 if (fmt_desc->unpack_s_8uint)
707 fmt_desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
708
709 clear_depth_stencil(ice, p_res, level, box, true, true, true,
710 depth, stencil);
711 } else {
712 union isl_color_value color;
713 struct iris_resource *res = (void *) p_res;
714 enum isl_format format = res->surf.format;
715
716 if (!isl_format_supports_rendering(devinfo, format)) {
717 const struct isl_format_layout *fmtl = isl_format_get_layout(format);
718 // XXX: actually just get_copy_format_for_bpb from BLORP
719 // XXX: don't cut and paste this
720 switch (fmtl->bpb) {
721 case 8: format = ISL_FORMAT_R8_UINT; break;
722 case 16: format = ISL_FORMAT_R8G8_UINT; break;
723 case 24: format = ISL_FORMAT_R8G8B8_UINT; break;
724 case 32: format = ISL_FORMAT_R8G8B8A8_UINT; break;
725 case 48: format = ISL_FORMAT_R16G16B16_UINT; break;
726 case 64: format = ISL_FORMAT_R16G16B16A16_UINT; break;
727 case 96: format = ISL_FORMAT_R32G32B32_UINT; break;
728 case 128: format = ISL_FORMAT_R32G32B32A32_UINT; break;
729 default:
730 unreachable("Unknown format bpb");
731 }
732
733 /* No aux surfaces for non-renderable surfaces */
734 assert(res->aux.usage == ISL_AUX_USAGE_NONE);
735 }
736
737 isl_color_value_unpack(&color, format, data);
738
739 clear_color(ice, p_res, level, box, true, format,
740 ISL_SWIZZLE_IDENTITY, color);
741 }
742 }
743
744 /**
745 * The pipe->clear_render_target() driver hook.
746 *
747 * This clears the given render target surface.
748 */
749 static void
750 iris_clear_render_target(struct pipe_context *ctx,
751 struct pipe_surface *psurf,
752 const union pipe_color_union *p_color,
753 unsigned dst_x, unsigned dst_y,
754 unsigned width, unsigned height,
755 bool render_condition_enabled)
756 {
757 struct iris_context *ice = (void *) ctx;
758 struct iris_surface *isurf = (void *) psurf;
759 struct pipe_box box = {
760 .x = dst_x,
761 .y = dst_y,
762 .z = psurf->u.tex.first_layer,
763 .width = width,
764 .height = height,
765 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1
766 };
767
768 /* pipe_color_union and isl_color_value are interchangeable */
769 union isl_color_value *color = (void *) p_color;
770
771 clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
772 render_condition_enabled,
773 isurf->view.format, isurf->view.swizzle, *color);
774 }
775
776 /**
777 * The pipe->clear_depth_stencil() driver hook.
778 *
779 * This clears the given depth/stencil surface.
780 */
781 static void
782 iris_clear_depth_stencil(struct pipe_context *ctx,
783 struct pipe_surface *psurf,
784 unsigned flags,
785 double depth,
786 unsigned stencil,
787 unsigned dst_x, unsigned dst_y,
788 unsigned width, unsigned height,
789 bool render_condition_enabled)
790 {
791 struct iris_context *ice = (void *) ctx;
792 struct pipe_box box = {
793 .x = dst_x,
794 .y = dst_y,
795 .z = psurf->u.tex.first_layer,
796 .width = width,
797 .height = height,
798 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1
799 };
800
801 assert(util_format_is_depth_or_stencil(psurf->texture->format));
802
803 clear_depth_stencil(ice, psurf->texture, psurf->u.tex.level, &box,
804 render_condition_enabled,
805 flags & PIPE_CLEAR_DEPTH, flags & PIPE_CLEAR_STENCIL,
806 depth, stencil);
807 }
808
809 void
810 iris_init_clear_functions(struct pipe_context *ctx)
811 {
812 ctx->clear = iris_clear;
813 ctx->clear_texture = iris_clear_texture;
814 ctx->clear_render_target = iris_clear_render_target;
815 ctx->clear_depth_stencil = iris_clear_depth_stencil;
816 }