X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fnouveau%2Fcodegen%2Fnv50_ir_from_tgsi.cpp;h=1d2caaba72fc8016f27e1cd54ddd846976189adb;hb=99581ca393037e10d17aab1f4c90ff2bdb1ec557;hp=3c558e941bde8300b22e9d9604b852d3d5665204;hpb=ad75620863392b2164a415186087beb831ccfa4c;p=mesa.git diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp index 3c558e941bd..1d2caaba72f 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp @@ -376,6 +376,7 @@ static nv50_ir::SVSemantic translateSysVal(uint sysval) case TGSI_SEMANTIC_TESSOUTER: return nv50_ir::SV_TESS_OUTER; case TGSI_SEMANTIC_TESSINNER: return nv50_ir::SV_TESS_INNER; case TGSI_SEMANTIC_VERTICESIN: return nv50_ir::SV_VERTEX_COUNT; + case TGSI_SEMANTIC_HELPER_INVOCATION: return nv50_ir::SV_THREAD_KILL; default: assert(0); return nv50_ir::SV_CLOCK; @@ -631,6 +632,7 @@ static nv50_ir::operation translateOpcode(uint opcode) NV50_IR_OPCODE_CASE(SAD, SAD); NV50_IR_OPCODE_CASE(TXF, TXF); NV50_IR_OPCODE_CASE(TXQ, TXQ); + NV50_IR_OPCODE_CASE(TXQS, TXQ); NV50_IR_OPCODE_CASE(TG4, TXG); NV50_IR_OPCODE_CASE(LODQ, TXLQ); @@ -909,7 +911,7 @@ bool Source::scanSource() info->bin.tlsSpace += (scan.file_max[TGSI_FILE_TEMPORARY] + 1) * 16; if (info->io.genUserClip > 0) { - info->io.clipDistanceMask = (1 << info->io.genUserClip) - 1; + info->io.clipDistances = info->io.genUserClip; const unsigned int nOut = (info->io.genUserClip + 3) / 4; @@ -918,7 +920,7 @@ bool Source::scanSource() info->out[i].id = i; info->out[i].sn = TGSI_SEMANTIC_CLIPDIST; info->out[i].si = n; - info->out[i].mask = info->io.clipDistanceMask >> (n * 4); + info->out[i].mask = ((1 << info->io.clipDistances) - 1) >> (n * 4); } } @@ -968,6 +970,12 @@ void Source::scanProperty(const struct tgsi_full_property *prop) else info->prop.tp.outputPrim = PIPE_PRIM_TRIANGLES; /* anything but points */ break; + case TGSI_PROPERTY_NUM_CLIPDIST_ENABLED: + info->io.clipDistances = prop->u[0].Data; + break; + case TGSI_PROPERTY_NUM_CULLDIST_ENABLED: + info->io.cullDistances = prop->u[0].Data; + break; default: INFO("unhandled TGSI property %d\n", prop->Property.PropertyName); break; @@ -1053,7 +1061,7 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl) default: break; } - if (decl->Interp.Location || info->io.sampleInterp) + if (decl->Interp.Location) info->in[i].centroid = 1; } @@ -1085,8 +1093,6 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl) clipVertexOutput = i; break; case TGSI_SEMANTIC_CLIPDIST: - info->io.clipDistanceMask |= - decl->Declaration.UsageMask << (si * 4); info->io.genUserClip = -1; break; case TGSI_SEMANTIC_SAMPLEMASK: @@ -1118,6 +1124,10 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl) case TGSI_SEMANTIC_VERTEXID: info->io.vertexId = first; break; + case TGSI_SEMANTIC_SAMPLEID: + case TGSI_SEMANTIC_SAMPLEPOS: + info->prop.fp.sampleInterp = 1; + break; default: break; } @@ -1324,7 +1334,7 @@ private: void setTexRS(TexInstruction *, unsigned int& s, int R, int S); void handleTEX(Value *dst0[4], int R, int S, int L, int C, int Dx, int Dy); void handleTXF(Value *dst0[4], int R, int L_M); - void handleTXQ(Value *dst0[4], enum TexQuery); + void handleTXQ(Value *dst0[4], enum TexQuery, int R); void handleLIT(Value *dst0[4]); void handleUserClipPlanes(); @@ -1337,6 +1347,8 @@ private: void handleINTERP(Value *dst0[4]); + uint8_t translateInterpMode(const struct nv50_ir_varying *var, + operation& op); Value *interpolate(tgsi::Instruction::SrcRegister, int c, Value *ptr); void insertConvergenceOps(BasicBlock *conv, BasicBlock *fork); @@ -1394,6 +1406,8 @@ private: Value *vtxBase[5]; // base address of vertex in primitive (for TP/GP) uint8_t vtxBaseValid; + Value *outBase; // base address of vertex out patch (for TCP) + Stack condBBs; // fork BB, then else clause BB Stack joinBBs; // fork BB, for inserting join ops on ENDIF Stack loopBBs; // loop headers @@ -1448,8 +1462,8 @@ Converter::makeSym(uint tgsiFile, int fileIdx, int idx, int c, uint32_t address) return sym; } -static inline uint8_t -translateInterpMode(const struct nv50_ir_varying *var, operation& op) +uint8_t +Converter::translateInterpMode(const struct nv50_ir_varying *var, operation& op) { uint8_t mode = NV50_IR_INTERP_PERSPECTIVE; @@ -1465,7 +1479,7 @@ translateInterpMode(const struct nv50_ir_varying *var, operation& op) op = (mode == NV50_IR_INTERP_PERSPECTIVE || mode == NV50_IR_INTERP_SC) ? OP_PINTERP : OP_LINTERP; - if (var->centroid) + if (var->centroid || info->prop.fp.sampleInterp) mode |= NV50_IR_INTERP_CENTROID; return mode; @@ -1537,13 +1551,7 @@ Converter::getOutputBase(int s) fetchSrc(tgsi.getSrc(s).getIndirect(1), 0, NULL), offset); vtxBaseValid |= 1 << s; - vtxBase[s] = mkOp2v( - OP_ADD, TYPE_U32, getSSA(), - mkOp2v( - OP_SUB, TYPE_U32, getSSA(), - mkOp1v(OP_RDSV, TYPE_U32, getSSA(), mkSysVal(SV_LANEID, 0)), - mkOp1v(OP_RDSV, TYPE_U32, getSSA(), mkSysVal(SV_INVOCATION_ID, 0))), - offset); + vtxBase[s] = mkOp2v(OP_ADD, TYPE_U32, getSSA(), outBase, offset); } return vtxBase[s]; } @@ -1631,7 +1639,7 @@ Converter::fetchSrc(tgsi::Instruction::SrcRegister src, int c, Value *ptr) // don't load masked inputs, won't be assigned a slot if (!ptr && !(info->in[idx].mask & (1 << swz))) return loadImm(NULL, swz == TGSI_SWIZZLE_W ? 1.0f : 0.0f); - if (!ptr && info->in[idx].sn == TGSI_SEMANTIC_FACE) + if (!ptr && info->in[idx].sn == TGSI_SEMANTIC_FACE) return mkOp1v(OP_RDSV, TYPE_F32, getSSA(), mkSysVal(SV_FACE, 0)); return interpolate(src, c, shiftAddress(ptr)); } else @@ -1799,7 +1807,7 @@ Converter::setTexRS(TexInstruction *tex, unsigned int& s, int R, int S) } void -Converter::handleTXQ(Value *dst0[4], enum TexQuery query) +Converter::handleTXQ(Value *dst0[4], enum TexQuery query, int R) { TexInstruction *tex = new_TexInstruction(func, OP_TXQ); tex->tex.query = query; @@ -1811,9 +1819,12 @@ Converter::handleTXQ(Value *dst0[4], enum TexQuery query) tex->tex.mask |= 1 << c; tex->setDef(d++, dst0[c]); } - tex->setSrc((c = 0), fetchSrc(0, 0)); // mip level + if (query == TXQ_DIMS) + tex->setSrc((c = 0), fetchSrc(0, 0)); // mip level + else + tex->setSrc((c = 0), zero); - setTexRS(tex, ++c, 1, -1); + setTexRS(tex, ++c, R, -1); bb->insertTail(tex); } @@ -2768,7 +2779,15 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn) break; case TGSI_OPCODE_TXQ: case TGSI_OPCODE_SVIEWINFO: - handleTXQ(dst0, TXQ_DIMS); + handleTXQ(dst0, TXQ_DIMS, 1); + break; + case TGSI_OPCODE_TXQS: + // The TXQ_TYPE query returns samples in its 3rd arg, but we need it to + // be in .x + dst0[1] = dst0[2] = dst0[3] = NULL; + std::swap(dst0[0], dst0[2]); + handleTXQ(dst0, TXQ_TYPE, 0); + std::swap(dst0[0], dst0[2]); break; case TGSI_OPCODE_F2I: case TGSI_OPCODE_F2U: @@ -2874,6 +2893,12 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn) bb->cfg.attach(&loopBB->cfg, Graph::Edge::BACK); } setPosition(reinterpret_cast(breakBBs.pop().u.p), true); + + // If the loop never breaks (e.g. only has RET's inside), then there + // will be no way to get to the break bb. However BGNLOOP will have + // already made a PREBREAK to it, so it must be in the CFG. + if (getBB()->cfg.incidentCount() == 0) + loopBB->cfg.attach(&getBB()->cfg, Graph::Edge::TREE); } break; case TGSI_OPCODE_BRK: @@ -2994,9 +3019,15 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn) case TGSI_OPCODE_UBFE: FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) { src0 = fetchSrc(0, c); - src1 = fetchSrc(1, c); - src2 = fetchSrc(2, c); - mkOp3(OP_INSBF, TYPE_U32, src1, src2, mkImm(0x808), src1); + if (tgsi.getSrc(1).getFile() == TGSI_FILE_IMMEDIATE && + tgsi.getSrc(2).getFile() == TGSI_FILE_IMMEDIATE) { + src1 = loadImm(NULL, tgsi.getSrc(2).getValueU32(c, info) << 8 | + tgsi.getSrc(1).getValueU32(c, info)); + } else { + src1 = fetchSrc(1, c); + src2 = fetchSrc(2, c); + mkOp3(OP_INSBF, TYPE_U32, src1, src2, mkImm(0x808), src1); + } mkOp2(OP_EXTBF, dstTy, dst0[c], src0, src1); } break; @@ -3369,10 +3400,21 @@ Converter::run() clipVtx[c] = getScratch(); } - if (prog->getType() == Program::TYPE_FRAGMENT) { + switch (prog->getType()) { + case Program::TYPE_TESSELLATION_CONTROL: + outBase = mkOp2v( + OP_SUB, TYPE_U32, getSSA(), + mkOp1v(OP_RDSV, TYPE_U32, getSSA(), mkSysVal(SV_LANEID, 0)), + mkOp1v(OP_RDSV, TYPE_U32, getSSA(), mkSysVal(SV_INVOCATION_ID, 0))); + break; + case Program::TYPE_FRAGMENT: { Symbol *sv = mkSysVal(SV_POSITION, 3); fragCoord[3] = mkOp1v(OP_RDSV, TYPE_F32, getSSA(), sv); mkOp1(OP_RCP, TYPE_F32, fragCoord[3], fragCoord[3]); + break; + } + default: + break; } if (info->io.viewportId >= 0)