mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-15 00:11:06 +00:00
2eff420d9a
This was straightforward to implement in GLSL. The `ShadingRateInterlockOrderedEXT` and `ShadingRateInterlockUnorderedEXT` modes aren't implemented yet, because we don't support `SPV_NV_shading_rate` or `SPV_EXT_fragment_invocation_density` yet. HLSL and MSL were more interesting. They don't support this directly, but they do support marking resources as "rasterizer ordered," which does roughly the same thing. So this implementation scans all accesses inside the critical section and marks all storage resources found therein as rasterizer ordered. They also don't support the fine-grained controls on pixel- vs. sample-level interlock and disabling ordering guarantees that GLSL and SPIR-V do, but that's OK. "Unordered" here merely means the order is undefined; that it just so happens to be the same as rasterizer order is immaterial. As for pixel- vs. sample-level interlock, Vulkan explicitly states: > With sample shading enabled, [the `PixelInterlockOrderedEXT` and > `PixelInterlockUnorderedEXT`] execution modes are treated like > `SampleInterlockOrderedEXT` or `SampleInterlockUnorderedEXT` > respectively. and: > If [the `SampleInterlockOrderedEXT` or `SampleInterlockUnorderedEXT`] > execution modes are used in single-sample mode they are treated like > `PixelInterlockOrderedEXT` or `PixelInterlockUnorderedEXT` > respectively. So this will DTRT for MoltenVK and gfx-rs, at least. MSL additionally supports multiple raster order groups; resources that are not accessed together can be placed in different ROGs to allow them to be synchronized separately. A more sophisticated analysis might be able to place resources optimally, but that's outside the scope of this change. For now, we assign all resources to group 0, which should do for our purposes. `glslang` doesn't support the `RasterizerOrdered` UAVs this implementation produces for HLSL, so the test case needs `fxc.exe`. It also insists on GLSL 4.50 for `GL_ARB_fragment_shader_interlock`, even though the spec says it needs either 4.20 or `GL_ARB_shader_image_load_store`; and it doesn't support the `GL_NV_fragment_shader_interlock` extension at all. So I haven't been able to test those code paths. Fixes #1002.
37 lines
855 B
GLSL
37 lines
855 B
GLSL
#version 450
|
|
#extension GL_ARB_fragment_shader_interlock : require
|
|
|
|
layout(pixel_interlock_ordered) in;
|
|
|
|
layout(binding = 0, rgba8) uniform writeonly image2D img;
|
|
layout(binding = 1, r32ui) uniform uimage2D img2;
|
|
layout(binding = 2, rgba8) uniform readonly image2D img3;
|
|
layout(binding = 3) coherent buffer Buffer
|
|
{
|
|
int foo;
|
|
uint bar;
|
|
};
|
|
layout(binding = 4) buffer Buffer2
|
|
{
|
|
uint quux;
|
|
};
|
|
|
|
layout(binding = 5, rgba8) uniform writeonly image2D img4;
|
|
layout(binding = 6) buffer Buffer3
|
|
{
|
|
int baz;
|
|
};
|
|
|
|
void main()
|
|
{
|
|
// Deliberately outside the critical section to test usage tracking.
|
|
baz = 0;
|
|
imageStore(img4, ivec2(1, 1), vec4(1.0, 0.0, 0.0, 1.0));
|
|
beginInvocationInterlockARB();
|
|
imageStore(img, ivec2(0, 0), imageLoad(img3, ivec2(0, 0)));
|
|
imageAtomicAdd(img2, ivec2(0, 0), 1u);
|
|
foo += 42;
|
|
atomicAnd(bar, quux);
|
|
endInvocationInterlockARB();
|
|
}
|