/*! 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 *msgPayloads, uint32_t msgNum, uint32_t bti, uint32_t sampler, bool is3D);
+ void SAMPLE(GenRegister *dst, uint32_t dstNum, GenRegister *msgPayloads, uint32_t msgNum, uint32_t bti, uint32_t sampler, bool isLD);
/*! Encode typed write instructions */
void TYPED_WRITE(GenRegister *msgs, uint32_t msgNum, uint32_t bti, bool is3D);
/*! Get image information */
void Selection::Opaque::SAMPLE(GenRegister *dst, uint32_t dstNum,
GenRegister *msgPayloads, uint32_t msgNum,
- uint32_t bti, uint32_t sampler, bool is3D) {
+ uint32_t bti, uint32_t sampler, bool isLD) {
SelectionInstruction *insn = this->appendInsn(SEL_OP_SAMPLE, dstNum, msgNum);
SelectionVector *dstVector = this->appendVector();
SelectionVector *msgVector = this->appendVector();
insn->extra.rdbti = bti;
insn->extra.sampler = sampler;
insn->extra.rdmsglen = msgNum;
+ insn->extra.isLD = isLD;
}
///////////////////////////////////////////////////////////////////////////
GenRegister dst[insn.getDstNum()];
uint32_t srcNum = insn.getSrcNum();
uint32_t valueID = 0;
+ uint32_t msgLen = 0;
for (valueID = 0; valueID < insn.getDstNum(); ++valueID)
dst[valueID] = sel.selReg(insn.getDst(valueID), insn.getDstType());
if (!insn.is3D())
srcNum--;
- /* U, V, [W] */
- for (valueID = 0; valueID < srcNum; ++valueID)
- msgPayloads[valueID] = sel.selReg(insn.getSrc(valueID), insn.getSrcType());
+ if (insn.getSamplerOffset() != 0) {
+ // U, lod, V, [W]
+ GBE_ASSERT(insn.getSrcType() != TYPE_FLOAT);
+ msgPayloads[0] = sel.selReg(insn.getSrc(0), insn.getSrcType());
+ msgPayloads[1] = sel.selReg(sel.reg(FAMILY_DWORD), TYPE_U32);
+ msgPayloads[2] = sel.selReg(insn.getSrc(1), insn.getSrcType());
+ if (srcNum > 2)
+ msgPayloads[3] = sel.selReg(insn.getSrc(2), insn.getSrcType());
+ // Clear the lod to zero.
+ sel.MOV(msgPayloads[1], GenRegister::immud(0));
+ msgLen = srcNum + 1;
+ } else {
+ // U, V, [W]
+ GBE_ASSERT(insn.getSrcType() == TYPE_FLOAT);
+ for (valueID = 0; valueID < srcNum; ++valueID)
+ msgPayloads[valueID] = sel.selReg(insn.getSrc(valueID), insn.getSrcType());
+ msgLen = srcNum;
+ }
uint32_t bti = insn.getImageIndex();
- /* We have the clamp border workaround. */
- uint32_t sampler = insn.getSamplerIndex() + insn.getSamplerOffset() * 8;
+ uint32_t sampler = insn.getSamplerIndex();
- sel.SAMPLE(dst, insn.getDstNum(), msgPayloads, srcNum, bti, sampler, insn.is3D());
+ sel.SAMPLE(dst, insn.getDstNum(), msgPayloads, msgLen, bti, sampler, insn.getSamplerOffset());
return true;
}
DECL_CTOR(SampleInstruction, 1, 1);
case GEN_OCL_READ_IMAGE_I_3D:
case GEN_OCL_READ_IMAGE_UI_3D:
case GEN_OCL_READ_IMAGE_F_3D:
+ case GEN_OCL_READ_IMAGE_I_I:
+ case GEN_OCL_READ_IMAGE_UI_I:
+ case GEN_OCL_READ_IMAGE_F_I:
+ case GEN_OCL_READ_IMAGE_I_3D_I:
+ case GEN_OCL_READ_IMAGE_UI_3D_I:
+ case GEN_OCL_READ_IMAGE_F_3D_I:
{
// dst is a 4 elements vector. We allocate all 4 registers here.
uint32_t elemNum;
case GEN_OCL_READ_IMAGE_I_3D:
case GEN_OCL_READ_IMAGE_UI_3D:
case GEN_OCL_READ_IMAGE_F_3D:
+ case GEN_OCL_READ_IMAGE_I_I:
+ case GEN_OCL_READ_IMAGE_UI_I:
+ case GEN_OCL_READ_IMAGE_F_I:
+ case GEN_OCL_READ_IMAGE_I_3D_I:
+ case GEN_OCL_READ_IMAGE_UI_3D_I:
+ case GEN_OCL_READ_IMAGE_F_3D_I:
{
GBE_ASSERT(AI != AE); const ir::Register surfaceReg = this->getRegister(*AI); ++AI;
const uint8_t surfaceID = ctx.getFunction().getImageSet()->getIdx(surfaceReg);
GBE_ASSERT(AI != AE); const ir::Register vcoord = this->getRegister(*AI); ++AI;
ir::Register wcoord;
bool is3D = false;
- if (it->second >= GEN_OCL_READ_IMAGE_I_3D) {
+ if (it->second == GEN_OCL_READ_IMAGE_I_3D ||
+ it->second == GEN_OCL_READ_IMAGE_UI_3D ||
+ it->second == GEN_OCL_READ_IMAGE_F_3D ||
+ it->second == GEN_OCL_READ_IMAGE_I_3D_I ||
+ it->second == GEN_OCL_READ_IMAGE_UI_3D_I ||
+ it->second == GEN_OCL_READ_IMAGE_F_3D_I) {
GBE_ASSERT(AI != AE); wcoord = this->getRegister(*AI); ++AI;
is3D = true;
} else
case GEN_OCL_READ_IMAGE_UI:
case GEN_OCL_READ_IMAGE_I_3D:
case GEN_OCL_READ_IMAGE_UI_3D:
+ case GEN_OCL_READ_IMAGE_I_I:
+ case GEN_OCL_READ_IMAGE_UI_I:
+ case GEN_OCL_READ_IMAGE_I_3D_I:
+ case GEN_OCL_READ_IMAGE_UI_3D_I:
dstType = ir::TYPE_U32;
break;
case GEN_OCL_READ_IMAGE_F:
case GEN_OCL_READ_IMAGE_F_3D:
+ case GEN_OCL_READ_IMAGE_F_I:
+ case GEN_OCL_READ_IMAGE_F_3D_I:
dstType = ir::TYPE_FLOAT;
break;
default:
GBE_ASSERT(0); // never been here.
}
+ bool isFloatCoord = it->second <= GEN_OCL_READ_IMAGE_F_3D;
+
ctx.SAMPLE(surfaceID, dstTuple, srcTuple, dstType == ir::TYPE_FLOAT,
- true, sampler, samplerOffset, is3D);
+ isFloatCoord, sampler, samplerOffset, is3D);
break;
}
case GEN_OCL_WRITE_IMAGE_I:
/////////////////////////////////////////////////////////////////////////////
OVERLOADABLE int4 __gen_ocl_read_imagei(uint surface_id, sampler_t sampler, float u, float v, uint sampler_offset);
+OVERLOADABLE int4 __gen_ocl_read_imagei(uint surface_id, sampler_t sampler, int u, int v, uint sampler_offset);
OVERLOADABLE uint4 __gen_ocl_read_imageui(uint surface_id, sampler_t sampler, float u, float v, uint sampler_offset);
+OVERLOADABLE uint4 __gen_ocl_read_imageui(uint surface_id, sampler_t sampler, int u, int v, uint sampler_offset);
OVERLOADABLE float4 __gen_ocl_read_imagef(uint surface_id, sampler_t sampler, float u, float v, uint sampler_offset);
+OVERLOADABLE float4 __gen_ocl_read_imagef(uint surface_id, sampler_t sampler, int u, int v, uint sampler_offset);
OVERLOADABLE int4 __gen_ocl_read_imagei(uint surface_id, sampler_t sampler, float u, float v, float w, uint sampler_offset);
+OVERLOADABLE int4 __gen_ocl_read_imagei(uint surface_id, sampler_t sampler, int u, int v, int w, uint sampler_offset);
OVERLOADABLE uint4 __gen_ocl_read_imageui(uint surface_id, sampler_t sampler, float u, float v, float w, uint sampler_offset);
+OVERLOADABLE uint4 __gen_ocl_read_imageui(uint surface_id, sampler_t sampler, int u, int v, int w, uint sampler_offset);
OVERLOADABLE float4 __gen_ocl_read_imagef(uint surface_id, sampler_t sampler, float u, float v, float w, uint sampler_offset);
+OVERLOADABLE float4 __gen_ocl_read_imagef(uint surface_id, sampler_t sampler, int u, int v, int w, uint sampler_offset);
OVERLOADABLE void __gen_ocl_write_imagei(uint surface_id, int u, int v, int4 color);
OVERLOADABLE void __gen_ocl_write_imageui(uint surface_id, int u, int v, uint4 color);
#define GEN_FIX_1 0
#endif
-#define DECL_READ_IMAGE(float_coord_rounding_fix, int_clamping_fix, \
- image_type, type, suffix, coord_type) \
+#define DECL_READ_IMAGE0(int_clamping_fix, \
+ image_type, type, suffix, coord_type, n) \
+ INLINE_OVERLOADABLE type read_image ##suffix(image_type cl_image, \
+ const sampler_t sampler, \
+ coord_type coord) \
+ { \
+ GET_IMAGE(cl_image, surface_id); \
+ if (int_clamping_fix && \
+ ((sampler & __CLK_ADDRESS_MASK) == CLK_ADDRESS_CLAMP) && \
+ ((sampler & __CLK_FILTER_MASK) == CLK_FILTER_NEAREST)) \
+ return __gen_ocl_read_image ##suffix( \
+ EXPEND_READ_COORD(surface_id, sampler, coord), 1); \
+ return __gen_ocl_read_image ##suffix( \
+ EXPEND_READ_COORD(surface_id, sampler, (float)coord), 0);\
+ }
+
+#define DECL_READ_IMAGE1(float_coord_rounding_fix, int_clamping_fix, \
+ image_type, type, suffix, coord_type, n) \
INLINE_OVERLOADABLE type read_image ##suffix(image_type cl_image, \
const sampler_t sampler, \
coord_type coord) \
GET_IMAGE(cl_image, surface_id); \
coord_type tmpCoord = coord; \
if (float_coord_rounding_fix | int_clamping_fix) { \
- if (((sampler & __CLK_ADDRESS_MASK) == CLK_ADDRESS_CLAMP) \
- && ((sampler & __CLK_FILTER_MASK) == CLK_FILTER_NEAREST)) { \
+ if (((sampler & __CLK_ADDRESS_MASK) == CLK_ADDRESS_CLAMP) \
+ && ((sampler & __CLK_FILTER_MASK) == CLK_FILTER_NEAREST)) { \
if (float_coord_rounding_fix \
- && ((sampler & CLK_NORMALIZED_COORDS_TRUE) == 0)) { \
+ && ((sampler & CLK_NORMALIZED_COORDS_TRUE) == 0)) { \
FIXUP_FLOAT_COORD(tmpCoord); \
} \
if (int_clamping_fix) { \
- if (OUT_OF_BOX(tmpCoord, surface_id, \
- (sampler & CLK_NORMALIZED_COORDS_TRUE))) { \
- unsigned int border_alpha; \
- int order = __gen_ocl_get_image_channel_order(surface_id); \
- if (!CLK_HAS_ALPHA(order)) { \
- border_alpha = 1; \
+ coord_type intCoord; \
+ if (sampler & CLK_NORMALIZED_COORDS_TRUE) { \
+ DENORMALIZE_COORD(surface_id, intCoord, tmpCoord); \
} else \
- border_alpha = 0; \
- return (type)(0, 0, 0, border_alpha); \
- } else \
+ intCoord = tmpCoord; \
return __gen_ocl_read_image ##suffix( \
- EXPEND_READ_COORD(surface_id, sampler, tmpCoord), 1);\
+ EXPEND_READ_COORD1(surface_id, sampler, intCoord), 1);\
} \
} \
} \
EXPEND_READ_COORD(surface_id, sampler, tmpCoord), 0);\
}
-
-#define DECL_READ_IMAGE_NOSAMPLER(image_type, type, suffix, coord_type) \
+#define DECL_READ_IMAGE_NOSAMPLER(image_type, type, suffix, coord_type, n) \
INLINE_OVERLOADABLE type read_image ##suffix(image_type cl_image, \
coord_type coord) \
{ \
EXPEND_READ_COORD(surface_id, \
CLK_NORMALIZED_COORDS_FALSE \
| CLK_ADDRESS_NONE \
- | CLK_FILTER_NEAREST, coord), 0); \
+ | CLK_FILTER_NEAREST, (float)coord), 0); \
}
#define DECL_WRITE_IMAGE(image_type, type, suffix, coord_type) \
}
#define EXPEND_READ_COORD(id, sampler, coord) id, sampler, coord.s0, coord.s1
+#define EXPEND_READ_COORD1(id, sampler, coord) id, sampler, (int)(coord.s0 < 0 ? -1 : coord.s0), \
+ (int)(coord.s1 < 0 ? -1 : coord.s1)
+#define DENORMALIZE_COORD(id, dstCoord, srcCoord) dstCoord.x = srcCoord.x * __gen_ocl_get_image_width(id); \
+ dstCoord.y = srcCoord.y * __gen_ocl_get_image_height(id);
#define EXPEND_WRITE_COORD(id, coord, color) id, coord.s0, coord.s1, color
#define OUT_OF_BOX(coord, surface, normalized) \
tmpCoord.s1 += -0x1p-9f; \
}
-#define DECL_IMAGE(int_clamping_fix, image_type, type, suffix, n) \
- DECL_READ_IMAGE(0, int_clamping_fix, image_type, type, suffix, int ##n) \
- DECL_READ_IMAGE(GEN_FIX_1, int_clamping_fix, image_type, type, suffix, float ##n) \
- DECL_READ_IMAGE_NOSAMPLER(image_type, type, suffix, int ##n) \
- DECL_WRITE_IMAGE(image_type, type, suffix, int ## n) \
+#define DECL_IMAGE(int_clamping_fix, image_type, type, suffix, n) \
+ DECL_READ_IMAGE0(int_clamping_fix, image_type, type, suffix, int ##n, n) \
+ DECL_READ_IMAGE1(GEN_FIX_1, int_clamping_fix, image_type, type, suffix, float ##n, n) \
+ DECL_READ_IMAGE_NOSAMPLER(image_type, type, suffix, int ##n, n) \
+ DECL_WRITE_IMAGE(image_type, type, suffix, int ## n) \
DECL_WRITE_IMAGE(image_type, type, suffix, float ## n)
DECL_IMAGE(GEN_FIX_1, image2d_t, int4, i, 2)
DECL_IMAGE(0, image2d_t, float4, f, 2)
#undef EXPEND_READ_COORD
+#undef EXPEND_READ_COORD1
+#undef DENORMALIZE_COORD
#undef EXPEND_WRITE_COORD
#undef OUT_OF_BOX
#undef FIXUP_FLOAT_COORD
#define EXPEND_READ_COORD(id, sampler, coord) id, sampler, coord.s0, coord.s1, coord.s2
+#define EXPEND_READ_COORD1(id, sampler, coord) id, sampler, (int) (coord.s0 < 0 ? -1 : coord.s0), \
+ (int)(coord.s1 < 0 ? -1 : coord.s1), (int)(coord.s2 < 0 ? -1 : coord.s2)
+#define DENORMALIZE_COORD(id, dstCoord, srcCoord) dstCoord.x = srcCoord.x * __gen_ocl_get_image_width(id); \
+ dstCoord.y = srcCoord.y * __gen_ocl_get_image_height(id); \
+ dstCoord.z = srcCoord.z * __gen_ocl_get_image_depth(id);
#define EXPEND_WRITE_COORD(id, coord, color) id, coord.s0, coord.s1, coord.s2, color
#define OUT_OF_BOX(coord, surface, normalized) \
(coord.s0 < 0 || coord.s1 < 0 || coord.s2 < 0 || \
DECL_IMAGE(GEN_FIX_1, image3d_t, uint4, ui, 3)
DECL_IMAGE(0, image3d_t, float4, f, 3)
#undef EXPEND_READ_COORD
+#undef DENORMALIZE_COORD
#undef EXPEND_WRITE_COORD
#undef OUT_OF_BOX
#undef FIXUP_FLOAT_COORD