[Beignet] [PATCH 2/4] GBE: Add support for get_image_width/height.

Zhigang Gong zhigang.gong at linux.intel.com
Fri May 17 01:59:58 PDT 2013


Implement the new GEN IR instruction GetImageInfo. This new instruction
will allocate curbe slot for a given image surface only if it really
referred by a get_image_xxx function. As one image information element
only takes 4 bytes, it's relatively cheap to keep it in the curbe region.

Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
---
 backend/src/backend/context.cpp                    | 16 ++++++++
 backend/src/backend/context.hpp                    |  3 ++
 backend/src/backend/gen_context.cpp                | 17 +++++++++
 backend/src/backend/gen_context.hpp                |  1 +
 .../src/backend/gen_insn_gen7_schedule_info.hxx    |  1 +
 backend/src/backend/gen_insn_selection.cpp         | 34 ++++++++++++++++-
 backend/src/backend/gen_insn_selection.hxx         |  1 +
 backend/src/backend/program.h                      |  4 +-
 backend/src/backend/program.hpp                    |  6 +--
 backend/src/ir/image.cpp                           | 41 +++++++++++++++++++-
 backend/src/ir/image.hpp                           |  6 +++
 backend/src/ir/instruction.cpp                     | 44 ++++++++++++++++++++++
 backend/src/ir/instruction.hpp                     | 37 ++++++++++++++++++
 backend/src/ir/instruction.hxx                     |  2 +-
 backend/src/llvm/llvm_gen_backend.cpp              | 25 ++++++++++--
 backend/src/llvm/llvm_scalarize.cpp                |  2 +
 16 files changed, 227 insertions(+), 13 deletions(-)

diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp
index 0beea1d..474c36a 100644
--- a/backend/src/backend/context.cpp
+++ b/backend/src/backend/context.cpp
@@ -29,6 +29,8 @@
 #include "ir/profile.hpp"
 #include "ir/liveness.hpp"
 #include "ir/value.hpp"
+#include "ir/image.hpp"
+#include "ir/sampler.hpp"
 #include "sys/cvar.hpp"
 #include <algorithm>
 
@@ -356,6 +358,20 @@ namespace gbe
     kernel->curbeSize = std::max(kernel->curbeSize, offset + size - GEN_REG_SIZE);
   }
 
+  uint32_t Context::getImageInfoCurbeOffset(ir::ImageInfoKey key, size_t size)
+  {
+    int32_t offset = fn.getImageSet()->getInfoOffset(key);
+    if (offset >= 0)
+      return offset;
+    newCurbeEntry(GBE_CURBE_IMAGE_INFO, key.data, size, 4);
+    std::sort(kernel->patches.begin(), kernel->patches.end());
+
+    offset = kernel->getCurbeOffset(GBE_CURBE_IMAGE_INFO, key.data);
+    GBE_ASSERT(offset >= 0); // XXX do we need to spill it out to bo?
+    fn.getImageSet()->appendInfo(key, offset);
+    return offset;
+  }
+
   void Context::buildPatchList(void) {
     const uint32_t ptrSize = unit.getPointerSize() == ir::POINTER_32_BITS ? 4u : 8u;
     kernel->curbeSize = 0u;
diff --git a/backend/src/backend/context.hpp b/backend/src/backend/context.hpp
index 245ad01..c205388 100644
--- a/backend/src/backend/context.hpp
+++ b/backend/src/backend/context.hpp
@@ -88,6 +88,9 @@ namespace gbe
     void deallocate(int16_t offset);
     /* allocate curbe for constant ptr argument */
     int32_t allocConstBuf(uint32_t argID);
+    /* allocate a new entry for a specific image's information */
+    /*! Get (search or allocate if fail to find one) image info curbeOffset.*/
+    uint32_t getImageInfoCurbeOffset(ir::ImageInfoKey key, size_t size);
   protected:
     /*! Build the instruction stream. Return false if failed */
     virtual bool emitCode(void) = 0;
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 4dec83c..18f6c11 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -365,6 +365,23 @@ namespace gbe
     p->pop();
   }
 
