I am trying to cross compile a Vulkan project from windows to linux, this works, only the vertex shader causes a problem on windows though it works perfectly fine on Linux... (Note that the code and validations work on windows if I do not try to add the shader stage to the graphics pipeline, obviously there is nothing being rendered.)
The compiler on linux (cross compiler for windows is: x86_64-w64-mingw32-gcc, which is not the same as mingw). In order to link Vulkan properly I downloaded the windows library including it in the project in the standard fashion.
The error I get (triggered upon calling vkCreateShaderModule, the VkResult is then VK_ERROR_VALIDATION_FAILED_EXT):
message: Validation Error: [ UNASSIGNED-CoreValidation-Shader-InconsistentSpirv ] Object 0: handle = 0x1a4c760cf78, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x6bbb14 | SPIR-V module not valid: Error: Result Id is 0
The vertex shader:
#version 460
layout(location = 0) in vec3 in_position;
void main() {
gl_Position = vec4(in_position.xyz, 1.0);
}
I tried compiling the shader with different versions (pretty much tried all viable glsl versions), but no luck. The shaders are compiled as follows (glslc was included in the VulkanSDK):
glslc shader.vert -o vert.spv
Note that if I try this exact same thing for the fragment shader, it works fine, I include the fragment shader for the sake of completeness:
#version 460
layout(location = 0) out vec4 out_color;
void main() {
out_color = vec4(0.0, 0.0, 1.0, 1.0);
}
I once again want to emphasize that when compiling for linux and running it there everything works just fine (I even get a triangle to pop up).
How I load the shader:
fseek(file, 0, SEEK_END);
shader->code_size = ftell(file);
uint8_t* code = (uint8_t*) calloc(shader->code_size, sizeof(uint8_t));
fseek(file, 0, SEEK_SET);
fread(code, 1, shader->code_size, file);
shader->code = code;
where file is a valid FILE pointer from stdio.h and shader is a wrapper around VkPipelineShaderStageCreateInfo which looks as follows:
typedef struct shader {
VkPipelineShaderStageCreateInfo get;
VkShaderModuleCreateInfo module_info;
VkShaderModule module;
size_t code_size;
uint32_t *code;
} Shader;
Note there is an implicit cast (code pointer) from uint8_t to uint32_t, this has to happen one way or another since VkPipelineShaderStageCreateInfo expects a uint32_t pointer. Once again: works on linux...
I also tried changing the vert.spv file for older compiled files from previous projects (which have functioned correctly on windows in the past), but I get the same validation error.
Before I go ahead and scream in Khronos' face for not fixing a bug, I want to make sure this is in fact a bug, so if you have any clue or suggestion for what might cause this issue, I would gladly hear it. If anyone can confirm this is a bug, I will file a bug report I guess.
EDIT: I did try to compile the shader on windows as well (with glslc.exe also from the VulkanSDK, no luck).
CodePudding user response:
Looks like you need to open the file in binary mode. See here for more info.