Alignment error compiling HLSL to SPIR-V. #334
-
I am a long-time programmer, mostly back-end-stuff, but new to Vulkan and Diligent. I created a fairly simple app to generate and dispaly a Fibonacci Sphere with a compute shader, and it worked fine. Now, I am trying something more ambitious.
This shader has multiple entry points. When I invoke CreateShader, I get an error about structure alignment:
The ShaderCreateInfo is configured as follows:
And the problem structure is:
I have no idea how this manages to violate SPIR-V alignment rules, and even less idea why the offset of member 1 would be 20, as opposed to 31. Can anybody explain this to me? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
First of all, in this line: shaderCI.Desc.Name = (std::string("Shader CS - ") + entryPoints[stageIdx]).c_str(); You create a temporary string on stack, which is immediately destroyed, so As to the topic, this appears to be an issue in GLSLang - it generates the code that does not pass validation by SPIRV-Tools. struct Bad {
float3 f3;
float4 f4;
}; As the shader will add padding between f3 and f4. Also, never use Going back to your question, try struct Cell {
uint4 ids[2]; // Store up to 8 different IDs per cell
uint4 count; // Number IDs in this cell
}; If the problem was indeed in this struct, this most likely should fix it. |
Beta Was this translation helpful? Give feedback.
-
Thanks very much for your reply. The automatic-scope string is SMH; thanks for pointing it out. The information about alignment is gold!
…On Tuesday, March 25th, 2025 at 7:00 PM, Assiduous ***@***.***> wrote:
First of all, in this line:
shaderCI.Desc.Name = (std::string(
"
Shader CS -
"
) + entryPoints[stageIdx]).c_str();
You create a temporary string on stack, which is immediately destroyed, so shaderCI.Desc.Name is a pointer to dead memory.
Note that Core Diligent API is c-compatible, so shaderCI.Desc.Name is a pointer, not std::string
There is GraphicsTypesX.hpp header that contains C++ wrappers, which are easier and safer to use.
As to the topic, this appears to be an issue in GLSLang - it generates the code that does not pass validation by SPIRV-Tools.
Note that indexing in Shaders can only be done on 4-vectors (e.g. float4, uint4). As a rule of thumb, always align you struct members by 4-vectors to avoid hard-to-debug problems caused by mismatch between CPU and GPU layouts.
For example, struct like this will cause a lot of pain:
struct
Bad
{
float3 f3;
float4 f4;
};
As the shader will add padding between f3 and f4. Also, never use float3 in constant buffers.
Going back to your question, try
struct
Cell
{
uint4 ids[
2
];
//
Store up to 8 different IDs per cell
uint4 count;
//
Number IDs in this cell
};
If the problem was indeed in this struct, this most likely should fix it.
—
Reply to this email directly, [view it on GitHub](#334 (comment)), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AG7INTF6RAOPEG6KXITXCPT2WHUYVAVCNFSM6AAAAABZY5BWGWVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTENRSGE2TAMI).
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Did you manage to fix the shader issue? |
Beta Was this translation helpful? Give feedback.
First of all, in this line:
shaderCI.Desc.Name = (std::string("Shader CS - ") + entryPoints[stageIdx]).c_str();
You create a temporary string on stack, which is immediately destroyed, so
shaderCI.Desc.Name
is a pointer to dead memory.Note that Core Diligent API is c-compatible, so
shaderCI.Desc.Name
is a pointer, notstd::string
There is
GraphicsTypesX.hpp
header that contains C++ wrappers, which are easier and safer to use.As to the topic, this appears to be an issue in GLSLang - it generates the code that does not pass validation by SPIRV-Tools.
Note that indexing in Shaders can only be done on 4-vectors (e.g.
float4
,uint4
). As a rule of thumb, always align you struct members by 4-ve…