veldrid-spirv
veldrid-spirv copied to clipboard
Output reflection data with resource binding info?
Hello again! I'm just having a little look at this library. Does it already generate some sort of resource reflection data? I saw some code for iterating resources but I'm not sure if that was doing something different.
spirv-cross
has a nice --reflection
flag now. I assume the same thing is available when using the API - would you be interested in having it exposed by this library?
@tgjones Sorry that I didn't respond to this issue. We did chat about this briefly in gitter, and I'm definitely interested in exposing the sort of information that the --reflection
flag gives. As I said yesterday, I think it would be very useful to be able to directly get a ResourceLayoutDescription[]
with all of the elements properly filled in from a set of shaders. On top of that, it should also be possible to get finer-grained information, like the struct types used, and all of the field offsets, etc.
I came here looking for the same thing too. I'd vote this solution as better than the ShaderGen one anyday because this solves the "glue code" problem elegantly.
After looking into SPIR-V code standard and trying to use the reflection for a project I can contribute to the conversation.
Subset of SPIR-V byte codes useful for reflection is quite small. You can use native code to do that but it won't tell you any more useful information. I would recommend to stick with fully managed code for the parser. Each SPIR-V instruction has size embedded into byte code so it's trivial to skip unknown instructions. I bet that the byte code won't change much here with upcoming Vulkan 1.1.
So from the code you can get Uniforms and Uniform Constants. Textures and Samplers are passed as Uniform Constants and every thing else I've encountered are Uniforms. For our purpose it doesn't matter and both could be treated the same way.
Through OpDecorate command we can learn Set and Binding values for each uniform. This is very useful as we can detect what resources are actually used in what stages of the shader. This becomes critical for Direct3D 11 compatibility as we need to remap the uniforms to registers. As Pipeline includes both Shaders and ResourceLayout we can easily mark sets in the layout using the reflection data. This alone would be a great progress for the library.
Through optinal OpName command we can get name of the uniform (it's not that straight forward for uniform buffer with a structure but it's just one hop away in the type info). As this info isn't available we can use an external resolver to get a name by set, binding and kind. All it need is resource layout information. At the same time it can check that set inf binding are valid indices and ResourceKind match the one provided via reflection.
Overall it doesn't look like a big change to the API but it could be very useful. @mellinoe would you agree to give it a try?
@gleblebedev I recently added reflection info into the VertexFragmentCompilationResult class. You will now get a VertexElementDescription[]
array, and a ResourceLayoutDescription[] array, usable for creating ResourceLayouts and/or Pipelines. On top of that, the next version of Veldrid is going to include the "overrides" described in https://github.com/mellinoe/veldrid/issues/203. There will also be a new
ResourceLayoutElementOptions.Unused` flag so that you can specify resource slots that aren't used by a Pipeline, and can be filled with anything without breaking validation.
The implementation of this doesn't used a managed SPIR-V parser, and just piggy-backs onto the resource scanning that the native cross-compiler already has to do. You could write a managed SPIR-V parser and output the same information that Veldrid.SPIRV does, and use it to fill in the "Reflected" data in a PipelineDescription.
It looks like you've already implemented the feature so I have nothing to do :)