From 67ea399fab0b984bfce23a19938709fd720137fd Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 11 Mar 2015 13:57:04 +0100 Subject: [PATCH 2/2] i965: Enable EWA algorithm in IvyBridge for isotropic filters As per description in bug 82463 this improves image quality when using isotropic filters in some cases. However, this breaks many tex-miplevel-selection tests for textureGrad. This is explained in the Haswell PRM, which includes the following Programming Note: "When EWA (is) used for non-anisotropic filtering and the coordinates have zero derivative the computed LOD is 0 instead of -inf." This means that in certain situations the EWA algorithm, when used in isotropic scenarios, leads to incorrect LOD computations, and thus, incorrect rendering. For textureGrad, we can fix this by enabling the lowering we are currently using for shadow samplers, where we compute the LOD manually for the texture gradients. However, that will only fix textureGrad but the problem will still exist for other texture functions. This is clearly visible with the following piglit test that is regressed after fixing textureGrad: bin/arb_shader_texture_lod-texgrad -auto -fbo This test renders two samples using texture() and textureGrad() and expects both renderings to be the same. This patch breaks this because for the textureGrad case we are computing LOD manually, but in the texture case the hardware is computing the LOD and thus, is subject to incorrect LOD computations in some cases, which leads to noticeable differences in the way the texture is rendered. --- src/mesa/drivers/dri/i965/brw_sampler_state.c | 17 ++++++++++++++--- src/mesa/drivers/dri/i965/brw_state.h | 3 ++- src/mesa/drivers/dri/i965/gen6_blorp.cpp | 3 ++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_sampler_state.c b/src/mesa/drivers/dri/i965/brw_sampler_state.c index c532850..7b205c2 100644 --- a/src/mesa/drivers/dri/i965/brw_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_sampler_state.c @@ -91,7 +91,8 @@ brw_emit_sampler_state(struct brw_context *brw, unsigned base_level, unsigned shadow_function, bool non_normalized_coordinates, - uint32_t border_color_offset) + uint32_t border_color_offset, + bool enable_ewa) { ss[0] = BRW_SAMPLER_LOD_PRECLAMP_ENABLE | SET_FIELD(base_level, BRW_SAMPLER_BASE_MIPLEVEL) | @@ -114,7 +115,7 @@ brw_emit_sampler_state(struct brw_context *brw, if (brw->gen >= 7) { ss[0] |= SET_FIELD(lod_bias & 0x1fff, GEN7_SAMPLER_LOD_BIAS); - if (min_filter == BRW_MAPFILTER_ANISOTROPIC) + if (enable_ewa) ss[0] |= GEN7_SAMPLER_EWA_ANISOTROPIC_ALGORITHM; ss[1] = SET_FIELD(min_lod, GEN7_SAMPLER_MIN_LOD) | @@ -444,6 +445,15 @@ brw_update_sampler_state(struct brw_context *brw, } } + /* Enable EWA algorithm for anisotropic filter and also + * for isotropic case in IvyBridge + */ + bool enable_ewa = false; + if (min_filter == BRW_MAPFILTER_ANISOTROPIC || + (brw->gen == 7 && !brw->is_haswell)) { + enable_ewa = true; + } + /* Set address rounding bits if not using nearest filtering. */ unsigned address_rounding = 0; if (min_filter != BRW_MAPFILTER_NEAREST) { @@ -525,7 +535,8 @@ brw_update_sampler_state(struct brw_context *brw, min_lod, max_lod, lod_bias, base_level, shadow_function, non_normalized_coords, - border_color_offset); + border_color_offset, + enable_ewa); } diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 71210b9..abf75ba 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -267,7 +267,8 @@ void brw_emit_sampler_state(struct brw_context *brw, unsigned base_level, unsigned shadow_function, bool non_normalized_coordinates, - uint32_t border_color_offset); + uint32_t border_color_offset, + bool enable_ewa); /* gen6_sf_state.c */ void diff --git a/src/mesa/drivers/dri/i965/gen6_blorp.cpp b/src/mesa/drivers/dri/i965/gen6_blorp.cpp index e45705a..b60c187 100644 --- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp +++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp @@ -482,7 +482,8 @@ gen6_blorp_emit_sampler_state(struct brw_context *brw, 0, /* base miplevel */ 0, /* shadow function */ true, /* non-normalized coordinates */ - 0); /* border color offset - unused */ + 0, /* border color offset - unused */ + false); /* enable EWA algorithm */ return sampler_offset; } -- 1.9.1