nv/codegen: Use nir_lower_clip

Reviewed-by: Karol Herbst <kherbst@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24653>
This commit is contained in:
M Henning 2023-08-11 23:06:25 -04:00 committed by Marge Bot
parent ab0f0d1563
commit c07d3f00c4
4 changed files with 51 additions and 71 deletions

View file

@ -1258,7 +1258,6 @@ nv50_ir_init_prog_info(struct nv50_ir_prog_info *info,
info->prop.cp.numThreads[2] = 1;
}
info_out->bin.smemSize = info->bin.smemSize;
info_out->io.genUserClip = info->io.genUserClip;
info_out->io.instanceId = 0xff;
info_out->io.vertexId = 0xff;
info_out->io.edgeFlagIn = 0xff;

View file

@ -53,33 +53,4 @@ ConverterCommon::translateInterpMode(const struct nv50_ir_varying *var, operatio
return mode;
}
void
ConverterCommon::handleUserClipPlanes()
{
Value *res[8];
int n, i, c;
for (c = 0; c < 4; ++c) {
for (i = 0; i < info_out->io.genUserClip; ++i) {
Symbol *sym = mkSymbol(FILE_MEMORY_CONST, info->io.auxCBSlot,
TYPE_F32, info->io.ucpBase + i * 16 + c * 4);
Value *ucp = mkLoadv(TYPE_F32, sym, NULL);
if (c == 0)
res[i] = mkOp2v(OP_MUL, TYPE_F32, getScratch(), clipVtx[c], ucp);
else
mkOp3(OP_MAD, TYPE_F32, res[i], clipVtx[c], ucp, res[i]);
}
}
const int first = info_out->numOutputs - (info_out->io.genUserClip + 3) / 4;
for (i = 0; i < info_out->io.genUserClip; ++i) {
n = i / 4 + first;
c = i % 4;
Symbol *sym =
mkSymbol(FILE_SHADER_OUTPUT, 0, TYPE_F32, info_out->out[n].slot[c] * 4);
mkStore(OP_EXPORT, TYPE_F32, sym, NULL, res[i]);
}
}
} // namespace nv50_ir

View file

@ -32,12 +32,9 @@ public:
protected:
uint8_t translateInterpMode(const struct nv50_ir_varying *var, operation& op);
void handleUserClipPlanes();
struct nv50_ir_prog_info *info;
struct nv50_ir_prog_info_out *info_out;
Value *fragCoord[4];
Value *clipVtx[4];
Value *outBase; // base address of vertex out patch (for TCP)
};

View file

