From 962558daaed43b0111cd062e32821aad106869d7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 4 May 2010 10:06:46 +0100 Subject: [PATCH] gallivm: Implement TXD. --- src/gallium/auxiliary/gallivm/lp_bld_sample.h | 2 + .../auxiliary/gallivm/lp_bld_sample_soa.c | 39 ++++++--------- src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 5 ++ .../auxiliary/gallivm/lp_bld_tgsi_soa.c | 49 ++++++++++++++----- src/gallium/drivers/llvmpipe/lp_tex_sample.c | 7 +-- 5 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h index 8ceb20473d5..40f2b571f79 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h @@ -173,6 +173,8 @@ lp_build_sample_soa(LLVMBuilderRef builder, unsigned unit, unsigned num_coords, const LLVMValueRef *coords, + const LLVMValueRef *ddx, + const LLVMValueRef *ddy, LLVMValueRef lodbias, 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 54c0ad7ce43..59279232717 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -913,6 +913,8 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *ddx, + const LLVMValueRef *ddy, LLVMValueRef shader_lod_bias, LLVMValueRef width, LLVMValueRef height, @@ -936,12 +938,6 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, bld->static_state->max_lod); LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0); - LLVMValueRef index1 = LLVMConstInt(LLVMInt32Type(), 1, 0); - LLVMValueRef index2 = LLVMConstInt(LLVMInt32Type(), 2, 0); - - LLVMValueRef s0, s1, s2; - LLVMValueRef t0, t1, t2; - LLVMValueRef r0, r1, r2; LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy; LLVMValueRef rho, lod; @@ -952,30 +948,20 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, * dtdy = abs(t[2] - t[0]); * drdx = abs(r[1] - r[0]); * drdy = abs(r[2] - r[0]); - * XXX we're assuming a four-element quad in 2x2 layout here. */ - s0 = LLVMBuildExtractElement(bld->builder, s, index0, "s0"); - s1 = LLVMBuildExtractElement(bld->builder, s, index1, "s1"); - s2 = LLVMBuildExtractElement(bld->builder, s, index2, "s2"); - dsdx = LLVMBuildSub(bld->builder, s1, s0, ""); + dsdx = LLVMBuildExtractElement(bld->builder, ddx[0], index0, "dsdx"); dsdx = lp_build_abs(float_bld, dsdx); - dsdy = LLVMBuildSub(bld->builder, s2, s0, ""); + dsdy = LLVMBuildExtractElement(bld->builder, ddy[0], index0, "dsdy"); dsdy = lp_build_abs(float_bld, dsdy); if (dims > 1) { - t0 = LLVMBuildExtractElement(bld->builder, t, index0, "t0"); - t1 = LLVMBuildExtractElement(bld->builder, t, index1, "t1"); - t2 = LLVMBuildExtractElement(bld->builder, t, index2, "t2"); - dtdx = LLVMBuildSub(bld->builder, t1, t0, ""); + dtdx = LLVMBuildExtractElement(bld->builder, ddx[1], index0, "dsdx"); dtdx = lp_build_abs(float_bld, dtdx); - dtdy = LLVMBuildSub(bld->builder, t2, t0, ""); + dtdy = LLVMBuildExtractElement(bld->builder, ddy[1], index0, "dtdy"); dtdy = lp_build_abs(float_bld, dtdy); if (dims > 2) { - r0 = LLVMBuildExtractElement(bld->builder, r, index0, "r0"); - r1 = LLVMBuildExtractElement(bld->builder, r, index1, "r1"); - r2 = LLVMBuildExtractElement(bld->builder, r, index2, "r2"); - drdx = LLVMBuildSub(bld->builder, r1, r0, ""); + drdx = LLVMBuildExtractElement(bld->builder, ddx[2], index0, "dsdx"); drdx = lp_build_abs(float_bld, drdx); - drdy = LLVMBuildSub(bld->builder, r2, r0, ""); + drdy = LLVMBuildExtractElement(bld->builder, ddy[2], index0, "drdy"); drdy = lp_build_abs(float_bld, drdy); } } @@ -1596,6 +1582,8 @@ lp_build_sample_general(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *ddx, + const LLVMValueRef *ddy, LLVMValueRef lodbias, LLVMValueRef width, LLVMValueRef height, @@ -1634,7 +1622,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, lodbias, width, height, depth); + lod = lp_build_lod_selector(bld, s, t, r, ddx, ddy, lodbias, + width, height, depth); } /* @@ -2092,6 +2081,8 @@ lp_build_sample_soa(LLVMBuilderRef builder, unsigned unit, unsigned num_coords, const LLVMValueRef *coords, + const LLVMValueRef *ddx, + const LLVMValueRef *ddy, LLVMValueRef lodbias, LLVMValueRef *texel) { @@ -2159,7 +2150,7 @@ lp_build_sample_soa(LLVMBuilderRef builder, row_stride_array, data_array, texel); } else { - lp_build_sample_general(&bld, unit, s, t, r, lodbias, + lp_build_sample_general(&bld, unit, s, t, r, ddx, ddy, lodbias, 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 2eac5da6c69..4ca730a98a0 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -45,6 +45,9 @@ struct lp_build_context; struct lp_build_mask_context; +#define LP_BLD_SAMPLER_EXPLICIT_DERIVATIVES 1 + + /** * Sampler code generation interface. * @@ -65,6 +68,8 @@ struct lp_build_sampler_soa unsigned unit, unsigned num_coords, const LLVMValueRef *coords, + const LLVMValueRef *ddx, + const LLVMValueRef *ddy, LLVMValueRef lodbias, 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 e699e44a24e..6659cff8706 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -592,18 +592,26 @@ emit_store( * High-level instruction translators. */ +enum tex_modifier { + TEX_MODIFIER_NONE = 0, + TEX_MODIFIER_PROJECTED, + TEX_MODIFIER_LOD_BIAS, + TEX_MODIFIER_EXPLICIT_LOD, + TEX_MODIFIER_EXPLICIT_DERIV +}; static void emit_tex( struct lp_build_tgsi_soa_context *bld, const struct tgsi_full_instruction *inst, - boolean apply_lodbias, - boolean projected, + enum tex_modifier modifier, LLVMValueRef *texel) { - const uint unit = inst->Src[1].Register.Index; + unsigned unit; LLVMValueRef lodbias; LLVMValueRef oow = NULL; LLVMValueRef coords[3]; + LLVMValueRef ddx[3]; + LLVMValueRef ddy[3]; unsigned num_coords; unsigned i; @@ -635,29 +643,45 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, return; } - if(apply_lodbias) + /* FIXME: Treat TEX_MODIFIER_EXPLICIT_LOD correctly */ + if (modifier == TEX_MODIFIER_LOD_BIAS || TEX_MODIFIER_EXPLICIT_LOD) lodbias = emit_fetch( bld, inst, 0, 3 ); else lodbias = bld->base.zero; - if (projected) { + if (modifier == TEX_MODIFIER_PROJECTED) { oow = emit_fetch( bld, inst, 0, 3 ); oow = lp_build_rcp(&bld->base, oow); } for (i = 0; i < num_coords; i++) { coords[i] = emit_fetch( bld, inst, 0, i ); - if (projected) + if (modifier == TEX_MODIFIER_PROJECTED) coords[i] = lp_build_mul(&bld->base, coords[i], oow); } for (i = num_coords; i < 3; i++) { coords[i] = bld->base.undef; } + if (modifier == TEX_MODIFIER_EXPLICIT_DERIV) { + for (i = 0; i < num_coords; i++) { + ddx[i] = emit_fetch( bld, inst, 1, i ); + ddy[i] = emit_fetch( bld, inst, 2, i ); + } + unit = inst->Src[3].Register.Index; + } else { + for (i = 0; i < num_coords; i++) { + ddx[i] = emit_ddx( bld, coords[i] ); + ddy[i] = emit_ddy( bld, coords[i] ); + } + unit = inst->Src[1].Register.Index; + } + bld->sampler->emit_fetch_texel(bld->sampler, bld->base.builder, bld->base.type, - unit, num_coords, coords, lodbias, + unit, num_coords, coords, + ddx, ddy, lodbias, texel); } @@ -1361,12 +1385,11 @@ emit_instruction( break; case TGSI_OPCODE_TEX: - emit_tex( bld, inst, FALSE, FALSE, dst0 ); + emit_tex( bld, inst, TEX_MODIFIER_NONE, dst0 ); break; case TGSI_OPCODE_TXD: - /* FIXME */ - return FALSE; + emit_tex( bld, inst, TEX_MODIFIER_EXPLICIT_DERIV, dst0 ); break; case TGSI_OPCODE_UP2H: @@ -1468,7 +1491,7 @@ emit_instruction( break; case TGSI_OPCODE_TXB: - emit_tex( bld, inst, TRUE, FALSE, dst0 ); + emit_tex( bld, inst, TEX_MODIFIER_LOD_BIAS, dst0 ); break; case TGSI_OPCODE_NRM: @@ -1573,11 +1596,11 @@ emit_instruction( break; case TGSI_OPCODE_TXL: - emit_tex( bld, inst, TRUE, FALSE, dst0 ); + emit_tex( bld, inst, TEX_MODIFIER_EXPLICIT_LOD, dst0 ); break; case TGSI_OPCODE_TXP: - emit_tex( bld, inst, FALSE, TRUE, dst0 ); + emit_tex( bld, inst, TEX_MODIFIER_PROJECTED, dst0 ); break; case TGSI_OPCODE_BRK: diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c index 74b7393e4ec..3f788e598fc 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c @@ -170,6 +170,8 @@ lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base, unsigned unit, unsigned num_coords, const LLVMValueRef *coords, + const LLVMValueRef *ddx, + const LLVMValueRef *ddy, LLVMValueRef lodbias, LLVMValueRef *texel) { @@ -182,9 +184,8 @@ lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base, &sampler->dynamic_state.base, type, unit, - num_coords, - coords, - lodbias, + num_coords, coords, + ddx, ddy, lodbias, texel); } -- 2.30.2