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