[Mesa-dev] [RFC 15/24] nv50/ir: make use of OP_SUQ for surfaces query
This implements RESQ for surfaces which comes from imageSize() GLSL bultin. As the dimensions are sticked into the driver constant buffer, this only has to be lowered with loads. Signed-off-by: Samuel Pitoiset --- .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 28 +++--- .../drivers/nouveau/codegen/nv50_ir_inlines.h | 6 ++-- .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 33 -- .../nouveau/codegen/nv50_ir_lowering_nvc0.h| 2 +- 4 files changed, 58 insertions(+), 11 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 e56b992..ce76874 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp @@ -3435,10 +3435,30 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn) handleATOM(dst0, dstTy, tgsi::opcodeToSubOp(tgsi.getOpcode())); break; case TGSI_OPCODE_RESQ: - geni = mkOp1(OP_BUFQ, TYPE_U32, dst0[0], - makeSym(TGSI_FILE_BUFFER, tgsi.getSrc(0).getIndex(0), -1, 0, 0)); - if (tgsi.getSrc(0).isIndirect(0)) - geni->setIndirect(0, 1, fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, 0)); + if (tgsi.getSrc(0).getFile() == TGSI_FILE_BUFFER) { + geni = mkOp1(OP_BUFQ, TYPE_U32, dst0[0], + makeSym(tgsi.getSrc(0).getFile(), + tgsi.getSrc(0).getIndex(0), -1, 0, 0)); + if (tgsi.getSrc(0).isIndirect(0)) +geni->setIndirect(0, 1, + fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, 0)); + } else { + assert(tgsi.getSrc(0).getFile() == TGSI_FILE_IMAGE); + + TexInstruction *texi = new_TexInstruction(func, OP_SUQ); + for (int c = 0, d = 0; c < 4; ++c) { +if (dst0[c]) { + texi->setDef(d++, dst0[c]); + texi->tex.mask |= 1 << c; +} + } + texi->tex.r = tgsi.getSrc(0).getIndex(0); + texi->tex.target = getImageTarget(code, texi->tex.r); + bb->insertTail(texi); + + if (tgsi.getSrc(0).isIndirect(0)) +texi->setIndirectR(fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, NULL)); + } break; case TGSI_OPCODE_IBFE: case TGSI_OPCODE_UBFE: diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h index e465f24..4c5de2e 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h @@ -48,7 +48,7 @@ static inline bool isTextureOp(operation op) static inline bool isSurfaceOp(operation op) { - return (op >= OP_SULDB && op <= OP_SULEA); + return (op >= OP_SULDB && op <= OP_SULEA) || (op == OP_SUQ); } static inline unsigned int typeSizeof(DataType ty) @@ -309,14 +309,14 @@ const FlowInstruction *Instruction::asFlow() const TexInstruction *Instruction::asTex() { - if (op >= OP_TEX && op <= OP_SULEA) + if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ) return static_cast(this); return NULL; } const TexInstruction *Instruction::asTex() const { - if (op >= OP_TEX && op <= OP_SULEA) + if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ) return static_cast(this); return NULL; } diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp index 60a3b4c..5920da6 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp @@ -1509,9 +1509,36 @@ static inline uint16_t getSuClampSubOp(const TexInstruction *su, int c) } bool -NVC0LoweringPass::handleSUQ(Instruction *suq) +NVC0LoweringPass::handleSUQ(TexInstruction *suq) { - /* TODO: will be updated in the next commit. */ + int dim = suq->tex.target.getDim(); + int arg = dim + (suq->tex.target.isArray() || suq->tex.target.isCube()); + uint8_t s = prog->driver->io.auxCBSlot; + Value *ind = suq->getIndirectR(); + uint32_t base; + int c; + + base = prog->driver->io.suInfoBase + suq->tex.r * NVE4_SU_INFO__STRIDE; + + if (ind) + ind = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getScratch(), + ind, bld.mkImm(6)); + + for (c = 0; c < arg; ++c) { + if (suq->defExists(c)) { + int offset; + + if (c == 1 && suq->tex.target == TEX_TARGET_1D_ARRAY) { +offset = base + NVE4_SU_INFO_SIZE(2); + } else { +offset = base + NVE4_SU_INFO_SIZE(c); + } + bld.mkLoad(TYPE_U32, suq->getDef(c), +bld.mkSymbol(FILE_MEMORY_CONST, s, TYPE_U32, offset), ind); + } + } + + bld.remove(suq); return true; } @@ -2263,7 +2290,7 @@ NVC0LoweringPass::visit(Instruction *i) handleSurfaceOpNVE4(i->asTex());
Re: [Mesa-dev] [RFC 15/24] nv50/ir: make use of OP_SUQ for surfaces query
On Tue, Apr 12, 2016 at 7:57 PM, Samuel Pitoiset wrote: > This implements RESQ for surfaces which comes from imageSize() GLSL > bultin. As the dimensions are sticked into the driver constant buffer, > this only has to be lowered with loads. > > Signed-off-by: Samuel Pitoiset > --- > .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 28 +++--- > .../drivers/nouveau/codegen/nv50_ir_inlines.h | 6 ++-- > .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 33 > -- > .../nouveau/codegen/nv50_ir_lowering_nvc0.h| 2 +- > 4 files changed, 58 insertions(+), 11 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 e56b992..ce76874 100644 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp > @@ -3435,10 +3435,30 @@ Converter::handleInstruction(const struct > tgsi_full_instruction *insn) >handleATOM(dst0, dstTy, tgsi::opcodeToSubOp(tgsi.getOpcode())); >break; > case TGSI_OPCODE_RESQ: > - geni = mkOp1(OP_BUFQ, TYPE_U32, dst0[0], > - makeSym(TGSI_FILE_BUFFER, tgsi.getSrc(0).getIndex(0), -1, > 0, 0)); > - if (tgsi.getSrc(0).isIndirect(0)) > - geni->setIndirect(0, 1, fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, > 0)); > + if (tgsi.getSrc(0).getFile() == TGSI_FILE_BUFFER) { > + geni = mkOp1(OP_BUFQ, TYPE_U32, dst0[0], > + makeSym(tgsi.getSrc(0).getFile(), > + tgsi.getSrc(0).getIndex(0), -1, 0, 0)); > + if (tgsi.getSrc(0).isIndirect(0)) > +geni->setIndirect(0, 1, > + fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, 0)); > + } else { > + assert(tgsi.getSrc(0).getFile() == TGSI_FILE_IMAGE); > + > + TexInstruction *texi = new_TexInstruction(func, OP_SUQ); > + for (int c = 0, d = 0; c < 4; ++c) { > +if (dst0[c]) { > + texi->setDef(d++, dst0[c]); > + texi->tex.mask |= 1 << c; > +} > + } > + texi->tex.r = tgsi.getSrc(0).getIndex(0); > + texi->tex.target = getImageTarget(code, texi->tex.r); > + bb->insertTail(texi); > + > + if (tgsi.getSrc(0).isIndirect(0)) > +texi->setIndirectR(fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, > NULL)); > + } >break; > case TGSI_OPCODE_IBFE: > case TGSI_OPCODE_UBFE: > diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h > b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h > index e465f24..4c5de2e 100644 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h > @@ -48,7 +48,7 @@ static inline bool isTextureOp(operation op) > > static inline bool isSurfaceOp(operation op) > { > - return (op >= OP_SULDB && op <= OP_SULEA); > + return (op >= OP_SULDB && op <= OP_SULEA) || (op == OP_SUQ); > } > > static inline unsigned int typeSizeof(DataType ty) > @@ -309,14 +309,14 @@ const FlowInstruction *Instruction::asFlow() const > > TexInstruction *Instruction::asTex() > { > - if (op >= OP_TEX && op <= OP_SULEA) > + if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ) >return static_cast(this); > return NULL; > } > > const TexInstruction *Instruction::asTex() const > { > - if (op >= OP_TEX && op <= OP_SULEA) > + if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ) >return static_cast(this); > return NULL; > } > diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp > b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp > index 60a3b4c..5920da6 100644 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp > @@ -1509,9 +1509,36 @@ static inline uint16_t getSuClampSubOp(const > TexInstruction *su, int c) > } > > bool > -NVC0LoweringPass::handleSUQ(Instruction *suq) > +NVC0LoweringPass::handleSUQ(TexInstruction *suq) > { > - /* TODO: will be updated in the next commit. */ > + int dim = suq->tex.target.getDim(); > + int arg = dim + (suq->tex.target.isArray() || suq->tex.target.isCube()); > + uint8_t s = prog->driver->io.auxCBSlot; > + Value *ind = suq->getIndirectR(); > + uint32_t base; > + int c; > + > + base = prog->driver->io.suInfoBase + suq->tex.r * NVE4_SU_INFO__STRIDE; > + > + if (ind) > + ind = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getScratch(), > + ind, bld.mkImm(6)); > + > + for (c = 0; c < arg; ++c) { > + if (suq->defExists(c)) { > + int offset; > + > + if (c == 1 && suq->tex.target == TEX_TARGET_1D_ARRAY) { > +offset = base + NVE4_SU_INFO_SIZE(2); > + } else { > +offset = base + NVE4_SU_INFO_SIZE(c); > + } >
Re: [Mesa-dev] [RFC 15/24] nv50/ir: make use of OP_SUQ for surfaces query
On 04/13/2016 10:33 PM, Ilia Mirkin wrote: On Tue, Apr 12, 2016 at 7:57 PM, Samuel Pitoiset wrote: This implements RESQ for surfaces which comes from imageSize() GLSL bultin. As the dimensions are sticked into the driver constant buffer, this only has to be lowered with loads. Signed-off-by: Samuel Pitoiset --- .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 28 +++--- .../drivers/nouveau/codegen/nv50_ir_inlines.h | 6 ++-- .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 33 -- .../nouveau/codegen/nv50_ir_lowering_nvc0.h| 2 +- 4 files changed, 58 insertions(+), 11 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 e56b992..ce76874 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp @@ -3435,10 +3435,30 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn) handleATOM(dst0, dstTy, tgsi::opcodeToSubOp(tgsi.getOpcode())); break; case TGSI_OPCODE_RESQ: - geni = mkOp1(OP_BUFQ, TYPE_U32, dst0[0], - makeSym(TGSI_FILE_BUFFER, tgsi.getSrc(0).getIndex(0), -1, 0, 0)); - if (tgsi.getSrc(0).isIndirect(0)) - geni->setIndirect(0, 1, fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, 0)); + if (tgsi.getSrc(0).getFile() == TGSI_FILE_BUFFER) { + geni = mkOp1(OP_BUFQ, TYPE_U32, dst0[0], + makeSym(tgsi.getSrc(0).getFile(), + tgsi.getSrc(0).getIndex(0), -1, 0, 0)); + if (tgsi.getSrc(0).isIndirect(0)) +geni->setIndirect(0, 1, + fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, 0)); + } else { + assert(tgsi.getSrc(0).getFile() == TGSI_FILE_IMAGE); + + TexInstruction *texi = new_TexInstruction(func, OP_SUQ); + for (int c = 0, d = 0; c < 4; ++c) { +if (dst0[c]) { + texi->setDef(d++, dst0[c]); + texi->tex.mask |= 1 << c; +} + } + texi->tex.r = tgsi.getSrc(0).getIndex(0); + texi->tex.target = getImageTarget(code, texi->tex.r); + bb->insertTail(texi); + + if (tgsi.getSrc(0).isIndirect(0)) +texi->setIndirectR(fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, NULL)); + } break; case TGSI_OPCODE_IBFE: case TGSI_OPCODE_UBFE: diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h index e465f24..4c5de2e 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h @@ -48,7 +48,7 @@ static inline bool isTextureOp(operation op) static inline bool isSurfaceOp(operation op) { - return (op >= OP_SULDB && op <= OP_SULEA); + return (op >= OP_SULDB && op <= OP_SULEA) || (op == OP_SUQ); } static inline unsigned int typeSizeof(DataType ty) @@ -309,14 +309,14 @@ const FlowInstruction *Instruction::asFlow() const TexInstruction *Instruction::asTex() { - if (op >= OP_TEX && op <= OP_SULEA) + if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ) return static_cast(this); return NULL; } const TexInstruction *Instruction::asTex() const { - if (op >= OP_TEX && op <= OP_SULEA) + if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ) return static_cast(this); return NULL; } diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp index 60a3b4c..5920da6 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp @@ -1509,9 +1509,36 @@ static inline uint16_t getSuClampSubOp(const TexInstruction *su, int c) } bool -NVC0LoweringPass::handleSUQ(Instruction *suq) +NVC0LoweringPass::handleSUQ(TexInstruction *suq) { - /* TODO: will be updated in the next commit. */ + int dim = suq->tex.target.getDim(); + int arg = dim + (suq->tex.target.isArray() || suq->tex.target.isCube()); + uint8_t s = prog->driver->io.auxCBSlot; + Value *ind = suq->getIndirectR(); + uint32_t base; + int c; + + base = prog->driver->io.suInfoBase + suq->tex.r * NVE4_SU_INFO__STRIDE; + + if (ind) + ind = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getScratch(), + ind, bld.mkImm(6)); + + for (c = 0; c < arg; ++c) { + if (suq->defExists(c)) { + int offset; + + if (c == 1 && suq->tex.target == TEX_TARGET_1D_ARRAY) { +offset = base + NVE4_SU_INFO_SIZE(2); + } else { +offset = base + NVE4_SU_INFO_SIZE(c); + } + bld.mkLoad(TYPE_U32, suq->getDef(c), +bld.mkSymbol(FILE_MEMORY_CONST, s, TYPE_U32, offset), ind); + } + } Make sure to load a 1 i