summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2010-05-04 10:06:46 +0100
committerJosé Fonseca <jfonseca@vmware.com>2010-05-04 10:08:10 +0100
commit962558daaed43b0111cd062e32821aad106869d7 (patch)
tree8304d2206532a69d3dc11740bb007cf604e63daa
parent3c6756d6f56644784b9e7c2550a6b796e7d1defd (diff)
gallivm: Implement TXD.
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c39
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.h5
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c49
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample.c7
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 8ceb20473d..40f2b571f7 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 54c0ad7ce4..5927923271 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 2eac5da6c6..4ca730a98a 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 e699e44a24..6659cff870 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 74b7393e4e..3f788e598f 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);
}