void blorp_ccs_resolve(struct blorp_batch *batch, struct blorp_surf *surf, enum isl_format format) { struct blorp_params params; blorp_params_init(¶ms); brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, surf, 0 /* level */, 0 /* layer */, format, true); /* From the Ivy Bridge PRM, Vol2 Part1 11.9 "Render Target Resolve": * * A rectangle primitive must be scaled down by the following factors * with respect to render target being resolved. * * The scaledown factors in the table that follows are related to the block * size of the CCS format. For IVB and HSW, we divide by two, for BDW we * multiply by 8 and 16. On Sky Lake, we multiply by 8. */ const struct isl_format_layout *aux_fmtl = isl_format_get_layout(params.dst.aux_surf.format); assert(aux_fmtl->txc == ISL_TXC_CCS); unsigned x_scaledown, y_scaledown; if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 9) { x_scaledown = aux_fmtl->bw * 8; y_scaledown = aux_fmtl->bh * 8; } else if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 8) { x_scaledown = aux_fmtl->bw * 8; y_scaledown = aux_fmtl->bh * 16; } else { x_scaledown = aux_fmtl->bw / 2; y_scaledown = aux_fmtl->bh / 2; } params.x0 = params.y0 = 0; params.x1 = params.dst.aux_surf.logical_level0_px.width; params.y1 = params.dst.aux_surf.logical_level0_px.height; params.x1 = ALIGN(params.x1, x_scaledown) / x_scaledown; params.y1 = ALIGN(params.y1, y_scaledown) / y_scaledown; if (batch->blorp->isl_dev->info->gen >= 9) { if (params.dst.aux_usage == ISL_AUX_USAGE_CCS_E) params.fast_clear_op = BLORP_FAST_CLEAR_OP_RESOLVE_FULL; else params.fast_clear_op = BLORP_FAST_CLEAR_OP_RESOLVE_PARTIAL; } else { /* Broadwell and earlier do not have a partial resolve */ params.fast_clear_op = BLORP_FAST_CLEAR_OP_RESOLVE_FULL; } /* Note: there is no need to initialize push constants because it doesn't * matter what data gets dispatched to the render target. However, we must * ensure that the fragment shader delivers the data using the "replicated * color" message. */ blorp_params_get_clear_kernel(batch->blorp, ¶ms, true); batch->blorp->exec(batch, ¶ms); }
void blorp_fast_clear(struct blorp_batch *batch, const struct blorp_surf *surf, enum isl_format format, uint32_t level, uint32_t start_layer, uint32_t num_layers, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1) { struct blorp_params params; blorp_params_init(¶ms); params.num_layers = num_layers; params.x0 = x0; params.y0 = y0; params.x1 = x1; params.y1 = y1; memset(¶ms.wm_inputs, 0xff, 4*sizeof(float)); params.fast_clear_op = BLORP_FAST_CLEAR_OP_CLEAR; get_fast_clear_rect(batch->blorp->isl_dev, surf->aux_surf, ¶ms.x0, ¶ms.y0, ¶ms.x1, ¶ms.y1); blorp_params_get_clear_kernel(batch->blorp, ¶ms, true); brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, surf, level, start_layer, format, true); batch->blorp->exec(batch, ¶ms); }
void brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt) { DBG("%s to mt %p\n", __FUNCTION__, mt); const mesa_format format = _mesa_get_srgb_format_linear(mt->format); struct brw_blorp_params params; brw_blorp_params_init(¶ms); brw_blorp_surface_info_init(brw, ¶ms.dst, mt, 0 /* level */, 0 /* layer */, format, true); brw_get_resolve_rect(brw, mt, ¶ms.x0, ¶ms.y0, ¶ms.x1, ¶ms.y1); if (intel_miptree_is_lossless_compressed(brw, mt)) params.resolve_type = GEN9_PS_RENDER_TARGET_RESOLVE_FULL; else params.resolve_type = GEN7_PS_RENDER_TARGET_RESOLVE_ENABLE; /* Note: there is no need to initialize push constants because it doesn't * matter what data gets dispatched to the render target. However, we must * ensure that the fragment shader delivers the data using the "replicated * color" message. */ brw_blorp_params_get_clear_kernel(brw, ¶ms, true); brw_blorp_exec(brw, ¶ms); mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED; }
void blorp_clear_depth_stencil(struct blorp_batch *batch, const struct blorp_surf *depth, const struct blorp_surf *stencil, uint32_t level, uint32_t start_layer, uint32_t num_layers, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, bool clear_depth, float depth_value, uint8_t stencil_mask, uint8_t stencil_value) { struct blorp_params params; blorp_params_init(¶ms); params.x0 = x0; params.y0 = y0; params.x1 = x1; params.y1 = y1; while (num_layers > 0) { params.num_layers = num_layers; if (stencil_mask) { brw_blorp_surface_info_init(batch->blorp, ¶ms.stencil, stencil, level, start_layer, ISL_FORMAT_UNSUPPORTED, true); params.stencil_mask = stencil_mask; params.stencil_ref = stencil_value; params.dst.surf.samples = params.stencil.surf.samples; params.dst.surf.logical_level0_px = params.stencil.surf.logical_level0_px; params.dst.view = params.depth.view; /* We may be restricted on the number of layers we can bind at any * one time. In particular, Sandy Bridge has a maximum number of * layers of 512 but a maximum 3D texture size is much larger. */ if (params.stencil.view.array_len < params.num_layers) params.num_layers = params.stencil.view.array_len; } if (clear_depth) { brw_blorp_surface_info_init(batch->blorp, ¶ms.depth, depth, level, start_layer, ISL_FORMAT_UNSUPPORTED, true); params.z = depth_value; params.depth_format = isl_format_get_depth_format(depth->surf->format, false); params.dst.surf.samples = params.depth.surf.samples; params.dst.surf.logical_level0_px = params.depth.surf.logical_level0_px; params.dst.view = params.depth.view; /* We may be restricted on the number of layers we can bind at any * one time. In particular, Sandy Bridge has a maximum number of * layers of 512 but a maximum 3D texture size is much larger. */ if (params.depth.view.array_len < params.num_layers) params.num_layers = params.depth.view.array_len; } batch->blorp->exec(batch, ¶ms); start_layer += params.num_layers; num_layers -= params.num_layers; } }
void blorp_clear(struct blorp_batch *batch, const struct blorp_surf *surf, enum isl_format format, struct isl_swizzle swizzle, uint32_t level, uint32_t start_layer, uint32_t num_layers, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, union isl_color_value clear_color, const bool color_write_disable[4]) { struct blorp_params params; blorp_params_init(¶ms); params.x0 = x0; params.y0 = y0; params.x1 = x1; params.y1 = y1; if (format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) { clear_color.u32[0] = float3_to_rgb9e5(clear_color.f32); format = ISL_FORMAT_R32_UINT; } memcpy(¶ms.wm_inputs, clear_color.f32, sizeof(float) * 4); bool use_simd16_replicated_data = true; /* From the SNB PRM (Vol4_Part1): * * "Replicated data (Message Type = 111) is only supported when * accessing tiled memory. Using this Message Type to access linear * (untiled) memory is UNDEFINED." */ if (surf->surf->tiling == ISL_TILING_LINEAR) use_simd16_replicated_data = false; /* Constant color writes ignore everyting in blend and color calculator * state. This is not documented. */ if (color_write_disable) { for (unsigned i = 0; i < 4; i++) { params.color_write_disable[i] = color_write_disable[i]; if (color_write_disable[i]) use_simd16_replicated_data = false; } } blorp_params_get_clear_kernel(batch->blorp, ¶ms, use_simd16_replicated_data); while (num_layers > 0) { brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, surf, level, start_layer, format, true); params.dst.view.swizzle = swizzle; /* We may be restricted on the number of layers we can bind at any one * time. In particular, Sandy Bridge has a maximum number of layers of * 512 but a maximum 3D texture size is much larger. */ params.num_layers = MIN2(params.dst.view.array_len, num_layers); batch->blorp->exec(batch, ¶ms); start_layer += params.num_layers; num_layers -= params.num_layers; } }
static bool do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb, struct gl_renderbuffer *rb, unsigned buf, bool partial_clear, bool encode_srgb, unsigned layer) { struct gl_context *ctx = &brw->ctx; struct intel_renderbuffer *irb = intel_renderbuffer(rb); mesa_format format = irb->mt->format; struct brw_blorp_params params; brw_blorp_params_init(¶ms); if (!encode_srgb && _mesa_get_format_color_encoding(format) == GL_SRGB) format = _mesa_get_srgb_format_linear(format); brw_blorp_surface_info_init(brw, ¶ms.dst, irb->mt, irb->mt_level, layer, format, true); /* Override the surface format according to the context's sRGB rules. */ params.dst.brw_surfaceformat = brw->render_target_format[format]; params.x0 = fb->_Xmin; params.x1 = fb->_Xmax; if (rb->Name != 0) { params.y0 = fb->_Ymin; params.y1 = fb->_Ymax; } else { params.y0 = rb->Height - fb->_Ymax; params.y1 = rb->Height - fb->_Ymin; } memcpy(¶ms.wm_inputs, ctx->Color.ClearColor.f, sizeof(float) * 4); bool use_simd16_replicated_data = true; /* From the SNB PRM (Vol4_Part1): * * "Replicated data (Message Type = 111) is only supported when * accessing tiled memory. Using this Message Type to access linear * (untiled) memory is UNDEFINED." */ if (irb->mt->tiling == I915_TILING_NONE) use_simd16_replicated_data = false; /* Constant color writes ignore everyting in blend and color calculator * state. This is not documented. */ if (set_write_disables(irb, ctx->Color.ColorMask[buf], params.color_write_disable)) use_simd16_replicated_data = false; if (irb->mt->fast_clear_state != INTEL_FAST_CLEAR_STATE_NO_MCS && !partial_clear && use_simd16_replicated_data && brw_is_color_fast_clear_compatible(brw, irb->mt, &ctx->Color.ClearColor)) { memset(¶ms.wm_inputs, 0xff, 4*sizeof(float)); params.fast_clear_op = GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE; brw_get_fast_clear_rect(brw, fb, irb->mt, ¶ms.x0, ¶ms.y0, ¶ms.x1, ¶ms.y1); } else { brw_meta_get_buffer_rect(fb, ¶ms.x0, ¶ms.y0, ¶ms.x1, ¶ms.y1); } brw_blorp_params_get_clear_kernel(brw, ¶ms, use_simd16_replicated_data); const bool is_fast_clear = params.fast_clear_op == GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE; if (is_fast_clear) { /* Record the clear color in the miptree so that it will be * programmed in SURFACE_STATE by later rendering and resolve * operations. */ const bool color_updated = brw_meta_set_fast_clear_color( brw, irb->mt, &ctx->Color.ClearColor); /* If the buffer is already in INTEL_FAST_CLEAR_STATE_CLEAR, the clear * is redundant and can be skipped. */ if (!color_updated && irb->mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR) return true; /* If the MCS buffer hasn't been allocated yet, we need to allocate * it now. */ if (!irb->mt->mcs_mt) { if (!intel_miptree_alloc_non_msrt_mcs(brw, irb->mt)) { /* MCS allocation failed--probably this will only happen in * out-of-memory conditions. But in any case, try to recover * by falling back to a non-blorp clear technique. */ return false; } } } const char *clear_type; if (is_fast_clear) clear_type = "fast"; else if (use_simd16_replicated_data) clear_type = "replicated"; else clear_type = "slow"; DBG("%s (%s) to mt %p level %d layer %d\n", __FUNCTION__, clear_type, irb->mt, irb->mt_level, irb->mt_layer); brw_blorp_exec(brw, ¶ms); if (is_fast_clear) { /* Now that the fast clear has occurred, put the buffer in * INTEL_FAST_CLEAR_STATE_CLEAR so that we won't waste time doing * redundant clears. */ irb->mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_CLEAR; } else if (intel_miptree_is_lossless_compressed(brw, irb->mt)) { /* Compressed buffers can be cleared also using normal rep-clear. In * such case they bahave such as if they were drawn using normal 3D * render pipeline, and we simply mark the mcs as dirty. */ assert(partial_clear); irb->mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_UNRESOLVED; } return true; }