+  void GenContext::emitGetImageInfoInstruction(const SelectionInstruction &insn) {
+    const unsigned char bti = insn.extra.function;
+    const unsigned char type = insn.extra.elem;
+    const uint32_t dstNum = ir::GetImageInfoInstruction::getDstNum4Type(type);
+    ir::ImageInfoKey key;
+    key.index = bti;
+    key.type = type;
+
+    uint32_t offset = this->getImageInfoCurbeOffset(key, dstNum * 4) + GEN_REG_SIZE;
+    for(uint32_t i = 0; i < dstNum; i++) {
+      const uint32_t nr = offset / GEN_REG_SIZE;
+      const uint32_t subnr = (offset % GEN_REG_SIZE) / sizeof(uint32_t);
+      p->MOV(ra->genReg(insn.dst(i)), GenRegister::ud1grf(nr, subnr));
+      offset += 32;
+    }
+  }
+
   BVAR(OCL_OUTPUT_REG_ALLOC, false);
   BVAR(OCL_OUTPUT_ASM, false);
   bool GenContext::emitCode(void) {
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp
index fccd0c6..7c28bdf 100644
--- a/backend/src/backend/gen_context.hpp
+++ b/backend/src/backend/gen_context.hpp
@@ -92,6 +92,7 @@ namespace gbe
     void emitByteScatterInstruction(const SelectionInstruction &insn);
     void emitSampleInstruction(const SelectionInstruction &insn);
     void emitTypedWriteInstruction(const SelectionInstruction &insn);
+    void emitGetImageInfoInstruction(const SelectionInstruction &insn);
 
     /*! Implements base class */
     virtual Kernel *allocateKernel(void);
diff --git a/backend/src/backend/gen_insn_gen7_schedule_info.hxx b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
index 113fa71..a2c0fba 100644
--- a/backend/src/backend/gen_insn_gen7_schedule_info.hxx
+++ b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
@@ -17,4 +17,5 @@ DECL_GEN7_SCHEDULE(ByteGather,      80,        1,        1)
 DECL_GEN7_SCHEDULE(ByteScatter,     80,        1,        1)
 DECL_GEN7_SCHEDULE(Sample,          80,        1,        1)
 DECL_GEN7_SCHEDULE(TypedWrite,      80,        1,        1)
+DECL_GEN7_SCHEDULE(GetImageInfo,    20,        4,        2)
 
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index b405676..08bc6af 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -469,6 +469,8 @@ namespace gbe
     void SAMPLE(GenRegister *dst, uint32_t dstNum, GenRegister *src, uint32_t srcNum, GenRegister *msgPayloads, uint32_t msgNum, uint32_t bti, uint32_t sampler);
     /*! Encode typed write instructions */
     void TYPED_WRITE(GenRegister *src, uint32_t srcNum, GenRegister *msgs, uint32_t msgNum, uint32_t bti);
+    /*! Get image information */
+    void GET_IMAGE_INFO(uint32_t type, GenRegister *dst, uint32_t dst_num, uint32_t bti);
     /*! Use custom allocators */
     GBE_CLASS(Opaque);
     friend class SelectionBlock;
@@ -1025,6 +1027,17 @@ namespace gbe
     msgVector->reg = &insn->src(0);
   }
 
+  void Selection::Opaque::GET_IMAGE_INFO(uint32_t infoType, GenRegister *dst,
+                                    uint32_t dstNum, uint32_t bti) {
+    SelectionInstruction *insn = this->appendInsn(SEL_OP_GET_IMAGE_INFO, dstNum, 0);
+
+    for(uint32_t i = 0; i < dstNum; ++i)
+      insn->dst(i) = dst[i];
+
+    insn->extra.function = bti;
+    insn->extra.elem = infoType;
+  }
+
   Selection::~Selection(void) { GBE_DELETE(this->opaque); }
 
   void Selection::select(void) {
@@ -2026,6 +2039,25 @@ namespace gbe
     DECL_CTOR(TypedWriteInstruction, 1, 1);
   };
 
