mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 20:50:09 +01:00
ac/llvm: Fix buffer_load_amd with larger than 32-bit channel sizes.
LLVM is unable to select instructions for larger than 32-bit channel types. Workaround by using i32 and casting to the correct type later. Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Qiang Yu <yuq825@gmail.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Acked-by: Konstantin Seurer <konstantin.seurer@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21358>
This commit is contained in:
parent
b5b0ded4c1
commit
a2755fc203
1 changed files with 23 additions and 15 deletions
|
|
@ -4054,24 +4054,32 @@ static bool visit_intrinsic(struct ac_nir_context *ctx, nir_intrinsic_instr *ins
|
|||
assert(instr->src[0].ssa->bit_size == 16 || instr->src[0].ssa->bit_size == 32);
|
||||
ac_build_buffer_store_format(&ctx->ac, descriptor, store_data, vidx, voffset, cache_policy);
|
||||
} else if (instr->intrinsic == nir_intrinsic_load_buffer_amd) {
|
||||
LLVMTypeRef channel_type;
|
||||
if (instr->dest.ssa.bit_size == 8)
|
||||
channel_type = ctx->ac.i8;
|
||||
else if (instr->dest.ssa.bit_size == 16)
|
||||
channel_type = ctx->ac.i16;
|
||||
else if (instr->dest.ssa.bit_size == 32)
|
||||
channel_type = ctx->ac.i32;
|
||||
else if (instr->dest.ssa.bit_size == 64)
|
||||
channel_type = ctx->ac.i64;
|
||||
else if (instr->dest.ssa.bit_size == 128)
|
||||
channel_type = ctx->ac.i128;
|
||||
else
|
||||
unreachable("Unsupported channel type for load_buffer_amd");
|
||||
/* LLVM is unable to select instructions for larger than 32-bit channel types.
|
||||
* Workaround by using i32 and casting to the correct type later.
|
||||
*/
|
||||
const unsigned fetch_num_components =
|
||||
num_components * MAX2(32, instr->dest.ssa.bit_size) / 32;
|
||||
LLVMTypeRef channel_type =
|
||||
LLVMIntTypeInContext(ctx->ac.context, MIN2(32, instr->dest.ssa.bit_size));
|
||||
|
||||
result = ac_build_buffer_load(&ctx->ac, descriptor, num_components, vidx, voffset,
|
||||
result = ac_build_buffer_load(&ctx->ac, descriptor, fetch_num_components, vidx, voffset,
|
||||
addr_soffset, channel_type, cache_policy, reorder, false);
|
||||
|
||||
result = ac_to_integer(&ctx->ac, ac_trim_vector(&ctx->ac, result, num_components));
|
||||
/* Trim to needed vector components. */
|
||||
result = ac_trim_vector(&ctx->ac, result, fetch_num_components);
|
||||
|
||||
/* Cast to larger than 32-bit sized components if needed. */
|
||||
if (instr->dest.ssa.bit_size > 32) {
|
||||
LLVMTypeRef cast_channel_type =
|
||||
LLVMIntTypeInContext(ctx->ac.context, instr->dest.ssa.bit_size);
|
||||
LLVMTypeRef cast_type =
|
||||
num_components == 1 ? cast_channel_type :
|
||||
LLVMVectorType(cast_channel_type, num_components);
|
||||
result = LLVMBuildBitCast(ctx->ac.builder, result, cast_type, "");
|
||||
}
|
||||
|
||||
/* Cast the result to an integer (or vector of integers). */
|
||||
result = ac_to_integer(&ctx->ac, result);
|
||||
} else {
|
||||
unsigned writemask = nir_intrinsic_write_mask(instr);
|
||||
while (writemask) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue