Is there some secret sauce to binding SRVs to StructuredBuffer parameters in vertex shaders on non-bindless platforms?
Say I have a parameter declared in LocalVertexFactory.ush as:
StructuredBuffer<Foo> FooBuffer;
In my corresponding FVertexFactoryShaderParameters in C++ I have
LAYOUT_FIELD(FShaderResourceParameter, FooBuffer)
…
FooBuffer.Bind(ParameterMap, TEXT("FooBuffer"));
…
ShaderBindings.Add(FooBuffer, GetFooBufferSRV());
in the appropriate places, where GetFooBufferSRV provides a FRHIShaderResourceView*. In the shader itself, FooBuffer is then accessed as an array of Foo objects. This totally works on all our platforms but one, the only difference being that the standout platform does not support bindless rendering.
As far as I’ve been able to trace this so far, I think what’s happening is that the shader compiler type reflection is interpreting the StructuredBuffer declaration in the shader as a uniform buffer, rather than an SRV. The ShaderBindings.Add call then silently goes wrong because it calls WriteBindingSRV instead of WriteBindingUniformBuffer, looking up some other buffer in the SRV array that happens to match BaseIndex. The vertex shader then executes with the StructuredBuffer parameter unbound. I have confirmed that on d3d12 on pc, the same parameter in the parameter map has the type “SRV” instead of “UniformBuffer”.
The weird thing is that the equivalent pattern does work totally fine on the same platform in our compute shaders. Only the vertex shader is going wrong here. What am I missing?
Answering my own question:
I was able to trace the issue and confirm my suspicion. Using r.DumpShaderDebugInfo=1, I noted that the StructuredBuffer parameter was being identified, correctly, as an SSBO. I then found where SSBOs are processed in the platform specific shader compiler code, and noted that this code was calling HandleReflectedUniformBuffer for these types, which seems inconsistent with other platforms (for example the D3D_SIT_STRUCTURED case for d3d). By changing this code to instead call HandleReflectedShaderResource, my shader code now runs properly on all our platforms, and I don’t observe ill effect in any other rendering systems we use.
Interesting, would you be able to share with us what platform / RHI this issue occurs for? It may be an engine bug, in which case I will need to create a bug report for this.
Regards,
Lance Chaney
Sure, but it’s an under-NDA platform, hence the vagueness. I just wasn’t sure it was a platform-specific issue at the time. Can I just specify the platform here or would you rather email me?
Two options,
Either you can make the case confidential, or you can email through the extra information to us at [Content removed]
If you mention the NDA platform here, the case will probably go to moderation and might end marked confidential anyway.
I imagine you probably don’t want to waste your confidential case quota on something you have already resolved. So sending it through to our emails is probably the best.
Regards,
Lance Chaney
Hi again,
Sorry for the delay, I was away sick. Since we don’t have dev kits for this platform in house yet, I’m going to re-assign this case back to Epic to check and create the bug report if needed. To better facilitate this, it would be good if we could get either a set of very clear reproduction steps that can be followed step-by-step to reproduce the issue in a blank project / clean engine. Or, ideally, a reproduction project so that the team at Epic can just open this, package for the platform, and immediately see the issue.
Regards,
Lance Chaney