summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2016-01-01 20:37:38 +0100
committerMarek Olšák <marek.olsak@amd.com>2016-02-21 21:08:57 +0100
commitfe1b6ede0134168815527fedbff8ce06cca5a3aa (patch)
tree8b5caa13670595d758507ac3208cf1845ef85925
parent36202182acfa1ea04a5202e5d0a3066c96df9dac (diff)
radeonsi: compute how many input SGPRs and VGPRs shaders have
Prologs (shader binaries inserted before the API shader binary) need to know this, so that they won't change the input registers unintentionally. Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c32
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.h2
2 files changed, 34 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 422608eb4ce..1145f896a39 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -3580,6 +3580,26 @@ static void declare_streamout_params(struct si_shader_context *ctx,
}
}
+static unsigned llvm_get_type_size(LLVMTypeRef type)
+{
+ LLVMTypeKind kind = LLVMGetTypeKind(type);
+
+ switch (kind) {
+ case LLVMIntegerTypeKind:
+ return LLVMGetIntTypeWidth(type) / 8;
+ case LLVMFloatTypeKind:
+ return 4;
+ case LLVMPointerTypeKind:
+ return 8;
+ case LLVMVectorTypeKind:
+ return LLVMGetVectorSize(type) *
+ llvm_get_type_size(LLVMGetElementType(type));
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
static void create_function(struct si_shader_context *ctx)
{
struct lp_build_tgsi_context *bld_base = &ctx->radeon_bld.soa.bld_base;
@@ -3717,6 +3737,9 @@ static void create_function(struct si_shader_context *ctx)
radeon_llvm_shader_type(ctx->radeon_bld.main_fn, ctx->type);
ctx->return_value = LLVMGetUndef(ctx->radeon_bld.return_type);
+ shader->num_input_sgprs = 0;
+ shader->num_input_vgprs = 0;
+
for (i = 0; i <= last_sgpr; ++i) {
LLVMValueRef P = LLVMGetParam(ctx->radeon_bld.main_fn, i);
@@ -3726,8 +3749,17 @@ static void create_function(struct si_shader_context *ctx)
LLVMAddAttribute(P, LLVMByValAttribute);
else
LLVMAddAttribute(P, LLVMInRegAttribute);
+
+ shader->num_input_sgprs += llvm_get_type_size(params[i]) / 4;
}
+ /* Unused fragment shader inputs are eliminated by the compiler,
+ * so we don't know yet how many there will be.
+ */
+ if (ctx->type != TGSI_PROCESSOR_FRAGMENT)
+ for (; i < num_params; ++i)
+ shader->num_input_vgprs += llvm_get_type_size(params[i]) / 4;
+
if (bld_base->info &&
(bld_base->info->opcode_count[TGSI_OPCODE_DDX] > 0 ||
bld_base->info->opcode_count[TGSI_OPCODE_DDY] > 0 ||
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index dc75e0330e4..131455b6d0f 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -279,6 +279,8 @@ struct si_shader {
struct radeon_shader_binary binary;
struct si_shader_config config;
+ ubyte num_input_sgprs;
+ ubyte num_input_vgprs;
unsigned vs_output_param_offset[PIPE_MAX_SHADER_OUTPUTS];
bool uses_instanceid;
unsigned nr_pos_exports;