0

I've just downloaded the lastest Vulkan SDK version (1.3.224.1) and when I try to compile a shader using shaderc I get this error: error: OpenGL compatibility profile is not supported.

I've cloned Hazel-2D Engine: https://github.com/TheCherno/Hazel by The Cherno just to check if it works fine because it builds the same Vulkan SDK things as in my project and has the same shaderc and spirv-cross code. It works in hazel but does not work inside my project.

shader code:

#version 450 core

layout(location = 0) in vec2 a_position;
layout(location = 1) in vec2 a_uv;

layout(location = 0) out vec2 v_uv;

void main()
{
    v_uv = a_uv;

    vec4 position = vec4(a_position, 0.0, 1.0);
    gl_Position = position;
}
#version 450 core

layout(location = 0) out vec4 f_color;

layout(location = 0) in vec2 v_uv;

void main()
{         
    f_color = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}

I guess it's not important to show the whole premake script since the project builds fine. I'll show just the most important part: dependencies are defined like this:

VULKAN_SDK = os.getenv("VULKAN_SDK")

IncludeDir["VulkanSDK"]   = "%{VULKAN_SDK}/Include"

LibraryDir = {}
LibraryDir["VulkanSDK"] = "%{VULKAN_SDK}/Lib"

Library = {}

Library["ShaderC_Debug"]            = "%{LibraryDir.VulkanSDK}/shaderc_sharedd.lib"
Library["SPIRV_Cross_Debug"]        = "%{LibraryDir.VulkanSDK}/spirv-cross-cored.lib"
Library["SPIRV_Cross_GLSL_Debug"]   = "%{LibraryDir.VulkanSDK}/spirv-cross-glsld.lib"
Library["SPIRV_Tools_Debug"]        = "%{LibraryDir.VulkanSDK}/SPIRV-Toolsd.lib"

and linked like this:

    includedirs {
        --other things...
        "%{IncludeDir.VulkanSDK}",
    }

    filter "configurations:Debug"
        symbols "On"
        
        links { 
            "%{Library.ShaderC_Debug}",
            "%{Library.SPIRV_Cross_Debug}",
            "%{Library.SPIRV_Cross_GLSL_Debug}",
            "%{Library.SPIRV_Tools_Debug}",
        }

What I do first is compile Vulkan GLSL code into a spirv binaries (+ caching, but to provide a minimal example I removed it):

std::unordered_map<uint32_t, std::vector<uint32_t>> Shader::CompileGLSLToVulkanSpirvAndCache(const std::unordered_map<uint32_t, std::string>& shaderSource)
    {
        std::unordered_map<uint32_t, std::vector<uint32_t>> resultBinaries;

        shaderc::Compiler compiler;
        shaderc::CompileOptions options;
        options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_2);
        

        uint32_t shadersCount = static_cast<uint32_t>(shaderSource.size());
        resultBinaries.reserve(shadersCount);
        
        for(const auto& [type, source] : shaderSource) {
            shaderc::SpvCompilationResult compilationResult = compiler.CompileGlslToSpv(source, GLShaderTypeToShadercShaderType(type), filepath.generic_string().c_str(), options);
        
            if(compilationResult.GetCompilationStatus() != shaderc_compilation_status_success) {
                EngineLogError(compilationResult.GetErrorMessage());
                __debugbreak();
            }
        
            resultBinaries[type] = std::vector<uint32_t>(compilationResult.cbegin(), compilationResult.cend());
        }
        

        return resultBinaries;
    }

and then using spirv_cross::CompilerGLSL I compile the vulkan spirv binaries to opengl spirv.

    std::unordered_map<uint32_t, std::vector<uint32_t>> Shader::CompileFromVulkanToOpengl(const std::unordered_map<uint32_t, std::vector<uint32_t>>& vulkanBinaries)
    {
        std::unordered_map<uint32_t, std::vector<uint32_t>> resultBinaries;

        shaderc::Compiler compiler;
        shaderc::CompileOptions options;
        options.SetTargetEnvironment(shaderc_target_env_opengl_compat, shaderc_env_version_opengl_4_5);

        uint32_t shadersCount = static_cast<uint32_t>(vulkanBinaries.size());
        resultBinaries.reserve(shadersCount);

        for(const auto& [type, binaries] : vulkanBinaries) {
            spirv_cross::CompilerGLSL glsl(binaries);   
            std::string source = glsl.compile();
        
            shaderc::SpvCompilationResult compilationResult = compiler.CompileGlslToSpv(source, GLShaderTypeToShadercShaderType(type), filepath.generic_string().c_str(), options);
        
            if(compilationResult.GetCompilationStatus() != shaderc_compilation_status_success) {
                EngineLogError(compilationResult.GetErrorMessage());
                __debugbreak();
            }
        
            resultBinaries[type] = std::vector<uint32_t>(compilationResult.cbegin(), compilationResult.cend());
        }
        
        return resultBinaries;
    }

and CompileFromVulkanToOpengl this function returns this error: error: OpenGL compatibility profile is not supported.

How to fix it? Why it works in hazel 2d and does not work in my project?

OpenGL Info:
OpenGL Info:
  Vendor: NVIDIA Corporation
  Renderer: NVIDIA GeForce GTX 1080/PCIe/SSE2
  Version: 4.6.0 NVIDIA 516.94
Shout
  • 338
  • 5
  • 14
  • 1
    Whats your shader code? – BDL Sep 06 '22 at 12:39
  • right, sorry, I've just edited the post. The code is on the top. – Shout Sep 06 '22 at 12:44
  • Funny thing is that I've got shaderc and spirv-cross libs built by myself from the google and khronos group github and it works. But I'd like these dependencies to be included from Vulkan SDK. – Shout Sep 06 '22 at 12:47
  • 3
    Vulcan is not OpenGL. – Jesper Juhl Sep 06 '22 at 13:07
  • Yes, but vulkan glsl code can be translated to opengl glsl. My question is not "Is Vulkan OpenGL?" My question is why the same code works in the other project and does not work in mine. Plus when I built shaderc and spirv-cross libs downloaded from github, included and linked into my project, it does work. – Shout Sep 06 '22 at 13:30
  • Also the shader code I'm trying to compile does not contain any Vulkan Specific glsl code, no sets, no push constants. – Shout Sep 06 '22 at 13:33
  • @Shout: "*Why it works in hazel 2d and does not work in my project?*" Because Hazel 2D doesn't convert SPIR-V meant for Vulkan into SPIR-V meant for OpenGL. "*the shader code I'm trying to compile does not contain any Vulkan Specific glsl code, no sets, no push constants*" But you're cross-compiling *SPIR-V*, not GLSL. So what does the SPIR-V look like? – Nicol Bolas Sep 06 '22 at 14:24
  • Hazel 2D does exactly the same thing as I do. First it compiles the shader code into vulkan binaries and then using spirv-cross it compiles vulkan spirv binaries into opengl glsl code. See https://github.com/TheCherno/Hazel/blob/49da3c1e08245feb5b978269119f50b0873dc9d1/Hazel/src/Platform/OpenGL/OpenGLShader.cpp#L192 – Shout Sep 06 '22 at 14:30
  • 2
    The code in the repository compiles the code to `shaderc_target_env_opengl` while yours uses `shaderc_target_env_opengl_compat`. The error message clearly states the compatibility is not supported. That's a hardcoded error message that happens whenever someone tries to use `shaderc_target_env_opengl_compat`. You can't use this approach to compile to OpenGL compatibility profile, it only works for OpenGL core profile which makes sense since your shaders are written against core anyway – BDL Sep 06 '22 at 14:50

0 Answers0