@ -23,6 +23,7 @@
*/
#include "compiler/nir/nir.h"
#include "compiler/nir/nir_builder.h"
#include "util/u_debug.h"
#include "util/u_prim.h"
@ -65,6 +66,34 @@ function_temp_type_info(const struct glsl_type *type, unsigned *size, unsigned *
}
}
bool
nv50_nir_lower_load_user_clip_plane_cb(nir_builder *b, nir_intrinsic_instr *intrin, void *params)
{
struct nv50_ir_prog_info *info = (struct nv50_ir_prog_info *)params;
if (intrin->intrinsic != nir_intrinsic_load_user_clip_plane)
return false;
uint16_t offset = info->io.ucpBase + nir_intrinsic_ucp_id(intrin) * 16;
b->cursor = nir_before_instr(&intrin->instr);
nir_def *replacement =
nir_load_ubo(b, 4, 32, nir_imm_int(b, info->io.auxCBSlot),
nir_imm_int(b, offset), .range = ~0u);
nir_def_rewrite_uses(&intrin->def, replacement);
nir_instr_remove(&intrin->instr);
return true;
}
bool
nv50_nir_lower_load_user_clip_plane(nir_shader *nir, struct nv50_ir_prog_info *info) {
return nir_shader_intrinsics_pass(nir, nv50_nir_lower_load_user_clip_plane_cb,
nir_metadata_block_index | nir_metadata_dominance,
info);
}
class Converter : public ConverterCommon
{
public:
@ -1044,9 +1073,6 @@ bool Converter::assignSlots() {
info_out->numPatchConstants = MAX2(info_out->numPatchConstants, index + slots);
switch (name) {
case TGSI_SEMANTIC_CLIPDIST:
info_out->io.genUserClip = -1;
break;
case TGSI_SEMANTIC_CLIPVERTEX:
clipVertexOutput = vary;
break;
@ -1115,20 +1141,6 @@ bool Converter::assignSlots() {
}
}
if (info_out->io.genUserClip > 0) {
info_out->io.clipDistances = info_out->io.genUserClip;
const unsigned int nOut = (info_out->io.genUserClip + 3) / 4;
for (unsigned int n = 0; n < nOut; ++n) {
unsigned int i = info_out->numOutputs++;
info_out->out[i].id = i;
info_out->out[i].sn = TGSI_SEMANTIC_CLIPDIST;
info_out->out[i].si = n;
info_out->out[i].mask = ((1 << info_out->io.clipDistances) - 1) >> (n * 4);
}
}
return info->assignSlots(info_out) == 0;
}
@ -1336,11 +1348,6 @@ Converter::visit(nir_function *function)
setPosition(entry, true);
if (info_out->io.genUserClip > 0) {
for (int c = 0; c < 4; ++c)
clipVtx[c] = getScratch();
}
switch (prog->getType()) {
case Program::TYPE_TESSELLATION_CONTROL:
outBase = mkOp2v(
@ -1367,11 +1374,6 @@ Converter::visit(nir_function *function)
bb->cfg.attach(&exit->cfg, Graph::Edge::TREE);
setPosition(exit, true);
if ((prog->getType() == Program::TYPE_VERTEX ||
prog->getType() == Program::TYPE_TESSELLATION_EVAL)
&& info_out->io.genUserClip > 0)
handleUserClipPlanes();
// TODO: for non main function this needs to be a OP_RETURN
mkOp(OP_EXIT, TYPE_NONE, NULL)->terminator = 1;
return true;
@ -1683,15 +1685,6 @@ Converter::visit(nir_intrinsic_instr *insn)
}
break;
}
case Program::TYPE_GEOMETRY:
case Program::TYPE_TESSELLATION_EVAL:
case Program::TYPE_VERTEX: {
if (info_out->io.genUserClip > 0 && idx == (uint32_t)clipVertexOutput) {
mkMov(clipVtx[i], src);
src = clipVtx[i];
}
break;
}
default:
break;
}
@ -2001,8 +1994,6 @@ Converter::visit(nir_intrinsic_instr *insn)
break;
}
case nir_intrinsic_emit_vertex: {
if (info_out->io.genUserClip > 0)
handleUserClipPlanes();
uint32_t idx = nir_intrinsic_stream_id(insn);
mkOp1(getOperation(op), TYPE_U32, NULL, mkImm(idx))->fixed = 1;
break;
@ -3239,6 +3230,28 @@ Converter::run()
(nir->options->lower_flrp64 ? 64 : 0);
assert(lower_flrp);
info_out->io.genUserClip = info->io.genUserClip;
if (info->io.genUserClip > 0) {
bool lowered = false;
if (nir->info.stage == MESA_SHADER_VERTEX ||
nir->info.stage == MESA_SHADER_TESS_EVAL)
NIR_PASS(lowered, nir, nir_lower_clip_vs,
(1 << info->io.genUserClip) - 1, true, false, NULL);
else if (nir->info.stage == MESA_SHADER_GEOMETRY)
NIR_PASS(lowered, nir, nir_lower_clip_gs,
(1 << info->io.genUserClip) - 1, false, NULL);
if (lowered) {
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
NIR_PASS_V(nir, nir_lower_io_to_temporaries, impl, true, false);
NIR_PASS_V(nir, nir_lower_global_vars_to_local);
NIR_PASS_V(nir, nv50_nir_lower_load_user_clip_plane, info);
} else {
info_out->io.genUserClip = -1;
}
}
/* prepare for IO lowering */
NIR_PASS_V(nir, nir_lower_flrp, lower_flrp, false);
NIR_PASS_V(nir, nir_opt_deref);