llvmpipe: Fix type mismatch when storing residency info

The storage allocated was always the same for both the ordinary texture
result data as well as the residency info. However, the former can be
float vector, whereas the latter is always int vector.
At least some llvm versions/builds will assert on this mismatch when
storing the data.
While here, also cut unnecessary zero initialization (lp_build_alloca()
already explicitly does this).

Fixes: 6168317b84 (lavapipe: Implement shaderResourceResidency)

Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com>
Reviewed-by: Brian Paul <brian.paul@broadcom.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30878>
(cherry picked from commit 9b717596b2)
This commit is contained in:
Roland Scheidegger 2024-08-27 19:19:11 +02:00 committed by Eric Engestrom
parent 8b277994be
commit 2950194ea6
2 changed files with 21 additions and 15 deletions

View file

@ -534,7 +534,7 @@
"description": "llvmpipe: Fix type mismatch when storing residency info",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "6168317b849150db28dc222f8ac68cb1b371eb2e",
"notes": null

View file

@ -153,12 +153,13 @@ lp_bld_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base
if (params->texture_resource) {
LLVMTypeRef out_data_type = lp_build_vec_type(gallivm, params->type);
LLVMTypeRef out_residency_type = lp_build_vec_type(gallivm, lp_int_type(params->type));
LLVMValueRef out_data[5];
for (uint32_t i = 0; i < ARRAY_SIZE(out_data); i++) {
for (uint32_t i = 0; i < ARRAY_SIZE(out_data) - 1; i++) {
out_data[i] = lp_build_alloca(gallivm, out_data_type, "");
LLVMBuildStore(builder, lp_build_const_vec(gallivm, params->type, 0), out_data[i]);
}
out_data[ARRAY_SIZE(out_data) - 1] = lp_build_alloca(gallivm, out_residency_type, "");
struct lp_type uint_type = lp_uint_type(params->type);
LLVMValueRef uint_zero = lp_build_const_int_vec(gallivm, uint_type, 0);
@ -265,7 +266,7 @@ lp_bld_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base
LLVMValueRef result = LLVMBuildCall2(builder, texture_function_type, texture_function, args, num_args, "");
for (unsigned i = 0; i < ARRAY_SIZE(out_data); i++) {
params->texel[i] = LLVMBuildExtractValue(gallivm->builder, result, i, "");
params->texel[i] = LLVMBuildExtractValue(builder, result, i, "");
if (params->type.length != lp_native_vector_width / 32)
params->texel[i] = truncate_to_type_width(gallivm, params->texel[i], params->type);
@ -275,8 +276,10 @@ lp_bld_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base
lp_build_endif(&if_state);
for (unsigned i = 0; i < ARRAY_SIZE(out_data); i++)
params->texel[i] = LLVMBuildLoad2(gallivm->builder, out_data_type, out_data[i], "");
for (unsigned i = 0; i < ARRAY_SIZE(out_data) - 1; i++)
params->texel[i] = LLVMBuildLoad2(builder, out_data_type, out_data[i], "");
params->texel[ARRAY_SIZE(out_data) - 1] =
LLVMBuildLoad2(builder, out_residency_type, out_data[ARRAY_SIZE(out_data) - 1], "");
return;
}
@ -295,7 +298,7 @@ lp_bld_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base
if (params->texture_index_offset) {
LLVMValueRef unit =
LLVMBuildAdd(gallivm->builder, params->texture_index_offset,
LLVMBuildAdd(builder, params->texture_index_offset,
lp_build_const_int32(gallivm, texture_index), "");
struct lp_build_sample_array_switch switch_info;
@ -335,7 +338,6 @@ lp_bld_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
LLVMValueRef out_data[4];
for (uint32_t i = 0; i < 4; i++) {
out_data[i] = lp_build_alloca(gallivm, out_data_type, "");
LLVMBuildStore(builder, lp_build_const_vec(gallivm, params->int_type, 0), out_data[i]);
}
struct lp_type uint_type = lp_uint_type(params->int_type);
@ -441,13 +443,15 @@ lp_bld_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
if (params->resource) {
const struct util_format_description *desc = util_format_description(params->format);
LLVMTypeRef out_data_type = lp_build_vec_type(gallivm, lp_build_texel_type(params->type, desc));
struct lp_type texel_type = lp_build_texel_type(params->type, desc);
LLVMTypeRef out_data_type = lp_build_vec_type(gallivm, texel_type);
LLVMTypeRef out_residency_type = lp_build_vec_type(gallivm, lp_int_type(texel_type));
LLVMValueRef out_data[5];
for (uint32_t i = 0; i < ARRAY_SIZE(out_data); i++) {
for (uint32_t i = 0; i < ARRAY_SIZE(out_data) - 1; i++) {
out_data[i] = lp_build_alloca(gallivm, out_data_type, "");
LLVMBuildStore(builder, lp_build_const_vec(gallivm, lp_build_texel_type(params->type, desc), 0), out_data[i]);
}
out_data[ARRAY_SIZE(out_data) - 1] = lp_build_alloca(gallivm, out_residency_type, "");
struct lp_type uint_type = lp_uint_type(params->type);
LLVMValueRef uint_zero = lp_build_const_int_vec(gallivm, uint_type, 0);
@ -534,7 +538,7 @@ lp_bld_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
if (params->img_op != LP_IMG_STORE) {
uint32_t channel_count = params->img_op == LP_IMG_LOAD_SPARSE ? 5 : 4;
for (unsigned i = 0; i < channel_count; i++) {
LLVMValueRef channel = LLVMBuildExtractValue(gallivm->builder, result, i, "");
LLVMValueRef channel = LLVMBuildExtractValue(builder, result, i, "");
if (params->type.length != lp_native_vector_width / 32)
channel = truncate_to_type_width(gallivm, channel, params->type);
@ -545,9 +549,11 @@ lp_bld_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
lp_build_endif(&if_state);
if (params->img_op != LP_IMG_STORE) {
for (unsigned i = 0; i < ARRAY_SIZE(out_data); i++) {
params->outdata[i] = LLVMBuildLoad2(gallivm->builder, out_data_type, out_data[i], "");
for (unsigned i = 0; i < ARRAY_SIZE(out_data) - 1; i++) {
params->outdata[i] = LLVMBuildLoad2(builder, out_data_type, out_data[i], "");
}
params->outdata[ARRAY_SIZE(out_data) - 1] =
LLVMBuildLoad2(builder, out_residency_type, out_data[ARRAY_SIZE(out_data) - 1], "");
}
return;
@ -560,7 +566,7 @@ lp_bld_llvm_image_soa_emit_op(const struct lp_build_image_soa *base,
if (params->image_index_offset) {
struct lp_build_img_op_array_switch switch_info;
memset(&switch_info, 0, sizeof(switch_info));
LLVMValueRef unit = LLVMBuildAdd(gallivm->builder,
LLVMValueRef unit = LLVMBuildAdd(builder,
params->image_index_offset,
lp_build_const_int32(gallivm,
image_index), "");