util: Make helper functions for pack/unpacking pixel rows.
[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 (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, &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 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, &batch->screen->isl_dev, &surf,
379 p_res, aux_usage, level, 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, &batch->screen->isl_dev,
587 &z_surf, &z_res->base, z_res->aux.usage,
588 level, true);
589 }
590
591 struct blorp_batch blorp_batch;
592 blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
593
594 uint8_t stencil_mask = clear_stencil && stencil_res ? 0xff : 0;
595 if (stencil_mask) {
596 iris_resource_prepare_access(ice, batch, stencil_res, level, 1, box->z,
597 box->depth, stencil_res->aux.usage, false);
598 iris_blorp_surf_for_resource(&ice->vtbl, &batch->screen->isl_dev,
599 &stencil_surf, &stencil_res->base,
600 stencil_res->aux.usage, level, true);
601 }
602
603 blorp_clear_depth_stencil(&blorp_batch, &z_surf, &stencil_surf,
604 level, box->z, box->depth,
605 box->x, box->y,
606 box->x + box->width,
607 box->y + box->height,
608 clear_depth && z_res, depth,
609 stencil_mask, stencil);
610
611 blorp_batch_finish(&blorp_batch);
612 iris_flush_and_dirty_for_history(ice, batch, res, 0,
613 "cache history: post slow ZS clear");
614
615 if (clear_depth && z_res) {
616 iris_resource_finish_depth(ice, z_res, level,
617 box->z, box->depth, true);
618 }
619
620 if (stencil_mask) {
621 iris_resource_finish_write(ice, stencil_res, level, box->z, box->depth,
622 stencil_res->aux.usage);
623 }
624 }
625
626 /**
627 * The pipe->clear() driver hook.
628 *
629 * This clears buffers attached to the current draw framebuffer.
630 */
631 static void
632 iris_clear(struct pipe_context *ctx,
633 unsigned buffers,
634 const union pipe_color_union *p_color,
635 double depth,
636 unsigned stencil)
637 {
638 struct iris_context *ice = (void *) ctx;
639 struct pipe_framebuffer_state *cso_fb = &ice->state.framebuffer;
640
641 assert(buffers != 0);
642
643 if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
644 struct pipe_surface *psurf = cso_fb->zsbuf;
645 struct pipe_box box = {
646 .width = cso_fb->width,
647 .height = cso_fb->height,
648 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1,
649 .z = psurf->u.tex.first_layer,
650 };
651
652 clear_depth_stencil(ice, psurf->texture, psurf->u.tex.level, &box, true,
653 buffers & PIPE_CLEAR_DEPTH,
654 buffers & PIPE_CLEAR_STENCIL,
655 depth, stencil);
656 }
657
658 if (buffers & PIPE_CLEAR_COLOR) {
659 /* pipe_color_union and isl_color_value are interchangeable */
660 union isl_color_value *color = (void *) p_color;
661
662 for (unsigned i = 0; i < cso_fb->nr_cbufs; i++) {
663 if (buffers & (PIPE_CLEAR_COLOR0 << i)) {
664 struct pipe_surface *psurf = cso_fb->cbufs[i];
665 struct iris_surface *isurf = (void *) psurf;
666 struct pipe_box box = {
667 .width = cso_fb->width,
668 .height = cso_fb->height,
669 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1,
670 .z = psurf->u.tex.first_layer,
671 };
672
673 clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
674 true, isurf->view.format, isurf->view.swizzle,
675 *color);
676 }
677 }
678 }
679 }
680
681 /**
682 * The pipe->clear_texture() driver hook.
683 *
684 * This clears the given texture resource.
685 */
686 static void
687 iris_clear_texture(struct pipe_context *ctx,
688 struct pipe_resource *p_res,
689 unsigned level,
690 const struct pipe_box *box,
691 const void *data)
692 {
693 struct iris_context *ice = (void *) ctx;
694 struct iris_screen *screen = (void *) ctx->screen;
695 const struct gen_device_info *devinfo = &screen->devinfo;
696
697 if (util_format_is_depth_or_stencil(p_res->format)) {
698 const struct util_format_description *fmt_desc =
699 util_format_description(p_res->format);
700
701 float depth = 0.0;
702 uint8_t stencil = 0;
703
704 if (fmt_desc->unpack_z_float)
705 util_format_unpack_z_float(p_res->format, &depth, data, 1);
706
707 if (fmt_desc->unpack_s_8uint)
708 util_format_unpack_s_8uint(p_res->format, &stencil, data, 1);
709
710 clear_depth_stencil(ice, p_res, level, box, true, true, true,
711 depth, stencil);
712 } else {
713 union isl_color_value color;
714 struct iris_resource *res = (void *) p_res;
715 enum isl_format format = res->surf.format;
716
717 if (!isl_format_supports_rendering(devinfo, format)) {
718 const struct isl_format_layout *fmtl = isl_format_get_layout(format);
719 // XXX: actually just get_copy_format_for_bpb from BLORP
720 // XXX: don't cut and paste this
721 switch (fmtl->bpb) {
722 case 8: format = ISL_FORMAT_R8_UINT; break;
723 case 16: format = ISL_FORMAT_R8G8_UINT; break;
724 case 24: format = ISL_FORMAT_R8G8B8_UINT; break;
725 case 32: format = ISL_FORMAT_R8G8B8A8_UINT; break;
726 case 48: format = ISL_FORMAT_R16G16B16_UINT; break;
727 case 64: format = ISL_FORMAT_R16G16B16A16_UINT; break;
728 case 96: format = ISL_FORMAT_R32G32B32_UINT; break;
729 case 128: format = ISL_FORMAT_R32G32B32A32_UINT; break;
730 default:
731 unreachable("Unknown format bpb");
732 }
733
734 /* No aux surfaces for non-renderable surfaces */
735 assert(res->aux.usage == ISL_AUX_USAGE_NONE);
736 }
737
738 isl_color_value_unpack(&color, format, data);
739
740 clear_color(ice, p_res, level, box, true, format,
741 ISL_SWIZZLE_IDENTITY, color);
742 }
743 }
744
745 /**
746 * The pipe->clear_render_target() driver hook.
747 *
748 * This clears the given render target surface.
749 */
750 static void
751 iris_clear_render_target(struct pipe_context *ctx,
752 struct pipe_surface *psurf,
753 const union pipe_color_union *p_color,
754 unsigned dst_x, unsigned dst_y,
755 unsigned width, unsigned height,
756 bool render_condition_enabled)
757 {
758 struct iris_context *ice = (void *) ctx;
759 struct iris_surface *isurf = (void *) psurf;
760 struct pipe_box box = {
761 .x = dst_x,
762 .y = dst_y,
763 .z = psurf->u.tex.first_layer,
764 .width = width,
765 .height = height,
766 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1
767 };
768
769 /* pipe_color_union and isl_color_value are interchangeable */
770 union isl_color_value *color = (void *) p_color;
771
772 clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
773 render_condition_enabled,
774 isurf->view.format, isurf->view.swizzle, *color);
775 }
776
777 /**
778 * The pipe->clear_depth_stencil() driver hook.
779 *
780 * This clears the given depth/stencil surface.
781 */
782 static void
783 iris_clear_depth_stencil(struct pipe_context *ctx,
784 struct pipe_surface *psurf,
785 unsigned flags,
786 double depth,
787 unsigned stencil,
788 unsigned dst_x, unsigned dst_y,
789 unsigned width, unsigned height,
790 bool render_condition_enabled)
791 {
792 struct iris_context *ice = (void *) ctx;
793 struct pipe_box box = {
794 .x = dst_x,
795 .y = dst_y,
796 .z = psurf->u.tex.first_layer,
797 .width = width,
798 .height = height,
799 .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1
800 };
801
802 assert(util_format_is_depth_or_stencil(psurf->texture->format));
803
804 clear_depth_stencil(ice, psurf->texture, psurf->u.tex.level, &box,
805 render_condition_enabled,
806 flags & PIPE_CLEAR_DEPTH, flags & PIPE_CLEAR_STENCIL,
807 depth, stencil);
808 }
809
810 void
811 iris_init_clear_functions(struct pipe_context *ctx)
812 {
813 ctx->clear = iris_clear;
814 ctx->clear_texture = iris_clear_texture;
815 ctx->clear_render_target = iris_clear_render_target;
816 ctx->clear_depth_stencil = iris_clear_depth_stencil;
817 }