aboutsummaryrefslogtreecommitdiffstats
path: root/src/amd
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2020-01-27 12:16:41 +0100
committerMarge Bot <[email protected]>2020-01-29 09:49:50 +0000
commit3922d95b5111af21b40e720ef30b869f39bbcfdc (patch)
treead2ee3f150bc52af4720b21a31d247e9968acd71 /src/amd
parent6f4c30091900262598c7348a83841250a2922c78 (diff)
aco: implement VK_AMD_shader_explicit_vertex_parameter
Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3578>
Diffstat (limited to 'src/amd')
-rw-r--r--src/amd/compiler/aco_instruction_selection.cpp42
-rw-r--r--src/amd/compiler/aco_instruction_selection_setup.cpp5
2 files changed, 42 insertions, 5 deletions
diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp
index af18e9a4bdd..5859cb536e2 100644
--- a/src/amd/compiler/aco_instruction_selection.cpp
+++ b/src/amd/compiler/aco_instruction_selection.cpp
@@ -3339,7 +3339,8 @@ void visit_load_input(isel_context *ctx, nir_intrinsic_instr *instr)
ctx->allocated_vec.emplace(dst.id(), elems);
}
} else if (ctx->stage == fragment_fs) {
- nir_instr *off_instr = instr->src[0].ssa->parent_instr;
+ unsigned offset_idx = instr->intrinsic == nir_intrinsic_load_input ? 0 : 1;
+ nir_instr *off_instr = instr->src[offset_idx].ssa->parent_instr;
if (off_instr->type != nir_instr_type_load_const ||
nir_instr_as_load_const(off_instr)->value[0].u32 != 0) {
fprintf(stderr, "Unimplemented nir_intrinsic_load_input offset\n");
@@ -3348,13 +3349,13 @@ void visit_load_input(isel_context *ctx, nir_intrinsic_instr *instr)
}
Temp prim_mask = get_arg(ctx, ctx->args->ac.prim_mask);
- nir_const_value* offset = nir_src_as_const_value(instr->src[0]);
+ nir_const_value* offset = nir_src_as_const_value(instr->src[offset_idx]);
if (offset) {
assert(offset->u32 == 0);
} else {
/* the lower 15bit of the prim_mask contain the offset into LDS
* while the upper bits contain the number of prims */
- Temp offset_src = get_ssa_temp(ctx, instr->src[0].ssa);
+ Temp offset_src = get_ssa_temp(ctx, instr->src[offset_idx].ssa);
assert(offset_src.regClass() == s1 && "TODO: divergent offsets...");
Builder bld(ctx->program, ctx->block);
Temp stride = bld.sop2(aco_opcode::s_lshr_b32, bld.def(s1), bld.def(s1, scc), prim_mask, Operand(16u));
@@ -3366,13 +3367,31 @@ void visit_load_input(isel_context *ctx, nir_intrinsic_instr *instr)
unsigned idx = nir_intrinsic_base(instr);
unsigned component = nir_intrinsic_component(instr);
+ unsigned vertex_id = 2; /* P0 */
+
+ if (instr->intrinsic == nir_intrinsic_load_input_vertex) {
+ nir_const_value* src0 = nir_src_as_const_value(instr->src[0]);
+ switch (src0->u32) {
+ case 0:
+ vertex_id = 2; /* P0 */
+ break;
+ case 1:
+ vertex_id = 0; /* P10 */
+ break;
+ case 2:
+ vertex_id = 1; /* P20 */
+ break;
+ default:
+ unreachable("invalid vertex index");
+ }
+ }
if (dst.size() == 1) {
- bld.vintrp(aco_opcode::v_interp_mov_f32, Definition(dst), Operand(2u), bld.m0(prim_mask), idx, component);
+ bld.vintrp(aco_opcode::v_interp_mov_f32, Definition(dst), Operand(vertex_id), bld.m0(prim_mask), idx, component);
} else {
aco_ptr<Pseudo_instruction> vec{create_instruction<Pseudo_instruction>(aco_opcode::p_create_vector, Format::PSEUDO, dst.size(), 1)};
for (unsigned i = 0; i < dst.size(); i++)
- vec->operands[i] = bld.vintrp(aco_opcode::v_interp_mov_f32, bld.def(v1), Operand(2u), bld.m0(prim_mask), idx, component + i);
+ vec->operands[i] = bld.vintrp(aco_opcode::v_interp_mov_f32, bld.def(v1), Operand(vertex_id), bld.m0(prim_mask), idx, component + i);
vec->definitions[0] = Definition(dst);
bld.insert(std::move(vec));
}
@@ -6010,6 +6029,18 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
emit_split_vector(ctx, dst, 2);
break;
}
+ case nir_intrinsic_load_barycentric_model: {
+ Temp model = get_arg(ctx, ctx->args->ac.pull_model);
+
+ Temp dst = get_ssa_temp(ctx, &instr->dest.ssa);
+ Temp p1 = emit_extract_vector(ctx, model, 0, v1);
+ Temp p2 = emit_extract_vector(ctx, model, 1, v1);
+ Temp p3 = emit_extract_vector(ctx, model, 2, v1);
+ bld.pseudo(aco_opcode::p_create_vector, Definition(dst),
+ Operand(p1), Operand(p2), Operand(p3));
+ emit_split_vector(ctx, dst, 3);
+ break;
+ }
case nir_intrinsic_load_barycentric_at_sample: {
uint32_t sample_pos_offset = RING_PS_SAMPLE_POSITIONS * 16;
switch (ctx->options->key.fs.num_samples) {
@@ -6140,6 +6171,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
visit_store_output(ctx, instr);
break;
case nir_intrinsic_load_input:
+ case nir_intrinsic_load_input_vertex:
visit_load_input(ctx, instr);
break;
case nir_intrinsic_load_per_vertex_input:
diff --git a/src/amd/compiler/aco_instruction_selection_setup.cpp b/src/amd/compiler/aco_instruction_selection_setup.cpp
index c23f59e30a9..66e45ef2998 100644
--- a/src/amd/compiler/aco_instruction_selection_setup.cpp
+++ b/src/amd/compiler/aco_instruction_selection_setup.cpp
@@ -302,11 +302,13 @@ void init_context(isel_context *ctx, nir_shader *shader)
case nir_intrinsic_load_sample_id:
case nir_intrinsic_load_sample_mask_in:
case nir_intrinsic_load_input:
+ case nir_intrinsic_load_input_vertex:
case nir_intrinsic_load_per_vertex_input:
case nir_intrinsic_load_vertex_id:
case nir_intrinsic_load_vertex_id_zero_base:
case nir_intrinsic_load_barycentric_sample:
case nir_intrinsic_load_barycentric_pixel:
+ case nir_intrinsic_load_barycentric_model:
case nir_intrinsic_load_barycentric_centroid:
case nir_intrinsic_load_barycentric_at_sample:
case nir_intrinsic_load_barycentric_at_offset:
@@ -435,6 +437,9 @@ void init_context(isel_context *ctx, nir_shader *shader)
spi_ps_inputs |= get_interp_input(intrinsic->intrinsic, mode);
break;
}
+ case nir_intrinsic_load_barycentric_model:
+ spi_ps_inputs |= S_0286CC_PERSP_PULL_MODEL_ENA(1);
+ break;
case nir_intrinsic_load_front_face:
spi_ps_inputs |= S_0286CC_FRONT_FACE_ENA(1);
break;