diff options
author | Topi Pohjolainen <[email protected]> | 2016-08-31 10:08:17 +0300 |
---|---|---|
committer | Topi Pohjolainen <[email protected]> | 2016-09-12 11:46:13 +0300 |
commit | 1b6fcc08df677725cf5ee4e913ebfbd2bff27e22 (patch) | |
tree | ba5db5f3804ec08ef1b501ef47268c7fdc1e1f74 | |
parent | 22d9a4824baf0bf89bb8e39025ad01fecb213888 (diff) |
i965/rbc: Consult rb settings for texture surface setup
Once mcs buffer gets allocated without delay for lossless
compression (same as we do for msaa), one gets regression in:
GL45-CTS.texture_barrier_ARB.same-texel-rw
Setting the auxiliary surface for both sampling engine and data
port seems to fix this. I haven't found any hardware documentation
backing this though.
v2 (Jason): Prepare also for the case where surface is sampled with
non-compressible format forcing also rendering without
compression.
v3: Split asserts and decision making.
v4: Detailed comment provided by Jason explaining the need for using
auxiliary buffer for texturing when the same surface is also
used as render target.
Added check for existence of renderbuffer before considering if
underlying miptree matches.
Signed-off-by: Topi Pohjolainen <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 67 |
1 files changed, 60 insertions, 7 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 62a4eb8ed27..f12df8f634e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -140,9 +140,7 @@ brw_emit_surface_state(struct brw_context *brw, struct isl_surf *aux_surf = NULL, aux_surf_s; uint64_t aux_offset = 0; enum isl_aux_usage aux_usage = ISL_AUX_USAGE_NONE; - if (mt->mcs_mt && - ((view.usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) || - mt->fast_clear_state != INTEL_FAST_CLEAR_STATE_RESOLVED)) { + if (mt->mcs_mt && !(flags & INTEL_AUX_BUFFER_DISABLED)) { intel_miptree_get_aux_isl_surf(brw, mt, &aux_surf_s, &aux_usage); aux_surf = &aux_surf_s; assert(mt->mcs_mt->offset == 0); @@ -425,6 +423,58 @@ swizzle_to_scs(GLenum swizzle, bool need_green_to_blue) return (need_green_to_blue && scs == HSW_SCS_GREEN) ? HSW_SCS_BLUE : scs; } +static unsigned +brw_find_matching_rb(const struct gl_framebuffer *fb, + const struct intel_mipmap_tree *mt) +{ + for (unsigned i = 0; i < fb->_NumColorDrawBuffers; i++) { + const struct intel_renderbuffer *irb = + intel_renderbuffer(fb->_ColorDrawBuffers[i]); + + if (irb && irb->mt == mt) + return i; + } + + return fb->_NumColorDrawBuffers; +} + +static bool +brw_disable_aux_surface(const struct brw_context *brw, + const struct intel_mipmap_tree *mt) +{ + /* Nothing to disable. */ + if (!mt->mcs_mt) + return false; + + /* There are special cases only for lossless compression. */ + if (!intel_miptree_is_lossless_compressed(brw, mt)) + return mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED; + + const struct gl_framebuffer *fb = brw->ctx.DrawBuffer; + const unsigned rb_index = brw_find_matching_rb(fb, mt); + + /* If we are drawing into this with compression enabled, then we must also + * enable compression when texturing from it regardless of + * fast_clear_state. If we don't then, after the first draw call with + * this setup, there will be data in the CCS which won't get picked up by + * subsequent texturing operations as required by ARB_texture_barrier. + * Since we don't want to re-emit the binding table or do a resolve + * operation every draw call, the easiest thing to do is just enable + * compression on the texturing side. This is completely safe to do + * since, if compressed texturing weren't allowed, we would have disabled + * compression of render targets in whatever_that_function_is_called(). + */ + if (rb_index < fb->_NumColorDrawBuffers) { + if (brw->draw_aux_buffer_disabled[rb_index]) { + assert(mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED); + } + + return brw->draw_aux_buffer_disabled[rb_index]; + } + + return mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED; +} + void brw_update_texture_surface(struct gl_context *ctx, unsigned unit, @@ -542,7 +592,8 @@ brw_update_texture_surface(struct gl_context *ctx, obj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) view.usage |= ISL_SURF_USAGE_CUBE_BIT; - const int flags = 0; + const int flags = + brw_disable_aux_surface(brw, mt) ? INTEL_AUX_BUFFER_DISABLED : 0; brw_emit_surface_state(brw, mt, flags, mt->target, view, surface_state_infos[brw->gen].tex_mocs, surf_offset, surf_index, @@ -1113,7 +1164,8 @@ update_renderbuffer_read_surfaces(struct brw_context *brw) .usage = ISL_SURF_USAGE_TEXTURE_BIT, }; - const int flags = 0; + const int flags = brw->draw_aux_buffer_disabled[i] ? + INTEL_AUX_BUFFER_DISABLED : 0; brw_emit_surface_state(brw, irb->mt, flags, target, view, surface_state_infos[brw->gen].tex_mocs, surf_offset, surf_index, @@ -1672,8 +1724,9 @@ update_image_surface(struct brw_context *brw, }; const int surf_index = surf_offset - &brw->wm.base.surf_offset[0]; - - const int flags = 0; + const int flags = + mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED ? + INTEL_AUX_BUFFER_DISABLED : 0; brw_emit_surface_state(brw, mt, flags, mt->target, view, surface_state_infos[brw->gen].tex_mocs, surf_offset, surf_index, |