Re: [Mesa-dev] [RFC 15/24] nv50/ir: make use of OP_SUQ for surfaces query

2016-04-14 Thread Samuel Pitoiset



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, 

Re: [Mesa-dev] [RFC 15/24] nv50/ir: make use of OP_SUQ for surfaces query

2016-04-13 Thread Ilia Mirkin
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 {
> +

[Mesa-dev] [RFC 15/24] nv50/ir: make use of OP_SUQ for surfaces query

2016-04-12 Thread Samuel Pitoiset
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)