summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeonsi
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2017-04-25 23:33:29 +0100
committerDave Airlie <[email protected]>2017-04-27 05:17:47 +0100
commite2659176cef99f5761c01aebe992a75a7aea842f (patch)
tree61319582b8caad80810e62f4697e19a43dad3ef2 /src/gallium/drivers/radeonsi
parent9da104593386f6e8ddec8f0d9d288aceb8908fe1 (diff)
radeonsi/ac: move vertex export remove to common code.
This code can be shared by radv, we bump the max to VARYING_SLOT_MAX here, but that shouldn't have too much fallout. Reviewed-by: Marek Olšák <[email protected]> Reviewed-by: Nicolai Hähnle <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeonsi')
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c152
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.h12
-rw-r--r--src/gallium/drivers/radeonsi/si_state_shaders.c13
3 files changed, 14 insertions, 163 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 69634b12c33..125affbaeb1 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -41,6 +41,7 @@
#include "ac_binary.h"
#include "ac_llvm_util.h"
+#include "ac_exp_param.h"
#include "si_shader_internal.h"
#include "si_pipe.h"
#include "sid.h"
@@ -6809,76 +6810,10 @@ static void si_init_shader_ctx(struct si_shader_context *ctx,
bld_base->op_actions[TGSI_OPCODE_BARRIER].emit = si_llvm_emit_barrier;
}
-#define EXP_TARGET (HAVE_LLVM >= 0x0500 ? 0 : 3)
-#define EXP_OUT0 (HAVE_LLVM >= 0x0500 ? 2 : 5)
-
-/* Return true if the PARAM export has been eliminated. */
-static bool si_eliminate_const_output(struct si_shader_context *ctx,
- LLVMValueRef inst, unsigned offset)
-{
- struct si_shader *shader = ctx->shader;
- unsigned num_outputs = shader->selector->info.num_outputs;
- unsigned i, default_val; /* SPI_PS_INPUT_CNTL_i.DEFAULT_VAL */
- bool is_zero[4] = {}, is_one[4] = {};
-
- for (i = 0; i < 4; i++) {
- LLVMBool loses_info;
- LLVMValueRef p = LLVMGetOperand(inst, EXP_OUT0 + i);
-
- /* It's a constant expression. Undef outputs are eliminated too. */
- if (LLVMIsUndef(p)) {
- is_zero[i] = true;
- is_one[i] = true;
- } else if (LLVMIsAConstantFP(p)) {
- double a = LLVMConstRealGetDouble(p, &loses_info);
-
- if (a == 0)
- is_zero[i] = true;
- else if (a == 1)
- is_one[i] = true;
- else
- return false; /* other constant */
- } else
- return false;
- }
-
- /* Only certain combinations of 0 and 1 can be eliminated. */
- if (is_zero[0] && is_zero[1] && is_zero[2])
- default_val = is_zero[3] ? 0 : 1;
- else if (is_one[0] && is_one[1] && is_one[2])
- default_val = is_zero[3] ? 2 : 3;
- else
- return false;
-
- /* The PARAM export can be represented as DEFAULT_VAL. Kill it. */
- LLVMInstructionEraseFromParent(inst);
-
- /* Change OFFSET to DEFAULT_VAL. */
- for (i = 0; i < num_outputs; i++) {
- if (shader->info.vs_output_param_offset[i] == offset) {
- shader->info.vs_output_param_offset[i] =
- EXP_PARAM_DEFAULT_VAL_0000 + default_val;
- break;
- }
- }
- return true;
-}
-
-struct si_vs_exports {
- unsigned num;
- unsigned offset[SI_MAX_VS_OUTPUTS];
- LLVMValueRef inst[SI_MAX_VS_OUTPUTS];
-};
-
static void si_eliminate_const_vs_outputs(struct si_shader_context *ctx)
{
struct si_shader *shader = ctx->shader;
struct tgsi_shader_info *info = &shader->selector->info;
- LLVMBasicBlockRef bb;
- struct si_vs_exports exports;
- bool removed_any = false;
-
- exports.num = 0;
if (ctx->type == PIPE_SHADER_FRAGMENT ||
ctx->type == PIPE_SHADER_COMPUTE ||
@@ -6886,84 +6821,11 @@ static void si_eliminate_const_vs_outputs(struct si_shader_context *ctx)
shader->key.as_ls)
return;
- /* Process all LLVM instructions. */
- bb = LLVMGetFirstBasicBlock(ctx->main_fn);
- while (bb) {
- LLVMValueRef inst = LLVMGetFirstInstruction(bb);
-
- while (inst) {
- LLVMValueRef cur = inst;
- inst = LLVMGetNextInstruction(inst);
-
- if (LLVMGetInstructionOpcode(cur) != LLVMCall)
- continue;
-
- LLVMValueRef callee = lp_get_called_value(cur);
-
- if (!lp_is_function(callee))
- continue;
-
- const char *name = LLVMGetValueName(callee);
- unsigned num_args = LLVMCountParams(callee);
-
- /* Check if this is an export instruction. */
- if ((num_args != 9 && num_args != 8) ||
- (strcmp(name, "llvm.SI.export") &&
- strcmp(name, "llvm.amdgcn.exp.f32")))
- continue;
-
- LLVMValueRef arg = LLVMGetOperand(cur, EXP_TARGET);
- unsigned target = LLVMConstIntGetZExtValue(arg);
-
- if (target < V_008DFC_SQ_EXP_PARAM)
- continue;
-
- target -= V_008DFC_SQ_EXP_PARAM;
-
- /* Eliminate constant value PARAM exports. */
- if (si_eliminate_const_output(ctx, cur, target)) {
- removed_any = true;
- } else {
- exports.offset[exports.num] = target;
- exports.inst[exports.num] = cur;
- exports.num++;
- }
- }
- bb = LLVMGetNextBasicBlock(bb);
- }
-
- /* Remove holes in export memory due to removed PARAM exports.
- * This is done by renumbering all PARAM exports.
- */
- if (removed_any) {
- ubyte current_offset[SI_MAX_VS_OUTPUTS];
- unsigned new_count = 0;
- unsigned out, i;
-
- /* Make a copy of the offsets. We need the old version while
- * we are modifying some of them. */
- assert(sizeof(current_offset) ==
- sizeof(shader->info.vs_output_param_offset));
- memcpy(current_offset, shader->info.vs_output_param_offset,
- sizeof(current_offset));
-
- for (i = 0; i < exports.num; i++) {
- unsigned offset = exports.offset[i];
-
- for (out = 0; out < info->num_outputs; out++) {
- if (current_offset[out] != offset)
- continue;
-
- LLVMSetOperand(exports.inst[i], EXP_TARGET,
- LLVMConstInt(ctx->i32,
- V_008DFC_SQ_EXP_PARAM + new_count, 0));
- shader->info.vs_output_param_offset[out] = new_count;
- new_count++;
- break;
- }
- }
- shader->info.nr_param_exports = new_count;
- }
+ ac_eliminate_const_vs_outputs(&ctx->ac,
+ ctx->main_fn,
+ shader->info.vs_output_param_offset,
+ info->num_outputs,
+ &shader->info.nr_param_exports);
}
static void si_count_scratch_private_memory(struct si_shader_context *ctx)
@@ -7537,7 +7399,7 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
si_init_shader_ctx(&ctx, sscreen, shader, tm);
ctx.separate_prolog = !is_monolithic;
- memset(shader->info.vs_output_param_offset, EXP_PARAM_UNDEFINED,
+ memset(shader->info.vs_output_param_offset, AC_EXP_PARAM_UNDEFINED,
sizeof(shader->info.vs_output_param_offset));
shader->info.uses_instanceid = sel->info.uses_instanceid;
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index 05c0e623b4a..3c01a3d3031 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -482,18 +482,6 @@ struct si_shader_config {
unsigned rsrc2;
};
-enum {
- /* SPI_PS_INPUT_CNTL_i.OFFSET[0:4] */
- EXP_PARAM_OFFSET_0 = 0,
- EXP_PARAM_OFFSET_31 = 31,
- /* SPI_PS_INPUT_CNTL_i.DEFAULT_VAL[0:1] */
- EXP_PARAM_DEFAULT_VAL_0000 = 64,
- EXP_PARAM_DEFAULT_VAL_0001,
- EXP_PARAM_DEFAULT_VAL_1110,
- EXP_PARAM_DEFAULT_VAL_1111,
- EXP_PARAM_UNDEFINED = 255,
-};
-
/* GCN-specific shader info. */
struct si_shader_info {
ubyte vs_output_param_offset[SI_MAX_VS_OUTPUTS];
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 8afc7314918..06ea99c05c3 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -39,6 +39,7 @@
#include "util/disk_cache.h"
#include "util/mesa-sha1.h"
+#include "ac_exp_param.h"
/* SHADER_CACHE */
@@ -1506,7 +1507,7 @@ void si_init_shader_selector_async(void *job, int thread_index)
for (i = 0; i < sel->info.num_outputs; i++) {
unsigned offset = shader->info.vs_output_param_offset[i];
- if (offset <= EXP_PARAM_OFFSET_31)
+ if (offset <= AC_EXP_PARAM_OFFSET_31)
continue;
unsigned name = sel->info.output_semantic_name[i];
@@ -2001,18 +2002,18 @@ static unsigned si_get_ps_input_cntl(struct si_context *sctx,
index == vsinfo->output_semantic_index[j]) {
offset = vs->info.vs_output_param_offset[j];
- if (offset <= EXP_PARAM_OFFSET_31) {
+ if (offset <= AC_EXP_PARAM_OFFSET_31) {
/* The input is loaded from parameter memory. */
ps_input_cntl |= S_028644_OFFSET(offset);
} else if (!G_028644_PT_SPRITE_TEX(ps_input_cntl)) {
- if (offset == EXP_PARAM_UNDEFINED) {
+ if (offset == AC_EXP_PARAM_UNDEFINED) {
/* This can happen with depth-only rendering. */
offset = 0;
} else {
/* The input is a DEFAULT_VAL constant. */
- assert(offset >= EXP_PARAM_DEFAULT_VAL_0000 &&
- offset <= EXP_PARAM_DEFAULT_VAL_1111);
- offset -= EXP_PARAM_DEFAULT_VAL_0000;
+ assert(offset >= AC_EXP_PARAM_DEFAULT_VAL_0000 &&
+ offset <= AC_EXP_PARAM_DEFAULT_VAL_1111);
+ offset -= AC_EXP_PARAM_DEFAULT_VAL_0000;
}
ps_input_cntl = S_028644_OFFSET(0x20) |