gallivm: honor explicit derivatives values for cube maps.

This is trivial now, though need to make sure we pass all the necessary
derivative values (which is 3 each for ddx/ddy not 2).
Passes piglit arb_shader_texture_lod-texgradcube test.

v2: add the forgotten abs() for all incoming derivatives (discovered
by new piglit arb_shader_texture_lod-texgradcube test, though more by
luck as it was failing only for exactly one pixel...).

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
This commit is contained in:
Roland Scheidegger 2013-04-04 00:56:23 +02:00
parent f621015cb5
commit ce5096a0a9
4 changed files with 60 additions and 28 deletions

View file

@ -1287,6 +1287,7 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
const struct lp_derivatives *derivs, /* optional */
LLVMValueRef *face,
LLVMValueRef *face_s,
LLVMValueRef *face_t,
@ -1296,7 +1297,6 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
LLVMBuilderRef builder = bld->gallivm->builder;
struct gallivm_state *gallivm = bld->gallivm;
LLVMValueRef si, ti, ri;
boolean implicit_derivs = TRUE;
boolean need_derivs = TRUE;
if (1 || coord_bld->type.length > 4) {
@ -1334,9 +1334,9 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
assert(PIPE_TEX_FACE_NEG_Z == PIPE_TEX_FACE_POS_Z + 1);
/*
* TODO do this only when needed, and implement explicit derivs (trivial).
* TODO do this only when needed.
*/
if (need_derivs && implicit_derivs) {
if (need_derivs && !derivs) {
LLVMValueRef ddx_ddy[2], tmp[2];
/*
* This isn't quite the same as the "ordinary" path since
@ -1374,9 +1374,16 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
dmax[2] = lp_build_max(coord_bld, tmp[0], tmp[1]);
}
else if (need_derivs) {
/* dmax[0] = lp_build_max(coord_bld, derivs->ddx[0], derivs->ddy[0]);
dmax[1] = lp_build_max(coord_bld, derivs->ddx[1], derivs->ddy[1]);
dmax[2] = lp_build_max(coord_bld, derivs->ddx[2], derivs->ddy[2]); */
LLVMValueRef abs_ddx[3], abs_ddy[3];
abs_ddx[0] = lp_build_abs(coord_bld, derivs->ddx[0]);
abs_ddx[1] = lp_build_abs(coord_bld, derivs->ddx[1]);
abs_ddx[2] = lp_build_abs(coord_bld, derivs->ddx[2]);
abs_ddy[0] = lp_build_abs(coord_bld, derivs->ddy[0]);
abs_ddy[1] = lp_build_abs(coord_bld, derivs->ddy[1]);
abs_ddy[2] = lp_build_abs(coord_bld, derivs->ddy[2]);
dmax[0] = lp_build_max(coord_bld, abs_ddx[0], abs_ddy[0]);
dmax[1] = lp_build_max(coord_bld, abs_ddx[1], abs_ddy[1]);
dmax[2] = lp_build_max(coord_bld, abs_ddx[2], abs_ddy[2]);
}
si = LLVMBuildBitCast(builder, s, lp_build_vec_type(gallivm, intctype), "");

View file

@ -433,6 +433,7 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
const struct lp_derivatives *derivs, /* optional */
LLVMValueRef *face,
LLVMValueRef *face_s,
LLVMValueRef *face_t,

View file

@ -1102,7 +1102,7 @@ lp_build_sample_common(struct lp_build_sample_context *bld,
*/
if (target == PIPE_TEXTURE_CUBE) {
LLVMValueRef face, face_s, face_t;
lp_build_cube_lookup(bld, *s, *t, *r, &face, &face_s, &face_t, &cube_rho);
lp_build_cube_lookup(bld, *s, *t, *r, derivs, &face, &face_s, &face_t, &cube_rho);
*s = face_s; /* vec */
*t = face_t; /* vec */
/* use 'r' to indicate cube face */

View file

@ -1277,8 +1277,7 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
LLVMValueRef offsets[3] = { NULL };
struct lp_derivatives derivs;
struct lp_derivatives *deriv_ptr = NULL;
unsigned num_coords;
unsigned dims;
unsigned num_coords, num_derivs, num_offsets;
unsigned i;
if (!bld->sampler) {
@ -1292,37 +1291,52 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
switch (inst->Texture.Texture) {
case TGSI_TEXTURE_1D:
num_coords = 1;
dims = 1;
num_offsets = 1;
num_derivs = 1;
break;
case TGSI_TEXTURE_1D_ARRAY:
num_coords = 2;
dims = 1;
num_offsets = 1;
num_derivs = 1;
break;
case TGSI_TEXTURE_2D:
case TGSI_TEXTURE_RECT:
num_coords = 2;
dims = 2;
num_offsets = 2;
num_derivs = 2;
break;
case TGSI_TEXTURE_SHADOW1D:
case TGSI_TEXTURE_SHADOW1D_ARRAY:
num_coords = 3;
dims = 1;
num_offsets = 1;
num_derivs = 1;
break;
case TGSI_TEXTURE_SHADOW2D:
case TGSI_TEXTURE_SHADOWRECT:
case TGSI_TEXTURE_2D_ARRAY:
num_coords = 3;
num_offsets = 2;
num_derivs = 2;
break;
case TGSI_TEXTURE_CUBE:
num_coords = 3;
dims = 2;
num_offsets = 2;
num_derivs = 3;
break;
case TGSI_TEXTURE_3D:
num_coords = 3;
dims = 3;
num_offsets = 3;
num_derivs = 3;
break;
case TGSI_TEXTURE_SHADOW2D_ARRAY:
num_coords = 4;
num_offsets = 2;
num_derivs = 2;
break;
case TGSI_TEXTURE_SHADOWCUBE:
num_coords = 4;
dims = 2;
num_offsets = 2;
num_derivs = 3;
break;
default:
assert(0);
@ -1362,20 +1376,20 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
unsigned dim;
for (dim = 0; dim < dims; ++dim) {
for (dim = 0; dim < num_derivs; ++dim) {
derivs.ddx[dim] = lp_build_emit_fetch( &bld->bld_base, inst, 1, dim );
derivs.ddy[dim] = lp_build_emit_fetch( &bld->bld_base, inst, 2, dim );
}
deriv_ptr = &derivs;
unit = inst->Src[3].Register.Index;
} else {
} else {
unit = inst->Src[1].Register.Index;
}
/* some advanced gather instructions (txgo) would require 4 offsets */
if (inst->Texture.NumOffsets == 1) {
unsigned dim;
for (dim = 0; dim < dims; dim++) {
for (dim = 0; dim < num_offsets; dim++) {
offsets[dim] = lp_build_emit_fetch_texoffset(&bld->bld_base, inst, 0, dim );
}
}
@ -1406,7 +1420,7 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
LLVMValueRef offsets[3] = { NULL };
struct lp_derivatives derivs;
struct lp_derivatives *deriv_ptr = NULL;
unsigned num_coords, dims;
unsigned num_coords, num_offsets, num_derivs;
unsigned i;
if (!bld->sampler) {
@ -1432,29 +1446,39 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
switch (bld->sv[texture_unit].Resource) {
case TGSI_TEXTURE_1D:
num_coords = 1;
dims = 1;
num_offsets = 1;
num_derivs = 1;
break;
case TGSI_TEXTURE_1D_ARRAY:
num_coords = 2;
dims = 1;
num_offsets = 1;
num_derivs = 1;
break;
case TGSI_TEXTURE_2D:
case TGSI_TEXTURE_RECT:
num_coords = 2;
dims = 2;
num_offsets = 2;
num_derivs = 2;
break;
case TGSI_TEXTURE_2D_ARRAY:
num_coords = 3;
num_offsets = 2;
num_derivs = 2;
break;
case TGSI_TEXTURE_CUBE:
num_coords = 3;
dims = 2;
num_offsets = 2;
num_derivs = 3;
break;
case TGSI_TEXTURE_3D:
num_coords = 3;
dims = 3;
num_offsets = 3;
num_derivs = 3;
break;
case TGSI_TEXTURE_CUBE_ARRAY:
num_coords = 4;
dims = 3;
num_offsets = 2;
num_derivs = 3;
break;
default:
assert(0);
@ -1505,7 +1529,7 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
unsigned dim;
for (dim = 0; dim < dims; ++dim) {
for (dim = 0; dim < num_derivs; ++dim) {
derivs.ddx[dim] = lp_build_emit_fetch( &bld->bld_base, inst, 3, dim );
derivs.ddy[dim] = lp_build_emit_fetch( &bld->bld_base, inst, 4, dim );
}
@ -1515,7 +1539,7 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
/* some advanced gather instructions (txgo) would require 4 offsets */
if (inst->Texture.NumOffsets == 1) {
unsigned dim;
for (dim = 0; dim < dims; dim++) {
for (dim = 0; dim < num_offsets; dim++) {
offsets[dim] = lp_build_emit_fetch_texoffset(&bld->bld_base, inst, 0, dim );
}
}