From: José Fonseca Date: Tue, 4 May 2010 12:51:54 +0000 (+0100) Subject: gallivm: Proper implementation of TXL opcode. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ec43b2eb45a1b2e33f328f76624c987484e329f3;p=mesa.git gallivm: Proper implementation of TXL opcode. --- diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h index 40f2b571f79..955b1d21ee5 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h @@ -175,7 +175,8 @@ lp_build_sample_soa(LLVMBuilderRef builder, const LLVMValueRef *coords, const LLVMValueRef *ddx, const LLVMValueRef *ddy, - LLVMValueRef lodbias, + LLVMValueRef lod_bias, + LLVMValueRef explicit_lod, LLVMValueRef *texel); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index d1592c22f43..3f0ea05b795 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -30,6 +30,7 @@ * Texture sampling -- SoA. * * @author Jose Fonseca + * @author Brian Paul */ #include "pipe/p_defines.h" @@ -903,10 +904,14 @@ lp_build_minify(struct lp_build_sample_context *bld, * \param s vector of texcoord s values * \param t vector of texcoord t values * \param r vector of texcoord r values - * \param shader_lod_bias vector float with the shader lod bias, + * \param lod_bias optional float vector with the shader lod bias + * \param explicit_lod optional float vector with the explicit lod * \param width scalar int texture width * \param height scalar int texture height * \param depth scalar int texture depth + * + * XXX: The resulting lod is scalar, so ignore all but the first element of + * derivatives, lod_bias, etc that are passed by the shader. */ static LLVMValueRef lp_build_lod_selector(struct lp_build_sample_context *bld, @@ -915,7 +920,8 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, LLVMValueRef r, const LLVMValueRef *ddx, const LLVMValueRef *ddy, - LLVMValueRef shader_lod_bias, + LLVMValueRef lod_bias, /* optional */ + LLVMValueRef explicit_lod, /* optional */ LLVMValueRef width, LLVMValueRef height, LLVMValueRef depth) @@ -928,7 +934,6 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, return LLVMConstReal(LLVMFloatType(), bld->static_state->min_lod); } else { - const int dims = texture_dims(bld->static_state->target); struct lp_build_context *float_bld = &bld->float_bld; LLVMValueRef sampler_lod_bias = LLVMConstReal(LLVMFloatType(), bld->static_state->lod_bias); @@ -936,67 +941,76 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, bld->static_state->min_lod); LLVMValueRef max_lod = LLVMConstReal(LLVMFloatType(), bld->static_state->max_lod); - LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0); - LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy; - LLVMValueRef rho, lod; - - /* - * dsdx = abs(s[1] - s[0]); - * dsdy = abs(s[2] - s[0]); - * dtdx = abs(t[1] - t[0]); - * dtdy = abs(t[2] - t[0]); - * drdx = abs(r[1] - r[0]); - * drdy = abs(r[2] - r[0]); - */ - dsdx = LLVMBuildExtractElement(bld->builder, ddx[0], index0, "dsdx"); - dsdx = lp_build_abs(float_bld, dsdx); - dsdy = LLVMBuildExtractElement(bld->builder, ddy[0], index0, "dsdy"); - dsdy = lp_build_abs(float_bld, dsdy); - if (dims > 1) { - dtdx = LLVMBuildExtractElement(bld->builder, ddx[1], index0, "dtdx"); - dtdx = lp_build_abs(float_bld, dtdx); - dtdy = LLVMBuildExtractElement(bld->builder, ddy[1], index0, "dtdy"); - dtdy = lp_build_abs(float_bld, dtdy); - if (dims > 2) { - drdx = LLVMBuildExtractElement(bld->builder, ddx[2], index0, "drdx"); - drdx = lp_build_abs(float_bld, drdx); - drdy = LLVMBuildExtractElement(bld->builder, ddy[2], index0, "drdy"); - drdy = lp_build_abs(float_bld, drdy); - } + LLVMValueRef lod; + + if (explicit_lod) { + lod = LLVMBuildExtractElement(bld->builder, explicit_lod, + index0, ""); } + else { + const int dims = texture_dims(bld->static_state->target); + LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy; + LLVMValueRef rho; + + /* + * dsdx = abs(s[1] - s[0]); + * dsdy = abs(s[2] - s[0]); + * dtdx = abs(t[1] - t[0]); + * dtdy = abs(t[2] - t[0]); + * drdx = abs(r[1] - r[0]); + * drdy = abs(r[2] - r[0]); + */ + dsdx = LLVMBuildExtractElement(bld->builder, ddx[0], index0, "dsdx"); + dsdx = lp_build_abs(float_bld, dsdx); + dsdy = LLVMBuildExtractElement(bld->builder, ddy[0], index0, "dsdy"); + dsdy = lp_build_abs(float_bld, dsdy); + if (dims > 1) { + dtdx = LLVMBuildExtractElement(bld->builder, ddx[1], index0, "dtdx"); + dtdx = lp_build_abs(float_bld, dtdx); + dtdy = LLVMBuildExtractElement(bld->builder, ddy[1], index0, "dtdy"); + dtdy = lp_build_abs(float_bld, dtdy); + if (dims > 2) { + drdx = LLVMBuildExtractElement(bld->builder, ddx[2], index0, "drdx"); + drdx = lp_build_abs(float_bld, drdx); + drdy = LLVMBuildExtractElement(bld->builder, ddy[2], index0, "drdy"); + drdy = lp_build_abs(float_bld, drdy); + } + } - /* Compute rho = max of all partial derivatives scaled by texture size. - * XXX this could be vectorized somewhat - */ - rho = LLVMBuildMul(bld->builder, - lp_build_max(float_bld, dsdx, dsdy), - lp_build_int_to_float(float_bld, width), ""); - if (dims > 1) { - LLVMValueRef max; - max = LLVMBuildMul(bld->builder, - lp_build_max(float_bld, dtdx, dtdy), - lp_build_int_to_float(float_bld, height), ""); - rho = lp_build_max(float_bld, rho, max); - if (dims > 2) { + /* Compute rho = max of all partial derivatives scaled by texture size. + * XXX this could be vectorized somewhat + */ + rho = LLVMBuildMul(bld->builder, + lp_build_max(float_bld, dsdx, dsdy), + lp_build_int_to_float(float_bld, width), ""); + if (dims > 1) { + LLVMValueRef max; max = LLVMBuildMul(bld->builder, - lp_build_max(float_bld, drdx, drdy), - lp_build_int_to_float(float_bld, depth), ""); + lp_build_max(float_bld, dtdx, dtdy), + lp_build_int_to_float(float_bld, height), ""); rho = lp_build_max(float_bld, rho, max); + if (dims > 2) { + max = LLVMBuildMul(bld->builder, + lp_build_max(float_bld, drdx, drdy), + lp_build_int_to_float(float_bld, depth), ""); + rho = lp_build_max(float_bld, rho, max); + } } - } - /* compute lod = log2(rho) */ - lod = lp_build_log2(float_bld, rho); + /* compute lod = log2(rho) */ + lod = lp_build_log2(float_bld, rho); - /* add sampler lod bias */ - lod = LLVMBuildAdd(bld->builder, lod, sampler_lod_bias, "sampler LOD bias"); + /* add shader lod bias */ + if (lod_bias) { + lod_bias = LLVMBuildExtractElement(bld->builder, lod_bias, + index0, ""); + lod = LLVMBuildAdd(bld->builder, lod, lod_bias, "shader_lod_bias"); + } + } - /* add shader lod bias */ - /* XXX for now we take only the first element since our lod is scalar */ - shader_lod_bias = LLVMBuildExtractElement(bld->builder, shader_lod_bias, - LLVMConstInt(LLVMInt32Type(), 0, 0), ""); - lod = LLVMBuildAdd(bld->builder, lod, shader_lod_bias, "shader LOD bias"); + /* add sampler lod bias */ + lod = LLVMBuildAdd(bld->builder, lod, sampler_lod_bias, "sampler_lod_bias"); /* clamp lod */ lod = lp_build_clamp(float_bld, lod, min_lod, max_lod); @@ -1584,7 +1598,8 @@ lp_build_sample_general(struct lp_build_sample_context *bld, LLVMValueRef r, const LLVMValueRef *ddx, const LLVMValueRef *ddy, - LLVMValueRef lodbias, + LLVMValueRef lod_bias, /* optional */ + LLVMValueRef explicit_lod, /* optional */ LLVMValueRef width, LLVMValueRef height, LLVMValueRef depth, @@ -1622,7 +1637,8 @@ lp_build_sample_general(struct lp_build_sample_context *bld, /* Need to compute lod either to choose mipmap levels or to * distinguish between minification/magnification with one mipmap level. */ - lod = lp_build_lod_selector(bld, s, t, r, ddx, ddy, lodbias, + lod = lp_build_lod_selector(bld, s, t, r, ddx, ddy, + lod_bias, explicit_lod, width, height, depth); } @@ -2083,7 +2099,8 @@ lp_build_sample_soa(LLVMBuilderRef builder, const LLVMValueRef *coords, const LLVMValueRef *ddx, const LLVMValueRef *ddy, - LLVMValueRef lodbias, + LLVMValueRef lod_bias, /* optional */ + LLVMValueRef explicit_lod, /* optional */ LLVMValueRef *texel) { struct lp_build_sample_context bld; @@ -2150,7 +2167,8 @@ lp_build_sample_soa(LLVMBuilderRef builder, row_stride_array, data_array, texel); } else { - lp_build_sample_general(&bld, unit, s, t, r, ddx, ddy, lodbias, + lp_build_sample_general(&bld, unit, s, t, r, ddx, ddy, + lod_bias, explicit_lod, width, height, depth, width_vec, height_vec, depth_vec, row_stride_array, img_stride_array, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 71c51db7869..5ce1385c480 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -67,7 +67,8 @@ struct lp_build_sampler_soa const LLVMValueRef *coords, const LLVMValueRef *ddx, const LLVMValueRef *ddy, - LLVMValueRef lodbias, + LLVMValueRef lod_bias, /* optional */ + LLVMValueRef explicit_lod, /* optional */ LLVMValueRef *texel); }; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 022223bb296..0b1a28a7ab7 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -607,7 +607,7 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, LLVMValueRef *texel) { unsigned unit; - LLVMValueRef lodbias; + LLVMValueRef lod_bias, explicit_lod; LLVMValueRef oow = NULL; LLVMValueRef coords[3]; LLVMValueRef ddx[3]; @@ -643,11 +643,18 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, return; } - /* FIXME: Treat TEX_MODIFIER_EXPLICIT_LOD correctly */ - if (modifier == TEX_MODIFIER_LOD_BIAS || modifier == TEX_MODIFIER_EXPLICIT_LOD) - lodbias = emit_fetch( bld, inst, 0, 3 ); - else - lodbias = bld->base.zero; + if (modifier == TEX_MODIFIER_LOD_BIAS) { + lod_bias = emit_fetch( bld, inst, 0, 3 ); + explicit_lod = NULL; + } + else if (modifier == TEX_MODIFIER_EXPLICIT_LOD) { + lod_bias = NULL; + explicit_lod = emit_fetch( bld, inst, 0, 3 ); + } + else { + lod_bias = NULL; + explicit_lod = NULL; + } if (modifier == TEX_MODIFIER_PROJECTED) { oow = emit_fetch( bld, inst, 0, 3 ); @@ -685,7 +692,8 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, bld->base.builder, bld->base.type, unit, num_coords, coords, - ddx, ddy, lodbias, + ddx, ddy, + lod_bias, explicit_lod, texel); } diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c index 3f788e598fc..d3a9d39f616 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c @@ -172,7 +172,8 @@ lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base, const LLVMValueRef *coords, const LLVMValueRef *ddx, const LLVMValueRef *ddy, - LLVMValueRef lodbias, + LLVMValueRef lod_bias, /* optional */ + LLVMValueRef explicit_lod, /* optional */ LLVMValueRef *texel) { struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base; @@ -185,7 +186,8 @@ lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base, type, unit, num_coords, coords, - ddx, ddy, lodbias, + ddx, ddy, + lod_bias, explicit_lod, texel); }