[Mesa-dev] [PATCH 1/2] radeonsi: split per-patch from per-vertex indices
Nicolai Hähnle
nhaehnle at gmail.com
Wed May 3 13:54:15 UTC 2017
From: Nicolai Hähnle <nicolai.haehnle at amd.com>
Make it a bit clearer that the index spaces are logically seperate by
having them defined in different functions.
---
src/gallium/drivers/radeonsi/si_shader.c | 56 +++++++++++++++++--------
src/gallium/drivers/radeonsi/si_shader.h | 1 +
src/gallium/drivers/radeonsi/si_state_shaders.c | 6 +--
3 files changed, 42 insertions(+), 21 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 77dd6b1..a48a552 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -98,20 +98,42 @@ static bool is_merged_shader(struct si_shader *shader)
if (shader->selector->screen->b.chip_class <= VI)
return false;
return shader->key.as_ls ||
shader->key.as_es ||
shader->selector->type == PIPE_SHADER_TESS_CTRL ||
shader->selector->type == PIPE_SHADER_GEOMETRY;
}
/**
+ * Returns a unique index for a per-patch semantic name and index. The index
+ * must be less than 32, so that a 32-bit bitmask of used inputs or outputs
+ * can be calculated.
+ */
+unsigned si_shader_io_get_unique_index_patch(unsigned semantic_name, unsigned index)
+{
+ switch (semantic_name) {
+ case TGSI_SEMANTIC_TESSOUTER:
+ return 0;
+ case TGSI_SEMANTIC_TESSINNER:
+ return 1;
+ case TGSI_SEMANTIC_PATCH:
+ assert(index < 30);
+ return 2 + index;
+
+ default:
+ assert(!"invalid semantic name");
+ return 0;
+ }
+}
+
+/**
* Returns a unique index for a semantic name and index. The index must be
* less than 64, so that a 64-bit bitmask of used inputs or outputs can be
* calculated.
*/
unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index)
{
switch (semantic_name) {
case TGSI_SEMANTIC_POSITION:
return 0;
case TGSI_SEMANTIC_PSIZE:
@@ -119,28 +141,20 @@ unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index)
case TGSI_SEMANTIC_CLIPDIST:
assert(index <= 1);
return 2 + index;
case TGSI_SEMANTIC_GENERIC:
if (index <= 63-4)
return 4 + index;
assert(!"invalid generic index");
return 0;
- /* patch indices are completely separate and thus start from 0 */
- case TGSI_SEMANTIC_TESSOUTER:
- return 0;
- case TGSI_SEMANTIC_TESSINNER:
- return 1;
- case TGSI_SEMANTIC_PATCH:
- return 2 + index;
-
default:
assert(!"invalid semantic name");
return 0;
}
}
unsigned si_shader_io_get_unique_index2(unsigned name, unsigned index)
{
switch (name) {
case TGSI_SEMANTIC_FOG:
@@ -670,24 +684,29 @@ static LLVMValueRef get_dw_address(struct si_shader_context *ctx,
else
first = reg.Register.Index;
ind_index = get_indirect_index(ctx, ®.Indirect,
reg.Register.Index - first);
base_addr = LLVMBuildAdd(gallivm->builder, base_addr,
LLVMBuildMul(gallivm->builder, ind_index,
LLVMConstInt(ctx->i32, 4, 0), ""), "");
- param = si_shader_io_get_unique_index(name[first], index[first]);
+ param = reg.Register.Dimension ?
+ si_shader_io_get_unique_index(name[first], index[first]) :
+ si_shader_io_get_unique_index_patch(name[first], index[first]);
} else {
- param = si_shader_io_get_unique_index(name[reg.Register.Index],
- index[reg.Register.Index]);
+ param = reg.Register.Dimension ?
+ si_shader_io_get_unique_index(name[reg.Register.Index],
+ index[reg.Register.Index]) :
+ si_shader_io_get_unique_index_patch(name[reg.Register.Index],
+ index[reg.Register.Index]);
}
/* Add the base address of the element. */
return LLVMBuildAdd(gallivm->builder, base_addr,
LLVMConstInt(ctx->i32, param * 4, 0), "");
}
/* The offchip buffer layout for TCS->TES is
*
* - attribute 0 of patch 0 vertex 0
@@ -795,22 +814,23 @@ static LLVMValueRef get_tcs_tes_buffer_address_from_reg(
param_base = reg.Register.Index;
param_index = get_indirect_index(ctx, ®.Indirect,
reg.Register.Index - param_base);
} else {
param_base = reg.Register.Index;
param_index = ctx->i32_0;
}
- param_index_base = si_shader_io_get_unique_index(name[param_base],
- index[param_base]);
+ param_index_base = reg.Register.Dimension ?
+ si_shader_io_get_unique_index(name[param_base], index[param_base]) :
+ si_shader_io_get_unique_index_patch(name[param_base], index[param_base]);
param_index = LLVMBuildAdd(gallivm->builder, param_index,
LLVMConstInt(ctx->i32, param_index_base, 0),
"");
return get_tcs_tes_buffer_address(ctx, get_rel_patch_id(ctx),
vertex_index, param_index);
}
static LLVMValueRef buffer_load(struct lp_build_tgsi_context *bld_base,
@@ -1548,21 +1568,21 @@ static void declare_system_value(struct si_shader_context *ctx,
else if (ctx->type == PIPE_SHADER_TESS_EVAL)
value = unpack_param(ctx, ctx->param_tcs_offchip_layout, 6, 6);
else
assert(!"invalid shader stage for TGSI_SEMANTIC_VERTICESIN");
break;
case TGSI_SEMANTIC_TESSINNER:
case TGSI_SEMANTIC_TESSOUTER:
{
LLVMValueRef buffer, base, addr;
- int param = si_shader_io_get_unique_index(decl->Semantic.Name, 0);
+ int param = si_shader_io_get_unique_index_patch(decl->Semantic.Name, 0);
buffer = desc_from_addr_base64k(ctx, ctx->param_tcs_offchip_addr_base64k);
base = LLVMGetParam(ctx->main_fn, ctx->param_tcs_offchip_offset);
addr = get_tcs_tes_buffer_address(ctx, get_rel_patch_id(ctx), NULL,
LLVMConstInt(ctx->i32, param, 0));
value = buffer_load(&ctx->bld_base, TGSI_TYPE_FLOAT,
~0, buffer, base, addr, true);
@@ -2537,22 +2557,22 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
inner_comps = 2;
break;
default:
assert(0);
return;
}
/* Load tess_inner and tess_outer from LDS.
* Any invocation can write them, so we can't get them from a temporary.
*/
- tess_inner_index = si_shader_io_get_unique_index(TGSI_SEMANTIC_TESSINNER, 0);
- tess_outer_index = si_shader_io_get_unique_index(TGSI_SEMANTIC_TESSOUTER, 0);
+ tess_inner_index = si_shader_io_get_unique_index_patch(TGSI_SEMANTIC_TESSINNER, 0);
+ tess_outer_index = si_shader_io_get_unique_index_patch(TGSI_SEMANTIC_TESSOUTER, 0);
lds_base = tcs_out_current_patch_data_offset;
lds_inner = LLVMBuildAdd(gallivm->builder, lds_base,
LLVMConstInt(ctx->i32,
tess_inner_index * 4, 0), "");
lds_outer = LLVMBuildAdd(gallivm->builder, lds_base,
LLVMConstInt(ctx->i32,
tess_outer_index * 4, 0), "");
for (i = 0; i < 4; i++) {
@@ -2621,33 +2641,33 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
/* Store the tess factors into the offchip buffer if TES reads them. */
if (shader->key.part.tcs.epilog.tes_reads_tess_factors) {
LLVMValueRef buf, base, inner_vec, outer_vec, tf_outer_offset;
LLVMValueRef tf_inner_offset;
unsigned param_outer, param_inner;
buf = desc_from_addr_base64k(ctx, ctx->param_tcs_offchip_addr_base64k);
base = LLVMGetParam(ctx->main_fn, ctx->param_tcs_offchip_offset);
- param_outer = si_shader_io_get_unique_index(
+ param_outer = si_shader_io_get_unique_index_patch(
TGSI_SEMANTIC_TESSOUTER, 0);
tf_outer_offset = get_tcs_tes_buffer_address(ctx, rel_patch_id, NULL,
LLVMConstInt(ctx->i32, param_outer, 0));
outer_vec = lp_build_gather_values(gallivm, outer,
util_next_power_of_two(outer_comps));
ac_build_buffer_store_dword(&ctx->ac, buf, outer_vec,
outer_comps, tf_outer_offset,
base, 0, 1, 0, true, false);
if (inner_comps) {
- param_inner = si_shader_io_get_unique_index(
+ param_inner = si_shader_io_get_unique_index_patch(
TGSI_SEMANTIC_TESSINNER, 0);
tf_inner_offset = get_tcs_tes_buffer_address(ctx, rel_patch_id, NULL,
LLVMConstInt(ctx->i32, param_inner, 0));
inner_vec = inner_comps == 1 ? inner[0] :
lp_build_gather_values(gallivm, inner, inner_comps);
ac_build_buffer_store_dword(&ctx->ac, buf, inner_vec,
inner_comps, tf_inner_offset,
base, 0, 1, 0, true, false);
}
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index 0988d91..cb8a902 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -598,20 +598,21 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
struct pipe_debug_callback *debug);
int si_compile_llvm(struct si_screen *sscreen,
struct ac_shader_binary *binary,
struct si_shader_config *conf,
LLVMTargetMachineRef tm,
LLVMModuleRef mod,
struct pipe_debug_callback *debug,
unsigned processor,
const char *name);
void si_shader_destroy(struct si_shader *shader);
+unsigned si_shader_io_get_unique_index_patch(unsigned semantic_name, unsigned index);
unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index);
unsigned si_shader_io_get_unique_index2(unsigned name, unsigned index);
int si_shader_binary_upload(struct si_screen *sscreen, struct si_shader *shader);
void si_shader_dump(struct si_screen *sscreen, struct si_shader *shader,
struct pipe_debug_callback *debug, unsigned processor,
FILE *f, bool check_debug_option);
void si_multiwave_lds_size_workaround(struct si_screen *sscreen,
unsigned *lds_size);
void si_shader_apply_scratch_relocs(struct si_context *sctx,
struct si_shader *shader,
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index e479422..68f4d21 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -1975,35 +1975,35 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
sel->max_gs_stream = MAX2(sel->max_gs_stream,
sel->so.output[i].stream);
sel->gs_input_verts_per_prim =
u_vertices_per_prim(sel->info.properties[TGSI_PROPERTY_GS_INPUT_PRIM]);
break;
case PIPE_SHADER_TESS_CTRL:
/* Always reserve space for these. */
sel->patch_outputs_written |=
- (1llu << si_shader_io_get_unique_index(TGSI_SEMANTIC_TESSINNER, 0)) |
- (1llu << si_shader_io_get_unique_index(TGSI_SEMANTIC_TESSOUTER, 0));
+ (1llu << si_shader_io_get_unique_index_patch(TGSI_SEMANTIC_TESSINNER, 0)) |
+ (1llu << si_shader_io_get_unique_index_patch(TGSI_SEMANTIC_TESSOUTER, 0));
/* fall through */
case PIPE_SHADER_VERTEX:
case PIPE_SHADER_TESS_EVAL:
for (i = 0; i < sel->info.num_outputs; i++) {
unsigned name = sel->info.output_semantic_name[i];
unsigned index = sel->info.output_semantic_index[i];
switch (name) {
case TGSI_SEMANTIC_TESSINNER:
case TGSI_SEMANTIC_TESSOUTER:
case TGSI_SEMANTIC_PATCH:
sel->patch_outputs_written |=
- 1llu << si_shader_io_get_unique_index(name, index);
+ 1llu << si_shader_io_get_unique_index_patch(name, index);
break;
case TGSI_SEMANTIC_GENERIC:
/* don't process indices the function can't handle */
if (index >= 60)
break;
/* fall through */
case TGSI_SEMANTIC_POSITION:
case TGSI_SEMANTIC_PSIZE:
case TGSI_SEMANTIC_CLIPDIST:
--
2.9.3
More information about the mesa-dev
mailing list