The OpenCL image_width/height/depth functions have variants which can
take an LOD parameter. More importantly, LLVM-SPIRV-Translator always
generates OpImageQuerySizeLod even if the LOD is guaranteed to be zero.
Given that over half the hardware out there has an LOD field for image
size queries (based on a rudimentary scan through their NIR -> whatever
code), we may as well just add the source to the NIR intrinsic. If this
is ever a problem for anyone, the lowering is pretty trivial.
I've also added asserts to everyone's drivers that should alert them if
they ever see an LOD other than zero. This will never happen with GL or
Vulkan so there's no need for panic.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6396>
+ assert(nir_src_as_uint(instr->src[1]) == 0);
Temp lod = bld.vop1(aco_opcode::v_mov_b32, bld.def(v1), Operand(0u));
/* Resource */
Temp lod = bld.vop1(aco_opcode::v_mov_b32, bld.def(v1), Operand(0u));
/* Resource */
args.dmask = 0xf;
args.resource = get_image_descriptor(ctx, instr, dynamic_index, AC_DESC_IMAGE, false);
args.opcode = ac_image_get_resinfo;
args.dmask = 0xf;
args.resource = get_image_descriptor(ctx, instr, dynamic_index, AC_DESC_IMAGE, false);
args.opcode = ac_image_get_resinfo;
+ assert(nir_src_as_uint(instr->src[1]) == 0);
args.lod = ctx->ac.i32_0;
args.attributes = AC_FUNC_ATTR_READNONE;
args.lod = ctx->ac.i32_0;
args.attributes = AC_FUNC_ATTR_READNONE;
unsigned image_index = nir_src_as_uint(instr->src[0]);
bool is_array = nir_intrinsic_image_array(instr);
unsigned image_index = nir_src_as_uint(instr->src[0]);
bool is_array = nir_intrinsic_image_array(instr);
+ assert(nir_src_as_uint(instr->src[1]) == 0);
+
ntq_store_dest(c, &instr->dest, 0,
vir_uniform(c, QUNIFORM_IMAGE_WIDTH, image_index));
if (instr->num_components > 1) {
ntq_store_dest(c, &instr->dest, 0,
vir_uniform(c, QUNIFORM_IMAGE_WIDTH, image_index));
if (instr->num_components > 1) {
if (op == nir_intrinsic_image_deref_size ||
op == nir_intrinsic_image_deref_samples) {
if (op == nir_intrinsic_image_deref_size ||
op == nir_intrinsic_image_deref_samples) {
+ /* image_deref_size takes an LOD parameter which is always 0
+ * coming from GLSL.
+ */
+ if (op == nir_intrinsic_image_deref_size)
+ instr->src[1] = nir_src_for_ssa(nir_imm_int(&b, 0));
nir_builder_instr_insert(&b, &instr->instr);
break;
}
nir_builder_instr_insert(&b, &instr->instr);
break;
}
image("atomic_exchange", src_comp=[4, 1, 1], dest_comp=1)
image("atomic_comp_swap", src_comp=[4, 1, 1, 1], dest_comp=1)
image("atomic_fadd", src_comp=[4, 1, 1], dest_comp=1)
image("atomic_exchange", src_comp=[4, 1, 1], dest_comp=1)
image("atomic_comp_swap", src_comp=[4, 1, 1, 1], dest_comp=1)
image("atomic_fadd", src_comp=[4, 1, 1], dest_comp=1)
-image("size", dest_comp=0, flags=[CAN_ELIMINATE, CAN_REORDER])
+image("size", dest_comp=0, src_comp=[1], flags=[CAN_ELIMINATE, CAN_REORDER])
image("samples", dest_comp=1, flags=[CAN_ELIMINATE, CAN_REORDER])
image("atomic_inc_wrap", src_comp=[4, 1, 1], dest_comp=1)
image("atomic_dec_wrap", src_comp=[4, 1, 1], dest_comp=1)
image("samples", dest_comp=1, flags=[CAN_ELIMINATE, CAN_REORDER])
image("atomic_inc_wrap", src_comp=[4, 1, 1], dest_comp=1)
image("atomic_dec_wrap", src_comp=[4, 1, 1], dest_comp=1)
intrin->src[0] = nir_src_for_ssa(&image.image->dest.ssa);
intrin->src[0] = nir_src_for_ssa(&image.image->dest.ssa);
- /* ImageQuerySize doesn't take any extra parameters */
- if (opcode != SpvOpImageQuerySize) {
+ if (opcode == SpvOpImageQuerySize) {
+ /* ImageQuerySize only has an LOD which is currently always 0 */
+ intrin->src[1] = nir_src_for_ssa(nir_imm_int(&b->nb, 0));
+ } else {
/* The image coordinate is always 4 components but we may not have that
* many. Swizzle to compensate.
*/
/* The image coordinate is always 4 components but we may not have that
* many. Swizzle to compensate.
*/
TYPE_U16 : TYPE_U32;
info.flags |= flags;
TYPE_U16 : TYPE_U32;
info.flags |= flags;
+ assert(nir_src_as_uint(intr->src[1]) == 0);
lod = create_immed(b, 0);
sam = emit_sam(ctx, OPC_GETSIZE, info, dst_type, 0b1111, lod, NULL);
lod = create_immed(b, 0);
sam = emit_sam(ctx, OPC_GETSIZE, info, dst_type, 0b1111, lod, NULL);
break;
case nir_intrinsic_bindless_image_size:
case nir_intrinsic_image_size:
break;
case nir_intrinsic_bindless_image_size:
case nir_intrinsic_image_size:
+ assert(nir_src_as_uint(insn->src[1]) == 0);
ty = TYPE_U32;
bindless = op == nir_intrinsic_bindless_image_size;
break;
ty = TYPE_U32;
bindless = op == nir_intrinsic_bindless_image_size;
break;
GPRVector dest = vec_from_nir(intrin->dest, nir_dest_num_components(intrin->dest));
GPRVector src{0,{4,4,4,4}};
GPRVector dest = vec_from_nir(intrin->dest, nir_dest_num_components(intrin->dest));
GPRVector src{0,{4,4,4,4}};
+ assert(nir_src_as_uint(intrin->src[1]) == 0);
+
auto const_offset = nir_src_as_const_value(intrin->src[0]);
auto dyn_offset = PValue();
int res_id = R600_IMAGE_REAL_RESOURCE_OFFSET;
auto const_offset = nir_src_as_const_value(intrin->src[0]);
auto dyn_offset = PValue();
int res_id = R600_IMAGE_REAL_RESOURCE_OFFSET;
BRW_REGISTER_TYPE_UD);
image = bld.emit_uniformize(image);
BRW_REGISTER_TYPE_UD);
image = bld.emit_uniformize(image);
+ assert(nir_src_as_uint(instr->src[1]) == 0);
+
fs_reg srcs[TEX_LOGICAL_NUM_SRCS];
if (instr->intrinsic == nir_intrinsic_image_size)
srcs[TEX_LOGICAL_SRC_SURFACE] = image;
fs_reg srcs[TEX_LOGICAL_NUM_SRCS];
if (instr->intrinsic == nir_intrinsic_image_size)
srcs[TEX_LOGICAL_SRC_SURFACE] = image;
if (isl_has_matching_typed_storage_image_format(devinfo, image_fmt))
return false;
if (isl_has_matching_typed_storage_image_format(devinfo, image_fmt))
return false;
+ assert(nir_src_as_uint(intrin->src[1]) == 0);
+
b->cursor = nir_instr_remove(&intrin->instr);
nir_ssa_def *size = load_image_param(b, deref, SIZE);
b->cursor = nir_instr_remove(&intrin->instr);
nir_ssa_def *size = load_image_param(b, deref, SIZE);