+  /*! get image info instruction pattern. */
+  DECL_PATTERN(GetImageInfoInstruction)
+  {
+    INLINE bool emitOne(Selection::Opaque &sel, const ir::GetImageInfoInstruction &insn) const
+    {
+      using namespace ir;
+      const uint32_t infoType = insn.getInfoType();
+      GenRegister dst[4];
+      uint32_t dstNum = ir::GetImageInfoInstruction::getDstNum4Type(infoType);
+      for (uint32_t valueID = 0; valueID < dstNum; ++valueID)
+        dst[valueID] = sel.selReg(insn.getDst(valueID), TYPE_U32);
+      uint32_t bti = sel.ctx.getFunction().getImageSet()->getIdx
+                       (insn.getSrc(0));
+      sel.GET_IMAGE_INFO(infoType, dst, dstNum, bti);
+      return true;
+    }
+    DECL_CTOR(GetImageInfoInstruction, 1, 1);
+  };
+
   /*! Branch instruction pattern */
   DECL_PATTERN(BranchInstruction)
   {
@@ -2179,7 +2211,6 @@ namespace gbe
   SelectionLibrary::SelectionLibrary(void) {
     this->insert<UnaryInstructionPattern>();
     this->insert<BinaryInstructionPattern>();
-    this->insert<SampleInstructionPattern>();
     this->insert<TypedWriteInstructionPattern>();
     this->insert<SyncInstructionPattern>();
     this->insert<LoadImmInstructionPattern>();
@@ -2195,6 +2226,7 @@ namespace gbe
     this->insert<MulAddInstructionPattern>();
     this->insert<SelectModifierInstructionPattern>();
     this->insert<SampleInstructionPattern>();
+    this->insert<GetImageInfoInstructionPattern>();
 
     // Sort all the patterns with the number of instructions they output
     for (uint32_t op = 0; op < ir::OP_INVALID; ++op)
diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
index 4c6a3de..455bb92 100644
--- a/backend/src/backend/gen_insn_selection.hxx
+++ b/backend/src/backend/gen_insn_selection.hxx
@@ -35,3 +35,4 @@ DECL_SELECTION_IR(BYTE_GATHER, ByteGatherInstruction)
 DECL_SELECTION_IR(BYTE_SCATTER, ByteScatterInstruction)
 DECL_SELECTION_IR(SAMPLE, SampleInstruction)
 DECL_SELECTION_IR(TYPED_WRITE, TypedWriteInstruction)
+DECL_SELECTION_IR(GET_IMAGE_INFO, GetImageInfoInstruction)
diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h
index b2b2814..f178f8b 100644
--- a/backend/src/backend/program.h
+++ b/backend/src/backend/program.h
@@ -71,9 +71,7 @@ enum gbe_curbe_type {
   GBE_CURBE_GROUP_NUM_Z,
   GBE_CURBE_GLOBAL_CONSTANT_OFFSET,
   GBE_CURBE_GLOBAL_CONSTANT_DATA,
-  GBE_CURBE_IMAGE_WIDTH,
-  GBE_CURBE_IMAGE_HEIGHT,
-  GBE_CURBE_IMAGE_DEPTH,
+  GBE_CURBE_IMAGE_INFO,
   GBE_CURBE_STACK_POINTER,
   GBE_CURBE_KERNEL_ARGUMENT,
   GBE_CURBE_EXTRA_ARGUMENT,
diff --git a/backend/src/backend/program.hpp b/backend/src/backend/program.hpp
index dfabf3b..2d67310 100644
--- a/backend/src/backend/program.hpp
+++ b/backend/src/backend/program.hpp
@@ -55,9 +55,9 @@ namespace gbe {
     INLINE PatchInfo(gbe_curbe_type type, uint32_t subType = 0u, uint32_t offset = 0u) :
       type(uint32_t(type)), subType(subType), offset(offset) {}
     INLINE PatchInfo(void) {}
-    uint32_t type : 8;    //!< Type of the patch (see program.h for the list)
-    uint32_t subType : 8; //!< Optional sub-type of the patch (see program.h)
-    uint32_t offset : 16; //!< Optional offset to encode
+    uint64_t type : 16;    //!< Type of the patch (see program.h for the list)
+    uint64_t subType : 32; //!< Optional sub-type of the patch (see program.h)
+    uint64_t offset : 16; //!< Optional offset to encode
   };
 
   /*! We will sort PatchInfo to make binary search */
diff --git a/backend/src/ir/image.cpp b/backend/src/ir/image.cpp
index 1180e14..9398e22 100644
--- a/backend/src/ir/image.cpp
+++ b/backend/src/ir/image.cpp
@@ -28,6 +28,36 @@
 namespace gbe {
 namespace ir {
 
+  static uint32_t getInfoOffset4Type(struct ImageInfo *imageInfo, int type)
+  {
+    switch (type) {
+      case GetImageInfoInstruction::WIDTH: return imageInfo->wSlot;
+      case GetImageInfoInstruction::HEIGHT: return imageInfo->hSlot;
+      default:
+        NOT_IMPLEMENTED;
+    }
+    return 0;
+  }
+
+  static uint32_t setInfoOffset4Type(struct ImageInfo *imageInfo, int type, uint32_t offset)
+  {
+    switch (type) {
+      case GetImageInfoInstruction::WIDTH: imageInfo->wSlot = offset; break;
+      case GetImageInfoInstruction::HEIGHT: imageInfo->hSlot = offset; break;
+      default:
+        NOT_IMPLEMENTED;
+    }
+    return 0;
+  }
+
+  void ImageSet::appendInfo(ImageInfoKey key, uint32_t offset)
+  {
+    auto it = indexMap.find(key.index);
+    assert(it != indexMap.end());
+    struct ImageInfo *imageInfo = it->second;
+    setInfoOffset4Type(imageInfo, key.type, offset);
+  }
+
   void ImageSet::append(Register imageReg, Context *ctx)
   {
     ir::FunctionArgument *arg =  ctx->getFunction().getArg(imageReg);
@@ -44,8 +74,17 @@ namespace ir {
     imageInfo->dataTypeSlot = -1;
     imageInfo->channelOrderSlot = -1;
     imageInfo->dimOrderSlot = -1;
-
     regMap.insert(std::make_pair(imageReg, imageInfo));
+    indexMap.insert(std::make_pair(imageInfo->idx, imageInfo));
+  }
+
+  const int32_t ImageSet::getInfoOffset(ImageInfoKey key) const
+  {
+    auto it = indexMap.find(key.index);
+    if (it == indexMap.end())
+      return -1;
+    struct ImageInfo *imageInfo = it->second;
+    return getInfoOffset4Type(imageInfo, key.type);
   }
 
   const uint32_t ImageSet::getIdx(const Register imageReg) const
diff --git a/backend/src/ir/image.hpp b/backend/src/ir/image.hpp
index acad459..04e78e6 100644
--- a/backend/src/ir/image.hpp
+++ b/backend/src/ir/image.hpp
@@ -24,6 +24,7 @@
 #define __GBE_IR_IMAGE_HPP__
 
 #include "ir/register.hpp"
+#include "ir/instruction.hpp" // for ImageInfoKey
 #include "sys/map.hpp"
 
 extern "C" {
@@ -44,10 +45,14 @@ namespace ir {
   public:
     /*! Append an image argument. */
     void append(Register imageReg, Context *ctx);
+    /*! Append an image info slot. */
+    void appendInfo(ImageInfoKey key, uint32_t offset);
     /*! Get the image's index(actual location). */
     const uint32_t getIdx(const Register imageReg) const;
     size_t getDataSize(void) { return regMap.size(); }
     size_t getDataSize(void) const { return regMap.size(); }
+
+    const int32_t getInfoOffset(ImageInfoKey key) const;
     void getData(struct ImageInfo *imageInfos) const;
     void operator = (const ImageSet& other) {
       regMap.insert(other.regMap.begin(), other.regMap.end());
@@ -57,6 +62,7 @@ namespace ir {
     ~ImageSet();
   private:
     map<Register, struct ImageInfo *> regMap;
+    map<uint32_t, struct ImageInfo *> indexMap;
     GBE_CLASS(ImageSet);
   };
 } /* namespace ir */
diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp
index e8d52ae..a57c204 100644
--- a/backend/src/ir/instruction.cpp
+++ b/backend/src/ir/instruction.cpp
@@ -470,6 +470,39 @@ namespace ir {
       Register dst[0];               //!< No dest register
     };
 
+    class ALIGNED_INSTRUCTION GetImageInfoInstruction :
+      public BasePolicy,
+      public NSrcPolicy<GetImageInfoInstruction, 1>,
+      public TupleDstPolicy<GetImageInfoInstruction>
+    {
+    public:
+      GetImageInfoInstruction( int type,
+                               Tuple dst,
+                               Register src)
+      {
+        this->opcode = OP_GET_IMAGE_INFO;
+        this->infoType = type;
+        this->dst = dst;
+        this->src[0] = src;
+      }
+
+      INLINE uint32_t getInfoType(void) const { return infoType; }
+      INLINE bool wellFormed(const Function &fn, std::string &why) const;
+      INLINE void out(std::ostream &out, const Function &fn) const {
+        this->outOpcode(out);
+        out << "." << this->getInfoType()
+            << " surface id %" << this->getSrc(fn, 0)
+            << " %" << this->getDst(fn, 0);
+      }
+
+      uint8_t infoType;                 //!< Type of the requested information.
+      Register src[1];                  //!< Surface to get info
+      Tuple dst;                        //!< dest register to put the information.
+      static const uint32_t dstNum = 4; //! The maximum dst number. Not the actual number
+                                        // of destination tuple. We use the infoType to determin
+                                        // the actual num.
+    };
+
     class ALIGNED_INSTRUCTION LoadImmInstruction :
       public BasePolicy,
       public NSrcPolicy<LoadImmInstruction, 0>,
@@ -758,6 +791,8 @@ namespace ir {
     { return true; }
     INLINE bool TypedWriteInstruction::wellFormed(const Function &fn, std::string &why) const
     { return true; }
+    INLINE bool GetImageInfoInstruction::wellFormed(const Function &fn, std::string &why) const
+    { return true; }
 
     // Ensure that types and register family match
     INLINE bool LoadImmInstruction::wellFormed(const Function &fn, std::string &whyNot) const
@@ -990,6 +1025,10 @@ START_INTROSPECTION(TypedWriteInstruction)
 #include "ir/instruction.hxx"
 END_INTROSPECTION(TypedWriteInstruction)
 
+START_INTROSPECTION(GetImageInfoInstruction)
+#include "ir/instruction.hxx"
+END_INTROSPECTION(GetImageInfoInstruction)
+
 START_INTROSPECTION(LoadImmInstruction)
 #include "ir/instruction.hxx"
 END_INTROSPECTION(LoadImmInstruction)
@@ -1175,6 +1214,7 @@ DECL_MEM_FN(SampleInstruction, Type, getSrcType(void), getSrcType())
 DECL_MEM_FN(SampleInstruction, Type, getDstType(void), getDstType())
 DECL_MEM_FN(TypedWriteInstruction, Type, getSrcType(void), getSrcType())
 DECL_MEM_FN(TypedWriteInstruction, Type, getCoordType(void), getCoordType())
+DECL_MEM_FN(GetImageInfoInstruction, uint32_t, getInfoType(void), getInfoType())
 
 #undef DECL_MEM_FN
 
@@ -1316,6 +1356,10 @@ DECL_MEM_FN(TypedWriteInstruction, Type, getCoordType(void), getCoordType())
     return internal::TypedWriteInstruction(src, srcType, coordType).convert();
   }
 
+  Instruction GET_IMAGE_INFO(int infoType, Tuple dst, Register src) {
+    return internal::GetImageInfoInstruction(infoType, dst, src).convert();
+  }
+
   std::ostream &operator<< (std::ostream &out, const Instruction &insn) {
     const Function &fn = insn.getFunction();
     switch (insn.getOpcode()) {
diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp
index b6ec79f..c948d2c 100644
--- a/backend/src/ir/instruction.hpp
+++ b/backend/src/ir/instruction.hpp
@@ -319,6 +319,41 @@ namespace ir {
     Type getDstType(void) const;
   };
 
+  typedef union {
+    struct {
+     uint16_t index; /*! the allocated image index */
+     uint16_t type;  /*! the information type */
+    };
+    uint32_t data;
+  } ImageInfoKey;
+  /*! Get image information */
+  class GetImageInfoInstruction : public Instruction {
+  public:
+    enum {
+     SURFACE_BTI = 0
+    };
+    enum {
+     WIDTH = 0,
+     HEIGHT = 1,
+    };
+
+    static INLINE uint32_t getDstNum4Type(int infoType) {
+      switch (infoType) {
+        case GetImageInfoInstruction::WIDTH:
+        case GetImageInfoInstruction::HEIGHT:
+          return 1;
+        break;
+        default:
+          GBE_ASSERT(0);
+     }
+     return 0;
+   }
+
+    uint32_t getInfoType() const;
+    /*! Return true if the given instruction is an instance of this class */
+    static bool isClassOf(const Instruction &insn);
+  };
+
   /*! Branch instruction is the unified way to branch (with or without
    *  predicate)
    */
@@ -528,6 +563,8 @@ namespace ir {
   Instruction TYPED_WRITE(Tuple src, Type srcType, Type coordType);
   /*! sample textures */
   Instruction SAMPLE(Tuple dst, Tuple src, Type dstType, Type srcType);
+  /*! get image information , such as width/height/depth/... */
+  Instruction GET_IMAGE_INFO(int infoType, Tuple dst, Register src);
   /*! label labelIndex */
   Instruction LABEL(LabelIndex labelIndex);
 
diff --git a/backend/src/ir/instruction.hxx b/backend/src/ir/instruction.hxx
index b16c22f..5cf37d2 100644
--- a/backend/src/ir/instruction.hxx
+++ b/backend/src/ir/instruction.hxx
@@ -70,4 +70,4 @@ DECL_INSN(TYPED_WRITE, TypedWriteInstruction)
 DECL_INSN(SAMPLE, SampleInstruction)
 DECL_INSN(SYNC, SyncInstruction)
 DECL_INSN(LABEL, LabelInstruction)
-
+DECL_INSN(GET_IMAGE_INFO, GetImageInfoInstruction)
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 93fca4b..deda687 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -1828,7 +1828,24 @@ namespace gbe
           case GEN_OCL_GET_IMAGE_WIDTH:
           case GEN_OCL_GET_IMAGE_HEIGHT:
           {
-            //GBE_ASSERT(AI != AE); const ir::Register surface_id = this->getRegister(*AI); ++AI; break;
+            GBE_ASSERT(AI != AE); const ir::Register surface_id = this->getRegister(*AI); ++AI;
+            uint32_t elemNum;
+            (void)getVectorInfo(ctx, I.getType(), &I, elemNum);
+            vector<ir::Register> dstTupleData;
+            ir::Register lastReg;
+            for (uint32_t elemID = 0; elemID < elemNum; ++elemID) {
+              const ir::Register reg = this->getRegister(&I, elemID);
+              dstTupleData.push_back(reg);
+              lastReg = reg;
+            }
+            // A walk around for the gen IR limitation.
+            for (uint32_t elemID = elemNum; elemID < 4; ++ elemID) {
+              dstTupleData.push_back(lastReg);
+            }
+            const ir::Tuple dstTuple = ctx.arrayTuple(&dstTupleData[0], 4);
+            int infoType = it->second - GEN_OCL_GET_IMAGE_WIDTH;
+
+            ctx.GET_IMAGE_INFO(infoType, dstTuple, surface_id);
             break;
           }
           case GEN_OCL_READ_IMAGE0:
@@ -1852,9 +1869,9 @@ namespace gbe
             {
               // This is not a kernel argument sampler, we need to append it to sampler set,
               // and allocate a sampler slot for it.
-               auto x = processConstant<ir::Immediate>(CPV, InsertExtractFunctor(ctx));
-               GBE_ASSERTM(x.type == ir::TYPE_U32 || x.type == ir::TYPE_S32, "Invalid sampler type");
-               sampler = ctx.getFunction().getSamplerSet()->append(x.data.u32, &ctx);
+              auto x = processConstant<ir::Immediate>(CPV, InsertExtractFunctor(ctx));
+              GBE_ASSERTM(x.type == ir::TYPE_U32 || x.type == ir::TYPE_S32, "Invalid sampler type");
+              sampler = ctx.getFunction().getSamplerSet()->append(x.data.u32, &ctx);
             } else {
               sampler = this->getRegister(*AI);
               ctx.getFunction().getSamplerSet()->append(sampler, &ctx);
diff --git a/backend/src/llvm/llvm_scalarize.cpp b/backend/src/llvm/llvm_scalarize.cpp
index 4de1fce..f71401f 100644
--- a/backend/src/llvm/llvm_scalarize.cpp
+++ b/backend/src/llvm/llvm_scalarize.cpp
@@ -638,6 +638,8 @@ namespace gbe {
           case GEN_OCL_READ_IMAGE13:
           case GEN_OCL_READ_IMAGE14:
           case GEN_OCL_READ_IMAGE15:
+          case GEN_OCL_GET_IMAGE_WIDTH:
+          case GEN_OCL_GET_IMAGE_HEIGHT:
           {
             extractFromeVector(call);
             break;
-- 
1.7.11.7



More information about the Beignet mailing list