const unsigned char sampler = insn.extra.sampler;
const unsigned int msgLen = insn.extra.rdmsglen;
uint32_t simdWidth = p->curr.execWidth;
- //p->push();
p->SAMPLE(dst, msgPayload, msgLen, false, bti, sampler, simdWidth, -1, 0);
- //p->pop();
}
void GenContext::scratchWrite(const GenRegister header, uint32_t offset, uint32_t reg_num, uint32_t reg_type, uint32_t channel_mode) {
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.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;
- const uint32_t nr = header.nr;
- p->curr.predicate = GEN_PREDICATE_NONE;
- p->curr.noMask = 1;
- p->MOV(header, GenRegister::immud(0x0));
- p->curr.execWidth = 1;
-
- // prepare mesg desc and move to a0.0.
- // desc = bti | (msg_type << 14) | (header_present << 19))
- // prepare header, we need to enable all the 8 planes.
- p->MOV(GenRegister::ud8grf(nr, 7), GenRegister::immud(0xffff));
- p->curr.execWidth = 8;
- // Typed write only support SIMD8.
- // Prepare message payload U + V + R(ignored) + LOD(0) + RGBA.
- // Currently, we don't support non-zero lod, so we clear all lod to
- // zero for both quarters thus save one instruction here.
- // Thus we must put this instruction in noMask and no predication state.
- p->MOV(GenRegister::ud8grf(nr + 4, 0), GenRegister::immud(0)); //LOD
- p->pop();
- p->push();
- p->curr.execWidth = 8;
- // TYPED WRITE send instruction only support SIMD8, if we are SIMD16, we
- // need to call it twice.
- uint32_t quarterNum = (simdWidth == 8) ? 1 : 2;
-
- for( uint32_t quarter = 0; quarter < quarterNum; quarter++)
- {
-#define QUARTER_MOV0(dst_nr, src) p->MOV(GenRegister::ud8grf(dst_nr, 0), \
- GenRegister::retype(GenRegister::QnPhysical(src, quarter), src.type))
-#define QUARTER_MOV1(dst_nr, src) p->MOV(GenRegister::retype(GenRegister::ud8grf(dst_nr, 0), src.type), \
- GenRegister::retype(GenRegister::QnPhysical(src,quarter), src.type))
- if (quarter == 1)
- p->curr.quarterControl = GEN_COMPRESSION_Q2;
- QUARTER_MOV0(nr + 1, ucoord);
- QUARTER_MOV0(nr + 2, vcoord);
- 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);
- QUARTER_MOV1(nr + 8, A);
-#undef QUARTER_MOV
- p->TYPED_WRITE(header, true, bti);
- }
- p->pop();
+ const uint32_t bti = insn.extra.bti;
+ p->TYPED_WRITE(header, true, bti);
}
BVAR(OCL_OUTPUT_REG_ALLOC, false);
/*! Encode sample instructions */
void SAMPLE(GenRegister *dst, uint32_t dstNum, 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, bool is3D);
+ void TYPED_WRITE(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 */
this->opaque = GBE_NEW(Selection::Opaque, ctx);
}
- void Selection::Opaque::TYPED_WRITE(GenRegister *src, uint32_t srcNum,
- GenRegister *msgs, uint32_t msgNum,
+ void Selection::Opaque::TYPED_WRITE(GenRegister *msgs, uint32_t msgNum,
uint32_t bti, bool is3D) {
uint32_t elemID = 0;
uint32_t i;
- SelectionInstruction *insn = this->appendInsn(SEL_OP_TYPED_WRITE, 0, msgNum + srcNum);
+ SelectionInstruction *insn = this->appendInsn(SEL_OP_TYPED_WRITE, 0, msgNum);
SelectionVector *msgVector = this->appendVector();;
for( i = 0; i < msgNum; ++i, ++elemID)
insn->src(elemID) = msgs[i];
- for (i = 0; i < srcNum; ++i, ++elemID)
- insn->src(elemID) = src[i];
insn->extra.bti = bti;
insn->extra.msglen = msgNum;
{
using namespace ir;
const uint32_t simdWidth = sel.ctx.getSimdWidth();
- uint32_t valueID;
GenRegister msgs[9]; // (header + U + V + R + LOD + 4)
- GenRegister src[insn.getSrcNum()];
- uint32_t msgNum = (8 / (simdWidth / 8)) + 1;
- uint32_t coordNum = 3;
+ const uint32_t msgNum = (8 / (simdWidth / 8)) + 1;
+ const uint32_t coordNum = 3;
- for(uint32_t i = 0; i < msgNum; i++)
- msgs[i] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
-
- // u, v, w coords should use coord type.
- for (valueID = 0; valueID < coordNum; ++valueID)
- src[valueID] = sel.selReg(insn.getSrc(valueID), insn.getCoordType());
+ if (simdWidth == 16) {
+ for(uint32_t i = 0; i < msgNum; i++)
+ msgs[i] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
+ } else {
+ uint32_t valueID = 0;
+ msgs[0] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
+ for(uint32_t msgID = 1; msgID < 1 + coordNum; msgID++, valueID++)
+ msgs[msgID] = sel.selReg(insn.getSrc(msgID - 1), insn.getCoordType());
+ // fake w.
+ if (!insn.is3D())
+ msgs[3] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
+ // LOD.
+ msgs[4] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
+ for(uint32_t msgID = 5; valueID < insn.getSrcNum(); msgID++, valueID++)
+ msgs[msgID] = sel.selReg(insn.getSrc(valueID), insn.getSrcType());
+ }
- for (; valueID < insn.getSrcNum(); ++valueID)
- src[valueID] = sel.selReg(insn.getSrc(valueID), insn.getSrcType());
+ sel.push();
+ sel.curr.predicate = GEN_PREDICATE_NONE;
+ sel.curr.noMask = 1;
+ sel.MOV(msgs[0], GenRegister::immud(0));
+ sel.curr.execWidth = 1;
+
+ GenRegister channelEn = GenRegister::offset(msgs[0], 0, 7*4);
+ channelEn.subphysical = 1;
+ // Enable all channels.
+ sel.MOV(channelEn, GenRegister::immud(0xffff));
+ sel.curr.execWidth = 8;
+ // Set zero LOD.
+ if (simdWidth == 8)
+ sel.MOV(msgs[4], GenRegister::immud(0));
+ else
+ sel.MOV(GenRegister::Qn(msgs[2], 0), GenRegister::immud(0));
+ sel.pop();
uint32_t bti = insn.getImageIndex();
- sel.TYPED_WRITE(src, insn.getSrcNum(), msgs, msgNum, bti, insn.is3D());
+ if (simdWidth == 8)
+ sel.TYPED_WRITE(msgs, msgNum, bti, insn.is3D());
+ else {
+ sel.push();
+ sel.curr.execWidth = 8;
+ for( uint32_t quarter = 0; quarter < 2; quarter++)
+ {
+ #define QUARTER_MOV0(msgs, msgid, src) \
+ sel.MOV(GenRegister::Qn(GenRegister::retype(msgs[msgid/2], GEN_TYPE_UD), msgid % 2), \
+ GenRegister::Qn(src, quarter))
+
+ #define QUARTER_MOV1(msgs, msgid, src) \
+ sel.MOV(GenRegister::Qn(GenRegister::retype(msgs[msgid/2], src.type), msgid % 2), \
+ GenRegister::Qn(src, quarter))
+ sel.curr.quarterControl = (quarter == 0) ? GEN_COMPRESSION_Q1 : GEN_COMPRESSION_Q2;
+ // Set U,V,W
+ QUARTER_MOV0(msgs, 1, sel.selReg(insn.getSrc(0), insn.getCoordType()));
+ QUARTER_MOV0(msgs, 2, sel.selReg(insn.getSrc(1), insn.getCoordType()));
+ if (insn.is3D())
+ QUARTER_MOV0(msgs, 3, sel.selReg(insn.getSrc(2), insn.getCoordType()));
+ // Set R, G, B, A
+ QUARTER_MOV1(msgs, 5, sel.selReg(insn.getSrc(3), insn.getSrcType()));
+ QUARTER_MOV1(msgs, 6, sel.selReg(insn.getSrc(4), insn.getSrcType()));
+ QUARTER_MOV1(msgs, 7, sel.selReg(insn.getSrc(5), insn.getSrcType()));
+ QUARTER_MOV1(msgs, 8, sel.selReg(insn.getSrc(6), insn.getSrcType()));
+ sel.TYPED_WRITE(msgs, msgNum, bti, insn.is3D());
+ #undef QUARTER_MOV0
+ #undef QUARTER_MOV1
+ }
+ sel.pop();
+ }
return true;
}
DECL_CTOR(TypedWriteInstruction, 1, 1);
OVERLOADABLE float4 __gen_ocl_read_imagef(uint surface_id, sampler_t sampler, float u, float v, float w, uint sampler_offset);
OVERLOADABLE void __gen_ocl_write_imagei(uint surface_id, int u, int v, int4 color);
-OVERLOADABLE void __gen_ocl_write_imagei(uint surface_id, float u, float v, int4 color);
+//OVERLOADABLE void __gen_ocl_write_imagei(uint surface_id, float u, float v, int4 color);
OVERLOADABLE void __gen_ocl_write_imageui(uint surface_id, int u, int v, uint4 color);
-OVERLOADABLE void __gen_ocl_write_imageui(uint surface_id, float u, float v, uint4 color);
+//OVERLOADABLE void __gen_ocl_write_imageui(uint surface_id, float u, float v, uint4 color);
OVERLOADABLE void __gen_ocl_write_imagef(uint surface_id, int u, int v, float4 color);
-OVERLOADABLE void __gen_ocl_write_imagef(uint surface_id, float u, float v, float4 color);
+//OVERLOADABLE void __gen_ocl_write_imagef(uint surface_id, float u, float v, float4 color);
OVERLOADABLE void __gen_ocl_write_imagei(uint surface_id, int u, int v, int w, int4 color);
-OVERLOADABLE void __gen_ocl_write_imagei(uint surface_id, float u, float v, float w, int4 color);
+//OVERLOADABLE void __gen_ocl_write_imagei(uint surface_id, float u, float v, float w, int4 color);
OVERLOADABLE void __gen_ocl_write_imageui(uint surface_id, int u, int v, int w, uint4 color);
-OVERLOADABLE void __gen_ocl_write_imageui(uint surface_id, float u, float v, float w, uint4 color);
+//OVERLOADABLE void __gen_ocl_write_imageui(uint surface_id, float u, float v, float w, uint4 color);
OVERLOADABLE void __gen_ocl_write_imagef(uint surface_id, int u, int v, int w, float4 color);
-OVERLOADABLE void __gen_ocl_write_imagef(uint surface_id, float u, float v, float w, float4 color);
+//OVERLOADABLE void __gen_ocl_write_imagef(uint surface_id, float u, float v, float w, float4 color);
int __gen_ocl_get_image_width(uint surface_id);
int __gen_ocl_get_image_height(uint surface_id);
int __gen_ocl_get_image_channel_data_type(uint surface_id);