From: Roland Scheidegger Date: Thu, 8 Aug 2013 00:34:32 +0000 (+0200) Subject: gallivm: honor d3d10's wishes of out-of-bounds behavior for texture size query X-Git-Tag: upstream/10.0.5~1940 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=38ad404f7633aded98a0d67438e6bec0d684a5c6;p=platform%2Fupstream%2Fmesa.git gallivm: honor d3d10's wishes of out-of-bounds behavior for texture size query Specifically, must return 0 for non-existent mip levels (and non-existent textures which is an unsolved problem) for everything but total mip count. Reviewed-by: Zack Rusin --- diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 4305c49..b0bb58b 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -1948,11 +1948,11 @@ lp_build_size_query_soa(struct gallivm_state *gallivm, LLVMValueRef explicit_lod, LLVMValueRef *sizes_out) { - LLVMValueRef lod; - LLVMValueRef size; + LLVMValueRef lod, level, size; LLVMValueRef first_level = NULL; int dims, i; boolean has_array; + unsigned num_lods = 1; struct lp_build_context bld_int_vec; dims = texture_dims(static_state->target); @@ -1975,9 +1975,8 @@ lp_build_size_query_soa(struct gallivm_state *gallivm, /* FIXME: this needs to honor per-element lod */ 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, - LLVMBuildAdd(gallivm->builder, lod, first_level, "lod")); - + level = LLVMBuildAdd(gallivm->builder, lod, first_level, "level"); + lod = lp_build_broadcast_scalar(&bld_int_vec, level); } else { lod = bld_int_vec.zero; } @@ -2013,10 +2012,30 @@ lp_build_size_query_soa(struct gallivm_state *gallivm, 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) + * d3d10 requires zero for x/y/z values (but not w, i.e. mip levels) + * if level is out of bounds (note this can't cover unbound texture + * here, which also requires returning zero). */ - + if (explicit_lod && need_nr_mips) { + LLVMValueRef last_level, out, out1; + struct lp_build_context leveli_bld; + + /* everything is scalar for now */ + lp_build_context_init(&leveli_bld, gallivm, lp_type_int_vec(32, 32)); + last_level = dynamic_state->last_level(dynamic_state, gallivm, texture_unit); + + out = lp_build_cmp(&leveli_bld, PIPE_FUNC_LESS, level, first_level); + out1 = lp_build_cmp(&leveli_bld, PIPE_FUNC_GREATER, level, last_level); + out = lp_build_or(&leveli_bld, out, out1); + if (num_lods == 1) { + out = lp_build_broadcast_scalar(&bld_int_vec, out); + } + else { + /* TODO */ + assert(0); + } + size = lp_build_andnot(&bld_int_vec, size, out); + } 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,