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();
/* 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);
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;
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);
/*! 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 */
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();
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;
}
///////////////////////////////////////////////////////////////////////////
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);
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;
/* 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);
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);
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);
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 */
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;
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 {
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;
{
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 {
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; }
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())
}
// 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) {
/*! 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;
/*! 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;
class GetImageInfoInstruction : public Instruction {
public:
enum {
- SURFACE_BTI = 0
- };
- enum {
WIDTH = 0,
HEIGHT = 1,
DEPTH = 2,
/*! 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 */
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;
}
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:
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;
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: