static enum isl_format brw_blorp_to_isl_format(struct brw_context *brw, mesa_format format, bool is_render_target) { switch (format) { case MESA_FORMAT_NONE: return ISL_FORMAT_UNSUPPORTED; case MESA_FORMAT_S_UINT8: return ISL_FORMAT_R8_UINT; case MESA_FORMAT_Z24_UNORM_X8_UINT: return ISL_FORMAT_R24_UNORM_X8_TYPELESS; case MESA_FORMAT_Z_FLOAT32: return ISL_FORMAT_R32_FLOAT; case MESA_FORMAT_Z_UNORM16: return ISL_FORMAT_R16_UNORM; default: { if (is_render_target) { assert(brw->format_supported_as_render_target[format]); return brw->render_target_format[format]; } else { return brw_format_for_mesa_format(format); } break; } } }
void brw_blorp_surface_info::set(struct brw_context *brw, struct intel_mipmap_tree *mt, unsigned int level, unsigned int layer, mesa_format format, bool is_render_target) { brw_blorp_mip_info::set(mt, level, layer); this->num_samples = mt->num_samples; this->array_layout = mt->array_layout; this->map_stencil_as_y_tiled = false; this->msaa_layout = mt->msaa_layout; if (format == MESA_FORMAT_NONE) format = mt->format; switch (format) { case MESA_FORMAT_S_UINT8: /* The miptree is a W-tiled stencil buffer. Surface states can't be set * up for W tiling, so we'll need to use Y tiling and have the WM * program swizzle the coordinates. */ this->map_stencil_as_y_tiled = true; this->brw_surfaceformat = BRW_SURFACEFORMAT_R8_UNORM; break; case MESA_FORMAT_Z24_UNORM_X8_UINT: /* It would make sense to use BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS * here, but unfortunately it isn't supported as a render target, which * would prevent us from blitting to 24-bit depth. * * The miptree consists of 32 bits per pixel, arranged as 24-bit depth * values interleaved with 8 "don't care" bits. Since depth values don't * require any blending, it doesn't matter how we interpret the bit * pattern as long as we copy the right amount of data, so just map it * as 8-bit BGRA. */ this->brw_surfaceformat = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; break; case MESA_FORMAT_Z_FLOAT32: this->brw_surfaceformat = BRW_SURFACEFORMAT_R32_FLOAT; break; case MESA_FORMAT_Z_UNORM16: this->brw_surfaceformat = BRW_SURFACEFORMAT_R16_UNORM; break; default: { mesa_format linear_format = _mesa_get_srgb_format_linear(format); if (is_render_target) { assert(brw->format_supported_as_render_target[linear_format]); this->brw_surfaceformat = brw->render_target_format[linear_format]; } else { this->brw_surfaceformat = brw_format_for_mesa_format(linear_format); } break; } } }
bool brw_meta_fast_clear(struct brw_context *brw, struct gl_framebuffer *fb, GLbitfield buffers, bool partial_clear) { struct gl_context *ctx = &brw->ctx; mesa_format format; enum { FAST_CLEAR, REP_CLEAR, PLAIN_CLEAR } clear_type; GLbitfield plain_clear_buffers, meta_save, rep_clear_buffers, fast_clear_buffers; struct rect fast_clear_rect, clear_rect; int layers; fast_clear_buffers = rep_clear_buffers = plain_clear_buffers = 0; /* First we loop through the color draw buffers and determine which ones * can be fast cleared, which ones can use the replicated write and which * ones have to fall back to regular color clear. */ for (unsigned buf = 0; buf < fb->_NumColorDrawBuffers; buf++) { struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf]; struct intel_renderbuffer *irb = intel_renderbuffer(rb); int index = fb->_ColorDrawBufferIndexes[buf]; /* Only clear the buffers present in the provided mask */ if (((1 << index) & buffers) == 0) continue; /* If this is an ES2 context or GL_ARB_ES2_compatibility is supported, * the framebuffer can be complete with some attachments missing. In * this case the _ColorDrawBuffers pointer will be NULL. */ if (rb == NULL) continue; clear_type = FAST_CLEAR; /* We don't have fast clear until gen7. */ if (brw->gen < 7) clear_type = REP_CLEAR; /* If we're mapping the render format to a different format than the * format we use for texturing then it is a bit questionable whether it * should be possible to use a fast clear. Although we only actually * render using a renderable format, without the override workaround it * wouldn't be possible to have a non-renderable surface in a fast clear * state so the hardware probably legitimately doesn't need to support * this case. At least on Gen9 this really does seem to cause problems. */ if (brw->gen >= 9 && brw_format_for_mesa_format(irb->mt->format) != brw->render_target_format[irb->mt->format]) clear_type = REP_CLEAR; /* Gen9 doesn't support fast clear on single-sampled SRGB buffers. When * GL_FRAMEBUFFER_SRGB is enabled any color renderbuffers will be * resolved in intel_update_state. In that case it's pointless to do a * fast clear because it's very likely to be immediately resolved. */ if (brw->gen >= 9 && irb->mt->num_samples <= 1 && brw->ctx.Color.sRGBEnabled && _mesa_get_srgb_format_linear(irb->mt->format) != irb->mt->format) clear_type = REP_CLEAR; if (irb->mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_NO_MCS) clear_type = REP_CLEAR; /* We can't do scissored fast clears because of the restrictions on the * fast clear rectangle size. */ if (partial_clear) clear_type = REP_CLEAR; /* Fast clear is only supported for colors where all components are * either 0 or 1. */ format = _mesa_get_render_format(ctx, irb->mt->format); if (!is_color_fast_clear_compatible(brw, format, &ctx->Color.ClearColor)) clear_type = REP_CLEAR; /* 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) { perf_debug("Falling back to plain clear because %dx%d buffer is untiled\n", irb->mt->logical_width0, irb->mt->logical_height0); clear_type = PLAIN_CLEAR; } /* Constant color writes ignore everything in blend and color calculator * state. This is not documented. */ GLubyte *color_mask = ctx->Color.ColorMask[buf]; for (int i = 0; i < 4; i++) { if (_mesa_format_has_color_component(irb->mt->format, i) && !color_mask[i]) { perf_debug("Falling back to plain clear on %dx%d buffer because of color mask\n", irb->mt->logical_width0, irb->mt->logical_height0); clear_type = PLAIN_CLEAR; } } /* Allocate the MCS for non MSRT surfaces now if we're doing a fast * clear and we don't have the MCS yet. On failure, fall back to * replicated clear. */ if (clear_type == FAST_CLEAR && irb->mt->mcs_mt == NULL) if (!intel_miptree_alloc_non_msrt_mcs(brw, irb->mt)) clear_type = REP_CLEAR; switch (clear_type) { case FAST_CLEAR: set_fast_clear_color(brw, irb->mt, &ctx->Color.ClearColor); irb->need_downsample = true; /* If the buffer is already in INTEL_FAST_CLEAR_STATE_CLEAR, the * clear is redundant and can be skipped. Only skip after we've * updated the fast clear color above though. */ if (irb->mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR) continue; /* Set fast_clear_state to RESOLVED so we don't try resolve them when * we draw, in case the mt is also bound as a texture. */ irb->mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED; irb->need_downsample = true; fast_clear_buffers |= 1 << index; get_fast_clear_rect(brw, fb, irb, &fast_clear_rect); break; case REP_CLEAR: rep_clear_buffers |= 1 << index; get_buffer_rect(fb, &clear_rect); break; case PLAIN_CLEAR: plain_clear_buffers |= 1 << index; get_buffer_rect(fb, &clear_rect); continue; } } assert((fast_clear_buffers & rep_clear_buffers) == 0); if (!(fast_clear_buffers | rep_clear_buffers)) { if (plain_clear_buffers) /* If we only have plain clears, skip the meta save/restore. */ goto out; else /* Nothing left to do. This happens when we hit the redundant fast * clear case above and nothing else. */ return true; } meta_save = MESA_META_ALPHA_TEST | MESA_META_BLEND | MESA_META_DEPTH_TEST | MESA_META_RASTERIZATION | MESA_META_SHADER | MESA_META_STENCIL_TEST | MESA_META_VERTEX | MESA_META_VIEWPORT | MESA_META_CLIP | MESA_META_CLAMP_FRAGMENT_COLOR | MESA_META_MULTISAMPLE | MESA_META_OCCLUSION_QUERY | MESA_META_DRAW_BUFFERS; _mesa_meta_begin(ctx, meta_save); if (!brw_fast_clear_init(brw)) { /* This is going to be hard to recover from, most likely out of memory. * Bail and let meta try and (probably) fail for us. */ plain_clear_buffers = buffers; goto bail_to_meta; } /* Clears never have the color clamped. */ if (ctx->Extensions.ARB_color_buffer_float) _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE); _mesa_DepthMask(GL_FALSE); _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE); use_rectlist(brw, true); layers = MAX2(1, fb->MaxNumLayers); if (brw->gen >= 9 && fast_clear_buffers) { fast_clear_attachments(brw, fb, fast_clear_buffers, fast_clear_rect); } else if (fast_clear_buffers) { _mesa_meta_drawbuffers_from_bitfield(fast_clear_buffers); brw_bind_rep_write_shader(brw, (float *) fast_clear_color); set_fast_clear_op(brw, GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE); brw_draw_rectlist(brw, &fast_clear_rect, layers); set_fast_clear_op(brw, 0); /* Now set the mcs we cleared to INTEL_FAST_CLEAR_STATE_CLEAR so we'll * resolve them eventually. */ for (unsigned buf = 0; buf < fb->_NumColorDrawBuffers; buf++) { struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf]; struct intel_renderbuffer *irb = intel_renderbuffer(rb); int index = fb->_ColorDrawBufferIndexes[buf]; if ((1 << index) & fast_clear_buffers) irb->mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_CLEAR; } } if (rep_clear_buffers) { _mesa_meta_drawbuffers_from_bitfield(rep_clear_buffers); brw_bind_rep_write_shader(brw, ctx->Color.ClearColor.f); brw_draw_rectlist(brw, &clear_rect, layers); } bail_to_meta: /* Dirty _NEW_BUFFERS so we reemit SURFACE_STATE which sets the fast clear * color before resolve and sets irb->mt->fast_clear_state to UNRESOLVED if * we render to it. */ brw->NewGLState |= _NEW_BUFFERS; /* Set the custom state back to normal and dirty the same bits as above */ use_rectlist(brw, false); _mesa_meta_end(ctx); /* From BSpec: Render Target Fast Clear: * * After Render target fast clear, pipe-control with color cache * write-flush must be issued before sending any DRAW commands on that * render target. */ brw_emit_mi_flush(brw); /* If we had to fall back to plain clear for any buffers, clear those now * by calling into meta. */ out: if (plain_clear_buffers) _mesa_meta_glsl_Clear(&brw->ctx, plain_clear_buffers); return true; }