[Beignet] [PATCH 2/2] GBE: fixed the hacky code of 3D image read/write.
Zhigang Gong
zhigang.gong at intel.com
Thu Jan 16 21:12:05 PST 2014
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 at intel.com>
---
backend/src/backend/gen_context.cpp | 28 +++++++++++++---------------
backend/src/backend/gen_insn_selection.cpp | 24 +++++++++++++-----------
backend/src/backend/gen_insn_selection.hpp | 10 ++++++++++
backend/src/ir/instruction.cpp | 23 ++++++++++++++++-------
backend/src/ir/instruction.hpp | 17 ++++-------------
backend/src/llvm/llvm_gen_backend.cpp | 12 ++++++++----
6 files changed, 64 insertions(+), 50 deletions(-)
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 6a9461b..ecb8ef3 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -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);
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index f34da74..3d2ebcc 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -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);
diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp
index 7566928..d1f1950 100644
--- a/backend/src/backend/gen_insn_selection.hpp
+++ b/backend/src/backend/gen_insn_selection.hpp
@@ -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 */
diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp
index 3eb28ea..5e3cd84 100644
--- a/backend/src/ir/instruction.cpp
+++ b/backend/src/ir/instruction.cpp
@@ -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) {
diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp
index 88f7ebf..c827b9a 100644
--- a/backend/src/ir/instruction.hpp
+++ b/backend/src/ir/instruction.hpp
@@ -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 */
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index e75dd49..30f1eff 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -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:
--
1.7.9.5
More information about the Beignet
mailing list