aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2013-02-05 13:37:57 -0800
committerRoland Scheidegger <[email protected]>2013-02-08 18:54:40 -0800
commit614982d320985c04e247293b54b66d7df5c19004 (patch)
tree53a17cb7593ba82d1140bd218a7f192606cf332a /src/gallium/auxiliary
parent0a8043bb766f9c38af559438b646c3659614b103 (diff)
gallivm: fix up size queries for dx10 sviewinfo opcode
Need to calculate the number of mip levels (if it would be worthwile could store it in dynamic state). While here, the query code also used chan 2 for the lod value. This worked with mesa state tracker but it seems safer to use chan 0. Still passes piglit textureSize (with some handwaving), though the non-GL parts are (largely) untested. v2: clarify and expect the sviewinfo opcode to return ints, not floats, just like the OpenGL textureSize (dx10 supports dst modifiers with resinfo). Also simplify some code. Reviewed-by: Jose Fonseca <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm_sample.c2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.h1
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c64
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.h1
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c66
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.c4
6 files changed, 64 insertions, 74 deletions
diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c
index 03a25921d65..e51e01101f6 100644
--- a/src/gallium/auxiliary/draw/draw_llvm_sample.c
+++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c
@@ -269,6 +269,7 @@ draw_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
struct gallivm_state *gallivm,
struct lp_type type,
unsigned texture_unit,
+ boolean need_nr_mips,
LLVMValueRef explicit_lod, /* optional */
LLVMValueRef *sizes_out)
{
@@ -281,6 +282,7 @@ draw_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
&sampler->dynamic_state.base,
type,
texture_unit,
+ need_nr_mips,
explicit_lod,
sizes_out);
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
index 77ce00869be..f5022167123 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -487,6 +487,7 @@ lp_build_size_query_soa(struct gallivm_state *gallivm,
struct lp_sampler_dynamic_state *dynamic_state,
struct lp_type int_type,
unsigned texture_unit,
+ boolean need_nr_mips,
LLVMValueRef explicit_lod,
LLVMValueRef *sizes_out);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 778400af5f0..c5b48b52da3 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -1742,39 +1742,27 @@ lp_build_size_query_soa(struct gallivm_state *gallivm,
struct lp_sampler_dynamic_state *dynamic_state,
struct lp_type int_type,
unsigned texture_unit,
+ boolean need_nr_mips,
LLVMValueRef explicit_lod,
LLVMValueRef *sizes_out)
{
LLVMValueRef lod;
LLVMValueRef size;
+ LLVMValueRef first_level = NULL;
int dims, i;
- boolean has_array = FALSE;
+ boolean has_array;
struct lp_build_context bld_int_vec;
+ dims = texture_dims(static_state->target);
+
switch (static_state->target) {
- case PIPE_TEXTURE_1D:
- case PIPE_BUFFER:
- dims = 1;
- break;
case PIPE_TEXTURE_1D_ARRAY:
- dims = 1;
- has_array = TRUE;
- break;
- case PIPE_TEXTURE_2D:
- case PIPE_TEXTURE_CUBE:
- case PIPE_TEXTURE_RECT:
- dims = 2;
- break;
- case PIPE_TEXTURE_3D:
- dims = 3;
- break;
case PIPE_TEXTURE_2D_ARRAY:
- dims = 2;
has_array = TRUE;
break;
default:
- assert(0);
- return;
+ has_array = FALSE;
+ break;
}
assert(!int_type.floating);
@@ -1782,7 +1770,6 @@ lp_build_size_query_soa(struct gallivm_state *gallivm,
lp_build_context_init(&bld_int_vec, gallivm, lp_type_int_vec(32, 128));
if (explicit_lod) {
- LLVMValueRef first_level;
lod = LLVMBuildExtractElement(gallivm->builder, explicit_lod, lp_build_const_int32(gallivm, 0), "");
first_level = dynamic_state->first_level(dynamic_state, gallivm, texture_unit);
lod = lp_build_broadcast_scalar(&bld_int_vec,
@@ -1792,7 +1779,12 @@ lp_build_size_query_soa(struct gallivm_state *gallivm,
lod = bld_int_vec.zero;
}
- size = bld_int_vec.undef;
+ if (need_nr_mips) {
+ size = bld_int_vec.zero;
+ }
+ else {
+ size = bld_int_vec.undef;
+ }
size = LLVMBuildInsertElement(gallivm->builder, size,
dynamic_state->width(dynamic_state, gallivm, texture_unit),
@@ -1811,15 +1803,43 @@ lp_build_size_query_soa(struct gallivm_state *gallivm,
}
size = lp_build_minify(&bld_int_vec, size, lod);
-
+
if (has_array)
size = LLVMBuildInsertElement(gallivm->builder, size,
dynamic_state->depth(dynamic_state, gallivm, texture_unit),
lp_build_const_int32(gallivm, dims), "");
+ /*
+ * XXX for out-of-bounds lod, should set size to zero vector here
+ * (for dx10-style only, i.e. need_nr_mips)
+ */
+
for (i = 0; i < dims + (has_array ? 1 : 0); i++) {
sizes_out[i] = lp_build_extract_broadcast(gallivm, bld_int_vec.type, int_type,
size,
lp_build_const_int32(gallivm, i));
}
+
+ /*
+ * if there's no explicit_lod (buffers, rects) queries requiring nr of
+ * mips would be illegal.
+ */
+ if (need_nr_mips && explicit_lod) {
+ struct lp_build_context bld_int_scalar;
+ LLVMValueRef num_levels;
+ lp_build_context_init(&bld_int_scalar, gallivm, lp_type_int(32));
+
+ if (static_state->level_zero_only) {
+ num_levels = bld_int_scalar.one;
+ }
+ else {
+ LLVMValueRef last_level;
+
+ last_level = dynamic_state->last_level(dynamic_state, gallivm, texture_unit);
+ num_levels = lp_build_sub(&bld_int_scalar, last_level, first_level);
+ num_levels = lp_build_add(&bld_int_scalar, num_levels, bld_int_scalar.one);
+ }
+ sizes_out[3] = lp_build_broadcast(gallivm, lp_build_vec_type(gallivm, int_type),
+ num_levels);
+ }
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
index 837394fb890..3446a8fd46d 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
@@ -189,6 +189,7 @@ struct lp_build_sampler_soa
struct gallivm_state *gallivm,
struct lp_type type,
unsigned unit,
+ boolean need_nr_mips,
LLVMValueRef explicit_lod, /* optional */
LLVMValueRef *sizes_out);
};
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 5eeaaf4ed98..52a60dd43b6 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -1621,69 +1621,35 @@ emit_txf( struct lp_build_tgsi_soa_context *bld,
}
static void
-emit_txq( struct lp_build_tgsi_soa_context *bld,
- const struct tgsi_full_instruction *inst,
- LLVMValueRef *sizes_out)
+emit_size_query( struct lp_build_tgsi_soa_context *bld,
+ const struct tgsi_full_instruction *inst,
+ LLVMValueRef *sizes_out,
+ boolean is_sviewinfo)
{
LLVMValueRef explicit_lod;
- unsigned num_coords, has_lod;
+ unsigned has_lod;
unsigned i;
switch (inst->Texture.Texture) {
- case TGSI_TEXTURE_1D:
- case TGSI_TEXTURE_SHADOW1D:
- num_coords = 1;
- has_lod = 1;
- break;
- case TGSI_TEXTURE_2D:
- case TGSI_TEXTURE_SHADOW2D:
- case TGSI_TEXTURE_CUBE:
- case TGSI_TEXTURE_SHADOWCUBE:
- case TGSI_TEXTURE_1D_ARRAY:
- case TGSI_TEXTURE_SHADOW1D_ARRAY:
- num_coords = 2;
- has_lod = 1;
- break;
- case TGSI_TEXTURE_3D:
-// case TGSI_TEXTURE_CUBE_ARRAY:
-// case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
- case TGSI_TEXTURE_2D_ARRAY:
- case TGSI_TEXTURE_SHADOW2D_ARRAY:
- num_coords = 3;
- has_lod = 1;
- break;
-
case TGSI_TEXTURE_BUFFER:
- num_coords = 1;
- has_lod = 0;
- break;
-
case TGSI_TEXTURE_RECT:
case TGSI_TEXTURE_SHADOWRECT:
-// case TGSI_TEXTURE_2D_MS:
- num_coords = 2;
has_lod = 0;
break;
-
-// case TGSI_TEXTURE_2D_MS_ARRAY:
-// num_coords = 3;
-// has_lod = 0;
-// break;
-
default:
- assert(0);
- return;
+ has_lod = 1;
+ break;
}
if (!bld->sampler) {
_debug_printf("warning: found texture query instruction but no sampler generator supplied\n");
- for (i = 0; i < num_coords; i++)
- sizes_out[i] = bld->bld_base.base.undef;
+ for (i = 0; i < 4; i++)
+ sizes_out[i] = bld->bld_base.int_bld.undef;
return;
}
if (has_lod)
- explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 2 );
+ explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 0 );
else
explicit_lod = NULL;
@@ -1691,6 +1657,7 @@ emit_txq( struct lp_build_tgsi_soa_context *bld,
bld->bld_base.base.gallivm,
bld->bld_base.int_bld.type,
inst->Src[1].Register.Index,
+ is_sviewinfo,
explicit_lod,
sizes_out);
}
@@ -2078,7 +2045,7 @@ txq_emit(
{
struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
- emit_txq(bld, emit_data->inst, emit_data->output);
+ emit_size_query(bld, emit_data->inst, emit_data->output, FALSE);
}
static void
@@ -2174,13 +2141,8 @@ sviewinfo_emit(
struct lp_build_emit_data * emit_data)
{
struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
- /*
- * FIXME: unlike txq we are required to return number of mipmap levels
- * too, and the unused channels are defined to be zero.
- * Either always do that (and hope llvm can optimize it away?)
- * or pass a parameter all the way down.
- */
- emit_txq(bld, emit_data->inst, emit_data->output);
+
+ emit_size_query(bld, emit_data->inst, emit_data->output, TRUE);
}
static void
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index 94b6f60ca89..f8a3cb665f9 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -293,7 +293,10 @@ tgsi_opcode_infer_src_type( uint opcode )
case TGSI_OPCODE_USHR:
case TGSI_OPCODE_SHL:
case TGSI_OPCODE_TXQ:
+ case TGSI_OPCODE_SVIEWINFO:
case TGSI_OPCODE_TXF:
+ case TGSI_OPCODE_SAMPLE_I:
+ case TGSI_OPCODE_SAMPLE_I_MS:
return TGSI_TYPE_UNSIGNED;
case TGSI_OPCODE_MOD:
case TGSI_OPCODE_I2F:
@@ -343,6 +346,7 @@ tgsi_opcode_infer_dst_type( uint opcode )
case TGSI_OPCODE_SHL:
case TGSI_OPCODE_TXQ:
case TGSI_OPCODE_TXQ_LZ:
+ case TGSI_OPCODE_SVIEWINFO:
return TGSI_TYPE_UNSIGNED;
case TGSI_OPCODE_F2I:
case TGSI_OPCODE_IDIV: