Skip to content

Commit c3037be

Browse files
committed
gpu: Implement GLSL to SPIR-V compilation using glslang
Add glslang library dependency for runtime GLSL to SPIR-V compilation in the Vulkan unit test framework. This enables the Vulkan GPU tests to actually run by compiling OCIO-generated GLSL shaders to SPIR-V. Changes: - CMakeLists.txt: Add find_package(glslang) and link glslang libraries - vulkanapp.cpp: Implement compileGLSLToSPIRV() using glslang API The implementation: - Initializes glslang process (thread-safe, one-time init) - Configures Vulkan 1.2 / SPIR-V 1.5 target environment - Parses GLSL compute shader source - Links shader program - Generates optimized SPIR-V bytecode Signed-off-by: pmady <pavan4devops@gmail.com>
1 parent 4ec87bd commit c3037be

File tree

2 files changed

+72
-18
lines changed

2 files changed

+72
-18
lines changed

src/libutils/oglapphelpers/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ endif()
3434
if(OCIO_VULKAN_ENABLED)
3535

3636
find_package(Vulkan REQUIRED)
37+
find_package(glslang REQUIRED)
3738

3839
list(APPEND SOURCES
3940
vulkanapp.cpp
@@ -133,6 +134,9 @@ if(OCIO_VULKAN_ENABLED)
133134
target_link_libraries(oglapphelpers
134135
PRIVATE
135136
Vulkan::Vulkan
137+
glslang::glslang
138+
glslang::glslang-default-resource-limits
139+
glslang::SPIRV
136140
)
137141
target_compile_definitions(oglapphelpers
138142
PRIVATE

src/libutils/oglapphelpers/vulkanapp.cpp

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#include <cstring>
1010
#include <fstream>
1111

12+
#include <glslang/Public/ShaderLang.h>
13+
#include <glslang/Public/ResourceLimits.h>
14+
#include <glslang/SPIRV/GlslangToSpv.h>
15+
1216
#include "vulkanapp.h"
1317

1418
namespace OCIO_NAMESPACE
@@ -651,25 +655,71 @@ void VulkanBuilder::buildShader(GpuShaderDescRcPtr & shaderDesc)
651655

652656
std::vector<uint32_t> VulkanBuilder::compileGLSLToSPIRV(const std::string & glslSource)
653657
{
654-
// This is a placeholder for GLSL to SPIR-V compilation.
655-
// In a real implementation, you would use:
656-
// - glslang library (libglslang)
657-
// - shaderc library
658-
// - Or call glslangValidator/glslc externally
659-
660-
// For now, we'll throw an error indicating that SPIR-V compilation
661-
// needs to be implemented with a proper shader compiler.
658+
// Initialize glslang (safe to call multiple times)
659+
static bool glslangInitialized = false;
660+
if (!glslangInitialized)
661+
{
662+
glslang::InitializeProcess();
663+
glslangInitialized = true;
664+
}
665+
666+
// Create shader object
667+
glslang::TShader shader(EShLangCompute);
662668

663-
// TODO: Implement GLSL to SPIR-V compilation using glslang or shaderc
664-
// Example with shaderc:
665-
// shaderc::Compiler compiler;
666-
// shaderc::CompileOptions options;
667-
// options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_2);
668-
// auto result = compiler.CompileGlslToSpv(glslSource, shaderc_compute_shader, "shader.comp", options);
669-
// return std::vector<uint32_t>(result.cbegin(), result.cend());
670-
671-
throw std::runtime_error("GLSL to SPIR-V compilation not yet implemented. "
672-
"Please link against glslang or shaderc library.");
669+
const char * shaderStrings[1] = { glslSource.c_str() };
670+
shader.setStrings(shaderStrings, 1);
671+
672+
// Set up Vulkan 1.2 / SPIR-V 1.5 environment
673+
shader.setEnvInput(glslang::EShSourceGlsl, EShLangCompute, glslang::EShClientVulkan, 460);
674+
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_2);
675+
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_5);
676+
677+
// Get default resource limits
678+
const TBuiltInResource * resources = GetDefaultResources();
679+
680+
// Parse the shader
681+
const int defaultVersion = 460;
682+
const bool forwardCompatible = false;
683+
const EShMessages messages = static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
684+
685+
if (!shader.parse(resources, defaultVersion, forwardCompatible, messages))
686+
{
687+
std::string errorMsg = "GLSL parsing failed:\n";
688+
errorMsg += shader.getInfoLog();
689+
errorMsg += "\n";
690+
errorMsg += shader.getInfoDebugLog();
691+
throw std::runtime_error(errorMsg);
692+
}
693+
694+
// Create program and link
695+
glslang::TProgram program;
696+
program.addShader(&shader);
697+
698+
if (!program.link(messages))
699+
{
700+
std::string errorMsg = "GLSL linking failed:\n";
701+
errorMsg += program.getInfoLog();
702+
errorMsg += "\n";
703+
errorMsg += program.getInfoDebugLog();
704+
throw std::runtime_error(errorMsg);
705+
}
706+
707+
// Convert to SPIR-V
708+
std::vector<uint32_t> spirv;
709+
glslang::SpvOptions spvOptions;
710+
spvOptions.generateDebugInfo = false;
711+
spvOptions.stripDebugInfo = true;
712+
spvOptions.disableOptimizer = false;
713+
spvOptions.optimizeSize = false;
714+
715+
glslang::GlslangToSpv(*program.getIntermediate(EShLangCompute), spirv, &spvOptions);
716+
717+
if (spirv.empty())
718+
{
719+
throw std::runtime_error("SPIR-V generation produced empty output");
720+
}
721+
722+
return spirv;
673723
}
674724

675725
void VulkanBuilder::allocateAllTextures(unsigned maxTextureSize)

0 commit comments

Comments
 (0)