ac: add support for 16bit UBO loads

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
Daniel Schürmann 2018-02-07 19:40:43 +01:00 committed by Bas Nieuwenhuizen
parent 3109c5257b
commit a6a21e651d
3 changed files with 51 additions and 3 deletions

View file

@ -1103,6 +1103,31 @@ LLVMValueRef ac_build_buffer_load_format_gfx9_safe(struct ac_llvm_context *ctx,
can_speculate, true);
}
LLVMValueRef
ac_build_tbuffer_load_short(struct ac_llvm_context *ctx,
LLVMValueRef rsrc,
LLVMValueRef vindex,
LLVMValueRef voffset,
LLVMValueRef soffset,
LLVMValueRef immoffset)
{
const char *name = "llvm.amdgcn.tbuffer.load.i32";
LLVMTypeRef type = ctx->i32;
LLVMValueRef params[] = {
rsrc,
vindex,
voffset,
soffset,
immoffset,
LLVMConstInt(ctx->i32, V_008F0C_BUF_DATA_FORMAT_16, false),
LLVMConstInt(ctx->i32, V_008F0C_BUF_NUM_FORMAT_UINT, false),
ctx->i1false,
ctx->i1false,
};
LLVMValueRef res = ac_build_intrinsic(ctx, name, type, params, 9, 0);
return LLVMBuildTrunc(ctx->builder, res, ctx->i16, "");
}
/**
* Set range metadata on an instruction. This can only be used on load and
* call instructions. If you know an instruction can only produce the values

View file

@ -252,6 +252,14 @@ LLVMValueRef ac_build_buffer_load_format_gfx9_safe(struct ac_llvm_context *ctx,
bool glc,
bool can_speculate);
LLVMValueRef
ac_build_tbuffer_load_short(struct ac_llvm_context *ctx,
LLVMValueRef rsrc,
LLVMValueRef vindex,
LLVMValueRef voffset,
LLVMValueRef soffset,
LLVMValueRef immoffset);
LLVMValueRef
ac_get_thread_id(struct ac_llvm_context *ctx);

View file

@ -1677,9 +1677,24 @@ static LLVMValueRef visit_load_ubo_buffer(struct ac_nir_context *ctx,
if (instr->dest.ssa.bit_size == 64)
num_components *= 2;
ret = ac_build_buffer_load(&ctx->ac, rsrc, num_components, NULL, offset,
NULL, 0, false, false, true, true);
ret = ac_trim_vector(&ctx->ac, ret, num_components);
if (instr->dest.ssa.bit_size == 16) {
LLVMValueRef results[num_components];
for (unsigned i = 0; i < num_components; ++i) {
results[i] = ac_build_tbuffer_load_short(&ctx->ac,
rsrc,
ctx->ac.i32_0,
offset,
ctx->ac.i32_0,
LLVMConstInt(ctx->ac.i32, 2 * i, 0));
}
ret = ac_build_gather_values(&ctx->ac, results, num_components);
} else {
ret = ac_build_buffer_load(&ctx->ac, rsrc, num_components, NULL, offset,
NULL, 0, false, false, true, true);
ret = ac_trim_vector(&ctx->ac, ret, num_components);
}
return LLVMBuildBitCast(ctx->ac.builder, ret,
get_def_type(ctx, &instr->dest.ssa), "");
}