[Mesa-dev] [PATCH 44/92] ac, radeonsi: add ac_shader_abi::emit_outputs for hardware VS shaders
Nicolai Hähnle
nhaehnle at gmail.com
Mon Jun 26 14:10:23 UTC 2017
From: Nicolai Hähnle <nicolai.haehnle at amd.com>
---
src/amd/common/ac_shader_abi.h | 4 +++
src/gallium/drivers/radeonsi/si_shader.c | 37 ++++++++++++++++-------
src/gallium/drivers/radeonsi/si_shader_internal.h | 7 +++++
3 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/src/amd/common/ac_shader_abi.h b/src/amd/common/ac_shader_abi.h
index 16b63d1..0d91dd2 100644
--- a/src/amd/common/ac_shader_abi.h
+++ b/src/amd/common/ac_shader_abi.h
@@ -33,13 +33,17 @@ struct ac_shader_abi {
int param_draw_id;
int param_vertex_id;
int param_instance_id;
/* For VS and PS: pre-loaded shader inputs.
*
* Currently only used for NIR shaders; indexed by variables'
* driver_location.
*/
LLVMValueRef *inputs;
+
+ void (*emit_outputs)(struct ac_shader_abi *abi,
+ unsigned max_outputs,
+ LLVMValueRef *addrs);
};
#endif /* AC_SHADER_ABI_H */
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 0c975ae..c3ea666 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -2946,29 +2946,32 @@ static LLVMValueRef si_get_gs_wave_id(struct si_shader_context *ctx)
}
static void si_llvm_emit_gs_epilogue(struct lp_build_tgsi_context *bld_base)
{
struct si_shader_context *ctx = si_shader_context(bld_base);
ac_build_sendmsg(&ctx->ac, AC_SENDMSG_GS_OP_NOP | AC_SENDMSG_GS_DONE,
si_get_gs_wave_id(ctx));
}
-static void si_llvm_emit_vs_epilogue(struct lp_build_tgsi_context *bld_base)
+static void si_llvm_emit_vs_epilogue(struct ac_shader_abi *abi,
+ unsigned max_outputs,
+ LLVMValueRef *addrs)
{
- struct si_shader_context *ctx = si_shader_context(bld_base);
+ struct si_shader_context *ctx = si_shader_context_from_abi(abi);
struct gallivm_state *gallivm = &ctx->gallivm;
struct tgsi_shader_info *info = &ctx->shader->selector->info;
struct si_shader_output_values *outputs = NULL;
int i,j;
assert(!ctx->shader->is_gs_copy_shader);
+ assert(info->num_outputs <= max_outputs);
outputs = MALLOC((info->num_outputs + 1) * sizeof(outputs[0]));
/* Vertex color clamping.
*
* This uses a state constant loaded in a user data SGPR and
* an IF statement is added that clamps all colors if the constant
* is true.
*/
if (ctx->type == PIPE_SHADER_VERTEX) {
@@ -2985,66 +2988,74 @@ static void si_llvm_emit_vs_epilogue(struct lp_build_tgsi_context *bld_base)
if (!cond) {
/* The state is in the first bit of the user SGPR. */
cond = LLVMGetParam(ctx->main_fn,
ctx->param_vs_state_bits);
cond = LLVMBuildTrunc(gallivm->builder, cond,
ctx->i1, "");
lp_build_if(&if_ctx, gallivm, cond);
}
for (j = 0; j < 4; j++) {
- addr = ctx->outputs[i][j];
+ addr = addrs[4 * i + j];
val = LLVMBuildLoad(gallivm->builder, addr, "");
val = ac_build_clamp(&ctx->ac, val);
LLVMBuildStore(gallivm->builder, val, addr);
}
}
if (cond)
lp_build_endif(&if_ctx);
}
for (i = 0; i < info->num_outputs; i++) {
outputs[i].semantic_name = info->output_semantic_name[i];
outputs[i].semantic_index = info->output_semantic_index[i];
for (j = 0; j < 4; j++) {
outputs[i].values[j] =
LLVMBuildLoad(gallivm->builder,
- ctx->outputs[i][j],
+ addrs[4 * i + j],
"");
outputs[i].vertex_stream[j] =
(info->output_streams[i] >> (2 * j)) & 3;
}
}
if (ctx->shader->selector->so.num_outputs)
si_llvm_emit_streamout(ctx, outputs, i, 0);
/* Export PrimitiveID. */
if (ctx->shader->key.mono.u.vs_export_prim_id) {
outputs[i].semantic_name = TGSI_SEMANTIC_PRIMID;
outputs[i].semantic_index = 0;
- outputs[i].values[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
- get_primitive_id(ctx, 0));
+ outputs[i].values[0] = LLVMBuildBitCast(gallivm->builder,
+ get_primitive_id(ctx, 0), ctx->f32, "");
for (j = 1; j < 4; j++)
outputs[i].values[j] = LLVMConstReal(ctx->f32, 0);
memset(outputs[i].vertex_stream, 0,
sizeof(outputs[i].vertex_stream));
i++;
}
- si_llvm_export_vs(bld_base, outputs, i);
+ si_llvm_export_vs(&ctx->bld_base, outputs, i);
FREE(outputs);
}
+static void si_tgsi_emit_epilogue(struct lp_build_tgsi_context *bld_base)
+{
+ struct si_shader_context *ctx = si_shader_context(bld_base);
+
+ ctx->abi.emit_outputs(&ctx->abi, RADEON_LLVM_MAX_OUTPUTS,
+ &ctx->outputs[0][0]);
+}
+
struct si_ps_exports {
unsigned num;
struct ac_export_args args[10];
};
unsigned si_get_spi_shader_z_format(bool writes_z, bool writes_stencil,
bool writes_samplemask)
{
if (writes_z) {
/* Z needs 32 bits. */
@@ -5492,35 +5503,39 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx,
struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
// TODO clean all this up!
switch (ctx->type) {
case PIPE_SHADER_VERTEX:
ctx->load_input = declare_input_vs;
if (shader->key.as_ls)
bld_base->emit_epilogue = si_llvm_emit_ls_epilogue;
else if (shader->key.as_es)
bld_base->emit_epilogue = si_llvm_emit_es_epilogue;
- else
- bld_base->emit_epilogue = si_llvm_emit_vs_epilogue;
+ else {
+ ctx->abi.emit_outputs = si_llvm_emit_vs_epilogue;
+ bld_base->emit_epilogue = si_tgsi_emit_epilogue;
+ }
break;
case PIPE_SHADER_TESS_CTRL:
bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tcs;
bld_base->emit_fetch_funcs[TGSI_FILE_OUTPUT] = fetch_output_tcs;
bld_base->emit_store = store_output_tcs;
bld_base->emit_epilogue = si_llvm_emit_tcs_epilogue;
break;
case PIPE_SHADER_TESS_EVAL:
bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tes;
if (shader->key.as_es)
bld_base->emit_epilogue = si_llvm_emit_es_epilogue;
- else
- bld_base->emit_epilogue = si_llvm_emit_vs_epilogue;
+ else {
+ ctx->abi.emit_outputs = si_llvm_emit_vs_epilogue;
+ bld_base->emit_epilogue = si_tgsi_emit_epilogue;
+ }
break;
case PIPE_SHADER_GEOMETRY:
bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_gs;
bld_base->emit_epilogue = si_llvm_emit_gs_epilogue;
break;
case PIPE_SHADER_FRAGMENT:
ctx->load_input = declare_input_fs;
bld_base->emit_epilogue = si_llvm_return_fs_outputs;
break;
case PIPE_SHADER_COMPUTE:
diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h
index 2054a73..c8dcd5c 100644
--- a/src/gallium/drivers/radeonsi/si_shader_internal.h
+++ b/src/gallium/drivers/radeonsi/si_shader_internal.h
@@ -235,20 +235,27 @@ struct si_shader_context {
LLVMValueRef shared_memory;
};
static inline struct si_shader_context *
si_shader_context(struct lp_build_tgsi_context *bld_base)
{
return (struct si_shader_context*)bld_base;
}
+static inline struct si_shader_context *
+si_shader_context_from_abi(struct ac_shader_abi *abi)
+{
+ struct si_shader_context *ctx = NULL;
+ return container_of(abi, ctx, abi);
+}
+
void si_llvm_add_attribute(LLVMValueRef F, const char *name, int value);
LLVMTargetRef si_llvm_get_amdgpu_target(const char *triple);
unsigned si_llvm_compile(LLVMModuleRef M, struct ac_shader_binary *binary,
LLVMTargetMachineRef tm,
struct pipe_debug_callback *debug);
LLVMTypeRef tgsi2llvmtype(struct lp_build_tgsi_context *bld_base,
enum tgsi_opcode_type type);
--
2.9.3
More information about the mesa-dev
mailing list