This is loosely based on the previous lowering pass wrote by calim four years ago. I did clean the code and fixed some issues.
Signed-off-by: Samuel Pitoiset <samuel.pitoi...@gmail.com> --- .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 155 ++++++++++++++++++++- 1 file changed, 152 insertions(+), 3 deletions(-) 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 44b39db..ba14979 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp @@ -1445,7 +1445,7 @@ private: void handleUserClipPlanes(); // Symbol *getResourceBase(int r); - // void getResourceCoords(std::vector<Value *>&, int r, int s); + void getImageCoords(std::vector<Value *>&, int r, int s); void handleLOAD(Value *dst0[4]); void handleSTORE(); @@ -2247,7 +2247,7 @@ Converter::getResourceCoords(std::vector<Value *> &coords, int r, int s) coords[0] = mkOp1v(OP_MOV, TYPE_U32, getScratch(4, FILE_ADDRESS), coords[0]); } - +*/ static inline int partitionLoadStore(uint8_t comp[2], uint8_t size[2], uint8_t mask) { @@ -2272,7 +2272,30 @@ partitionLoadStore(uint8_t comp[2], uint8_t size[2], uint8_t mask) } return n + 1; } -*/ + +static inline nv50_ir::TexTarget +getImageTarget(const tgsi::Source *code, int r) +{ + return tgsi::translateTexture(code->images.at(r).target); +} + +static inline const nv50_ir::TexInstruction::ImgFormatDesc * +getImageFormat(const tgsi::Source *code, int r) +{ + return &nv50_ir::TexInstruction::formatTable[ + tgsi::translateImgFormat(code->images.at(r).format)]; +} + +void +Converter::getImageCoords(std::vector<Value *> &coords, int r, int s) +{ + TexInstruction::Target t = + TexInstruction::Target(getImageTarget(code, r)); + const int arg = t.getDim() + (t.isArray() || t.isCube()); + + for (int c = 0; c < arg; ++c) + coords.push_back(fetchSrc(s, c)); +} // For raw loads, granularity is 4 byte. // Usage of the texture read mask on OP_SULDP is not allowed. @@ -2306,6 +2329,66 @@ Converter::handleLOAD(Value *dst0[4]) ld->setIndirect(0, 1, fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, 0)); } break; + case TGSI_FILE_IMAGE: + getImageCoords(off, r, 1); + + if (code->images[r].raw) { + uint8_t mask = 0; + uint8_t comp[2] = { 0, 0 }; + uint8_t size[2] = { 0, 0 }; + + // determine the base and size of the at most 2 load ops + for (c = 0; c < 4; ++c) + if (!tgsi.getDst(0).isMasked(c)) + mask |= 1 << (tgsi.getSrc(0).getSwizzle(c) - TGSI_SWIZZLE_X); + + int n = partitionLoadStore(comp, size, mask); + + src = off; + + def.resize(4); // index by component, the ones we need will be non-NULL + for (c = 0; c < 4; ++c) { + if (dst0[c] && tgsi.getSrc(0).getSwizzle(c) == (TGSI_SWIZZLE_X + c)) + def[c] = dst0[c]; + else + if (mask & (1 << c)) + def[c] = getScratch(); + } + + for (int i = 0; i < n; ++i) { + ldv.assign(def.begin() + comp[i], def.begin() + comp[i] + size[i]); + + if (comp[i]) // adjust x component of source address if necessary + src[0] = mkOp2v(OP_ADD, TYPE_U32, getSSA(4, off[0]->reg.file), + off[0], mkImm(comp[i] * 4)); + else + src[0] = off[0]; + + mkTex(OP_SULDB, getImageTarget(code, r), code->images[r].slot, + 0, ldv, src)->dType = typeOfSize(size[i] * 4); + } + } else { + def.resize(4); + for (c = 0; c < 4; ++c) { + if (!dst0[c] || tgsi.getSrc(0).getSwizzle(c) != (TGSI_SWIZZLE_X + c)) + def[c] = getScratch(); + else + def[c] = dst0[c]; + } + + TexInstruction *ld = + mkTex(OP_SULDP, getImageTarget(code, r), code->images[r].slot, 0, + def, off); + ld->tex.mask = tgsi.getDst(0).getMask(); + ld->tex.format = getImageFormat(code, r); + ld->cache = tgsi.getCacheMode(); + if (tgsi.getSrc(0).isIndirect(0)) + ld->setIndirectR(fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, NULL)); + } + FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) + if (dst0[c] != def[c]) + mkMov(dst0[c], def[tgsi.getSrc(0).getSwizzle(c)]); + break; default: assert(!"Unsupported srcFile for LOAD"); } @@ -2412,6 +2495,48 @@ Converter::handleSTORE() st->setIndirect(0, 1, fetchSrc(tgsi.getDst(0).getIndirect(0), 0, 0)); } break; + case TGSI_FILE_IMAGE: { + getImageCoords(off, r, 0); + src = off; + const int s = src.size(); + + if (code->images[r].raw) { + uint8_t comp[2] = { 0, 0 }; + uint8_t size[2] = { 0, 0 }; + + int n = partitionLoadStore(comp, size, tgsi.getDst(0).getMask()); + + for (int i = 0; i < n; ++i) { + if (comp[i]) // adjust x component of source address if necessary + src[0] = mkOp2v(OP_ADD, TYPE_U32, getSSA(4, off[0]->reg.file), + off[0], mkImm(comp[i] * 4)); + else + src[0] = off[0]; + + const DataType stTy = typeOfSize(size[i] * 4); + + // attach values to be stored + src.resize(s + size[i]); + for (c = 0; c < size[i]; ++c) + src[s + c] = fetchSrc(1, comp[i] + c); + mkTex(OP_SUSTB, getImageTarget(code, r), code->images[r].slot, + 0, dummy, src)->setType(stTy); + } + } else { + FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) + src.push_back(fetchSrc(1, c)); + + TexInstruction *st = + mkTex(OP_SUSTP, getImageTarget(code, r), code->images[r].slot, + 0, dummy, src); + st->tex.mask = tgsi.getDst(0).getMask(); + st->cache = tgsi.getCacheMode(); + if (tgsi.getSrc(0).isIndirect(0)) + st->setIndirectR(fetchSrc(tgsi.getSrc(0).getIndirect(0), + 0, NULL)); + } + } + break; default: assert(!"Unsupported dstFile for STORE"); } @@ -2510,6 +2635,30 @@ Converter::handleATOM(Value *dst0[4], DataType ty, uint16_t subOp) if (dst0[c]) dst0[c] = dst; // not equal to rDst so handleInstruction will do mkMov break; + case TGSI_FILE_IMAGE: { + operation op = code->images[r].raw ? OP_SUREDB : OP_SUREDP; + + getImageCoords(srcv, r, 1); + + defv.push_back(dst); + srcv.push_back(fetchSrc(2, 0)); + if (subOp == NV50_IR_SUBOP_ATOM_CAS) + srcv.push_back(fetchSrc(3, 0)); + + TexInstruction *tex = mkTex(op, getImageTarget(code, r), + code->images[r].slot, 0, defv, srcv); + tex->subOp = subOp; + tex->tex.mask = 1; + tex->setType(ty); + if (tgsi.getSrc(0).isIndirect(0)) + tex->setIndirectR(fetchSrc(tgsi.getSrc(0).getIndirect(0), + 0, NULL)); + + for (int c = 0; c < 4; ++c) + if (dst0[c]) + dst0[c] = dst; // not equal to rDst so handleInstruction will do mkMov + } + break; default: assert(!"Unsupported srcFile for ATOM"); } -- 2.8.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev