Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reflecting capabilities used by a shader more finely #222

Open
mbechard opened this issue Sep 8, 2023 · 8 comments · May be fixed by #224
Open

Reflecting capabilities used by a shader more finely #222

mbechard opened this issue Sep 8, 2023 · 8 comments · May be fixed by #224
Assignees

Comments

@mbechard
Copy link

mbechard commented Sep 8, 2023

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 in VkPhysicalDeviceShaderAtomicFloatFeaturesEXT. For example on macOS shaderImageFloat32AtomicAdd 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?

@spencer-lunarg
Copy link
Contributor

#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

@mbechard
Copy link
Author

mbechard commented Sep 8, 2023

That would be amazing. A related request is this:
#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.

@spencer-lunarg spencer-lunarg linked a pull request Sep 16, 2023 that will close this issue
@spencer-lunarg
Copy link
Contributor

@mbechard I have an implementation of this in #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

@mbechard
Copy link
Author

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

@spencer-lunarg
Copy link
Contributor

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

@chaoticbob
Copy link
Contributor

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.

@spencer-lunarg
Copy link
Contributor

spencer-lunarg commented Nov 21, 2023

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)

@mbechard
Copy link
Author

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants