[Mesa-dev] [PATCH 2/9] i965: Fix textureGrad with cube samplers
Roland Scheidegger
sroland at vmware.com
Tue Feb 24 10:39:32 PST 2015
As a side note (not really directly related to the patch) I think this
could benefit from some optimization, unless there's some passes
somewhere which can already do this.
The non-scalar (non-cube) calculation does this:
lod_info.lod = log2(max(sqrt(dot1), sqrt(dot2)))
The second sqrt can be trivially eliminated:
= log2(sqrt(max(dot1, dot2)))
And furthermore the remaining sqrt can be killed off too thanks to
n*log2(x) = log2(x^n)
= 0.5*log2(max(dot1, dot2)))
I don't really know anything about the hw, but I would think this should
be faster not only on the 1 mathbox-per-gpu ancient igps ;-).
Roland
Am 24.02.2015 um 19:02 schrieb Eduardo Lima Mitev:
> From: Iago Toral Quiroga <itoral at igalia.com>
>
> We can't use sampler messages with gradient information (like
> sample_g or sample_d) to deal with this scenario because according
> to the PRM:
>
> "The r coordinate and its gradients are required only for surface
> types that use the third coordinate. Usage of this message type on
> cube surfaces assumes that the u, v, and gradients have already been
> transformed onto the appropriate face, but still in [-1,+1] range.
> The r coordinate contains the faceid, and the r gradients are ignored
> by hardware."
>
> Instead, we should lower this to compute the LOD manually based on the
> gradients and use a different sample message that takes the computed
> LOD instead of the gradients. This is already being done in
> brw_lower_texture_gradients.cpp, but it is restricted to shadow
> samplers only, although there is a comment stating that we should
> probably do this also for samplerCube and samplerCubeArray.
>
> Because of this, both dEQP and Piglit test cases for textureGrad with
> cube maps currently fail.
>
> This patch does two things:
> 1) Activates the texturegrad lowering pass for all cube samplers.
> 2) Corrects the computation of the LOD value for cube samplers.
>
> I had to do 2) because for cube maps the calculations implemented
> in the lowering pass always compute a value of rho that is twice
> the value we want (so we get a LOD value one unit larger than we
> want). This only happens for cube map samplers (all kinds). I am
> not sure about why we need to do this, but I suspect that it is
> related to the fact that cube map coordinates, when transported
> to a specific face in the cube, are in the range [-1, 1] instead of
> [0, 1] so we probably need to divide the derivatives by 2 when
> we compute the LOD. Doing that would produce the same result as
> dividing the final rho computation by 2 (or removing a unit
> from the computed LOD, which is what we are doing here).
>
> Fixes the following piglit tests:
> bin/tex-miplevel-selection textureGrad Cube -auto -fbo
> bin/tex-miplevel-selection textureGrad CubeArray -auto -fbo
> bin/tex-miplevel-selection textureGrad CubeShadow -auto -fbo
>
> Fixes 10 dEQP tests in the following category:
> dEQP-GLES3.functional.shaders.texture_functions.texturegrad.*cube*
> ---
> .../dri/i965/brw_lower_texture_gradients.cpp | 26 +++++++++++++++-------
> 1 file changed, 18 insertions(+), 8 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp b/src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp
> index 9679d28..878a54e 100644
> --- a/src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_lower_texture_gradients.cpp
> @@ -89,19 +89,18 @@ txs_type(const glsl_type *type)
> ir_visitor_status
> lower_texture_grad_visitor::visit_leave(ir_texture *ir)
> {
> - /* Only lower textureGrad with shadow samplers */
> - if (ir->op != ir_txd || !ir->shadow_comparitor)
> + /* Only lower textureGrad with cube maps or shadow samplers */
> + if (ir->op != ir_txd ||
> + (ir->sampler->type->sampler_dimensionality != GLSL_SAMPLER_DIM_CUBE &&
> + !ir->shadow_comparitor))
> return visit_continue;
>
> - /* Lower textureGrad() with samplerCubeShadow even if we have the sample_d_c
> + /* Lower textureGrad() with samplerCube* even if we have the sample_d_c
> * message. GLSL provides gradients for the 'r' coordinate. Unfortunately:
> *
> * From the Ivybridge PRM, Volume 4, Part 1, sample_d message description:
> * "The r coordinate contains the faceid, and the r gradients are ignored
> * by hardware."
> - *
> - * We likely need to do a similar treatment for samplerCube and
> - * samplerCubeArray, but we have insufficient testing for that at the moment.
> */
> bool need_lowering = !has_sample_d_c ||
> ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE;
> @@ -153,9 +152,20 @@ lower_texture_grad_visitor::visit_leave(ir_texture *ir)
> expr(ir_unop_sqrt, dot(dPdy, dPdy)));
> }
>
> - /* lambda_base = log2(rho). We're ignoring GL state biases for now. */
> + /* lambda_base = log2(rho). We're ignoring GL state biases for now.
> + *
> + * For cube maps the result of these formulas is giving us a value of rho
> + * that is twice the value we should use, so divide it by 2 or,
> + * alternatively, remove one unit from the result of the log2 computation.
> + */
> ir->op = ir_txl;
> - ir->lod_info.lod = expr(ir_unop_log2, rho);
> + if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) {
> + ir->lod_info.lod = expr(ir_binop_add,
> + expr(ir_unop_log2, rho),
> + new(mem_ctx) ir_constant(-1.0f));
> + } else {
> + ir->lod_info.lod = expr(ir_unop_log2, rho);
> + }
>
> progress = true;
> return visit_continue;
>
More information about the mesa-dev
mailing list