GBE: fixed the hacky code of 3D image read/write.
authorZhigang Gong <zhigang.gong@intel.com>
Fri, 17 Jan 2014 05:05:20 +0000 (13:05 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Fri, 17 Jan 2014 06:27:59 +0000 (14:27 +0800)
The previous implementation use a magic virtual register(0) to
indiate this is a 2D read/write. This is too hacky and may hide
bugs in the future. Now fix it without create any dumy virtual
register.

Also clean up some useless enums.

Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>
Reviewed-by: "Yang, Rong R" <rong.r.yang@intel.com>
backend/src/backend/gen_context.cpp
backend/src/backend/gen_insn_selection.cpp
backend/src/backend/gen_insn_selection.hpp
backend/src/ir/instruction.cpp
backend/src/ir/instruction.hpp
backend/src/llvm/llvm_gen_backend.cpp

index 6a9461b..ecb8ef3 100644 (file)
@@ -1750,11 +1750,10 @@ namespace gbe
   void GenContext::emitSampleInstruction(const SelectionInstruction &insn) {
     const GenRegister dst = ra->genReg(insn.dst(0));
     const GenRegister msgPayload = GenRegister::retype(ra->genReg(insn.src(0)), GEN_TYPE_F);
-    const unsigned char bti = insn.extra.function;
-    const unsigned char sampler = insn.extra.elem;
+    const unsigned char bti = insn.extra.rdbti;
+    const unsigned char sampler = insn.extra.sampler;
     const GenRegister ucoord = ra->genReg(insn.src(4));
     const GenRegister vcoord = ra->genReg(insn.src(5));
-    const GenRegister wcoord = ra->genReg(insn.src(6));
     uint32_t simdWidth = p->curr.execWidth;
     uint32_t coord_cnt = 2;
     p->push();
@@ -1764,8 +1763,8 @@ namespace gbe
     /* Prepare message payload. */
     p->MOV(GenRegister::f8grf(nr , 0), ucoord);
     p->MOV(GenRegister::f8grf(nr + (simdWidth/8), 0), vcoord);
-    if (insn.src(6).reg() != 0) {
-      p->MOV(GenRegister::f8grf(nr + (simdWidth/4), 0), wcoord);
+    if (insn.extra.is3DRead) {
+      p->MOV(GenRegister::f8grf(nr + (simdWidth/4), 0), ra->genReg(insn.src(6)));
       coord_cnt++;
     }
     p->SAMPLE(dst, msgPayload, false, bti, sampler, coord_cnt, simdWidth, -1, 0);
@@ -1805,14 +1804,13 @@ namespace gbe
 
   void GenContext::emitTypedWriteInstruction(const SelectionInstruction &insn) {
     const GenRegister header = GenRegister::retype(ra->genReg(insn.src(0)), GEN_TYPE_UD);
-    const GenRegister ucoord = ra->genReg(insn.src(insn.extra.elem));
-    const GenRegister vcoord = ra->genReg(insn.src(1 + insn.extra.elem));
-    const GenRegister wcoord = ra->genReg(insn.src(2 + insn.extra.elem));
-    const GenRegister R = ra->genReg(insn.src(3 + insn.extra.elem));
-    const GenRegister G = ra->genReg(insn.src(4 + insn.extra.elem));
-    const GenRegister B = ra->genReg(insn.src(5 + insn.extra.elem));
-    const GenRegister A = ra->genReg(insn.src(6 + insn.extra.elem));
-    const unsigned char bti = insn.extra.function;
+    const GenRegister ucoord = ra->genReg(insn.src(insn.extra.msglen));
+    const GenRegister vcoord = ra->genReg(insn.src(1 + insn.extra.msglen));
+    const GenRegister R = ra->genReg(insn.src(3 + insn.extra.msglen));
+    const GenRegister G = ra->genReg(insn.src(4 + insn.extra.msglen));
+    const GenRegister B = ra->genReg(insn.src(5 + insn.extra.msglen));
+    const GenRegister A = ra->genReg(insn.src(6 + insn.extra.msglen));
+    const unsigned char bti = insn.extra.bti;
 
     p->push();
     uint32_t simdWidth = p->curr.execWidth;
@@ -1850,8 +1848,8 @@ namespace gbe
         p->curr.quarterControl = GEN_COMPRESSION_Q2;
       QUARTER_MOV0(nr + 1, ucoord);
       QUARTER_MOV0(nr + 2, vcoord);
-      if (insn.src(2 + insn.extra.elem).reg() != 0)
-        QUARTER_MOV0(nr + 3, wcoord);
+      if (insn.extra.is3DWrite)
+        QUARTER_MOV0(nr + 3, ra->genReg(insn.src(2 + insn.extra.msglen)));
       QUARTER_MOV1(nr + 5, R);
       QUARTER_MOV1(nr + 6, G);
       QUARTER_MOV1(nr + 7, B);
index f34da74..3d2ebcc 100644 (file)
@@ -543,9 +543,9 @@ namespace gbe
     /*! Encode ternary instructions */
     void ALU3(SelectionOpcode opcode, Reg dst, Reg src0, Reg src1, Reg src2);
     /*! Encode sample instructions */
-    void SAMPLE(GenRegister *dst, uint32_t dstNum, GenRegister *src, uint32_t srcNum, GenRegister *msgPayloads, uint32_t msgNum, uint32_t bti, uint32_t sampler);
+    void SAMPLE(GenRegister *dst, uint32_t dstNum, GenRegister *src, uint32_t srcNum, GenRegister *msgPayloads, uint32_t msgNum, uint32_t bti, uint32_t sampler, bool is3D);
     /*! Encode typed write instructions */
-    void TYPED_WRITE(GenRegister *src, uint32_t srcNum, GenRegister *msgs, uint32_t msgNum, uint32_t bti);
+    void TYPED_WRITE(GenRegister *src, uint32_t srcNum, GenRegister *msgs, uint32_t msgNum, uint32_t bti, bool is3D);
     /*! Get image information */
     void GET_IMAGE_INFO(uint32_t type, GenRegister *dst, uint32_t dst_num, uint32_t bti);
     /*! Multiply 64-bit integers */
@@ -1333,7 +1333,7 @@ namespace gbe
   void Selection::Opaque::SAMPLE(GenRegister *dst, uint32_t dstNum,
                                  GenRegister *src, uint32_t srcNum,
                                  GenRegister *msgPayloads, uint32_t msgNum,
-                                 uint32_t bti, uint32_t sampler) {
+                                 uint32_t bti, uint32_t sampler, bool is3D) {
     SelectionInstruction *insn = this->appendInsn(SEL_OP_SAMPLE, dstNum, msgNum + srcNum);
     SelectionVector *dstVector = this->appendVector();
     SelectionVector *msgVector = this->appendVector();
@@ -1356,8 +1356,9 @@ namespace gbe
     msgVector->isSrc = 1;
     msgVector->reg = &insn->src(0);
 
-    insn->extra.function = bti;
-    insn->extra.elem = sampler;
+    insn->extra.rdbti = bti;
+    insn->extra.sampler = sampler;
+    insn->extra.is3DRead = is3D;
   }
 
   ///////////////////////////////////////////////////////////////////////////
@@ -1371,7 +1372,7 @@ namespace gbe
 
   void Selection::Opaque::TYPED_WRITE(GenRegister *src, uint32_t srcNum,
                                       GenRegister *msgs, uint32_t msgNum,
-                                      uint32_t bti) {
+                                      uint32_t bti, bool is3D) {
     uint32_t elemID = 0;
     uint32_t i;
     SelectionInstruction *insn = this->appendInsn(SEL_OP_TYPED_WRITE, 0, msgNum + srcNum);
@@ -1382,8 +1383,9 @@ namespace gbe
     for (i = 0; i < srcNum; ++i, ++elemID)
       insn->src(elemID) = src[i];
 
-    insn->extra.function = bti;
-    insn->extra.elem = msgNum;
+    insn->extra.bti = bti;
+    insn->extra.msglen = msgNum;
+    insn->extra.is3DWrite = is3D;
     // Sends require contiguous allocation
     msgVector->regNum = msgNum;
     msgVector->isSrc = 1;
@@ -2938,7 +2940,7 @@ namespace gbe
       /* We have the clamp border workaround. */
       uint32_t sampler = insn.getSamplerIndex() + insn.getSamplerOffset() * 8;
 
-      sel.SAMPLE(dst, insn.getDstNum(), src, srcNum, msgPayloads, 4, bti, sampler);
+      sel.SAMPLE(dst, insn.getDstNum(), src, srcNum, msgPayloads, 4, bti, sampler, insn.is3D());
       return true;
     }
     DECL_CTOR(SampleInstruction, 1, 1);
@@ -2955,7 +2957,7 @@ namespace gbe
       GenRegister msgs[9]; // (header + U + V + R + LOD + 4)
       GenRegister src[insn.getSrcNum()];
       uint32_t msgNum = (8 / (simdWidth / 8)) + 1;
-      uint32_t coordNum = (insn.getSrcNum() == 6) ? 2 : 3;
+      uint32_t coordNum = 3;
 
       for(uint32_t i = 0; i < msgNum; i++)
         msgs[i] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
@@ -2968,7 +2970,7 @@ namespace gbe
         src[valueID] = sel.selReg(insn.getSrc(valueID), insn.getSrcType());
 
       uint32_t bti = insn.getImageIndex();
-      sel.TYPED_WRITE(src, insn.getSrcNum(), msgs, msgNum, bti);
+      sel.TYPED_WRITE(src, insn.getSrcNum(), msgs, msgNum, bti, insn.is3D());
       return true;
     }
     DECL_CTOR(TypedWriteInstruction, 1, 1);
index 7566928..d1f1950 100644 (file)
@@ -111,6 +111,16 @@ namespace gbe
         uint16_t scratchOffset;
         uint16_t scratchMsgHeader;
       };
+      struct {
+        uint16_t bti:8;
+        uint16_t msglen:5;
+        uint16_t is3DWrite:1;
+      };
+      struct {
+        uint16_t rdbti:8;
+        uint16_t sampler:5;
+        uint16_t is3DRead:1;
+      };
       uint32_t barrierType;
     } extra;
     /*! Gen opcode */
index 3eb28ea..5e3cd84 100644 (file)
@@ -491,7 +491,7 @@ namespace ir {
       public TupleDstPolicy<SampleInstruction>
     {
     public:
-      SampleInstruction(uint8_t imageIdx, Tuple dstTuple, Tuple srcTuple, bool dstIsFloat, bool srcIsFloat, uint8_t sampler, uint8_t samplerOffset) {
+      SampleInstruction(uint8_t imageIdx, Tuple dstTuple, Tuple srcTuple, bool dstIsFloat, bool srcIsFloat, uint8_t sampler, uint8_t samplerOffset, bool is3D) {
         this->opcode = OP_SAMPLE;
         this->dst = dstTuple;
         this->src = srcTuple;
@@ -500,6 +500,7 @@ namespace ir {
         this->samplerIdx = sampler;
         this->imageIdx = imageIdx;
         this->samplerOffset = samplerOffset;
+        this->is3DRead = is3D;
       }
       INLINE bool wellFormed(const Function &fn, std::string &why) const;
       INLINE void out(std::ostream &out, const Function &fn) const {
@@ -524,10 +525,12 @@ namespace ir {
       INLINE Type getDstType(void) const { return this->dstIsFloat ? TYPE_FLOAT : TYPE_U32; }
       INLINE const uint8_t getSamplerIndex(void) const { return this->samplerIdx; }
       INLINE const uint8_t getSamplerOffset(void) const { return this->samplerOffset; }
+      INLINE const bool is3D(void) const { return !!this->is3DRead; }
       uint8_t srcIsFloat:1;
       uint8_t dstIsFloat:1;
       uint8_t samplerIdx:4;
-      uint8_t samplerOffset:2;
+      uint8_t samplerOffset:1;
+      uint8_t is3DRead:1;
       uint8_t imageIdx;
       static const uint32_t srcNum = 4;
       static const uint32_t dstNum = 4;
@@ -540,12 +543,13 @@ namespace ir {
     {
     public:
 
-      INLINE TypedWriteInstruction(uint8_t imageIdx, Tuple srcTuple, Type srcType, Type coordType) {
+      INLINE TypedWriteInstruction(uint8_t imageIdx, Tuple srcTuple, Type srcType, Type coordType, bool is3D) {
         this->opcode = OP_TYPED_WRITE;
         this->src = srcTuple;
         this->coordType = coordType;
         this->srcType = srcType;
         this->imageIdx = imageIdx;
+        this->is3DWrite = is3D;
       }
       INLINE bool wellFormed(const Function &fn, std::string &why) const;
       INLINE void out(std::ostream &out, const Function &fn) const {
@@ -565,6 +569,9 @@ namespace ir {
       uint8_t srcType;
       uint8_t coordType;
       uint8_t imageIdx;
+      uint8_t is3DWrite;
+
+      INLINE const bool is3D(void) const { return !!this->is3DWrite; }
 
       INLINE const uint8_t getImageIndex(void) const { return this->imageIdx; }
       INLINE Type getSrcType(void) const { return (Type)this->srcType; }
@@ -1475,11 +1482,13 @@ DECL_MEM_FN(SyncInstruction, uint32_t, getParameters(void), getParameters())
 DECL_MEM_FN(SampleInstruction, Type, getSrcType(void), getSrcType())
 DECL_MEM_FN(SampleInstruction, Type, getDstType(void), getDstType())
 DECL_MEM_FN(SampleInstruction, const uint8_t, getSamplerIndex(void), getSamplerIndex())
+DECL_MEM_FN(SampleInstruction, const bool, is3D(void), is3D())
 DECL_MEM_FN(SampleInstruction, const uint8_t, getSamplerOffset(void), getSamplerOffset())
 DECL_MEM_FN(SampleInstruction, const uint8_t, getImageIndex(void), getImageIndex())
 DECL_MEM_FN(TypedWriteInstruction, Type, getSrcType(void), getSrcType())
 DECL_MEM_FN(TypedWriteInstruction, Type, getCoordType(void), getCoordType())
 DECL_MEM_FN(TypedWriteInstruction, const uint8_t, getImageIndex(void), getImageIndex())
+DECL_MEM_FN(TypedWriteInstruction, const bool, is3D(void), is3D())
 DECL_MEM_FN(GetImageInfoInstruction, uint32_t, getInfoType(void), getInfoType())
 DECL_MEM_FN(GetImageInfoInstruction, const uint8_t, getImageIndex(void), getImageIndex())
 DECL_MEM_FN(GetSamplerInfoInstruction, const uint8_t, getSamplerIndex(void), getSamplerIndex())
@@ -1660,12 +1669,12 @@ DECL_MEM_FN(GetSamplerInfoInstruction, const uint8_t, getSamplerIndex(void), get
   }
 
   // SAMPLE
-  Instruction SAMPLE(uint8_t imageIndex, Tuple dst, Tuple src, bool dstIsFloat, bool srcIsFloat, uint8_t sampler, uint8_t samplerOffset) {
-    return internal::SampleInstruction(imageIndex, dst, src, dstIsFloat, srcIsFloat, sampler, samplerOffset).convert();
+  Instruction SAMPLE(uint8_t imageIndex, Tuple dst, Tuple src, bool dstIsFloat, bool srcIsFloat, uint8_t sampler, uint8_t samplerOffset, bool is3D) {
+    return internal::SampleInstruction(imageIndex, dst, src, dstIsFloat, srcIsFloat, sampler, samplerOffset, is3D).convert();
   }
 
-  Instruction TYPED_WRITE(uint8_t imageIndex, Tuple src, Type srcType, Type coordType) {
-    return internal::TypedWriteInstruction(imageIndex, src, srcType, coordType).convert();
+  Instruction TYPED_WRITE(uint8_t imageIndex, Tuple src, Type srcType, Type coordType, bool is3D) {
+    return internal::TypedWriteInstruction(imageIndex, src, srcType, coordType, is3D).convert();
   }
 
   Instruction GET_IMAGE_INFO(int infoType, Register dst, uint8_t imageIndex, Register infoReg) {
index 88f7ebf..c827b9a 100644 (file)
@@ -347,10 +347,8 @@ namespace ir {
   /*! Store data in an texture */
   class TypedWriteInstruction : public Instruction {
   public:
-    enum {
-     SURFACE_BTI = 0
-    };
     /*! Return true if the given instruction is an instance of this class */
+    const bool is3D() const;
     static bool isClassOf(const Instruction &insn);
     const uint8_t getImageIndex() const;
     Type getSrcType(void) const;
@@ -360,11 +358,7 @@ namespace ir {
   /*! Load texels from a texture */
   class SampleInstruction : public Instruction {
   public:
-    enum {
-     SURFACE_BTI = 0,
-     SAMPLER_BTI = 1
-    };
-
+    const bool is3D() const;
     const uint8_t getImageIndex() const;
     const uint8_t getSamplerIndex(void) const;
     const uint8_t getSamplerOffset(void) const;
@@ -387,9 +381,6 @@ namespace ir {
   class GetImageInfoInstruction : public Instruction {
   public:
     enum {
-     SURFACE_BTI = 0
-    };
-    enum {
      WIDTH = 0,
      HEIGHT = 1,
      DEPTH = 2,
@@ -671,9 +662,9 @@ namespace ir {
   /*! sync.params... (see Sync instruction) */
   Instruction SYNC(uint32_t parameters);
   /*! typed write */
-  Instruction TYPED_WRITE(uint8_t imageIndex, Tuple src, Type srcType, Type coordType);
+  Instruction TYPED_WRITE(uint8_t imageIndex, Tuple src, Type srcType, Type coordType, bool is3D);
   /*! sample textures */
-  Instruction SAMPLE(uint8_t imageIndex, Tuple dst, Tuple src, bool dstIsFloat, bool srcIsFloat, uint8_t sampler, uint8_t samplerOffset);
+  Instruction SAMPLE(uint8_t imageIndex, Tuple dst, Tuple src, bool dstIsFloat, bool srcIsFloat, uint8_t sampler, uint8_t samplerOffset, bool is3D);
   /*! get image information , such as width/height/depth/... */
   Instruction GET_IMAGE_INFO(int infoType, Register dst, uint8_t imageIndex, Register infoReg);
   /*! get sampler information  */
index 1520b4a..c468b02 100644 (file)
@@ -2398,10 +2398,12 @@ namespace gbe
             GBE_ASSERT(AI != AE); const ir::Register ucoord = this->getRegister(*AI); ++AI;
             GBE_ASSERT(AI != AE); const ir::Register vcoord = this->getRegister(*AI); ++AI;
             ir::Register wcoord;
+            bool is3D = false;
             if (it->second >= GEN_OCL_READ_IMAGE10 && it->second <= GEN_OCL_READ_IMAGE15) {
               GBE_ASSERT(AI != AE); wcoord = this->getRegister(*AI); ++AI;
+              is3D = true;
             } else
-              wcoord = ir::Register(0);
+              wcoord = ucoord; // not used, just a padding.
 
             vector<ir::Register> dstTupleData, srcTupleData;
             const uint32_t elemNum = 4;
@@ -2454,7 +2456,7 @@ namespace gbe
             }
 
             ctx.SAMPLE(surfaceID, dstTuple, srcTuple, dstType == ir::TYPE_FLOAT,
-                       srcType == ir::TYPE_FLOAT, sampler, samplerOffset);
+                       srcType == ir::TYPE_FLOAT, sampler, samplerOffset, is3D);
             break;
           }
           case GEN_OCL_WRITE_IMAGE0:
@@ -2475,10 +2477,12 @@ namespace gbe
             GBE_ASSERT(AI != AE); const ir::Register ucoord = this->getRegister(*AI); ++AI;
             GBE_ASSERT(AI != AE); const ir::Register vcoord = this->getRegister(*AI); ++AI;
             ir::Register wcoord;
+            bool is3D = false;
             if(it->second >= GEN_OCL_WRITE_IMAGE10 && it->second <= GEN_OCL_WRITE_IMAGE15) {
               GBE_ASSERT(AI != AE); wcoord = this->getRegister(*AI); ++AI;
+              is3D = true;
             } else
-              wcoord = ir::Register(0);
+              wcoord = ucoord; // not used, just padding.
             GBE_ASSERT(AI != AE);
             vector<ir::Register> srcTupleData;
 
@@ -2522,7 +2526,7 @@ namespace gbe
                 GBE_ASSERT(0); // never been here.
             }
 
-            ctx.TYPED_WRITE(surfaceID, srcTuple, srcType, coordType);
+            ctx.TYPED_WRITE(surfaceID, srcTuple, srcType, coordType, is3D);
             break;
           }
           case GEN_OCL_MUL_HI_INT: