cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

silverlan
Adept I

Vulkan - "Initialization failed" in 'createGraphicsPipelines' when using certain output block locations

I have been able to replicate this problem on three different AMD GPUs (on different PCs). (1 from the R9 200 series, 1 from the R9 300 series and 1 from the R5 series.)

The problem does not occur on Nvidia GPUs and seems to be a driver bug.

I'm on the latest AMD drivers, 16.30.2311-160718a-305076C.

To replicate the issue, I've created a minimal adaptation of the cube demo from the Vulkan SDK. The full program is attached to this post.

The only changes I've made to the demo are the shaders, "cube.vert", and "cube.frag", and their respective .spv-files, no other files have been modified.

Here are the changes for the shader stages:

Vertex Shader: [OpenGL Shading] AMD location bug - GLSL Cube Vertex Shader - Pastebin.com

Fragment Shader: [OpenGL Shading] AMD location bug - GLSL Cube Fragment Shader - Pastebin.com

All the changes I've made from the original shaders are within the "/* Changed shader code block */" blocks. The interesting part is inside the vertex shader.

At line 44, there's an output block at location 5:

layout(location = 5) out LightData vs_light_out[8];

The block is accessed at line 57:

vs_light_out[0].light_dir_cs = vec3(0,gl_Position.x,gl_Position.y);

This line is what causes the crash. Without it, no crash occurs. This only happens if the location of the output block is >= 5, no crash happens if the location is lower than that.

Strangely enough, there is also no crash if some larger locations are used (e.g. 40), which shouldn't work in the first place.

According to the Vulkan specification, the maximum number of output locations you can have in a vertex shader is "maxVertexOutputComponents / 4" and the maximum input locations for a fragment shader is "maxFragmentInputComponents / 4".

The maximum vertex output and fragment input component number for my GPU is 128, so I should have 32 locations available.

This is what the Vulkan specification says about location consumption:

Inputs and outputs of the following types consume a single interface location:

32-bit scalar and vector types, and

64-bit scalar and 2-component vector types.

64-bit three- and four-component vectors consume two consecutive locations.

If a declared input or output is an array of size n and each element takes m locations, it will be assigned m × n consecutive locations starting with the location specified.

The "LightData" structure from the shader code has 3 vector-members:

struct LightData {    

    vec3 light_dir_cs; // Light direction in camera space    

    vec3 light_dir_ts; // Light direction in tangent space    

    vec4 vert_pos_ls; // Vertex Position in light space

};

That means the entire block should consume 8 *3 = 24 locations. If we add the location origin (5) to that, we end up at 29, which is still well within the limits.

0 Likes
1 Solution

We've just finished addressing this report internally. A fix is going to be included in one of the upcoming driver releases.

In the meantime, please consider using the latest glslang build (the one included in the latest SDK will be just fine). The SPIR-V blob you posted uses incorrect input/output locations for arrays of structures, which is a known glslang issue, and which has been recently addressed.

View solution in original post

9 Replies
dwitczak
Staff

Thanks for reporting this issue. I'm going to have a closer look at this sometime this week. Will get back to you as soon as I have more info to share.

0 Likes

Thank you, have you had a chance to take a look at it yet?

0 Likes

Apologies, I haven't had time to investigate this yet. I'll do my best to check the repro you prepared before EoW.

0 Likes

This indeed looks like a potential driver issue; will pass it down to the relevant team. Thank you very much for your contribution!

Any news on this? Is there an eta on when it will be fixed?

0 Likes

We've just finished addressing this report internally. A fix is going to be included in one of the upcoming driver releases.

In the meantime, please consider using the latest glslang build (the one included in the latest SDK will be just fine). The SPIR-V blob you posted uses incorrect input/output locations for arrays of structures, which is a known glslang issue, and which has been recently addressed.

I've updated to the latest driver version (16.40.2311-160916a-307329C, Vulkan Driver 1.3.0), which seems to have fixed the issue.

The program I've attached in my first post works with the new drivers, there's still a problem remaining, however:

If I run the shaders through the glslang-tool from the latest Vulkan SDK (1.0.26), and try to run the program with them, it crashes again. (VK_ERROR_INITIALIZATION_FAILED at vkCreateGraphicsPipelines, same as before.)

I haven't changed the actual shader code, it's just a newer version of the glslang-tool. (I've attached the SPIR-V shader files to this post, I haven't changed anything else on the test-project.)

I can get it to work by lowering the array size for the light-data array:

Vertex Shader:

// layout(location = 5) out LightData vs_light_out[8]; // Old (Results in crash)

layout(location = 5) out LightData vs_light_out[7]; // New (Works)

Fragment Shader:

// layout(location = 5) in LightData vs_light_out[8]; // Old (Results in crash)

layout(location = 5) in LightData vs_light_out[7]; // New (Works)

However even with an array size of 8, it should still be within the limits.

0 Likes

Can you try checking if the problem persists if you use the latest version of glslang, as built manually from the project's master branch? GitHub - KhronosGroup/glslang: Khronos reference front-end for GLSL and ESSL, and sample SPIR-V gene...

0 Likes

I just tried the latest GitHub-version, the issue remains. The generated .spv-files aren't any different from the ones I've added in my previous post.

0 Likes