KhronosGroup / glslang

Khronos-reference front end for GLSL/ESSL, partial front end for HLSL, and a SPIR-V generator.
Other
2.98k stars 823 forks source link

Problems with Hull Shader and Patch Constant Function in 1.2.141.2 #2269

Open dmaluev opened 4 years ago

dmaluev commented 4 years ago

I’ve moved to Vulkan SDK 1.2.141.2 to try out fixes in tessellation shaders (array flattening or something like that). My tessellation shaders are working fine in my D3D12 renderer, but there are problems running them in Vulkan (nothing is drawn). I’m using PN Triangles Tessellation method similar to this one: http://ogldev.atspace.co.uk/www/tutorial31/tutorial31.html

1) If I set disableOptimizer to true in glslang::SpvOptions, then vkCreateGraphicsPipelines with tessellation will crash in nvoglv64.dll, showing Access violation writing location 0x00007FF8E0321DC9.

2) There is a problem with patch constant function, implemented as a barrier + if(gl_InvocationID == 0) in Vulkan. I have this line of pseudocode in Hull Shader: oppositeEdgeTessFactor = (normal.z < -0.75) ? 0.0 : max(1.0, oppositeEdgeTessFactor * (1.0 - abs(normal.z * 0.75))). And nothing similar in patch constant function. When I decompile this shader in RenderDoc to GLSL I can see this: float _someNumber = (_1239.z < (-0.75)) ? … * (1.0 - abs(_someNumber.z * 0.75))); copied 1 time before barrier() and 3 times inside if(gl_InvocationID == 0) block (for every vertex, I assume). Why is it doing this? This is already calculated in Hull shader’s part, this should not be calculated again inside patch constant function’s if block, it’s just wasting GPU cycles. I can see some result drawn by changing patch constant function, so that it just sets some tessFactors and doesn’t send any output to domain shader (previously it was computing b111 center bezier control point). I think there is a problem with synchronization. I see that the code gets copied and shuffled from one side of barrier() to the other. Hull Shader and patch constant function should be treated as 2 different shaders without optimizations across barrier() call.

arcady-lunarg commented 1 year ago

Could you attach a full shader that reproduces the issue you're seeing? Code moving around a barrier doesn't seem ideal. Regarding your first point, if you are compiling HLSL with glslangValidator, it actually doesn't guarantee valid SPIR-V when optimization is disabled as it relies on an optimization pass to "legalize" the SPIR-V it produces.