radeonsi: use nir_lower_gs_intrinsics
Replace some llvm code. Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Signed-off-by: Qiang Yu <yuq825@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17109>
This commit is contained in:
@@ -4053,9 +4053,6 @@ static bool visit_intrinsic(struct ac_nir_context *ctx, nir_intrinsic_instr *ins
|
|||||||
false);
|
false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case nir_intrinsic_emit_vertex:
|
|
||||||
ctx->abi->emit_vertex(ctx->abi, nir_intrinsic_stream_id(instr), ctx->abi->outputs);
|
|
||||||
break;
|
|
||||||
case nir_intrinsic_emit_vertex_with_counter: {
|
case nir_intrinsic_emit_vertex_with_counter: {
|
||||||
unsigned stream = nir_intrinsic_stream_id(instr);
|
unsigned stream = nir_intrinsic_stream_id(instr);
|
||||||
LLVMValueRef next_vertex = get_src(ctx, instr->src[0]);
|
LLVMValueRef next_vertex = get_src(ctx, instr->src[0]);
|
||||||
|
@@ -68,8 +68,6 @@ struct ac_shader_abi {
|
|||||||
|
|
||||||
void (*export_vertex)(struct ac_shader_abi *abi);
|
void (*export_vertex)(struct ac_shader_abi *abi);
|
||||||
|
|
||||||
void (*emit_vertex)(struct ac_shader_abi *abi, unsigned stream, LLVMValueRef *addrs);
|
|
||||||
|
|
||||||
void (*emit_primitive)(struct ac_shader_abi *abi, unsigned stream);
|
void (*emit_primitive)(struct ac_shader_abi *abi, unsigned stream);
|
||||||
|
|
||||||
void (*emit_vertex_with_counter)(struct ac_shader_abi *abi, unsigned stream,
|
void (*emit_vertex_with_counter)(struct ac_shader_abi *abi, unsigned stream,
|
||||||
|
@@ -1885,27 +1885,12 @@ static LLVMValueRef ngg_gs_get_emit_primflag_ptr(struct si_shader_context *ctx,
|
|||||||
return LLVMBuildGEP2(ctx->ac.builder, vertexptr.pointee_type, vertexptr.value, gep_idx, 3, "");
|
return LLVMBuildGEP2(ctx->ac.builder, vertexptr.pointee_type, vertexptr.value, gep_idx, 3, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx10_ngg_gs_emit_vertex(struct si_shader_context *ctx, unsigned stream, LLVMValueRef *addrs)
|
void gfx10_ngg_gs_emit_vertex(struct si_shader_context *ctx, unsigned stream,
|
||||||
|
LLVMValueRef vertexidx, LLVMValueRef *addrs)
|
||||||
{
|
{
|
||||||
const struct si_shader_selector *sel = ctx->shader->selector;
|
const struct si_shader_selector *sel = ctx->shader->selector;
|
||||||
const struct si_shader_info *info = &sel->info;
|
const struct si_shader_info *info = &sel->info;
|
||||||
LLVMBuilderRef builder = ctx->ac.builder;
|
LLVMBuilderRef builder = ctx->ac.builder;
|
||||||
LLVMValueRef tmp;
|
|
||||||
const LLVMValueRef vertexidx = LLVMBuildLoad2(builder, ctx->ac.i32, ctx->gs_next_vertex[stream], "");
|
|
||||||
|
|
||||||
/* If this thread has already emitted the declared maximum number of
|
|
||||||
* vertices, skip the write: excessive vertex emissions are not
|
|
||||||
* supposed to have any effect.
|
|
||||||
*/
|
|
||||||
const LLVMValueRef can_emit =
|
|
||||||
LLVMBuildICmp(builder, LLVMIntULT, vertexidx,
|
|
||||||
LLVMConstInt(ctx->ac.i32, sel->info.base.gs.vertices_out, false), "");
|
|
||||||
|
|
||||||
tmp = LLVMBuildAdd(builder, vertexidx, ctx->ac.i32_1, "");
|
|
||||||
tmp = LLVMBuildSelect(builder, can_emit, tmp, vertexidx, "");
|
|
||||||
LLVMBuildStore(builder, tmp, ctx->gs_next_vertex[stream]);
|
|
||||||
|
|
||||||
ac_build_ifcc(&ctx->ac, can_emit, 9001);
|
|
||||||
|
|
||||||
const struct ac_llvm_pointer vertexptr = ngg_gs_emit_vertex_ptr(ctx, gfx10_get_thread_id_in_tg(ctx), vertexidx);
|
const struct ac_llvm_pointer vertexptr = ngg_gs_emit_vertex_ptr(ctx, gfx10_get_thread_id_in_tg(ctx), vertexidx);
|
||||||
unsigned out_idx = 0;
|
unsigned out_idx = 0;
|
||||||
@@ -1923,6 +1908,13 @@ void gfx10_ngg_gs_emit_vertex(struct si_shader_context *ctx, unsigned stream, LL
|
|||||||
}
|
}
|
||||||
assert(out_idx * 4 == info->gsvs_vertex_size);
|
assert(out_idx * 4 == info->gsvs_vertex_size);
|
||||||
|
|
||||||
|
/* Store the current number of emitted vertices to zero out remaining
|
||||||
|
* primitive flags in case the geometry shader doesn't emit the maximum
|
||||||
|
* number of vertices.
|
||||||
|
*/
|
||||||
|
LLVMValueRef tmp = LLVMBuildAdd(builder, vertexidx, ctx->ac.i32_1, "");
|
||||||
|
LLVMBuildStore(builder, tmp, ctx->gs_next_vertex[stream]);
|
||||||
|
|
||||||
/* Determine and store whether this vertex completed a primitive. */
|
/* Determine and store whether this vertex completed a primitive. */
|
||||||
const LLVMValueRef curverts = LLVMBuildLoad2(builder, ctx->ac.i32, ctx->gs_curprim_verts[stream], "");
|
const LLVMValueRef curverts = LLVMBuildLoad2(builder, ctx->ac.i32, ctx->gs_curprim_verts[stream], "");
|
||||||
|
|
||||||
@@ -1955,8 +1947,6 @@ void gfx10_ngg_gs_emit_vertex(struct si_shader_context *ctx, unsigned stream, LL
|
|||||||
tmp = LLVMBuildLoad2(builder, ctx->ac.i32, ctx->gs_generated_prims[stream], "");
|
tmp = LLVMBuildLoad2(builder, ctx->ac.i32, ctx->gs_generated_prims[stream], "");
|
||||||
tmp = LLVMBuildAdd(builder, tmp, LLVMBuildZExt(builder, iscompleteprim, ctx->ac.i32, ""), "");
|
tmp = LLVMBuildAdd(builder, tmp, LLVMBuildZExt(builder, iscompleteprim, ctx->ac.i32, ""), "");
|
||||||
LLVMBuildStore(builder, tmp, ctx->gs_generated_prims[stream]);
|
LLVMBuildStore(builder, tmp, ctx->gs_generated_prims[stream]);
|
||||||
|
|
||||||
ac_build_endif(&ctx->ac, 9001);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx10_ngg_gs_emit_begin(struct si_shader_context *ctx)
|
void gfx10_ngg_gs_emit_begin(struct si_shader_context *ctx)
|
||||||
|
@@ -188,7 +188,8 @@ void gfx10_ngg_culling_build_end(struct si_shader_context *ctx);
|
|||||||
void gfx10_ngg_build_end(struct si_shader_context *ctx);
|
void gfx10_ngg_build_end(struct si_shader_context *ctx);
|
||||||
void gfx10_ngg_atomic_add_prim_count(struct ac_shader_abi *abi, unsigned stream,
|
void gfx10_ngg_atomic_add_prim_count(struct ac_shader_abi *abi, unsigned stream,
|
||||||
LLVMValueRef prim_count, enum ac_prim_count count_type);
|
LLVMValueRef prim_count, enum ac_prim_count count_type);
|
||||||
void gfx10_ngg_gs_emit_vertex(struct si_shader_context *ctx, unsigned stream, LLVMValueRef *addrs);
|
void gfx10_ngg_gs_emit_vertex(struct si_shader_context *ctx, unsigned stream,
|
||||||
|
LLVMValueRef vertexidx, LLVMValueRef *addrs);
|
||||||
void gfx10_ngg_gs_emit_begin(struct si_shader_context *ctx);
|
void gfx10_ngg_gs_emit_begin(struct si_shader_context *ctx);
|
||||||
void gfx10_ngg_gs_build_end(struct si_shader_context *ctx);
|
void gfx10_ngg_gs_build_end(struct si_shader_context *ctx);
|
||||||
unsigned gfx10_ngg_get_scratch_dw_size(struct si_shader *shader);
|
unsigned gfx10_ngg_get_scratch_dw_size(struct si_shader *shader);
|
||||||
|
@@ -162,48 +162,23 @@ void si_llvm_gs_build_end(struct si_shader_context *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Emit one vertex from the geometry shader */
|
/* Emit one vertex from the geometry shader */
|
||||||
static void si_llvm_emit_vertex(struct ac_shader_abi *abi, unsigned stream, LLVMValueRef *addrs)
|
static void si_llvm_emit_vertex(struct ac_shader_abi *abi, unsigned stream,
|
||||||
|
LLVMValueRef vertexidx, LLVMValueRef *addrs)
|
||||||
{
|
{
|
||||||
struct si_shader_context *ctx = si_shader_context_from_abi(abi);
|
struct si_shader_context *ctx = si_shader_context_from_abi(abi);
|
||||||
|
|
||||||
if (ctx->shader->key.ge.as_ngg) {
|
if (ctx->shader->key.ge.as_ngg) {
|
||||||
gfx10_ngg_gs_emit_vertex(ctx, stream, addrs);
|
gfx10_ngg_gs_emit_vertex(ctx, stream, vertexidx, addrs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct si_shader_info *info = &ctx->shader->selector->info;
|
struct si_shader_info *info = &ctx->shader->selector->info;
|
||||||
struct si_shader *shader = ctx->shader;
|
struct si_shader *shader = ctx->shader;
|
||||||
LLVMValueRef soffset = ac_get_arg(&ctx->ac, ctx->args.gs2vs_offset);
|
LLVMValueRef soffset = ac_get_arg(&ctx->ac, ctx->args.gs2vs_offset);
|
||||||
LLVMValueRef gs_next_vertex;
|
|
||||||
LLVMValueRef can_emit;
|
|
||||||
unsigned chan, offset;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Write vertex attribute values to GSVS ring */
|
unsigned offset = 0;
|
||||||
gs_next_vertex = LLVMBuildLoad2(ctx->ac.builder, ctx->ac.i32, ctx->gs_next_vertex[stream], "");
|
for (unsigned i = 0; i < info->num_outputs; i++) {
|
||||||
|
for (unsigned chan = 0; chan < 4; chan++) {
|
||||||
/* If this thread has already emitted the declared maximum number of
|
|
||||||
* vertices, skip the write: excessive vertex emissions are not
|
|
||||||
* supposed to have any effect.
|
|
||||||
*
|
|
||||||
* If the shader has no writes to memory, kill it instead. This skips
|
|
||||||
* further memory loads and may allow LLVM to skip to the end
|
|
||||||
* altogether.
|
|
||||||
*/
|
|
||||||
can_emit =
|
|
||||||
LLVMBuildICmp(ctx->ac.builder, LLVMIntULT, gs_next_vertex,
|
|
||||||
LLVMConstInt(ctx->ac.i32, shader->selector->info.base.gs.vertices_out, 0), "");
|
|
||||||
|
|
||||||
bool use_kill = !info->base.writes_memory;
|
|
||||||
if (use_kill) {
|
|
||||||
ac_build_kill_if_false(&ctx->ac, can_emit);
|
|
||||||
} else {
|
|
||||||
ac_build_ifcc(&ctx->ac, can_emit, 6505);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = 0;
|
|
||||||
for (i = 0; i < info->num_outputs; i++) {
|
|
||||||
for (chan = 0; chan < 4; chan++) {
|
|
||||||
if (!(info->output_usagemask[i] & (1 << chan)) ||
|
if (!(info->output_usagemask[i] & (1 << chan)) ||
|
||||||
((info->output_streams[i] >> (2 * chan)) & 3) != stream)
|
((info->output_streams[i] >> (2 * chan)) & 3) != stream)
|
||||||
continue;
|
continue;
|
||||||
@@ -213,7 +188,7 @@ static void si_llvm_emit_vertex(struct ac_shader_abi *abi, unsigned stream, LLVM
|
|||||||
LLVMConstInt(ctx->ac.i32, offset * shader->selector->info.base.gs.vertices_out, 0);
|
LLVMConstInt(ctx->ac.i32, offset * shader->selector->info.base.gs.vertices_out, 0);
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
voffset = LLVMBuildAdd(ctx->ac.builder, voffset, gs_next_vertex, "");
|
voffset = LLVMBuildAdd(ctx->ac.builder, voffset, vertexidx, "");
|
||||||
voffset = LLVMBuildMul(ctx->ac.builder, voffset, LLVMConstInt(ctx->ac.i32, 4, 0), "");
|
voffset = LLVMBuildMul(ctx->ac.builder, voffset, LLVMConstInt(ctx->ac.i32, 4, 0), "");
|
||||||
|
|
||||||
out_val = ac_to_integer(&ctx->ac, out_val);
|
out_val = ac_to_integer(&ctx->ac, out_val);
|
||||||
@@ -223,9 +198,6 @@ static void si_llvm_emit_vertex(struct ac_shader_abi *abi, unsigned stream, LLVM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_next_vertex = LLVMBuildAdd(ctx->ac.builder, gs_next_vertex, ctx->ac.i32_1, "");
|
|
||||||
LLVMBuildStore(ctx->ac.builder, gs_next_vertex, ctx->gs_next_vertex[stream]);
|
|
||||||
|
|
||||||
/* Signal vertex emission if vertex data was written. */
|
/* Signal vertex emission if vertex data was written. */
|
||||||
if (offset) {
|
if (offset) {
|
||||||
ac_build_sendmsg(&ctx->ac, AC_SENDMSG_GS_OP_EMIT | AC_SENDMSG_GS | (stream << 8),
|
ac_build_sendmsg(&ctx->ac, AC_SENDMSG_GS_OP_EMIT | AC_SENDMSG_GS | (stream << 8),
|
||||||
@@ -234,9 +206,6 @@ static void si_llvm_emit_vertex(struct ac_shader_abi *abi, unsigned stream, LLVM
|
|||||||
ctx->gs_emitted_vertices = LLVMBuildAdd(ctx->ac.builder, ctx->gs_emitted_vertices,
|
ctx->gs_emitted_vertices = LLVMBuildAdd(ctx->ac.builder, ctx->gs_emitted_vertices,
|
||||||
ctx->ac.i32_1, "vert");
|
ctx->ac.i32_1, "vert");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!use_kill)
|
|
||||||
ac_build_endif(&ctx->ac, 6505);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cut one primitive from the geometry shader */
|
/* Cut one primitive from the geometry shader */
|
||||||
@@ -601,6 +570,6 @@ struct si_shader *si_generate_gs_copy_shader(struct si_screen *sscreen,
|
|||||||
|
|
||||||
void si_llvm_init_gs_callbacks(struct si_shader_context *ctx)
|
void si_llvm_init_gs_callbacks(struct si_shader_context *ctx)
|
||||||
{
|
{
|
||||||
ctx->abi.emit_vertex = si_llvm_emit_vertex;
|
ctx->abi.emit_vertex_with_counter = si_llvm_emit_vertex;
|
||||||
ctx->abi.emit_primitive = si_llvm_emit_primitive;
|
ctx->abi.emit_primitive = si_llvm_emit_primitive;
|
||||||
}
|
}
|
||||||
|
@@ -297,6 +297,9 @@ static void si_lower_nir(struct si_screen *sscreen, struct nir_shader *nir)
|
|||||||
nir->info.stage == MESA_SHADER_GEOMETRY)
|
nir->info.stage == MESA_SHADER_GEOMETRY)
|
||||||
NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_out);
|
NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_out);
|
||||||
|
|
||||||
|
if (nir->info.stage == MESA_SHADER_GEOMETRY)
|
||||||
|
NIR_PASS_V(nir, nir_lower_gs_intrinsics, nir_lower_gs_intrinsics_per_stream);
|
||||||
|
|
||||||
if (nir->info.stage == MESA_SHADER_COMPUTE) {
|
if (nir->info.stage == MESA_SHADER_COMPUTE) {
|
||||||
if (nir->info.cs.derivative_group == DERIVATIVE_GROUP_QUADS) {
|
if (nir->info.cs.derivative_group == DERIVATIVE_GROUP_QUADS) {
|
||||||
/* If we are shuffling local_invocation_id for quad derivatives, we
|
/* If we are shuffling local_invocation_id for quad derivatives, we
|
||||||
|
Reference in New Issue
Block a user