bool high = uniform.value >= 256;
switch (op) {
+ case AGX_OPCODE_IMAGE_LOAD:
case AGX_OPCODE_TEXTURE_LOAD:
case AGX_OPCODE_TEXTURE_SAMPLE:
return src_index != 1 && src_index != 2;
encoding_32 = (0x31, 0x7F, 8, 10), # XXX WRONG SIZE
srcs = 6, imms = [DIM, LOD_MODE, MASK, SCOREBOARD, OFFSET, SHADOW,
GATHER])
-op("texture_load",
- encoding_32 = (0x71, 0x7F, 8, 10), # XXX WRONG SIZE
- srcs = 6, imms = [DIM, LOD_MODE, MASK, SCOREBOARD, OFFSET])
+for memory, can_reorder in [("texture", True), ("image", False)]:
+ op(f"{memory}_load", encoding_32 = (0x71, 0x7F, 8, 10), # XXX WRONG SIZE
+ srcs = 6, imms = [DIM, LOD_MODE, MASK, SCOREBOARD, OFFSET],
+ can_reorder = can_reorder)
# sources are base, index
op("device_load",
/* Inline immediates if we can. TODO: systematic */
if (I->op != AGX_OPCODE_ST_VARY && I->op != AGX_OPCODE_COLLECT &&
I->op != AGX_OPCODE_TEXTURE_SAMPLE &&
- I->op != AGX_OPCODE_TEXTURE_LOAD &&
+ I->op != AGX_OPCODE_IMAGE_LOAD && I->op != AGX_OPCODE_TEXTURE_LOAD &&
I->op != AGX_OPCODE_UNIFORM_STORE &&
I->op != AGX_OPCODE_BLOCK_IMAGE_STORE)
agx_optimizer_inline_imm(defs, I, info.nr_srcs, info.is_float);
}
case AGX_OPCODE_TEXTURE_LOAD:
+ case AGX_OPCODE_IMAGE_LOAD:
case AGX_OPCODE_TEXTURE_SAMPLE: {
assert(I->mask != 0);
assert(I->format <= 0x10);
unsigned q3 = 12; // XXX
unsigned kill = 0; // helper invocation kill bit
+ /* Set bit 43 for image loads. This seems to makes sure that image loads
+ * get the value written by the latest image store, not some other image
+ * store that was already in flight, fixing
+ *
+ * KHR-GLES31.core.shader_image_load_store.basic-glsl-misc-fs
+ *
+ * Apple seems to set this bit unconditionally for read/write image loads
+ * and never for readonly image loads. Some sort of cache control.
+ */
+ if (I->op == AGX_OPCODE_IMAGE_LOAD)
+ q3 |= 1;
+
uint32_t extend = ((U & BITFIELD_MASK(5)) << 0) | (kill << 5) |
((I->dim >> 3) << 7) | ((R >> 6) << 8) |
((C >> 6) << 10) | ((D >> 6) << 12) | ((T >> 6) << 14) |
bool L = (extend != 0);
uint64_t raw =
- 0x31 | ((I->op == AGX_OPCODE_TEXTURE_LOAD) ? (1 << 6) : 0) |
+ 0x31 | ((I->op != AGX_OPCODE_TEXTURE_SAMPLE) ? (1 << 6) : 0) |
(Rt ? (1 << 8) : 0) | ((R & BITFIELD_MASK(6)) << 9) |
(L ? (1 << 15) : 0) | ((C & BITFIELD_MASK(6)) << 16) |
(Ct ? (1 << 22) : 0) | (q1 << 23) | ((D & BITFIELD_MASK(6)) << 24) |
assert(1 <= I->channels && I->channels <= 4);
return I->channels * size;
+ case AGX_OPCODE_IMAGE_LOAD:
case AGX_OPCODE_TEXTURE_LOAD:
case AGX_OPCODE_TEXTURE_SAMPLE:
/* Even when masked out, these clobber 4 registers */
else
return size;
+ case AGX_OPCODE_IMAGE_LOAD:
case AGX_OPCODE_TEXTURE_LOAD:
case AGX_OPCODE_TEXTURE_SAMPLE:
if (s == 0) {