summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRhys Perry <[email protected]>2018-12-06 13:56:01 +0000
committerSamuel Pitoiset <[email protected]>2019-03-21 09:02:16 +0100
commitb12e074b89ce4f12178c0ffc57b9d7c38acc38b3 (patch)
treeefbd7c5785b796c356fab32915ae98dcfe2426bd /src
parent104dbc64a5f7985d1b0d47db969ed3bb7b9e7b8d (diff)
ac/nir: implement 8-bit push constant, ssbo and ubo loads
Signed-off-by: Rhys Perry <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/amd/common/ac_nir_to_llvm.c65
1 files changed, 55 insertions, 10 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index fd6dbcce530..c088537e1fd 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -1432,7 +1432,30 @@ static LLVMValueRef visit_load_push_constant(struct ac_nir_context *ctx,
ptr = ac_build_gep0(&ctx->ac, ctx->abi->push_constants, addr);
- if (instr->dest.ssa.bit_size == 16) {
+ if (instr->dest.ssa.bit_size == 8) {
+ unsigned load_dwords = instr->dest.ssa.num_components > 1 ? 2 : 1;
+ LLVMTypeRef vec_type = LLVMVectorType(LLVMInt8TypeInContext(ctx->ac.context), 4 * load_dwords);
+ ptr = ac_cast_ptr(&ctx->ac, ptr, vec_type);
+ LLVMValueRef res = LLVMBuildLoad(ctx->ac.builder, ptr, "");
+
+ LLVMValueRef params[3];
+ if (load_dwords > 1) {
+ LLVMValueRef res_vec = LLVMBuildBitCast(ctx->ac.builder, res, LLVMVectorType(ctx->ac.i32, 2), "");
+ params[0] = LLVMBuildExtractElement(ctx->ac.builder, res_vec, LLVMConstInt(ctx->ac.i32, 1, false), "");
+ params[1] = LLVMBuildExtractElement(ctx->ac.builder, res_vec, LLVMConstInt(ctx->ac.i32, 0, false), "");
+ } else {
+ res = LLVMBuildBitCast(ctx->ac.builder, res, ctx->ac.i32, "");
+ params[0] = ctx->ac.i32_0;
+ params[1] = res;
+ }
+ params[2] = addr;
+ res = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.alignbyte", ctx->ac.i32, params, 3, 0);
+
+ res = LLVMBuildTrunc(ctx->ac.builder, res, LLVMIntTypeInContext(ctx->ac.context, instr->dest.ssa.num_components * 8), "");
+ if (instr->dest.ssa.num_components > 1)
+ res = LLVMBuildBitCast(ctx->ac.builder, res, LLVMVectorType(LLVMInt8TypeInContext(ctx->ac.context), instr->dest.ssa.num_components), "");
+ return res;
+ } else if (instr->dest.ssa.bit_size == 16) {
unsigned load_dwords = instr->dest.ssa.num_components / 2 + 1;
LLVMTypeRef vec_type = LLVMVectorType(LLVMInt16TypeInContext(ctx->ac.context), 2 * load_dwords);
ptr = ac_cast_ptr(&ctx->ac, ptr, vec_type);
@@ -1705,13 +1728,21 @@ static LLVMValueRef visit_load_buffer(struct ac_nir_context *ctx,
LLVMValueRef immoffset = LLVMConstInt(ctx->ac.i32, i * elem_size_bytes, false);
LLVMValueRef ret;
- if (load_bytes == 2) {
- ret = ac_build_tbuffer_load_short(&ctx->ac,
+
+ if (load_bytes == 1) {
+ ret = ac_build_tbuffer_load_byte(&ctx->ac,
rsrc,
offset,
ctx->ac.i32_0,
immoffset,
cache_policy & ac_glc);
+ } else if (load_bytes == 2) {
+ ret = ac_build_tbuffer_load_short(&ctx->ac,
+ rsrc,
+ offset,
+ ctx->ac.i32_0,
+ immoffset,
+ cache_policy & ac_glc);
} else {
int num_channels = util_next_power_of_two(load_bytes) / 4;
@@ -1751,15 +1782,29 @@ static LLVMValueRef visit_load_ubo_buffer(struct ac_nir_context *ctx,
if (instr->dest.ssa.bit_size == 64)
num_components *= 2;
- if (instr->dest.ssa.bit_size == 16) {
+ if (instr->dest.ssa.bit_size == 16 || instr->dest.ssa.bit_size == 8) {
+ unsigned load_bytes = instr->dest.ssa.bit_size / 8;
LLVMValueRef results[num_components];
for (unsigned i = 0; i < num_components; ++i) {
- results[i] = ac_build_tbuffer_load_short(&ctx->ac,
- rsrc,
- offset,
- ctx->ac.i32_0,
- LLVMConstInt(ctx->ac.i32, 2 * i, 0),
- false);
+ LLVMValueRef immoffset = LLVMConstInt(ctx->ac.i32,
+ load_bytes * i, 0);
+
+ if (load_bytes == 1) {
+ results[i] = ac_build_tbuffer_load_byte(&ctx->ac,
+ rsrc,
+ offset,
+ ctx->ac.i32_0,
+ immoffset,
+ false);
+ } else {
+ assert(load_bytes == 2);
+ results[i] = ac_build_tbuffer_load_short(&ctx->ac,
+ rsrc,
+ offset,
+ ctx->ac.i32_0,
+ immoffset,
+ false);
+ }
}
ret = ac_build_gather_values(&ctx->ac, results, num_components);
} else {