Open mbechard opened 1 year ago
#version 450
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable
#extension GL_EXT_shader_image_int64 : enable
layout(set = 0, binding = 0) buffer ssbo { uint64_t y; };
layout(set = 0, binding = 1, r64ui) uniform u64image2D z;
void main() {
y = imageAtomicAdd(z, ivec2(1, 1), y);
}
will currently show
accessed: 1
but I can see how having a "type of access" flag to list if it was atomic could be helpful
Seems like something I could take a crack at
That would be amazing. A related request is this: https://github.com/KhronosGroup/SPIRV-Reflect/issues/99 where it would be useful to know if the resource is used via a read and/or a write operation. This would allow more finely controlling the VkAccessFlags used on the resource before it's used.
@mbechard I have an implementation of this in https://github.com/KhronosGroup/SPIRV-Reflect/pull/224 (which I still need to invest more time before I feel comfortable merging it)
I would love feedback on it if you think it works as expected for your use case
Thanks! This looks great. Seems to work with a simple test case. Offhand I would expect the READ/WRITE flags to also be set when ATOMIC is set though. It allows for logic that is just looking if a resource is read or written to handle those flags regardless of if the operation happens to be atomic or not
I would expect the READ/WRITE flags to also be set when ATOMIC is set though
I wasn't 100% if it made sense to have it do that or not... I think you are right and would be easier to just have to check for READ
then READ or ATOMIC
I finally had some time to look at #224 .
I wanted to get a better understanding of what the purpose of the READ/WRITE flags are?
If the the READ/WRITE flag is to indicate if a descriptor binding is READ_ONLY or READ_WRITE, then having SPV_REFLECT_RESOURCE_FLAG_UAV
set on SpvReflectDescriptorBinding::resource_type
will indicate that it's READ_WRITE - otherwise is is READ_ONLY.
something else worth noting from my PR, something like
%ac = OpAccessChain %ptr %index
%14 = OpArrayLength %uint %ac 1
I am not sure if this is actually a "read" (seems it isn't from the spec) but currently this is marked as "accessed"
edit: this is a bug, OpArrayLength
is an access (https://gitlab.khronos.org/vulkan/vulkan/-/issues/3682)
@chaoticbob The purpose is to determine how a resource is actually used in the shader, rather than just using how it's declared. There may be code that writes to a READ_WRITE resource, however due to optimization it ends up getting removed in one compilation, thus the resource is only actually READ, and code that is using reflection to determine synchronization can optimize based on that more refined knowledge.
If I'm given an arbitrary shader and I want to see if it runs on the local hardware, I can use reflection to see if any capabilities are being requested that the hardware doesn't support. However this isn't quite fine grained enough in many cases. For example if SpvCapabilityAtomicFloat32AddEXT is declared, I can see if
VK_EXT_shader_atomic_float
is supported as a first check. However the hardware may support atomic float operations on some data types and not others, as per the entries inVkPhysicalDeviceShaderAtomicFloatFeaturesEXT
. For example on macOSshaderImageFloat32AtomicAdd
is not currently supported.Is there any path forward where we can see what kinds of operations are applied to data, such as flags on a reflected image descriptor saying it was used for an atomic float operation?