diff options
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm_sample.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample.h | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 64 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 66 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_info.c | 4 |
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: |