+ else {
+ unsigned j;
+ struct lp_build_sample_context bld4;
+ struct lp_type type4 = type;
+ unsigned i;
+ LLVMValueRef texelout4[4];
+ LLVMValueRef texelouttmp[4][LP_MAX_VECTOR_LENGTH/16];
+
+ type4.length = 4;
+
+ /* Setup our build context */
+ memset(&bld4, 0, sizeof bld4);
+ bld4.gallivm = bld.gallivm;
+ bld4.static_texture_state = bld.static_texture_state;
+ bld4.static_sampler_state = bld.static_sampler_state;
+ bld4.dynamic_state = bld.dynamic_state;
+ bld4.format_desc = bld.format_desc;
+ bld4.dims = bld.dims;
+ bld4.row_stride_array = bld.row_stride_array;
+ bld4.img_stride_array = bld.img_stride_array;
+ bld4.base_ptr = bld.base_ptr;
+ bld4.mip_offsets = bld.mip_offsets;
+ bld4.int_size = bld.int_size;
+
+ bld4.vector_width = lp_type_width(type4);
+
+ bld4.float_type = lp_type_float(32);
+ bld4.int_type = lp_type_int(32);
+ bld4.coord_type = type4;
+ bld4.int_coord_type = lp_int_type(type4);
+ bld4.float_size_in_type = lp_type_float(32);
+ bld4.float_size_in_type.length = dims > 1 ? 4 : 1;
+ bld4.int_size_in_type = lp_int_type(bld4.float_size_in_type);
+ bld4.texel_type = bld.texel_type;
+ bld4.texel_type.length = 4;
+ bld4.levelf_type = type4;
+ /* we want native vector size to be able to use our intrinsics */
+ bld4.levelf_type.length = 1;
+ bld4.leveli_type = lp_int_type(bld4.levelf_type);
+
+ if (explicit_lod && !scalar_lod &&
+ ((is_fetch && bld.static_texture_state->target != PIPE_BUFFER) ||
+ (!is_fetch && mip_filter != PIPE_TEX_MIPFILTER_NONE)))
+ bld4.num_lods = type4.length;
+ else
+ bld4.num_lods = 1;
+
+ bld4.levelf_type = type4;
+ /* we want native vector size to be able to use our intrinsics */
+ if (bld4.num_lods != type4.length) {
+ bld4.levelf_type.length = 1;
+ }
+ bld4.leveli_type = lp_int_type(bld4.levelf_type);
+ bld4.float_size_type = bld4.float_size_in_type;
+ if (bld4.num_lods > 1) {
+ bld4.float_size_type.length = bld4.num_lods == type4.length ?
+ bld4.num_lods * bld4.float_size_in_type.length :
+ type4.length;
+ }
+ bld4.int_size_type = lp_int_type(bld4.float_size_type);
+
+ lp_build_context_init(&bld4.float_bld, gallivm, bld4.float_type);
+ lp_build_context_init(&bld4.float_vec_bld, gallivm, type4);
+ lp_build_context_init(&bld4.int_bld, gallivm, bld4.int_type);
+ lp_build_context_init(&bld4.coord_bld, gallivm, bld4.coord_type);
+ lp_build_context_init(&bld4.int_coord_bld, gallivm, bld4.int_coord_type);
+ lp_build_context_init(&bld4.int_size_in_bld, gallivm, bld4.int_size_in_type);
+ lp_build_context_init(&bld4.float_size_in_bld, gallivm, bld4.float_size_in_type);
+ lp_build_context_init(&bld4.int_size_bld, gallivm, bld4.int_size_type);
+ lp_build_context_init(&bld4.float_size_bld, gallivm, bld4.float_size_type);
+ lp_build_context_init(&bld4.texel_bld, gallivm, bld4.texel_type);
+ lp_build_context_init(&bld4.levelf_bld, gallivm, bld4.levelf_type);
+ lp_build_context_init(&bld4.leveli_bld, gallivm, bld4.leveli_type);
+
+ for (i = 0; i < num_quads; i++) {
+ LLVMValueRef s4, t4, r4;
+ LLVMValueRef lod_ipart4, lod_fpart4 = NULL;
+ LLVMValueRef ilevel04, ilevel14 = NULL;
+ LLVMValueRef offsets4[4] = { NULL };
+ unsigned num_lods = bld4.num_lods;
+
+ s4 = lp_build_extract_range(gallivm, s, 4*i, 4);
+ t4 = lp_build_extract_range(gallivm, t, 4*i, 4);
+ r4 = lp_build_extract_range(gallivm, r, 4*i, 4);
+
+ if (offsets[0]) {
+ offsets4[0] = lp_build_extract_range(gallivm, offsets[0], 4*i, 4);
+ if (dims > 1) {
+ offsets4[1] = lp_build_extract_range(gallivm, offsets[1], 4*i, 4);
+ if (dims > 2) {
+ offsets4[2] = lp_build_extract_range(gallivm, offsets[2], 4*i, 4);
+ }
+ }
+ }
+ lod_ipart4 = lp_build_extract_range(gallivm, lod_ipart, num_lods * i, num_lods);
+ ilevel04 = lp_build_extract_range(gallivm, ilevel0, num_lods * i, num_lods);
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ ilevel14 = lp_build_extract_range(gallivm, ilevel1, num_lods * i, num_lods);
+ lod_fpart4 = lp_build_extract_range(gallivm, lod_fpart, num_lods * i, num_lods);
+ }
+
+ if (use_aos) {
+ /* do sampling/filtering with fixed pt arithmetic */
+ lp_build_sample_aos(&bld4, sampler_index,
+ s4, t4, r4, offsets4,
+ lod_ipart4, lod_fpart4,
+ ilevel04, ilevel14,
+ texelout4);
+ }
+
+ else {
+ lp_build_sample_general(&bld4, sampler_index,
+ s4, t4, r4, offsets4,
+ lod_ipart4, lod_fpart4,
+ ilevel04, ilevel14,
+ texelout4);
+ }
+ for (j = 0; j < 4; j++) {
+ texelouttmp[j][i] = texelout4[j];
+ }
+ }
+
+ for (j = 0; j < 4; j++) {
+ texel_out[j] = lp_build_concat(gallivm, texelouttmp[j], type4, num_quads);
+ }
+ }
+
+ lp_build_sample_compare(&bld, coords, texel_out);
+ }
+
+ if (static_texture_state->target != PIPE_BUFFER) {
+ apply_sampler_swizzle(&bld, texel_out);
+ }
+
+ /*
+ * texel type can be a (32bit) int/uint (for pure int formats only),
+ * however we are expected to always return floats (storage is untyped).
+ */
+ if (!bld.texel_type.floating) {
+ unsigned chan;
+ for (chan = 0; chan < 4; chan++) {
+ texel_out[chan] = LLVMBuildBitCast(builder, texel_out[chan],
+ lp_build_vec_type(gallivm, type), "");
+ }
+ }
+}
+
+void
+lp_build_size_query_soa(struct gallivm_state *gallivm,
+ const struct lp_static_texture_state *static_state,
+ struct lp_sampler_dynamic_state *dynamic_state,
+ struct lp_type int_type,
+ unsigned texture_unit,
+ unsigned target,
+ boolean need_nr_mips,
+ boolean scalar_lod,
+ LLVMValueRef explicit_lod,
+ LLVMValueRef *sizes_out)
+{
+ 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;