From 738ddcb89bb6ef58e158a56bfb7c9ed078d5e193 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 17 Jan 2014 13:05:20 +0800 Subject: [PATCH] GBE: fixed the hacky code of 3D image read/write. 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 Reviewed-by: "Yang, Rong R" --- 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 { 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 1520b4a..c468b02 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 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 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: -- 2.7.4