From 4b3aad36d48b8620279810e48e8d49318158f7ce Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Fri, 16 May 2025 18:33:47 +0200 Subject: [PATCH 01/19] Support for Vulkan GLSL (not yet active). Signed-off-by: Michael Horsch --- include/OpenColorIO/OpenColorIO.h | 25 ++-- include/OpenColorIO/OpenColorTypes.h | 1 + src/OpenColorIO/GpuShader.cpp | 103 ++++++++++------- src/OpenColorIO/GpuShader.h | 5 +- src/OpenColorIO/GpuShaderClassWrapper.cpp | 1 + src/OpenColorIO/GpuShaderClassWrapper.h | 16 +++ src/OpenColorIO/GpuShaderDesc.cpp | 69 +++++++---- src/OpenColorIO/GpuShaderUtils.cpp | 107 +++++++++++++++--- src/OpenColorIO/GpuShaderUtils.h | 6 +- src/OpenColorIO/ParseUtils.cpp | 2 + .../ExposureContrastOpGPU.cpp | 2 +- .../ops/fixedfunction/FixedFunctionOpGPU.cpp | 52 ++++----- .../gradingprimary/GradingPrimaryOpGPU.cpp | 6 +- .../gradingrgbcurve/GradingRGBCurveOpGPU.cpp | 6 +- .../ops/gradingtone/GradingToneOpGPU.cpp | 4 +- src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp | 26 ++--- src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp | 15 ++- src/apps/ociodisplay/main.cpp | 11 +- src/bindings/python/PyGpuShaderCreator.cpp | 9 +- src/bindings/python/PyTypes.cpp | 2 + src/libutils/oglapphelpers/glsl.cpp | 2 + tests/cpu/GpuShader_tests.cpp | 2 +- 22 files changed, 322 insertions(+), 150 deletions(-) diff --git a/include/OpenColorIO/OpenColorIO.h b/include/OpenColorIO/OpenColorIO.h index 5ef81b8112..e267d758f6 100644 --- a/include/OpenColorIO/OpenColorIO.h +++ b/include/OpenColorIO/OpenColorIO.h @@ -3356,13 +3356,13 @@ class OCIOEXPORT GpuShaderCreator * The 'values' parameter contains the LUT data which must be used as-is as the dimensions and * origin are hard-coded in the fragment shader program. So, it means one GPU texture per entry. **/ - virtual void addTexture(const char * textureName, - const char * samplerName, - unsigned width, unsigned height, - TextureType channel, - TextureDimensions dimensions, - Interpolation interpolation, - const float * values) = 0; + virtual unsigned addTexture(const char * textureName, + const char * samplerName, + unsigned width, unsigned height, + TextureType channel, + TextureDimensions dimensions, + Interpolation interpolation, + const float * values) = 0; /** * Add a 3D texture with RGB channel type. @@ -3372,14 +3372,15 @@ class OCIOEXPORT GpuShaderCreator * and origin are hard-coded in the fragment shader program. So, it means one GPU 3D texture * per entry. **/ - virtual void add3DTexture(const char * textureName, + virtual unsigned add3DTexture(const char * textureName, const char * samplerName, unsigned edgelen, Interpolation interpolation, const float * values) = 0; // Methods to specialize parts of a OCIO shader program - virtual void addToDeclareShaderCode(const char * shaderCode); + virtual void addToParameterDeclareShaderCode(const char * shaderCode); + virtual void addToTextureDeclareShaderCode(const char* shaderCode); virtual void addToHelperShaderCode(const char * shaderCode); virtual void addToFunctionHeaderShaderCode(const char * shaderCode); virtual void addToFunctionShaderCode(const char * shaderCode); @@ -3393,7 +3394,8 @@ class OCIOEXPORT GpuShaderCreator * to change some parts. Some product integrations add the color processing * within a client shader program, imposing constraints requiring this flexibility. */ - virtual void createShaderText(const char * shaderDeclarations, + virtual void createShaderText(const char * shaderParameterDeclarations, + const char * shaderTextureDeclarations, const char * shaderHelperMethods, const char * shaderFunctionHeader, const char * shaderFunctionBody, @@ -3586,6 +3588,7 @@ class OCIOEXPORT GpuShaderDesc : public GpuShaderCreator struct UniformData { UniformDataType m_type{ UNIFORM_UNKNOWN }; + std::size_t m_bufferOffset; DoubleGetter m_getDouble{}; BoolGetter m_getBool{}; Float3Getter m_getFloat3{}; @@ -3604,6 +3607,8 @@ class OCIOEXPORT GpuShaderDesc : public GpuShaderCreator /// Returns name of uniform and data as parameter. virtual const char * getUniform(unsigned index, UniformData & data) const = 0; + virtual std::size_t getUniformBufferSize() const noexcept = 0; + // 1D lut related methods virtual unsigned getNumTextures() const noexcept = 0; virtual void getTexture(unsigned index, diff --git a/include/OpenColorIO/OpenColorTypes.h b/include/OpenColorIO/OpenColorTypes.h index 21243eb363..9746c133b9 100644 --- a/include/OpenColorIO/OpenColorTypes.h +++ b/include/OpenColorIO/OpenColorTypes.h @@ -449,6 +449,7 @@ enum GpuLanguage GPU_LANGUAGE_GLSL_1_2, ///< OpenGL Shading Language GPU_LANGUAGE_GLSL_1_3, ///< OpenGL Shading Language GPU_LANGUAGE_GLSL_4_0, ///< OpenGL Shading Language + GPU_LANGUAGE_GLSL_VK_4_6, ///< OpenGL Shading Language for Vulkan GPU_LANGUAGE_HLSL_SM_5_0, ///< DirectX High Level Shading Language LANGUAGE_OSL_1, ///< Open Shading Language GPU_LANGUAGE_GLSL_ES_1_0, ///< OpenGL ES Shading Language diff --git a/src/OpenColorIO/GpuShader.cpp b/src/OpenColorIO/GpuShader.cpp index 7fbc30b43a..fbc8ac6f43 100644 --- a/src/OpenColorIO/GpuShader.cpp +++ b/src/OpenColorIO/GpuShader.cpp @@ -40,6 +40,8 @@ static void CreateArray(const float * buf, namespace GPUShaderImpl { +constexpr std::size_t UNIFORM_BUFFER_ALIGNMENT = 16; //Align variables in uniform buffers to 16 bytes + class PrivateImpl { public: @@ -104,43 +106,48 @@ class PrivateImpl struct Uniform { - Uniform(const char * name, const GpuShaderCreator::DoubleGetter & getDouble) + Uniform(const char * name, const GpuShaderCreator::DoubleGetter & getDouble, std::size_t bufferOffset) : Uniform(name) { m_data.m_type = UNIFORM_DOUBLE; m_data.m_getDouble = getDouble; + m_data.m_bufferOffset = bufferOffset; } - Uniform(const char * name, const GpuShaderCreator::BoolGetter & getBool) + Uniform(const char * name, const GpuShaderCreator::BoolGetter & getBool, std::size_t bufferOffset) : Uniform(name) { m_data.m_type = UNIFORM_BOOL; m_data.m_getBool = getBool; + m_data.m_bufferOffset = bufferOffset; } - Uniform(const char * name, const GpuShaderCreator::Float3Getter & getFloat3) + Uniform(const char * name, const GpuShaderCreator::Float3Getter & getFloat3, std::size_t bufferOffset) : Uniform(name) { m_data.m_type = UNIFORM_FLOAT3; m_data.m_getFloat3 = getFloat3; + m_data.m_bufferOffset = bufferOffset; } Uniform(const char * name, const GpuShaderCreator::SizeGetter & getSize, - const GpuShaderCreator::VectorFloatGetter & getVectorFloat) + const GpuShaderCreator::VectorFloatGetter & getVectorFloat, std::size_t bufferOffset) : Uniform(name) { m_data.m_type = UNIFORM_VECTOR_FLOAT; m_data.m_vectorFloat.m_getSize = getSize; m_data.m_vectorFloat.m_getVector = getVectorFloat; + m_data.m_bufferOffset = bufferOffset; } Uniform(const char * name, const GpuShaderCreator::SizeGetter & getSize, - const GpuShaderCreator::VectorIntGetter & getVectorInt) + const GpuShaderCreator::VectorIntGetter & getVectorInt, std::size_t bufferOffset) : Uniform(name) { m_data.m_type = UNIFORM_VECTOR_INT; m_data.m_vectorInt.m_getSize = getSize; m_data.m_vectorInt.m_getVector = getVectorInt; + m_data.m_bufferOffset = bufferOffset; } const std::string m_name; @@ -161,7 +168,7 @@ class PrivateImpl typedef std::vector Uniforms; public: - PrivateImpl() : m_max1DLUTWidth(4 * 1024), m_allowTexture1D(true) {} + PrivateImpl() : m_max1DLUTWidth(4 * 1024), m_allowTexture1D(true), m_uniformBufferSize(0) {} PrivateImpl(const PrivateImpl & rhs) = delete; PrivateImpl& operator= (const PrivateImpl & rhs) = delete; @@ -175,13 +182,13 @@ class PrivateImpl inline bool getAllowTexture1D() const { return m_allowTexture1D; } inline void setAllowTexture1D(bool allowed) { m_allowTexture1D = allowed; } - void addTexture(const char * textureName, - const char * samplerName, - unsigned width, unsigned height, - GpuShaderDesc::TextureType channel, - GpuShaderDesc::TextureDimensions dimensions, - Interpolation interpolation, - const float * values) + unsigned addTexture(const char * textureName, + const char * samplerName, + unsigned width, unsigned height, + GpuShaderDesc::TextureType channel, + GpuShaderDesc::TextureDimensions dimensions, + Interpolation interpolation, + const float * values) { if(width > get1dLutMaxWidth()) { @@ -190,10 +197,11 @@ class PrivateImpl << width << " > " << get1dLutMaxWidth(); throw Exception(ss.str().c_str()); } - + unsigned textureIndex = m_textures.size(); unsigned numDimensions = static_cast(dimensions); Texture t(textureName, samplerName, width, height, 1, channel, numDimensions, interpolation, values); m_textures.push_back(t); + return textureIndex; } void getTexture(unsigned index, @@ -243,11 +251,11 @@ class PrivateImpl values = &t.m_values[0]; } - void add3DTexture(const char * textureName, - const char * samplerName, - unsigned edgelen, - Interpolation interpolation, - const float * values) + unsigned add3DTexture(const char * textureName, + const char * samplerName, + unsigned edgelen, + Interpolation interpolation, + const float * values) { if(edgelen > get3dLutMaxLength()) { @@ -257,10 +265,12 @@ class PrivateImpl throw Exception(ss.str().c_str()); } + unsigned textureIndex = m_textures3D.size(); Texture t(textureName, samplerName, edgelen, edgelen, edgelen, GpuShaderDesc::TEXTURE_RGB_CHANNEL, 3, interpolation, values); m_textures3D.push_back(t); + return textureIndex; } void get3DTexture(unsigned index, @@ -323,7 +333,8 @@ class PrivateImpl // Uniform is already there. return false; } - m_uniforms.emplace_back(name, getter); + m_uniforms.emplace_back(name, getter, m_uniformBufferSize); + m_uniformBufferSize += UNIFORM_BUFFER_ALIGNMENT; return true; } @@ -334,7 +345,8 @@ class PrivateImpl // Uniform is already there. return false; } - m_uniforms.emplace_back(name, getter); + m_uniforms.emplace_back(name, getter, m_uniformBufferSize); + m_uniformBufferSize += UNIFORM_BUFFER_ALIGNMENT; //bool not supported for buffered uniforms, using int instead return true; } @@ -345,7 +357,8 @@ class PrivateImpl // Uniform is already there. return false; } - m_uniforms.emplace_back(name, getter); + m_uniforms.emplace_back(name, getter, m_uniformBufferSize); + m_uniformBufferSize += UNIFORM_BUFFER_ALIGNMENT; return true; } @@ -358,7 +371,9 @@ class PrivateImpl // Uniform is already there. return false; } - m_uniforms.emplace_back(name, getSize, getVector); + m_uniforms.emplace_back(name, getSize, getVector, m_uniformBufferSize); + const std::size_t arraySizeInBytes = sizeof(float) * getSize(); + m_uniformBufferSize += arraySizeInBytes + UNIFORM_BUFFER_ALIGNMENT - (arraySizeInBytes % UNIFORM_BUFFER_ALIGNMENT); return true; } @@ -371,9 +386,16 @@ class PrivateImpl // Uniform is already there. return false; } - m_uniforms.emplace_back(name, getSize, getVectorInt); + m_uniforms.emplace_back(name, getSize, getVectorInt, m_uniformBufferSize); + const std::size_t arraySizeInBytes = sizeof(int) * getSize(); + m_uniformBufferSize += arraySizeInBytes + UNIFORM_BUFFER_ALIGNMENT - (arraySizeInBytes % UNIFORM_BUFFER_ALIGNMENT); return true; } + + std::size_t getUniformBufferSize() const + { + return m_uniformBufferSize; + } Textures m_textures; Textures m_textures3D; Uniforms m_uniforms; @@ -392,6 +414,7 @@ class PrivateImpl } unsigned m_max1DLUTWidth; bool m_allowTexture1D; + unsigned m_uniformBufferSize; }; } // namespace GPUShaderImpl @@ -459,6 +482,10 @@ bool GenericGpuShaderDesc::addUniform(const char * name, return getImplGeneric()->addUniform(name, getSize, getVectorInt); } +std::size_t GenericGpuShaderDesc::getUniformBufferSize() const noexcept +{ + return getImplGeneric()->getUniformBufferSize(); +} unsigned GenericGpuShaderDesc::getTextureMaxWidth() const noexcept { @@ -485,15 +512,15 @@ unsigned GenericGpuShaderDesc::getNumTextures() const noexcept return unsigned(getImplGeneric()->m_textures.size()); } -void GenericGpuShaderDesc::addTexture(const char * textureName, - const char * samplerName, - unsigned width, unsigned height, - TextureType channel, - TextureDimensions dimensions, - Interpolation interpolation, - const float * values) +unsigned GenericGpuShaderDesc::addTexture(const char * textureName, + const char * samplerName, + unsigned width, unsigned height, + TextureType channel, + TextureDimensions dimensions, + Interpolation interpolation, + const float * values) { - getImplGeneric()->addTexture(textureName, samplerName, width, height, channel, dimensions, interpolation, values); + return getImplGeneric()->addTexture(textureName, samplerName, width, height, channel, dimensions, interpolation, values); } void GenericGpuShaderDesc::getTexture(unsigned index, @@ -517,13 +544,13 @@ unsigned GenericGpuShaderDesc::getNum3DTextures() const noexcept return unsigned(getImplGeneric()->m_textures3D.size()); } -void GenericGpuShaderDesc::add3DTexture(const char * textureName, - const char * samplerName, - unsigned edgelen, - Interpolation interpolation, - const float * values) +unsigned GenericGpuShaderDesc::add3DTexture(const char * textureName, + const char * samplerName, + unsigned edgelen, + Interpolation interpolation, + const float * values) { - getImplGeneric()->add3DTexture(textureName, samplerName, edgelen, interpolation, values); + return getImplGeneric()->add3DTexture(textureName, samplerName, edgelen, interpolation, values); } void GenericGpuShaderDesc::get3DTexture(unsigned index, diff --git a/src/OpenColorIO/GpuShader.h b/src/OpenColorIO/GpuShader.h index e9c39d56b1..352d7871c1 100644 --- a/src/OpenColorIO/GpuShader.h +++ b/src/OpenColorIO/GpuShader.h @@ -45,11 +45,12 @@ class GenericGpuShaderDesc : public GpuShaderDesc bool addUniform(const char * name, const SizeGetter & getSize, const VectorIntGetter & getVectorInt) override; + std::size_t getUniformBufferSize() const noexcept override; // Accessors to the 1D & 2D textures built from 1D LUT // unsigned getNumTextures() const noexcept override; - void addTexture(const char * textureName, + unsigned addTexture(const char * textureName, const char * samplerName, unsigned width, unsigned height, TextureType channel, @@ -68,7 +69,7 @@ class GenericGpuShaderDesc : public GpuShaderDesc // Accessors to the 3D textures built from 3D LUT // unsigned getNum3DTextures() const noexcept override; - void add3DTexture(const char * textureName, + unsigned add3DTexture(const char * textureName, const char * samplerName, unsigned edgelen, Interpolation interpolation, diff --git a/src/OpenColorIO/GpuShaderClassWrapper.cpp b/src/OpenColorIO/GpuShaderClassWrapper.cpp index 6ca5027ee5..675bd47163 100644 --- a/src/OpenColorIO/GpuShaderClassWrapper.cpp +++ b/src/OpenColorIO/GpuShaderClassWrapper.cpp @@ -31,6 +31,7 @@ std::unique_ptr GpuShaderClassWrapper::CreateClassWrapper case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_HLSL_SM_5_0: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: diff --git a/src/OpenColorIO/GpuShaderClassWrapper.h b/src/OpenColorIO/GpuShaderClassWrapper.h index c76373db90..ab21747606 100644 --- a/src/OpenColorIO/GpuShaderClassWrapper.h +++ b/src/OpenColorIO/GpuShaderClassWrapper.h @@ -30,6 +30,8 @@ class GpuShaderClassWrapper virtual std::string getClassWrapperHeader(const std::string & originalHeader) = 0; virtual std::string getClassWrapperFooter(const std::string & originalFooter) = 0; + virtual bool hasClassWrapperHeader() const = 0; + virtual std::unique_ptr clone() const = 0; virtual ~GpuShaderClassWrapper() = default; @@ -51,6 +53,10 @@ class NullGpuShaderClassWrapper : public GpuShaderClassWrapper { return originalFooter; } + bool hasClassWrapperHeader() const final + { + return false; + } std::unique_ptr clone() const final; }; @@ -68,6 +74,11 @@ class OSLShaderClassWrapper : public GpuShaderClassWrapper std::string getClassWrapperHeader(const std::string & originalHeader) final; std::string getClassWrapperFooter(const std::string & originalFooter) final; + bool hasClassWrapperHeader() const final + { + return true; + } + std::unique_ptr clone() const final; private: @@ -83,6 +94,11 @@ class MetalShaderClassWrapper : public GpuShaderClassWrapper std::string getClassWrapperHeader(const std::string & originalHeader) final; std::string getClassWrapperFooter(const std::string & originalFooter) final; + bool hasClassWrapperHeader() const final + { + return true; + } + std::unique_ptr clone() const final; MetalShaderClassWrapper& operator=(const MetalShaderClassWrapper& rhs); diff --git a/src/OpenColorIO/GpuShaderDesc.cpp b/src/OpenColorIO/GpuShaderDesc.cpp index 9a35f75486..2fbfcf23f3 100644 --- a/src/OpenColorIO/GpuShaderDesc.cpp +++ b/src/OpenColorIO/GpuShaderDesc.cpp @@ -32,7 +32,8 @@ class GpuShaderCreator::Impl mutable std::string m_cacheID; mutable Mutex m_cacheIDMutex; - std::string m_declarations; + std::string m_parameterDeclarations; + std::string m_textureDeclarations; std::string m_helperMethods; std::string m_functionHeader; std::string m_functionBody; @@ -69,11 +70,12 @@ class GpuShaderCreator::Impl m_numResources = rhs.m_numResources; m_cacheID = rhs.m_cacheID; - m_declarations = rhs.m_declarations; - m_helperMethods = rhs.m_helperMethods; - m_functionHeader = rhs.m_functionHeader; - m_functionBody = rhs.m_functionBody; - m_functionFooter = rhs.m_functionFooter; + m_parameterDeclarations = rhs.m_parameterDeclarations; + m_textureDeclarations = rhs.m_textureDeclarations; + m_helperMethods = rhs.m_helperMethods; + m_functionHeader = rhs.m_functionHeader; + m_functionBody = rhs.m_functionBody; + m_functionFooter = rhs.m_functionFooter; m_classWrappingInterface = rhs.m_classWrappingInterface->clone(); @@ -249,13 +251,22 @@ const char * GpuShaderCreator::getCacheID() const noexcept return getImpl()->m_cacheID.c_str(); } -void GpuShaderCreator::addToDeclareShaderCode(const char * shaderCode) +void GpuShaderCreator::addToParameterDeclareShaderCode(const char * shaderCode) { - if(getImpl()->m_declarations.empty()) + if(getImpl()->m_parameterDeclarations.empty()) { - getImpl()->m_declarations += "\n// Declaration of all variables\n\n"; + getImpl()->m_parameterDeclarations += "\n// Declaration of all variables\n\n"; } - getImpl()->m_declarations += (shaderCode && *shaderCode) ? shaderCode : ""; + getImpl()->m_parameterDeclarations += (shaderCode && *shaderCode) ? shaderCode : ""; +} + +void GpuShaderCreator::addToTextureDeclareShaderCode(const char* shaderCode) +{ + if (getImpl()->m_textureDeclarations.empty()) + { + getImpl()->m_textureDeclarations += "\n// Declaration of all textures\n\n"; + } + getImpl()->m_textureDeclarations += (shaderCode && *shaderCode) ? shaderCode : ""; } void GpuShaderCreator::addToHelperShaderCode(const char * shaderCode) @@ -282,7 +293,8 @@ void GpuShaderCreator::addToFunctionFooterShaderCode(const char * shaderCode) getImpl()->m_functionFooter += (shaderCode && *shaderCode) ? shaderCode : ""; } -void GpuShaderCreator::createShaderText(const char * shaderDeclarations, +void GpuShaderCreator::createShaderText(const char * shaderParameterDeclarations, + const char * shaderTextureDeclarations, const char * shaderHelperMethods, const char * shaderFunctionHeader, const char * shaderFunctionBody, @@ -292,11 +304,21 @@ void GpuShaderCreator::createShaderText(const char * shaderDeclarations, getImpl()->m_shaderCode.clear(); - getImpl()->m_shaderCode += (shaderDeclarations && *shaderDeclarations) ? shaderDeclarations : ""; - getImpl()->m_shaderCode += (shaderHelperMethods && *shaderHelperMethods) ? shaderHelperMethods : ""; - getImpl()->m_shaderCode += (shaderFunctionHeader && *shaderFunctionHeader) ? shaderFunctionHeader : ""; - getImpl()->m_shaderCode += (shaderFunctionBody && *shaderFunctionBody) ? shaderFunctionBody : ""; - getImpl()->m_shaderCode += (shaderFunctionFooter && *shaderFunctionFooter) ? shaderFunctionFooter : ""; + if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6) + { + getImpl()->m_shaderCode += "/*layout (set = 0, binding = 0) uniform OCIOParameters\n {\n*/"; + } + getImpl()->m_shaderCode += (shaderParameterDeclarations && *shaderParameterDeclarations) ? shaderParameterDeclarations : ""; + if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6) + { + getImpl()->m_shaderCode += "\n/*};*/\n"; + } + + getImpl()->m_shaderCode += (shaderTextureDeclarations && *shaderTextureDeclarations) ? shaderTextureDeclarations : ""; + getImpl()->m_shaderCode += (shaderHelperMethods && *shaderHelperMethods) ? shaderHelperMethods : ""; + getImpl()->m_shaderCode += (shaderFunctionHeader && *shaderFunctionHeader) ? shaderFunctionHeader : ""; + getImpl()->m_shaderCode += (shaderFunctionBody && *shaderFunctionBody) ? shaderFunctionBody : ""; + getImpl()->m_shaderCode += (shaderFunctionFooter && *shaderFunctionFooter) ? shaderFunctionFooter : ""; getImpl()->m_shaderCodeID = CacheIDHash(getImpl()->m_shaderCode.c_str(), getImpl()->m_shaderCode.length()); @@ -309,18 +331,25 @@ void GpuShaderCreator::finalize() // For some GPU languages, the default header and footer do not fit well so, the class wrapper // encapsulates differences when needed. + const std::string originalHeader = getImpl()->m_parameterDeclarations + std::string("\n") + getImpl()->m_textureDeclarations; getImpl()->m_classWrappingInterface->prepareClassWrapper(getResourcePrefix(), getImpl()->m_functionName, - getImpl()->m_declarations); + originalHeader); - getImpl()->m_declarations - = getImpl()->m_classWrappingInterface->getClassWrapperHeader(getImpl()->m_declarations); + if (getImpl()->m_classWrappingInterface->hasClassWrapperHeader()) + { + getImpl()->m_parameterDeclarations + = getImpl()->m_classWrappingInterface->getClassWrapperHeader(originalHeader); + getImpl()->m_textureDeclarations.clear(); //clear texture declarations since they're already included in the header + } getImpl()->m_functionFooter = getImpl()->m_classWrappingInterface->getClassWrapperFooter(getImpl()->m_functionFooter); + // Build the complete shader program. - createShaderText(getImpl()->m_declarations.c_str(), + createShaderText(getImpl()->m_parameterDeclarations.c_str(), + getImpl()->m_textureDeclarations.c_str(), getImpl()->m_helperMethods.c_str(), getImpl()->m_functionHeader.c_str(), getImpl()->m_functionBody.c_str(), diff --git a/src/OpenColorIO/GpuShaderUtils.cpp b/src/OpenColorIO/GpuShaderUtils.cpp index f8cbc88907..338e8aa008 100644 --- a/src/OpenColorIO/GpuShaderUtils.cpp +++ b/src/OpenColorIO/GpuShaderUtils.cpp @@ -43,6 +43,7 @@ std::string getVecKeyword(GpuLanguage lang) case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: { @@ -80,7 +81,8 @@ void getTexDecl(GpuLanguage lang, const std::string & textureName, const std::string & samplerName, std::string & textureDecl, - std::string & samplerDecl) + std::string & samplerDecl, + unsigned textureIndex) { switch (lang) { @@ -98,6 +100,15 @@ void getTexDecl(GpuLanguage lang, samplerDecl = kw.str(); break; } + case GPU_LANGUAGE_GLSL_VK_4_6: + { + textureDecl = ""; + + std::ostringstream kw; + kw << "/*layout(set=0, binding="<(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl); + getTexDecl<1>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex); if (!textureDecl.empty()) { @@ -842,10 +858,10 @@ void GpuShaderText::declareTex1D(const std::string & textureName) } } -void GpuShaderText::declareTex2D(const std::string & textureName) +void GpuShaderText::declareTex2D(const std::string & textureName, const unsigned textureIndex) { std::string textureDecl, samplerDecl; - getTexDecl<2>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl); + getTexDecl<2>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex); if (!textureDecl.empty()) { @@ -858,10 +874,10 @@ void GpuShaderText::declareTex2D(const std::string & textureName) } } -void GpuShaderText::declareTex3D(const std::string& textureName) +void GpuShaderText::declareTex3D(const std::string& textureName, const unsigned textureIndex) { std::string textureDecl, samplerDecl; - getTexDecl<3>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl); + getTexDecl<3>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex); if (!textureDecl.empty()) { @@ -895,27 +911,81 @@ std::string GpuShaderText::sampleTex3D(const std::string& textureName, void GpuShaderText::declareUniformFloat(const std::string & uniformName) { - newLine() << (m_lang == GPU_LANGUAGE_MSL_2_0 ? "" : "uniform ") << floatKeyword() << " " << uniformName << ";"; + std::string uniformDeclString("uniform"); + if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + { + uniformDeclString = "/*uniform */"; + } + newLine() << uniformDeclString << floatKeyword() << " " << uniformName << ";"; + if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + { + //add padding for 16 byte alignment required by Vulkan + newLine() << floatKeyword() << uniformName<<"_pad0, "<< uniformName<<"_pad1, "<< uniformName<<"_pad2;"; + } } void GpuShaderText::declareUniformBool(const std::string & uniformName) { - newLine() << (m_lang == GPU_LANGUAGE_MSL_2_0 ? "" : "uniform ") << "bool " << uniformName << ";"; + std::string uniformDeclString("uniform"); + std::string boolKeyword("bool"); + if (m_lang == GPU_LANGUAGE_MSL_2_0) + { + uniformDeclString = ""; + } + else if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + { + uniformDeclString = "/*uniform */"; + boolKeyword = "int"; + } + newLine() << uniformDeclString << boolKeyword << uniformName << ";"; + if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + { + //add padding for 16 byte alignment required by Vulkan + newLine() << boolKeyword << uniformName << "_pad0, " << uniformName << "_pad1, " << uniformName << "_pad2;"; + } } void GpuShaderText::declareUniformFloat3(const std::string & uniformName) { - newLine() << (m_lang == GPU_LANGUAGE_MSL_2_0 ? "" : "uniform ") << float3Keyword() << " " << uniformName << ";"; + std::string uniformDeclString("uniform"); + if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + { + uniformDeclString = "/*uniform */"; + } + newLine() << uniformDeclString << float3Keyword() << " " << uniformName << ";"; + if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + { + //add padding for 16 byte alignment required by Vulkan + newLine() << floatKeyword() << uniformName << "_pad;"; + } } void GpuShaderText::declareUniformArrayFloat(const std::string & uniformName, unsigned int size) { - newLine() << (m_lang == GPU_LANGUAGE_MSL_2_0 ? "" : "uniform ") << floatKeyword() << " " << uniformName << "[" << size << "];"; + std::string uniformDeclString("uniform"); + if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + { + uniformDeclString = "/*uniform */"; + if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + { + size = (size + 3) / 4 * 4; // round up to the next multiple of 4 for 16 byte alignment + } + } + newLine() << uniformDeclString << floatKeyword() << " " << uniformName << "[" << size << "];"; } void GpuShaderText::declareUniformArrayInt(const std::string & uniformName, unsigned int size) { - newLine() << (m_lang == GPU_LANGUAGE_MSL_2_0 ? "" : "uniform ") << intKeyword() << " " << uniformName << "[" << size << "];"; + std::string uniformDeclString("uniform"); + if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + { + uniformDeclString = "/*uniform */"; + if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + { + size = (size + 3) / 4 * 4; // round up to the next multiple of 4 for 16 byte alignment + } + } + newLine() << uniformDeclString << intKeyword() << " " << uniformName << "[" << size << "];"; } // Keep the method private as only float & double types are expected @@ -933,6 +1003,7 @@ std::string matrix3Mul(const T * m3x3, const std::string & vecName, GpuLanguage case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: { @@ -999,6 +1070,7 @@ std::string matrix4Mul(const T * m4x4, const std::string & vecName, GpuLanguage case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: { @@ -1061,6 +1133,7 @@ std::string GpuShaderText::lerp(const std::string & x, case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: case GPU_LANGUAGE_MSL_2_0: @@ -1092,6 +1165,7 @@ std::string GpuShaderText::float3GreaterThan(const std::string & a, case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: case GPU_LANGUAGE_CG: @@ -1127,6 +1201,7 @@ std::string GpuShaderText::float4GreaterThan(const std::string & a, case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: case GPU_LANGUAGE_CG: @@ -1171,6 +1246,7 @@ std::string GpuShaderText::float3GreaterThanEqual(const std::string& a, case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: case GPU_LANGUAGE_CG: @@ -1206,6 +1282,7 @@ std::string GpuShaderText::float4GreaterThanEqual(const std::string& a, case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: case GPU_LANGUAGE_CG: @@ -1251,6 +1328,7 @@ std::string GpuShaderText::atan2(const std::string & y, case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: { @@ -1290,6 +1368,7 @@ std::string GpuShaderText::sign(const std::string & v) const case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: case GPU_LANGUAGE_HLSL_SM_5_0: diff --git a/src/OpenColorIO/GpuShaderUtils.h b/src/OpenColorIO/GpuShaderUtils.h index 54fe58f62f..e753ddb25b 100644 --- a/src/OpenColorIO/GpuShaderUtils.h +++ b/src/OpenColorIO/GpuShaderUtils.h @@ -171,11 +171,11 @@ class GpuShaderText static std::string getSamplerName(const std::string& textureName); // Declare the global texture and sampler information for a 1D texture. - void declareTex1D(const std::string& textureName); + void declareTex1D(const std::string& textureName, unsigned textureIndex); // Declare the global texture and sampler information for a 2D texture. - void declareTex2D(const std::string& textureName); + void declareTex2D(const std::string& textureName, unsigned textureIndex); // Declare the global texture and sampler information for a 3D texture. - void declareTex3D(const std::string& textureName); + void declareTex3D(const std::string& textureName, unsigned textureIndex); // Get the texture lookup call for a 1D texture. std::string sampleTex1D(const std::string& textureName, const std::string& coords) const; diff --git a/src/OpenColorIO/ParseUtils.cpp b/src/OpenColorIO/ParseUtils.cpp index c8b77c5f3a..41e5a41503 100644 --- a/src/OpenColorIO/ParseUtils.cpp +++ b/src/OpenColorIO/ParseUtils.cpp @@ -263,6 +263,7 @@ const char * GpuLanguageToString(GpuLanguage language) case GPU_LANGUAGE_GLSL_1_2: return "glsl_1.2"; case GPU_LANGUAGE_GLSL_1_3: return "glsl_1.3"; case GPU_LANGUAGE_GLSL_4_0: return "glsl_4.0"; + case GPU_LANGUAGE_GLSL_VK_4_6: return "glsl_vk_4.6"; case GPU_LANGUAGE_GLSL_ES_1_0: return "glsl_es_1.0"; case GPU_LANGUAGE_GLSL_ES_3_0: return "glsl_es_3.0"; case GPU_LANGUAGE_HLSL_SM_5_0: return "hlsl_sm_5.0"; @@ -282,6 +283,7 @@ GpuLanguage GpuLanguageFromString(const char * s) else if(str == "glsl_1.2") return GPU_LANGUAGE_GLSL_1_2; else if(str == "glsl_1.3") return GPU_LANGUAGE_GLSL_1_3; else if(str == "glsl_4.0") return GPU_LANGUAGE_GLSL_4_0; + else if(str == "glsl_vk_4.6") return GPU_LANGUAGE_GLSL_VK_4_6; else if(str == "glsl_es_1.0") return GPU_LANGUAGE_GLSL_ES_1_0; else if(str == "glsl_es_3.0") return GPU_LANGUAGE_GLSL_ES_3_0; else if(str == "hlsl_sm_5.0") return GPU_LANGUAGE_HLSL_SM_5_0; diff --git a/src/OpenColorIO/ops/exposurecontrast/ExposureContrastOpGPU.cpp b/src/OpenColorIO/ops/exposurecontrast/ExposureContrastOpGPU.cpp index e12ecc88eb..97dd56faf3 100644 --- a/src/OpenColorIO/ops/exposurecontrast/ExposureContrastOpGPU.cpp +++ b/src/OpenColorIO/ops/exposurecontrast/ExposureContrastOpGPU.cpp @@ -30,7 +30,7 @@ void AddUniform(GpuShaderCreatorRcPtr & shaderCreator, // Declare uniform. GpuShaderText stDecl(shaderCreator->getLanguage()); stDecl.declareUniformFloat(name); - shaderCreator->addToDeclareShaderCode(stDecl.string().c_str()); + shaderCreator->addToParameterDeclareShaderCode(stDecl.string().c_str()); } std::string AddProperty(GpuShaderCreatorRcPtr & shaderCreator, diff --git a/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp b/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp index be2ca6c352..471b9a962b 100644 --- a/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp +++ b/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp @@ -527,28 +527,28 @@ std::string _Add_Reach_table( dimensions = GpuShaderDesc::TEXTURE_2D; } - shaderCreator->addTexture( - name.c_str(), - GpuShaderText::getSamplerName(name).c_str(), - table.total_size, - 1, - GpuShaderCreator::TEXTURE_RED_CHANNEL, - dimensions, - INTERP_NEAREST, - &(table[0])); + const unsigned textureIndex = shaderCreator->addTexture( + name.c_str(), + GpuShaderText::getSamplerName(name).c_str(), + table.total_size, + 1, + GpuShaderCreator::TEXTURE_RED_CHANNEL, + dimensions, + INTERP_NEAREST, + &(table[0])); if (dimensions == GpuShaderDesc::TEXTURE_1D) { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex1D(name); - shaderCreator->addToDeclareShaderCode(ss.string().c_str()); + ss.declareTex1D(name, textureIndex); + shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } else { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex2D(name); - shaderCreator->addToDeclareShaderCode(ss.string().c_str()); + ss.declareTex2D(name, textureIndex); + shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } // Sampler function @@ -825,27 +825,27 @@ std::string _Add_Cusp_table( dimensions = GpuShaderDesc::TEXTURE_2D; } - shaderCreator->addTexture( - name.c_str(), - GpuShaderText::getSamplerName(name).c_str(), - g.gamut_cusp_table.total_size, - 1, - GpuShaderCreator::TEXTURE_RGB_CHANNEL, - dimensions, - INTERP_NEAREST, - &(g.gamut_cusp_table[0][0])); + const unsigned textureIndex = shaderCreator->addTexture( + name.c_str(), + GpuShaderText::getSamplerName(name).c_str(), + g.gamut_cusp_table.total_size, + 1, + GpuShaderCreator::TEXTURE_RGB_CHANNEL, + dimensions, + INTERP_NEAREST, + &(g.gamut_cusp_table[0][0])); if (dimensions == GpuShaderDesc::TEXTURE_1D) { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex1D(name); - shaderCreator->addToDeclareShaderCode(ss.string().c_str()); + ss.declareTex1D(name, textureIndex); + shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } else { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex2D(name); - shaderCreator->addToDeclareShaderCode(ss.string().c_str()); + ss.declareTex2D(name, textureIndex); + shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } // Sampler function diff --git a/src/OpenColorIO/ops/gradingprimary/GradingPrimaryOpGPU.cpp b/src/OpenColorIO/ops/gradingprimary/GradingPrimaryOpGPU.cpp index 8e83ba45ed..d38314bc53 100644 --- a/src/OpenColorIO/ops/gradingprimary/GradingPrimaryOpGPU.cpp +++ b/src/OpenColorIO/ops/gradingprimary/GradingPrimaryOpGPU.cpp @@ -42,7 +42,7 @@ void AddUniform(GpuShaderCreatorRcPtr & shaderCreator, // Declare uniform. GpuShaderText stDecl(shaderCreator->getLanguage()); stDecl.declareUniformFloat(name); - shaderCreator->addToDeclareShaderCode(stDecl.string().c_str()); + shaderCreator->addToParameterDeclareShaderCode(stDecl.string().c_str()); } } @@ -56,7 +56,7 @@ void AddBoolUniform(GpuShaderCreatorRcPtr & shaderCreator, // Declare uniform. GpuShaderText stDecl(shaderCreator->getLanguage()); stDecl.declareUniformBool(name); - shaderCreator->addToDeclareShaderCode(stDecl.string().c_str()); + shaderCreator->addToParameterDeclareShaderCode(stDecl.string().c_str()); } } @@ -70,7 +70,7 @@ void AddUniform(GpuShaderCreatorRcPtr & shaderCreator, // Declare uniform. GpuShaderText stDecl(shaderCreator->getLanguage()); stDecl.declareUniformFloat3(name); - shaderCreator->addToDeclareShaderCode(stDecl.string().c_str()); + shaderCreator->addToParameterDeclareShaderCode(stDecl.string().c_str()); } } diff --git a/src/OpenColorIO/ops/gradingrgbcurve/GradingRGBCurveOpGPU.cpp b/src/OpenColorIO/ops/gradingrgbcurve/GradingRGBCurveOpGPU.cpp index 3ce01247cf..fd5349c6df 100644 --- a/src/OpenColorIO/ops/gradingrgbcurve/GradingRGBCurveOpGPU.cpp +++ b/src/OpenColorIO/ops/gradingrgbcurve/GradingRGBCurveOpGPU.cpp @@ -91,7 +91,7 @@ void AddUniform(GpuShaderCreatorRcPtr & shaderCreator, // Declare uniform. GpuShaderText stDecl(shaderCreator->getLanguage()); stDecl.declareUniformArrayFloat(name, maxSize); - shaderCreator->addToDeclareShaderCode(stDecl.string().c_str()); + shaderCreator->addToParameterDeclareShaderCode(stDecl.string().c_str()); } } @@ -107,7 +107,7 @@ void AddUniform(GpuShaderCreatorRcPtr & shaderCreator, GpuShaderText stDecl(shaderCreator->getLanguage()); // Need 2 ints for each RGBM curve. stDecl.declareUniformArrayInt(name, 8); - shaderCreator->addToDeclareShaderCode(stDecl.string().c_str()); + shaderCreator->addToParameterDeclareShaderCode(stDecl.string().c_str()); } } @@ -121,7 +121,7 @@ void AddUniform(GpuShaderCreatorRcPtr & shaderCreator, // Declare uniform. GpuShaderText stDecl(shaderCreator->getLanguage()); stDecl.declareUniformBool(name); - shaderCreator->addToDeclareShaderCode(stDecl.string().c_str()); + shaderCreator->addToParameterDeclareShaderCode(stDecl.string().c_str()); } } diff --git a/src/OpenColorIO/ops/gradingtone/GradingToneOpGPU.cpp b/src/OpenColorIO/ops/gradingtone/GradingToneOpGPU.cpp index 3c64b5046e..6e9c56bb16 100644 --- a/src/OpenColorIO/ops/gradingtone/GradingToneOpGPU.cpp +++ b/src/OpenColorIO/ops/gradingtone/GradingToneOpGPU.cpp @@ -66,7 +66,7 @@ void AddUniform(GpuShaderCreatorRcPtr & shaderCreator, // Declare uniform. GpuShaderText stDecl(shaderCreator->getLanguage()); stDecl.declareUniformFloat(name); - shaderCreator->addToDeclareShaderCode(stDecl.string().c_str()); + shaderCreator->addToParameterDeclareShaderCode(stDecl.string().c_str()); } } @@ -80,7 +80,7 @@ void AddBoolUniform(GpuShaderCreatorRcPtr & shaderCreator, // Declare uniform. GpuShaderText stDecl(shaderCreator->getLanguage()); stDecl.declareUniformBool(name); - shaderCreator->addToDeclareShaderCode(stDecl.string().c_str()); + shaderCreator->addToParameterDeclareShaderCode(stDecl.string().c_str()); } } diff --git a/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp b/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp index 26a5c7d712..7009fed0cb 100644 --- a/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp +++ b/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp @@ -199,15 +199,15 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, } // (Using CacheID here to potentially allow reuse of existing textures.) - shaderCreator->addTexture(name.c_str(), - GpuShaderText::getSamplerName(name).c_str(), - width, - height, - singleChannel ? GpuShaderCreator::TEXTURE_RED_CHANNEL - : GpuShaderCreator::TEXTURE_RGB_CHANNEL, - dimensions, - lutData->getConcreteInterpolation(), - &values[0]); + const unsigned textureIndex = shaderCreator->addTexture(name.c_str(), + GpuShaderText::getSamplerName(name).c_str(), + width, + height, + singleChannel ? GpuShaderCreator::TEXTURE_RED_CHANNEL + : GpuShaderCreator::TEXTURE_RGB_CHANNEL, + dimensions, + lutData->getConcreteInterpolation(), + &values[0]); // Add the LUT code to the OCIO shader program. @@ -219,8 +219,8 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex2D(name); - shaderCreator->addToDeclareShaderCode(ss.string().c_str()); + ss.declareTex2D(name, textureIndex); + shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } { @@ -303,8 +303,8 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, else { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex1D(name); - shaderCreator->addToDeclareShaderCode(ss.string().c_str()); + ss.declareTex1D(name, textureIndex); + shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } GpuShaderText ss(shaderCreator->getLanguage()); diff --git a/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp b/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp index 786f52961c..e9e046383f 100644 --- a/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp +++ b/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp @@ -39,19 +39,18 @@ void GetLut3DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, ConstLut3DO samplerInterpolation = INTERP_NEAREST; } // (Using CacheID here to potentially allow reuse of existing textures.) - shaderCreator->add3DTexture(name.c_str(), - GpuShaderText::getSamplerName(name).c_str(), - lutData->getGridSize(), - samplerInterpolation, - &lutData->getArray()[0]); + const unsigned textureIndex = shaderCreator->add3DTexture(name.c_str(), + GpuShaderText::getSamplerName(name).c_str(), + lutData->getGridSize(), + samplerInterpolation, + &lutData->getArray()[0]); { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex3D(name); - shaderCreator->addToDeclareShaderCode(ss.string().c_str()); + ss.declareTex3D(name, textureIndex); + shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } - const float dim = (float)lutData->getGridSize(); // incr = 1/dim (amount needed to increment one index in the grid) diff --git a/src/apps/ociodisplay/main.cpp b/src/apps/ociodisplay/main.cpp index ed7f09759a..4a481ea24b 100644 --- a/src/apps/ociodisplay/main.cpp +++ b/src/apps/ociodisplay/main.cpp @@ -380,8 +380,13 @@ void UpdateOCIOGLState() { double exponent = 1.0 / std::max(1e-6, static_cast(g_display_gamma)); const double exponent4f[4] = {exponent, exponent, exponent, exponent}; - OCIO::ExponentTransformRcPtr expTransform = OCIO::ExponentTransform::Create(); - expTransform->setValue(exponent4f); + //OCIO::ExponentTransformRcPtr expTransform = OCIO::ExponentTransform::Create(); + //expTransform->setValue(exponent4f); + + OCIO::GradingToneTransformRcPtr expTransform = OCIO::GradingToneTransform::Create(OCIO::GRADING_LOG); + expTransform->setDirection(OCIO::TRANSFORM_DIR_FORWARD); + expTransform->setStyle(OCIO::GRADING_LOG); + //expTransform->setValue(tones); vp->setDisplayCC(expTransform); } @@ -406,7 +411,7 @@ void UpdateOCIOGLState() #if __APPLE__ g_useMetal ? OCIO::GPU_LANGUAGE_MSL_2_0 : #endif - OCIO::GPU_LANGUAGE_GLSL_1_2); + OCIO::GPU_LANGUAGE_GLSL_VK_4_6);//OCIO::GPU_LANGUAGE_GLSL_1_2); shaderDesc->setFunctionName("OCIODisplay"); shaderDesc->setResourcePrefix("ocio_"); diff --git a/src/bindings/python/PyGpuShaderCreator.cpp b/src/bindings/python/PyGpuShaderCreator.cpp index c133cb3efd..34846227b0 100644 --- a/src/bindings/python/PyGpuShaderCreator.cpp +++ b/src/bindings/python/PyGpuShaderCreator.cpp @@ -94,8 +94,10 @@ void bindPyGpuShaderCreator(py::module & m) }) // Methods to specialize parts of a OCIO shader program - .def("addToDeclareShaderCode", &GpuShaderCreator::addToDeclareShaderCode, "shaderCode"_a, - DOC(GpuShaderCreator, addToDeclareShaderCode)) + .def("addToParameterDeclareShaderCode", &GpuShaderCreator::addToParameterDeclareShaderCode, "shaderCode"_a, + DOC(GpuShaderCreator, addToParameterDeclareShaderCode)) + .def("addToTextureDeclareShaderCode", &GpuShaderCreator::addToTextureDeclareShaderCode, "shaderCode"_a, + DOC(GpuShaderCreator, addToTextureDeclareShaderCode)) .def("addToHelperShaderCode", &GpuShaderCreator::addToHelperShaderCode, "shaderCode"_a, DOC(GpuShaderCreator, addToHelperShaderCode)) .def("addToFunctionHeaderShaderCode", @@ -109,7 +111,8 @@ void bindPyGpuShaderCreator(py::module & m) "shaderCode"_a, DOC(GpuShaderCreator, addToFunctionFooterShaderCode)) .def("createShaderText", &GpuShaderCreator::createShaderText, - "shaderDeclarations"_a, "shaderHelperMethods"_a, "shaderFunctionHeader"_a, + "shaderParameterDeclarations"_a, "shaderTextureDeclarations"_a, + "shaderHelperMethods"_a, "shaderFunctionHeader"_a, "shaderFunctionBody"_a, "shaderFunctionFooter"_a, DOC(GpuShaderCreator, createShaderText)) .def("finalize", &GpuShaderCreator::finalize, diff --git a/src/bindings/python/PyTypes.cpp b/src/bindings/python/PyTypes.cpp index 5b22b56195..80110f0122 100644 --- a/src/bindings/python/PyTypes.cpp +++ b/src/bindings/python/PyTypes.cpp @@ -519,6 +519,8 @@ void bindPyTypes(py::module & m) DOC(PyOpenColorIO, GpuLanguage, GPU_LANGUAGE_GLSL_1_3)) .value("GPU_LANGUAGE_GLSL_4_0", GPU_LANGUAGE_GLSL_4_0, DOC(PyOpenColorIO, GpuLanguage, GPU_LANGUAGE_GLSL_4_0)) + .value("GPU_LANGUAGE_GLSL_VK_4_6", GPU_LANGUAGE_GLSL_VK_4_6, + DOC(PyOpenColorIO, GpuLanguage, GPU_LANGUAGE_GLSL_VK_4_6)) .value("GPU_LANGUAGE_GLSL_ES_1_0", GPU_LANGUAGE_GLSL_ES_1_0, DOC(PyOpenColorIO, GpuLanguage, GPU_LANGUAGE_GLSL_ES_1_0)) .value("GPU_LANGUAGE_GLSL_ES_3_0", GPU_LANGUAGE_GLSL_ES_3_0, diff --git a/src/libutils/oglapphelpers/glsl.cpp b/src/libutils/oglapphelpers/glsl.cpp index 0154effa35..3d94238898 100644 --- a/src/libutils/oglapphelpers/glsl.cpp +++ b/src/libutils/oglapphelpers/glsl.cpp @@ -463,6 +463,8 @@ std::string OpenGLBuilder::getGLSLVersionString() return "#version 130"; case GPU_LANGUAGE_GLSL_4_0: return "#version 400 core"; + case GPU_LANGUAGE_GLSL_VK_4_6: + return "#version 120 //460 core"; case GPU_LANGUAGE_GLSL_ES_1_0: return "#version 100"; case GPU_LANGUAGE_GLSL_ES_3_0: diff --git a/tests/cpu/GpuShader_tests.cpp b/tests/cpu/GpuShader_tests.cpp index 961fe269bf..559e95b285 100644 --- a/tests/cpu/GpuShader_tests.cpp +++ b/tests/cpu/GpuShader_tests.cpp @@ -172,7 +172,7 @@ OCIO_ADD_TEST(GpuShader, generic_shader) } { - OCIO_CHECK_NO_THROW(shaderDesc->addToDeclareShaderCode("vec2 coords;\n")); + OCIO_CHECK_NO_THROW(shaderDesc->addToParameterDeclareShaderCode("vec2 coords;\n")); OCIO_CHECK_NO_THROW(shaderDesc->addToHelperShaderCode("vec2 helpers() {}\n\n")); OCIO_CHECK_NO_THROW(shaderDesc->addToFunctionHeaderShaderCode("void func() {\n")); OCIO_CHECK_NO_THROW(shaderDesc->addToFunctionShaderCode(" int i;\n")); From c457c3e142ebe668ba061796551780390b082e2f Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Mon, 19 May 2025 13:09:03 +0200 Subject: [PATCH 02/19] Activated Vulkan shader generation, fixed bool handling. Signed-off-by: Michael Horsch --- src/OpenColorIO/GpuShaderDesc.cpp | 8 ++--- src/OpenColorIO/GpuShaderUtils.cpp | 33 ++++++++++++------- src/OpenColorIO/GpuShaderUtils.h | 2 ++ .../gradingprimary/GradingPrimaryOpGPU.cpp | 6 ++-- .../gradingrgbcurve/GradingRGBCurveOpGPU.cpp | 4 +-- .../ops/gradingtone/GradingToneOpGPU.cpp | 2 +- src/apps/ociodisplay/main.cpp | 3 +- src/libutils/oglapphelpers/glsl.cpp | 2 +- 8 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/OpenColorIO/GpuShaderDesc.cpp b/src/OpenColorIO/GpuShaderDesc.cpp index 2fbfcf23f3..7282d31eb6 100644 --- a/src/OpenColorIO/GpuShaderDesc.cpp +++ b/src/OpenColorIO/GpuShaderDesc.cpp @@ -304,14 +304,14 @@ void GpuShaderCreator::createShaderText(const char * shaderParameterDeclarations getImpl()->m_shaderCode.clear(); - if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6) + if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6 && (shaderParameterDeclarations && *shaderParameterDeclarations)) { - getImpl()->m_shaderCode += "/*layout (set = 0, binding = 0) uniform OCIOParameters\n {\n*/"; + getImpl()->m_shaderCode += "layout (set = 0, binding = 0) uniform OCIOParameters\n {\n"; } getImpl()->m_shaderCode += (shaderParameterDeclarations && *shaderParameterDeclarations) ? shaderParameterDeclarations : ""; - if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6) + if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6 && (shaderParameterDeclarations && *shaderParameterDeclarations)) { - getImpl()->m_shaderCode += "\n/*};*/\n"; + getImpl()->m_shaderCode += "\n};\n"; } getImpl()->m_shaderCode += (shaderTextureDeclarations && *shaderTextureDeclarations) ? shaderTextureDeclarations : ""; diff --git a/src/OpenColorIO/GpuShaderUtils.cpp b/src/OpenColorIO/GpuShaderUtils.cpp index 338e8aa008..43f4f3319f 100644 --- a/src/OpenColorIO/GpuShaderUtils.cpp +++ b/src/OpenColorIO/GpuShaderUtils.cpp @@ -105,7 +105,7 @@ void getTexDecl(GpuLanguage lang, textureDecl = ""; std::ostringstream kw; - kw << "/*layout(set=0, binding="<setValue(exponent4f); - OCIO::GradingToneTransformRcPtr expTransform = OCIO::GradingToneTransform::Create(OCIO::GRADING_LOG); + OCIO::GradingPrimaryTransformRcPtr expTransform = OCIO::GradingPrimaryTransform::Create(OCIO::GRADING_LOG); expTransform->setDirection(OCIO::TRANSFORM_DIR_FORWARD); expTransform->setStyle(OCIO::GRADING_LOG); + expTransform->makeDynamic(); //expTransform->setValue(tones); vp->setDisplayCC(expTransform); } diff --git a/src/libutils/oglapphelpers/glsl.cpp b/src/libutils/oglapphelpers/glsl.cpp index 3d94238898..791648e66e 100644 --- a/src/libutils/oglapphelpers/glsl.cpp +++ b/src/libutils/oglapphelpers/glsl.cpp @@ -464,7 +464,7 @@ std::string OpenGLBuilder::getGLSLVersionString() case GPU_LANGUAGE_GLSL_4_0: return "#version 400 core"; case GPU_LANGUAGE_GLSL_VK_4_6: - return "#version 120 //460 core"; + return "#version 460 core"; case GPU_LANGUAGE_GLSL_ES_1_0: return "#version 100"; case GPU_LANGUAGE_GLSL_ES_3_0: From eff475785adfb22b8e4399ef9e378c50b921b49f Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Wed, 28 May 2025 11:49:03 +0200 Subject: [PATCH 03/19] Replaced tabs with spaces. Signed-off-by: Michael Horsch --- include/OpenColorIO/OpenColorIO.h | 4 +- include/OpenColorIO/OpenColorTypes.h | 2 +- src/OpenColorIO/GpuShader.cpp | 16 ++++---- src/OpenColorIO/GpuShaderClassWrapper.h | 16 ++++---- src/OpenColorIO/GpuShaderDesc.cpp | 10 ++--- src/OpenColorIO/GpuShaderUtils.cpp | 50 ++++++++++++------------- src/OpenColorIO/GpuShaderUtils.h | 2 +- src/OpenColorIO/ParseUtils.cpp | 2 +- src/apps/ociodisplay/main.cpp | 6 +-- 9 files changed, 54 insertions(+), 54 deletions(-) diff --git a/include/OpenColorIO/OpenColorIO.h b/include/OpenColorIO/OpenColorIO.h index e267d758f6..15e0a78d4a 100644 --- a/include/OpenColorIO/OpenColorIO.h +++ b/include/OpenColorIO/OpenColorIO.h @@ -3395,7 +3395,7 @@ class OCIOEXPORT GpuShaderCreator * within a client shader program, imposing constraints requiring this flexibility. */ virtual void createShaderText(const char * shaderParameterDeclarations, - const char * shaderTextureDeclarations, + const char * shaderTextureDeclarations, const char * shaderHelperMethods, const char * shaderFunctionHeader, const char * shaderFunctionBody, @@ -3607,7 +3607,7 @@ class OCIOEXPORT GpuShaderDesc : public GpuShaderCreator /// Returns name of uniform and data as parameter. virtual const char * getUniform(unsigned index, UniformData & data) const = 0; - virtual std::size_t getUniformBufferSize() const noexcept = 0; + virtual std::size_t getUniformBufferSize() const noexcept = 0; // 1D lut related methods virtual unsigned getNumTextures() const noexcept = 0; diff --git a/include/OpenColorIO/OpenColorTypes.h b/include/OpenColorIO/OpenColorTypes.h index 9746c133b9..4893c78234 100644 --- a/include/OpenColorIO/OpenColorTypes.h +++ b/include/OpenColorIO/OpenColorTypes.h @@ -449,7 +449,7 @@ enum GpuLanguage GPU_LANGUAGE_GLSL_1_2, ///< OpenGL Shading Language GPU_LANGUAGE_GLSL_1_3, ///< OpenGL Shading Language GPU_LANGUAGE_GLSL_4_0, ///< OpenGL Shading Language - GPU_LANGUAGE_GLSL_VK_4_6, ///< OpenGL Shading Language for Vulkan + GPU_LANGUAGE_GLSL_VK_4_6, ///< OpenGL Shading Language for Vulkan GPU_LANGUAGE_HLSL_SM_5_0, ///< DirectX High Level Shading Language LANGUAGE_OSL_1, ///< Open Shading Language GPU_LANGUAGE_GLSL_ES_1_0, ///< OpenGL ES Shading Language diff --git a/src/OpenColorIO/GpuShader.cpp b/src/OpenColorIO/GpuShader.cpp index fbc8ac6f43..b1f6bc09c1 100644 --- a/src/OpenColorIO/GpuShader.cpp +++ b/src/OpenColorIO/GpuShader.cpp @@ -111,7 +111,7 @@ class PrivateImpl { m_data.m_type = UNIFORM_DOUBLE; m_data.m_getDouble = getDouble; - m_data.m_bufferOffset = bufferOffset; + m_data.m_bufferOffset = bufferOffset; } Uniform(const char * name, const GpuShaderCreator::BoolGetter & getBool, std::size_t bufferOffset) @@ -270,7 +270,7 @@ class PrivateImpl GpuShaderDesc::TEXTURE_RGB_CHANNEL, 3, interpolation, values); m_textures3D.push_back(t); - return textureIndex; + return textureIndex; } void get3DTexture(unsigned index, @@ -372,7 +372,7 @@ class PrivateImpl return false; } m_uniforms.emplace_back(name, getSize, getVector, m_uniformBufferSize); - const std::size_t arraySizeInBytes = sizeof(float) * getSize(); + const std::size_t arraySizeInBytes = sizeof(float) * getSize(); m_uniformBufferSize += arraySizeInBytes + UNIFORM_BUFFER_ALIGNMENT - (arraySizeInBytes % UNIFORM_BUFFER_ALIGNMENT); return true; } @@ -392,10 +392,10 @@ class PrivateImpl return true; } - std::size_t getUniformBufferSize() const - { - return m_uniformBufferSize; - } + std::size_t getUniformBufferSize() const + { + return m_uniformBufferSize; + } Textures m_textures; Textures m_textures3D; Uniforms m_uniforms; @@ -484,7 +484,7 @@ bool GenericGpuShaderDesc::addUniform(const char * name, std::size_t GenericGpuShaderDesc::getUniformBufferSize() const noexcept { - return getImplGeneric()->getUniformBufferSize(); + return getImplGeneric()->getUniformBufferSize(); } unsigned GenericGpuShaderDesc::getTextureMaxWidth() const noexcept diff --git a/src/OpenColorIO/GpuShaderClassWrapper.h b/src/OpenColorIO/GpuShaderClassWrapper.h index ab21747606..cbe01b3545 100644 --- a/src/OpenColorIO/GpuShaderClassWrapper.h +++ b/src/OpenColorIO/GpuShaderClassWrapper.h @@ -53,10 +53,10 @@ class NullGpuShaderClassWrapper : public GpuShaderClassWrapper { return originalFooter; } - bool hasClassWrapperHeader() const final - { - return false; - } + bool hasClassWrapperHeader() const final + { + return false; + } std::unique_ptr clone() const final; }; @@ -74,10 +74,10 @@ class OSLShaderClassWrapper : public GpuShaderClassWrapper std::string getClassWrapperHeader(const std::string & originalHeader) final; std::string getClassWrapperFooter(const std::string & originalFooter) final; - bool hasClassWrapperHeader() const final - { - return true; - } + bool hasClassWrapperHeader() const final + { + return true; + } std::unique_ptr clone() const final; diff --git a/src/OpenColorIO/GpuShaderDesc.cpp b/src/OpenColorIO/GpuShaderDesc.cpp index 7282d31eb6..df4a30b800 100644 --- a/src/OpenColorIO/GpuShaderDesc.cpp +++ b/src/OpenColorIO/GpuShaderDesc.cpp @@ -33,7 +33,7 @@ class GpuShaderCreator::Impl mutable Mutex m_cacheIDMutex; std::string m_parameterDeclarations; - std::string m_textureDeclarations; + std::string m_textureDeclarations; std::string m_helperMethods; std::string m_functionHeader; std::string m_functionBody; @@ -71,7 +71,7 @@ class GpuShaderCreator::Impl m_cacheID = rhs.m_cacheID; m_parameterDeclarations = rhs.m_parameterDeclarations; - m_textureDeclarations = rhs.m_textureDeclarations; + m_textureDeclarations = rhs.m_textureDeclarations; m_helperMethods = rhs.m_helperMethods; m_functionHeader = rhs.m_functionHeader; m_functionBody = rhs.m_functionBody; @@ -306,7 +306,7 @@ void GpuShaderCreator::createShaderText(const char * shaderParameterDeclarations if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6 && (shaderParameterDeclarations && *shaderParameterDeclarations)) { - getImpl()->m_shaderCode += "layout (set = 0, binding = 0) uniform OCIOParameters\n {\n"; + getImpl()->m_shaderCode += "layout (set = 0, binding = 0) uniform OCIOParameters\n {\n"; } getImpl()->m_shaderCode += (shaderParameterDeclarations && *shaderParameterDeclarations) ? shaderParameterDeclarations : ""; if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6 && (shaderParameterDeclarations && *shaderParameterDeclarations)) @@ -340,7 +340,7 @@ void GpuShaderCreator::finalize() { getImpl()->m_parameterDeclarations = getImpl()->m_classWrappingInterface->getClassWrapperHeader(originalHeader); - getImpl()->m_textureDeclarations.clear(); //clear texture declarations since they're already included in the header + getImpl()->m_textureDeclarations.clear(); //clear texture declarations since they're already included in the header } getImpl()->m_functionFooter = getImpl()->m_classWrappingInterface->getClassWrapperFooter(getImpl()->m_functionFooter); @@ -349,7 +349,7 @@ void GpuShaderCreator::finalize() // Build the complete shader program. createShaderText(getImpl()->m_parameterDeclarations.c_str(), - getImpl()->m_textureDeclarations.c_str(), + getImpl()->m_textureDeclarations.c_str(), getImpl()->m_helperMethods.c_str(), getImpl()->m_functionHeader.c_str(), getImpl()->m_functionBody.c_str(), diff --git a/src/OpenColorIO/GpuShaderUtils.cpp b/src/OpenColorIO/GpuShaderUtils.cpp index 43f4f3319f..99825c5975 100644 --- a/src/OpenColorIO/GpuShaderUtils.cpp +++ b/src/OpenColorIO/GpuShaderUtils.cpp @@ -350,7 +350,7 @@ std::string GpuShaderText::constKeyword() const case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: - case GPU_LANGUAGE_GLSL_VK_4_6: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: case GPU_LANGUAGE_MSL_2_0: @@ -545,7 +545,7 @@ void GpuShaderText::declareFloatArrayConst(const std::string & name, int size, c case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: - case GPU_LANGUAGE_GLSL_VK_4_6: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: { @@ -608,7 +608,7 @@ void GpuShaderText::declareIntArrayConst(const std::string & name, int size, con case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: - case GPU_LANGUAGE_GLSL_VK_4_6: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: { @@ -912,31 +912,31 @@ std::string GpuShaderText::sampleTex3D(const std::string& textureName, void GpuShaderText::declareUniformFloat(const std::string & uniformName) { std::string uniformDeclString("uniform"); - if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { - uniformDeclString = ""; - } + uniformDeclString = ""; + } newLine() << uniformDeclString << floatKeyword() << " " << uniformName << ";"; - if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { - //add padding for 16 byte alignment required by Vulkan - newLine() << floatKeyword() << " " << uniformName<<"_pad0, "<< uniformName<<"_pad1, "<< uniformName<<"_pad2;"; - } + //add padding for 16 byte alignment required by Vulkan + newLine() << floatKeyword() << " " << uniformName<<"_pad0, "<< uniformName<<"_pad1, "<< uniformName<<"_pad2;"; + } } void GpuShaderText::declareUniformBool(const std::string & uniformName) { std::string uniformDeclString("uniform"); - std::string boolKeyword("bool"); + std::string boolKeyword("bool"); if (m_lang == GPU_LANGUAGE_MSL_2_0) { uniformDeclString = ""; } - else if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) - { + else if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + { uniformDeclString = ""; - boolKeyword = "int"; - } + boolKeyword = "int"; + } newLine() << uniformDeclString << boolKeyword << " " << uniformName << ";"; if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { @@ -966,10 +966,10 @@ void GpuShaderText::declareUniformArrayFloat(const std::string & uniformName, un if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { uniformDeclString = ""; - if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) + if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { - size = (size + 3) / 4 * 4; // round up to the next multiple of 4 for 16 byte alignment - } + size = (size + 3) / 4 * 4; // round up to the next multiple of 4 for 16 byte alignment + } } newLine() << uniformDeclString << floatKeyword() << " " << uniformName << "[" << size << "];"; } @@ -1003,7 +1003,7 @@ std::string matrix3Mul(const T * m3x3, const std::string & vecName, GpuLanguage case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: - case GPU_LANGUAGE_GLSL_VK_4_6: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: { @@ -1201,7 +1201,7 @@ std::string GpuShaderText::float4GreaterThan(const std::string & a, case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: - case GPU_LANGUAGE_GLSL_VK_4_6: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: case GPU_LANGUAGE_CG: @@ -1246,7 +1246,7 @@ std::string GpuShaderText::float3GreaterThanEqual(const std::string& a, case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: - case GPU_LANGUAGE_GLSL_VK_4_6: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: case GPU_LANGUAGE_CG: @@ -1282,7 +1282,7 @@ std::string GpuShaderText::float4GreaterThanEqual(const std::string& a, case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: - case GPU_LANGUAGE_GLSL_VK_4_6: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: case GPU_LANGUAGE_CG: @@ -1368,7 +1368,7 @@ std::string GpuShaderText::sign(const std::string & v) const case GPU_LANGUAGE_GLSL_1_2: case GPU_LANGUAGE_GLSL_1_3: case GPU_LANGUAGE_GLSL_4_0: - case GPU_LANGUAGE_GLSL_VK_4_6: + case GPU_LANGUAGE_GLSL_VK_4_6: case GPU_LANGUAGE_GLSL_ES_1_0: case GPU_LANGUAGE_GLSL_ES_3_0: case GPU_LANGUAGE_HLSL_SM_5_0: @@ -1395,9 +1395,9 @@ std::string GpuShaderText::castToBool(const std::string& v) const { if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { - return "bool(" + v + ")"; + return "bool(" + v + ")"; } - return v; + return v; } diff --git a/src/OpenColorIO/GpuShaderUtils.h b/src/OpenColorIO/GpuShaderUtils.h index d6e344809e..019b0311ff 100644 --- a/src/OpenColorIO/GpuShaderUtils.h +++ b/src/OpenColorIO/GpuShaderUtils.h @@ -231,7 +231,7 @@ class GpuShaderText // Get the string for taking the sign of a vector. std::string sign(const std::string & v) const; - std::string castToBool(const std::string& v) const; + std::string castToBool(const std::string& v) const; friend class GpuShaderLine; diff --git a/src/OpenColorIO/ParseUtils.cpp b/src/OpenColorIO/ParseUtils.cpp index 41e5a41503..e4c9707789 100644 --- a/src/OpenColorIO/ParseUtils.cpp +++ b/src/OpenColorIO/ParseUtils.cpp @@ -283,7 +283,7 @@ GpuLanguage GpuLanguageFromString(const char * s) else if(str == "glsl_1.2") return GPU_LANGUAGE_GLSL_1_2; else if(str == "glsl_1.3") return GPU_LANGUAGE_GLSL_1_3; else if(str == "glsl_4.0") return GPU_LANGUAGE_GLSL_4_0; - else if(str == "glsl_vk_4.6") return GPU_LANGUAGE_GLSL_VK_4_6; + else if(str == "glsl_vk_4.6") return GPU_LANGUAGE_GLSL_VK_4_6; else if(str == "glsl_es_1.0") return GPU_LANGUAGE_GLSL_ES_1_0; else if(str == "glsl_es_3.0") return GPU_LANGUAGE_GLSL_ES_3_0; else if(str == "hlsl_sm_5.0") return GPU_LANGUAGE_HLSL_SM_5_0; diff --git a/src/apps/ociodisplay/main.cpp b/src/apps/ociodisplay/main.cpp index b8492e73a5..977588e9dd 100644 --- a/src/apps/ociodisplay/main.cpp +++ b/src/apps/ociodisplay/main.cpp @@ -383,10 +383,10 @@ void UpdateOCIOGLState() //OCIO::ExponentTransformRcPtr expTransform = OCIO::ExponentTransform::Create(); //expTransform->setValue(exponent4f); - OCIO::GradingPrimaryTransformRcPtr expTransform = OCIO::GradingPrimaryTransform::Create(OCIO::GRADING_LOG); + OCIO::GradingPrimaryTransformRcPtr expTransform = OCIO::GradingPrimaryTransform::Create(OCIO::GRADING_LOG); expTransform->setDirection(OCIO::TRANSFORM_DIR_FORWARD); - expTransform->setStyle(OCIO::GRADING_LOG); - expTransform->makeDynamic(); + expTransform->setStyle(OCIO::GRADING_LOG); + expTransform->makeDynamic(); //expTransform->setValue(tones); vp->setDisplayCC(expTransform); } From c4300c4b8f372e4e0862392f097087c78f4c7350 Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Wed, 28 May 2025 16:27:11 +0200 Subject: [PATCH 04/19] Documentation added for new methods, return values and member variables. Signed-off-by: Michael Horsch --- include/OpenColorIO/OpenColorIO.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/OpenColorIO/OpenColorIO.h b/include/OpenColorIO/OpenColorIO.h index 15e0a78d4a..7fd4c76e92 100644 --- a/include/OpenColorIO/OpenColorIO.h +++ b/include/OpenColorIO/OpenColorIO.h @@ -3355,6 +3355,9 @@ class OCIOEXPORT GpuShaderCreator * \note * The 'values' parameter contains the LUT data which must be used as-is as the dimensions and * origin are hard-coded in the fragment shader program. So, it means one GPU texture per entry. + * + * \return Index of the texture. For shading languages using explicit texture bindings, the return + * value is the same as the texture binding index in the generated shader program. **/ virtual unsigned addTexture(const char * textureName, const char * samplerName, @@ -3371,6 +3374,9 @@ class OCIOEXPORT GpuShaderCreator * The 'values' parameter contains the 3D LUT data which must be used as-is as the dimension * and origin are hard-coded in the fragment shader program. So, it means one GPU 3D texture * per entry. + * + * \return Index of the texture. For shading languages using explicit texture bindings, the return + * value is the same as the texture binding index in the generated shader program. **/ virtual unsigned add3DTexture(const char * textureName, const char * samplerName, @@ -3584,6 +3590,11 @@ class OCIOEXPORT GpuShaderDesc : public GpuShaderCreator * * UNIFORM_FLOAT3: m_getFloat3. * * UNIFORM_VECTOR_FLOAT: m_vectorFloat. * * UNIFORM_VECTOR_INT: m_vectorInt. + * + * The m_bufferOffset is the offset in bytes from the start of the uniform buffer. + * For shading languages that use uniform buffers, the offset can be used to + * determine the location of the uniform in the buffer and fill it with the + * corresponding data. */ struct UniformData { @@ -3607,6 +3618,14 @@ class OCIOEXPORT GpuShaderDesc : public GpuShaderCreator /// Returns name of uniform and data as parameter. virtual const char * getUniform(unsigned index, UniformData & data) const = 0; + /** + * For shading languages that use uniform buffers, a uniform buffer + * containing all uniforms is generated in the shader code. This method can + * be used to create a buffer of the same size in the client code that can + * be filled with the corresponding data. + * + * \return Size of the uniform buffer in bytes + **/ virtual std::size_t getUniformBufferSize() const noexcept = 0; // 1D lut related methods From 6b46f921ba21abebcdc7b126176bfbf5f2dd4e22 Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Tue, 3 Jun 2025 13:54:26 +0200 Subject: [PATCH 05/19] Padding and alignment for uniform buffers optimized, smaller fixes. Signed-off-by: Michael Horsch --- include/OpenColorIO/OpenColorIO.h | 2 +- src/OpenColorIO/GpuShader.cpp | 41 ++++++++++++++++++++++-------- src/OpenColorIO/GpuShaderUtils.cpp | 25 +----------------- src/apps/ociodisplay/main.cpp | 7 +++++ 4 files changed, 39 insertions(+), 36 deletions(-) diff --git a/include/OpenColorIO/OpenColorIO.h b/include/OpenColorIO/OpenColorIO.h index 7fd4c76e92..cfe2995bad 100644 --- a/include/OpenColorIO/OpenColorIO.h +++ b/include/OpenColorIO/OpenColorIO.h @@ -3599,7 +3599,7 @@ class OCIOEXPORT GpuShaderDesc : public GpuShaderCreator struct UniformData { UniformDataType m_type{ UNIFORM_UNKNOWN }; - std::size_t m_bufferOffset; + std::size_t m_bufferOffset{}; DoubleGetter m_getDouble{}; BoolGetter m_getBool{}; Float3Getter m_getFloat3{}; diff --git a/src/OpenColorIO/GpuShader.cpp b/src/OpenColorIO/GpuShader.cpp index b1f6bc09c1..86d70c9775 100644 --- a/src/OpenColorIO/GpuShader.cpp +++ b/src/OpenColorIO/GpuShader.cpp @@ -35,12 +35,28 @@ static void CreateArray(const float * buf, res.resize(size); std::memcpy(&res[0], buf, size * sizeof(float)); } + +std::size_t alignOffset(std::size_t offset, std::size_t alignment) +{ + if (alignment == 0) + { + throw Exception("Alignment cannot be zero."); + } + return ((offset + alignment - 1) / alignment) * alignment; +} + } namespace GPUShaderImpl { -constexpr std::size_t UNIFORM_BUFFER_ALIGNMENT = 16; //Align variables in uniform buffers to 16 bytes +constexpr size_t GPU_FLOAT_SIZE = 4; +constexpr size_t GPU_FLOAT_ALIGNMENT = 4; +constexpr size_t GPU_INT_SIZE = 4; +constexpr size_t GPU_INT_ALIGNMENT = 4; +constexpr size_t GPU_VEC3_SIZE = 12; +constexpr size_t GPU_VEC3_ALIGNMENT = 16; +constexpr size_t GPU_ARRAY_ALIGNMENT = 16; class PrivateImpl { @@ -197,7 +213,7 @@ class PrivateImpl << width << " > " << get1dLutMaxWidth(); throw Exception(ss.str().c_str()); } - unsigned textureIndex = m_textures.size(); + unsigned textureIndex = static_cast(m_textures.size()); unsigned numDimensions = static_cast(dimensions); Texture t(textureName, samplerName, width, height, 1, channel, numDimensions, interpolation, values); m_textures.push_back(t); @@ -265,7 +281,7 @@ class PrivateImpl throw Exception(ss.str().c_str()); } - unsigned textureIndex = m_textures3D.size(); + unsigned textureIndex = static_cast(m_textures3D.size()); Texture t(textureName, samplerName, edgelen, edgelen, edgelen, GpuShaderDesc::TEXTURE_RGB_CHANNEL, 3, interpolation, values); @@ -333,8 +349,9 @@ class PrivateImpl // Uniform is already there. return false; } + m_uniformBufferSize = alignOffset(m_uniformBufferSize, GPU_FLOAT_ALIGNMENT); m_uniforms.emplace_back(name, getter, m_uniformBufferSize); - m_uniformBufferSize += UNIFORM_BUFFER_ALIGNMENT; + m_uniformBufferSize += GPU_FLOAT_SIZE; return true; } @@ -345,8 +362,9 @@ class PrivateImpl // Uniform is already there. return false; } + m_uniformBufferSize = alignOffset(m_uniformBufferSize, GPU_INT_ALIGNMENT); m_uniforms.emplace_back(name, getter, m_uniformBufferSize); - m_uniformBufferSize += UNIFORM_BUFFER_ALIGNMENT; //bool not supported for buffered uniforms, using int instead + m_uniformBufferSize += GPU_INT_SIZE; //bool not supported for buffered uniforms, using int instead return true; } @@ -357,8 +375,9 @@ class PrivateImpl // Uniform is already there. return false; } + m_uniformBufferSize = alignOffset(m_uniformBufferSize, GPU_VEC3_ALIGNMENT); m_uniforms.emplace_back(name, getter, m_uniformBufferSize); - m_uniformBufferSize += UNIFORM_BUFFER_ALIGNMENT; + m_uniformBufferSize += GPU_VEC3_SIZE; return true; } @@ -371,9 +390,9 @@ class PrivateImpl // Uniform is already there. return false; } + m_uniformBufferSize = alignOffset(m_uniformBufferSize, GPU_ARRAY_ALIGNMENT); m_uniforms.emplace_back(name, getSize, getVector, m_uniformBufferSize); - const std::size_t arraySizeInBytes = sizeof(float) * getSize(); - m_uniformBufferSize += arraySizeInBytes + UNIFORM_BUFFER_ALIGNMENT - (arraySizeInBytes % UNIFORM_BUFFER_ALIGNMENT); + m_uniformBufferSize += GPU_FLOAT_SIZE * getSize(); return true; } @@ -386,9 +405,9 @@ class PrivateImpl // Uniform is already there. return false; } + m_uniformBufferSize = alignOffset(m_uniformBufferSize, GPU_ARRAY_ALIGNMENT); m_uniforms.emplace_back(name, getSize, getVectorInt, m_uniformBufferSize); - const std::size_t arraySizeInBytes = sizeof(int) * getSize(); - m_uniformBufferSize += arraySizeInBytes + UNIFORM_BUFFER_ALIGNMENT - (arraySizeInBytes % UNIFORM_BUFFER_ALIGNMENT); + m_uniformBufferSize += GPU_INT_SIZE * getSize(); return true; } @@ -414,7 +433,7 @@ class PrivateImpl } unsigned m_max1DLUTWidth; bool m_allowTexture1D; - unsigned m_uniformBufferSize; + std::size_t m_uniformBufferSize; }; } // namespace GPUShaderImpl diff --git a/src/OpenColorIO/GpuShaderUtils.cpp b/src/OpenColorIO/GpuShaderUtils.cpp index 99825c5975..c815327075 100644 --- a/src/OpenColorIO/GpuShaderUtils.cpp +++ b/src/OpenColorIO/GpuShaderUtils.cpp @@ -505,7 +505,7 @@ std::string GpuShaderText::declareVarStr(const std::string & name, bool v) throw Exception("GPU variable name is empty."); } - if (m_lang==LANGUAGE_OSL_1 || m_lang==GPU_LANGUAGE_GLSL_VK_4_6) + if (m_lang==LANGUAGE_OSL_1) { return intKeyword() + " " + name + " = " + (v ? "1" : "0"); } @@ -917,11 +917,6 @@ void GpuShaderText::declareUniformFloat(const std::string & uniformName) uniformDeclString = ""; } newLine() << uniformDeclString << floatKeyword() << " " << uniformName << ";"; - if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) - { - //add padding for 16 byte alignment required by Vulkan - newLine() << floatKeyword() << " " << uniformName<<"_pad0, "<< uniformName<<"_pad1, "<< uniformName<<"_pad2;"; - } } void GpuShaderText::declareUniformBool(const std::string & uniformName) @@ -938,11 +933,6 @@ void GpuShaderText::declareUniformBool(const std::string & uniformName) boolKeyword = "int"; } newLine() << uniformDeclString << boolKeyword << " " << uniformName << ";"; - if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) - { - //add padding for 16 byte alignment required by Vulkan - newLine() << boolKeyword << " " << uniformName << "_pad0, " << uniformName << "_pad1, " << uniformName << "_pad2;"; - } } void GpuShaderText::declareUniformFloat3(const std::string & uniformName) @@ -953,11 +943,6 @@ void GpuShaderText::declareUniformFloat3(const std::string & uniformName) uniformDeclString = ""; } newLine() << uniformDeclString << float3Keyword() << " " << uniformName << ";"; - if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) - { - //add padding for 16 byte alignment required by Vulkan - newLine() << floatKeyword() << " " << uniformName << "_pad;"; - } } void GpuShaderText::declareUniformArrayFloat(const std::string & uniformName, unsigned int size) @@ -966,10 +951,6 @@ void GpuShaderText::declareUniformArrayFloat(const std::string & uniformName, un if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { uniformDeclString = ""; - if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) - { - size = (size + 3) / 4 * 4; // round up to the next multiple of 4 for 16 byte alignment - } } newLine() << uniformDeclString << floatKeyword() << " " << uniformName << "[" << size << "];"; } @@ -980,10 +961,6 @@ void GpuShaderText::declareUniformArrayInt(const std::string & uniformName, unsi if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { uniformDeclString = ""; - if (m_lang == GPU_LANGUAGE_GLSL_VK_4_6) - { - size = (size + 3) / 4 * 4; // round up to the next multiple of 4 for 16 byte alignment - } } newLine() << uniformDeclString << intKeyword() << " " << uniformName << "[" << size << "];"; } diff --git a/src/apps/ociodisplay/main.cpp b/src/apps/ociodisplay/main.cpp index 977588e9dd..8f49ab6371 100644 --- a/src/apps/ociodisplay/main.cpp +++ b/src/apps/ociodisplay/main.cpp @@ -421,6 +421,13 @@ void UpdateOCIOGLState() : processor->getOptimizedGPUProcessor(g_optimization); gpu->extractGpuShaderInfo(shaderDesc); + for (int i = 0; i < shaderDesc->getNumUniforms(); ++i) + { + OCIO::GpuShaderDesc::UniformData uniform; + const char* name = shaderDesc->getUniform(i, uniform); + std::cout << name << " " << uniform.m_type << " " << uniform.m_bufferOffset << std::endl; + } + g_oglApp->setShader(shaderDesc); } From d792677d078540b2e9b09240318623c629dea682 Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Tue, 3 Jun 2025 15:15:27 +0200 Subject: [PATCH 06/19] Restored ociodisplay and removed code for testing. Signed-off-by: Michael Horsch --- src/OpenColorIO/GpuShaderUtils.cpp | 1 - src/apps/ociodisplay/main.cpp | 19 +++---------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/OpenColorIO/GpuShaderUtils.cpp b/src/OpenColorIO/GpuShaderUtils.cpp index c815327075..70daf92ac3 100644 --- a/src/OpenColorIO/GpuShaderUtils.cpp +++ b/src/OpenColorIO/GpuShaderUtils.cpp @@ -186,7 +186,6 @@ std::string getTexSample(GpuLanguage lang, case GPU_LANGUAGE_GLSL_VK_4_6: { kw << "texture(" << samplerName << ", " << coords << ")"; - //kw << "texture" << N << "D(" << samplerName << ", " << coords << ")";//TODO: For testing only, remove before commit break; } case GPU_LANGUAGE_GLSL_ES_3_0: diff --git a/src/apps/ociodisplay/main.cpp b/src/apps/ociodisplay/main.cpp index 8f49ab6371..ed7f09759a 100644 --- a/src/apps/ociodisplay/main.cpp +++ b/src/apps/ociodisplay/main.cpp @@ -380,14 +380,8 @@ void UpdateOCIOGLState() { double exponent = 1.0 / std::max(1e-6, static_cast(g_display_gamma)); const double exponent4f[4] = {exponent, exponent, exponent, exponent}; - //OCIO::ExponentTransformRcPtr expTransform = OCIO::ExponentTransform::Create(); - //expTransform->setValue(exponent4f); - - OCIO::GradingPrimaryTransformRcPtr expTransform = OCIO::GradingPrimaryTransform::Create(OCIO::GRADING_LOG); - expTransform->setDirection(OCIO::TRANSFORM_DIR_FORWARD); - expTransform->setStyle(OCIO::GRADING_LOG); - expTransform->makeDynamic(); - //expTransform->setValue(tones); + OCIO::ExponentTransformRcPtr expTransform = OCIO::ExponentTransform::Create(); + expTransform->setValue(exponent4f); vp->setDisplayCC(expTransform); } @@ -412,7 +406,7 @@ void UpdateOCIOGLState() #if __APPLE__ g_useMetal ? OCIO::GPU_LANGUAGE_MSL_2_0 : #endif - OCIO::GPU_LANGUAGE_GLSL_VK_4_6);//OCIO::GPU_LANGUAGE_GLSL_1_2); + OCIO::GPU_LANGUAGE_GLSL_1_2); shaderDesc->setFunctionName("OCIODisplay"); shaderDesc->setResourcePrefix("ocio_"); @@ -421,13 +415,6 @@ void UpdateOCIOGLState() : processor->getOptimizedGPUProcessor(g_optimization); gpu->extractGpuShaderInfo(shaderDesc); - for (int i = 0; i < shaderDesc->getNumUniforms(); ++i) - { - OCIO::GpuShaderDesc::UniformData uniform; - const char* name = shaderDesc->getUniform(i, uniform); - std::cout << name << " " << uniform.m_type << " " << uniform.m_bufferOffset << std::endl; - } - g_oglApp->setShader(shaderDesc); } From a52231972e25b58eac025d02aac37e4d69cc0fea Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Mon, 16 Jun 2025 17:37:55 +0200 Subject: [PATCH 07/19] Added functions to set/get descriptor set index and texture binding start index. Signed-off-by: Michael Horsch --- include/OpenColorIO/OpenColorIO.h | 15 +++++++++ src/OpenColorIO/GpuShaderDesc.cpp | 31 ++++++++++++++++++- src/OpenColorIO/GpuShaderUtils.cpp | 12 +++---- src/OpenColorIO/GpuShaderUtils.h | 6 ++-- .../ops/fixedfunction/FixedFunctionOpGPU.cpp | 8 ++--- src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp | 4 +-- src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp | 2 +- 7 files changed, 61 insertions(+), 17 deletions(-) diff --git a/include/OpenColorIO/OpenColorIO.h b/include/OpenColorIO/OpenColorIO.h index cfe2995bad..a6a6f27c0e 100644 --- a/include/OpenColorIO/OpenColorIO.h +++ b/include/OpenColorIO/OpenColorIO.h @@ -3270,6 +3270,21 @@ class OCIOEXPORT GpuShaderCreator /// Set a prefix to the resource name void setResourcePrefix(const char * prefix) noexcept; + /** + * \brief Set the descriptor set index and texture binding start index to use for the shader program. + * + * \note Only supported for shading languages that use descriptor sets and texture bindings. + * + * \param index The descriptor set index to use. + * \param textureBindingStart The texture binding start index to use. If 0, the default binding index is used + * which starts at 1 and is incremented by 1 for each texture. If not 0, the texture + * binding starts at textureBindingStart and is incremented by 1 for each texture. + * The binding of a texture is equal to the texture index + textureBindingStart. + * */ + void setDescriptorSetIndex(unsigned index, unsigned textureBindingStart = 0) noexcept; + unsigned getDescriptorSetIndex() const noexcept; + unsigned getTextureBindingStart() const noexcept; + virtual const char * getCacheID() const noexcept; /// Start to collect the shader data. diff --git a/src/OpenColorIO/GpuShaderDesc.cpp b/src/OpenColorIO/GpuShaderDesc.cpp index df4a30b800..b541d11db4 100644 --- a/src/OpenColorIO/GpuShaderDesc.cpp +++ b/src/OpenColorIO/GpuShaderDesc.cpp @@ -46,6 +46,9 @@ class GpuShaderCreator::Impl std::unique_ptr m_classWrappingInterface; + unsigned m_descriptorSetIndex = 0; + unsigned m_textureBindingStart = 1; + Impl() : m_functionName("OCIOMain") , m_resourcePrefix("ocio") @@ -79,6 +82,9 @@ class GpuShaderCreator::Impl m_classWrappingInterface = rhs.m_classWrappingInterface->clone(); + m_descriptorSetIndex = rhs.m_descriptorSetIndex; + m_textureBindingStart = rhs.m_textureBindingStart; + m_shaderCode.clear(); m_shaderCodeID.clear(); } @@ -169,6 +175,29 @@ unsigned GpuShaderCreator::getNextResourceIndex() noexcept return getImpl()->m_numResources++; } +void GpuShaderCreator::setDescriptorSetIndex(unsigned index, unsigned textureBindingStart) noexcept +{ + getImpl()->m_descriptorSetIndex = index; + if (textureBindingStart != 0) + { + getImpl()->m_textureBindingStart = textureBindingStart; + } + else + { + getImpl()->m_textureBindingStart = 1; + } +} + +unsigned GpuShaderCreator::getDescriptorSetIndex() const noexcept +{ + return getImpl()->m_descriptorSetIndex; +} + +unsigned GpuShaderCreator::getTextureBindingStart() const noexcept +{ + return getImpl()->m_textureBindingStart; +} + bool GpuShaderCreator::hasDynamicProperty(DynamicPropertyType type) const { for (const auto & dp : getImpl()->m_dynamicProperties) @@ -306,7 +335,7 @@ void GpuShaderCreator::createShaderText(const char * shaderParameterDeclarations if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6 && (shaderParameterDeclarations && *shaderParameterDeclarations)) { - getImpl()->m_shaderCode += "layout (set = 0, binding = 0) uniform OCIOParameters\n {\n"; + getImpl()->m_shaderCode += "layout (set = "+std::to_string(getImpl()->m_descriptorSetIndex) + ", binding = 0) uniform " + getImpl()->m_functionName + "_Parameters\n {\n"; } getImpl()->m_shaderCode += (shaderParameterDeclarations && *shaderParameterDeclarations) ? shaderParameterDeclarations : ""; if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6 && (shaderParameterDeclarations && *shaderParameterDeclarations)) diff --git a/src/OpenColorIO/GpuShaderUtils.cpp b/src/OpenColorIO/GpuShaderUtils.cpp index 70daf92ac3..58c086c7ca 100644 --- a/src/OpenColorIO/GpuShaderUtils.cpp +++ b/src/OpenColorIO/GpuShaderUtils.cpp @@ -841,10 +841,10 @@ std::string GpuShaderText::getSamplerName(const std::string& textureName) return textureName + "Sampler"; } -void GpuShaderText::declareTex1D(const std::string & textureName, const unsigned textureIndex) +void GpuShaderText::declareTex1D(const std::string & textureName, unsigned textureIndex, unsigned textureBindingStart) { std::string textureDecl, samplerDecl; - getTexDecl<1>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex); + getTexDecl<1>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex + textureBindingStart); if (!textureDecl.empty()) { @@ -857,10 +857,10 @@ void GpuShaderText::declareTex1D(const std::string & textureName, const unsigned } } -void GpuShaderText::declareTex2D(const std::string & textureName, const unsigned textureIndex) +void GpuShaderText::declareTex2D(const std::string & textureName, unsigned textureIndex, unsigned textureBindingStart) { std::string textureDecl, samplerDecl; - getTexDecl<2>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex); + getTexDecl<2>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex + textureBindingStart); if (!textureDecl.empty()) { @@ -873,10 +873,10 @@ void GpuShaderText::declareTex2D(const std::string & textureName, const unsigned } } -void GpuShaderText::declareTex3D(const std::string& textureName, const unsigned textureIndex) +void GpuShaderText::declareTex3D(const std::string& textureName, unsigned textureIndex, unsigned textureBindingStart) { std::string textureDecl, samplerDecl; - getTexDecl<3>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex); + getTexDecl<3>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex + textureBindingStart); if (!textureDecl.empty()) { diff --git a/src/OpenColorIO/GpuShaderUtils.h b/src/OpenColorIO/GpuShaderUtils.h index 019b0311ff..59a953a65d 100644 --- a/src/OpenColorIO/GpuShaderUtils.h +++ b/src/OpenColorIO/GpuShaderUtils.h @@ -171,11 +171,11 @@ class GpuShaderText static std::string getSamplerName(const std::string& textureName); // Declare the global texture and sampler information for a 1D texture. - void declareTex1D(const std::string& textureName, unsigned textureIndex); + void declareTex1D(const std::string& textureName, unsigned textureIndex, unsigned textureBindingStart); // Declare the global texture and sampler information for a 2D texture. - void declareTex2D(const std::string& textureName, unsigned textureIndex); + void declareTex2D(const std::string& textureName, unsigned textureIndex, unsigned textureBindingStart); // Declare the global texture and sampler information for a 3D texture. - void declareTex3D(const std::string& textureName, unsigned textureIndex); + void declareTex3D(const std::string& textureName, unsigned textureIndex, unsigned textureBindingStart); // Get the texture lookup call for a 1D texture. std::string sampleTex1D(const std::string& textureName, const std::string& coords) const; diff --git a/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp b/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp index 471b9a962b..1928b264de 100644 --- a/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp +++ b/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp @@ -541,13 +541,13 @@ std::string _Add_Reach_table( if (dimensions == GpuShaderDesc::TEXTURE_1D) { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex1D(name, textureIndex); + ss.declareTex1D(name, textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } else { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex2D(name, textureIndex); + ss.declareTex2D(name, textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } @@ -838,13 +838,13 @@ std::string _Add_Cusp_table( if (dimensions == GpuShaderDesc::TEXTURE_1D) { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex1D(name, textureIndex); + ss.declareTex1D(name, textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } else { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex2D(name, textureIndex); + ss.declareTex2D(name, textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } diff --git a/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp b/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp index 7009fed0cb..9e535a1f5f 100644 --- a/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp +++ b/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp @@ -219,7 +219,7 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex2D(name, textureIndex); + ss.declareTex2D(name, textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } @@ -303,7 +303,7 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, else { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex1D(name, textureIndex); + ss.declareTex1D(name, textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } diff --git a/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp b/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp index e9e046383f..db9340b53f 100644 --- a/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp +++ b/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp @@ -47,7 +47,7 @@ void GetLut3DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, ConstLut3DO { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex3D(name, textureIndex); + ss.declareTex3D(name, textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } From 8d8f5bf8962bf304720677ce47f787fbc3f58d93 Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Tue, 17 Jun 2025 11:36:40 +0200 Subject: [PATCH 08/19] Added exception for invalid texture binding index, smaller fixes. Signed-off-by: Michael Horsch --- src/OpenColorIO/GpuShaderDesc.cpp | 19 +++++++++---------- src/OpenColorIO/GpuShaderUtils.h | 4 ++++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/OpenColorIO/GpuShaderDesc.cpp b/src/OpenColorIO/GpuShaderDesc.cpp index b541d11db4..4e94e34ae3 100644 --- a/src/OpenColorIO/GpuShaderDesc.cpp +++ b/src/OpenColorIO/GpuShaderDesc.cpp @@ -175,17 +175,14 @@ unsigned GpuShaderCreator::getNextResourceIndex() noexcept return getImpl()->m_numResources++; } -void GpuShaderCreator::setDescriptorSetIndex(unsigned index, unsigned textureBindingStart) noexcept +void GpuShaderCreator::setDescriptorSetIndex(unsigned index, unsigned textureBindingStart) { - getImpl()->m_descriptorSetIndex = index; - if (textureBindingStart != 0) - { - getImpl()->m_textureBindingStart = textureBindingStart; - } - else + if (textureBindingStart == 0) { - getImpl()->m_textureBindingStart = 1; + throw Exception("Texture binding start index must be greater than 0."); } + getImpl()->m_descriptorSetIndex = index; + getImpl()->m_textureBindingStart = textureBindingStart; } unsigned GpuShaderCreator::getDescriptorSetIndex() const noexcept @@ -335,9 +332,11 @@ void GpuShaderCreator::createShaderText(const char * shaderParameterDeclarations if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6 && (shaderParameterDeclarations && *shaderParameterDeclarations)) { - getImpl()->m_shaderCode += "layout (set = "+std::to_string(getImpl()->m_descriptorSetIndex) + ", binding = 0) uniform " + getImpl()->m_functionName + "_Parameters\n {\n"; + getImpl()->m_shaderCode += "layout (set = "+std::to_string(getImpl()->m_descriptorSetIndex) + + ", binding = 0) uniform " + + getImpl()->m_functionName + "_Parameters\n {\n"; } - getImpl()->m_shaderCode += (shaderParameterDeclarations && *shaderParameterDeclarations) ? shaderParameterDeclarations : ""; + getImpl()->m_shaderCode += (shaderParameterDeclarations && *shaderParameterDeclarations) ? shaderParameterDeclarations : ""; if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6 && (shaderParameterDeclarations && *shaderParameterDeclarations)) { getImpl()->m_shaderCode += "\n};\n"; diff --git a/src/OpenColorIO/GpuShaderUtils.h b/src/OpenColorIO/GpuShaderUtils.h index 59a953a65d..14d5cc5c73 100644 --- a/src/OpenColorIO/GpuShaderUtils.h +++ b/src/OpenColorIO/GpuShaderUtils.h @@ -231,6 +231,10 @@ class GpuShaderText // Get the string for taking the sign of a vector. std::string sign(const std::string & v) const; + + //Add a cast to bool for shading languages that don't support implicit casts from int to bool. + //It is required to use this function when doing boolean operations on a bool uniform to be + //compatible with all shading languages. std::string castToBool(const std::string& v) const; friend class GpuShaderLine; From 716893127d852290045906e7d25e8545b6aac15e Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Tue, 17 Jun 2025 11:22:04 +0200 Subject: [PATCH 09/19] Suggested documentation update Co-authored-by: Aleksi Sapon Signed-off-by: Michael Horsch --- include/OpenColorIO/OpenColorIO.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/OpenColorIO/OpenColorIO.h b/include/OpenColorIO/OpenColorIO.h index a6a6f27c0e..d06c10ba21 100644 --- a/include/OpenColorIO/OpenColorIO.h +++ b/include/OpenColorIO/OpenColorIO.h @@ -3281,7 +3281,12 @@ class OCIOEXPORT GpuShaderCreator * binding starts at textureBindingStart and is incremented by 1 for each texture. * The binding of a texture is equal to the texture index + textureBindingStart. * */ - void setDescriptorSetIndex(unsigned index, unsigned textureBindingStart = 0) noexcept; + * \param textureBindingStart The texture binding start index to use. The default index starts at 1 + * and is incremented by 1 for each texture. Otherwise, the texture binding starts + * at textureBindingStart and is incremented by 1 for each texture. + * The binding of a texture is equal to the texture index + textureBindingStart. + * */ + void setDescriptorSetIndex(unsigned index, unsigned textureBindingStart = 1) noexcept; unsigned getDescriptorSetIndex() const noexcept; unsigned getTextureBindingStart() const noexcept; From 0844139f0a5672ab491a60ba3866aadcec7a49dc Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Tue, 17 Jun 2025 12:05:36 +0200 Subject: [PATCH 10/19] Merge conflicts fixed. Signed-off-by: Michael Horsch --- include/OpenColorIO/OpenColorIO.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/include/OpenColorIO/OpenColorIO.h b/include/OpenColorIO/OpenColorIO.h index d06c10ba21..8d09eb0bd4 100644 --- a/include/OpenColorIO/OpenColorIO.h +++ b/include/OpenColorIO/OpenColorIO.h @@ -3276,17 +3276,14 @@ class OCIOEXPORT GpuShaderCreator * \note Only supported for shading languages that use descriptor sets and texture bindings. * * \param index The descriptor set index to use. - * \param textureBindingStart The texture binding start index to use. If 0, the default binding index is used - * which starts at 1 and is incremented by 1 for each texture. If not 0, the texture - * binding starts at textureBindingStart and is incremented by 1 for each texture. - * The binding of a texture is equal to the texture index + textureBindingStart. - * */ * \param textureBindingStart The texture binding start index to use. The default index starts at 1 * and is incremented by 1 for each texture. Otherwise, the texture binding starts * at textureBindingStart and is incremented by 1 for each texture. * The binding of a texture is equal to the texture index + textureBindingStart. + * The texture binding start index must be greater than 0, as binding 0 is reserved + * for the uniform buffer binding * */ - void setDescriptorSetIndex(unsigned index, unsigned textureBindingStart = 1) noexcept; + void setDescriptorSetIndex(unsigned index, unsigned textureBindingStart = 1); unsigned getDescriptorSetIndex() const noexcept; unsigned getTextureBindingStart() const noexcept; From 2bc72d06a2f5c2c5a66dcbd5bf22a9a901ba2416 Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Tue, 24 Jun 2025 14:54:39 +0200 Subject: [PATCH 11/19] Fixed missing space for non-Vulkan GLSL uniforms. Signed-off-by: Michael Horsch --- src/OpenColorIO/GpuShaderUtils.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OpenColorIO/GpuShaderUtils.cpp b/src/OpenColorIO/GpuShaderUtils.cpp index 58c086c7ca..f36ceeea01 100644 --- a/src/OpenColorIO/GpuShaderUtils.cpp +++ b/src/OpenColorIO/GpuShaderUtils.cpp @@ -915,7 +915,7 @@ void GpuShaderText::declareUniformFloat(const std::string & uniformName) { uniformDeclString = ""; } - newLine() << uniformDeclString << floatKeyword() << " " << uniformName << ";"; + newLine() << uniformDeclString << " " << floatKeyword() << " " << uniformName << ";"; } void GpuShaderText::declareUniformBool(const std::string & uniformName) @@ -931,7 +931,7 @@ void GpuShaderText::declareUniformBool(const std::string & uniformName) uniformDeclString = ""; boolKeyword = "int"; } - newLine() << uniformDeclString << boolKeyword << " " << uniformName << ";"; + newLine() << uniformDeclString << " " << boolKeyword << " " << uniformName << ";"; } void GpuShaderText::declareUniformFloat3(const std::string & uniformName) @@ -941,7 +941,7 @@ void GpuShaderText::declareUniformFloat3(const std::string & uniformName) { uniformDeclString = ""; } - newLine() << uniformDeclString << float3Keyword() << " " << uniformName << ";"; + newLine() << uniformDeclString << " " << float3Keyword() << " " << uniformName << ";"; } void GpuShaderText::declareUniformArrayFloat(const std::string & uniformName, unsigned int size) @@ -951,7 +951,7 @@ void GpuShaderText::declareUniformArrayFloat(const std::string & uniformName, un { uniformDeclString = ""; } - newLine() << uniformDeclString << floatKeyword() << " " << uniformName << "[" << size << "];"; + newLine() << uniformDeclString << " " << floatKeyword() << " " << uniformName << "[" << size << "];"; } void GpuShaderText::declareUniformArrayInt(const std::string & uniformName, unsigned int size) @@ -961,7 +961,7 @@ void GpuShaderText::declareUniformArrayInt(const std::string & uniformName, unsi { uniformDeclString = ""; } - newLine() << uniformDeclString << intKeyword() << " " << uniformName << "[" << size << "];"; + newLine() << uniformDeclString << " " << intKeyword() << " " << uniformName << "[" << size << "];"; } // Keep the method private as only float & double types are expected From ef11c67c9f7940ca8d3aeee18046f63696881c4d Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Wed, 25 Jun 2025 18:34:26 +0200 Subject: [PATCH 12/19] Fixed descriptorSetIndex for textures. Signed-off-by: Michael Horsch --- src/OpenColorIO/GpuShaderUtils.cpp | 15 ++++++++------- src/OpenColorIO/GpuShaderUtils.h | 6 +++--- .../ops/fixedfunction/FixedFunctionOpGPU.cpp | 8 ++++---- src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp | 4 ++-- src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp | 2 +- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/OpenColorIO/GpuShaderUtils.cpp b/src/OpenColorIO/GpuShaderUtils.cpp index f36ceeea01..8e9b0716b5 100644 --- a/src/OpenColorIO/GpuShaderUtils.cpp +++ b/src/OpenColorIO/GpuShaderUtils.cpp @@ -82,6 +82,7 @@ void getTexDecl(GpuLanguage lang, const std::string & samplerName, std::string & textureDecl, std::string & samplerDecl, + unsigned descriptorSetIndex, unsigned textureIndex) { switch (lang) @@ -105,7 +106,7 @@ void getTexDecl(GpuLanguage lang, textureDecl = ""; std::ostringstream kw; - kw << "layout(set=0, binding="<(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex + textureBindingStart); + getTexDecl<1>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, descriptorSetIndex, textureIndex + textureBindingStart); if (!textureDecl.empty()) { @@ -857,10 +858,10 @@ void GpuShaderText::declareTex1D(const std::string & textureName, unsigned textu } } -void GpuShaderText::declareTex2D(const std::string & textureName, unsigned textureIndex, unsigned textureBindingStart) +void GpuShaderText::declareTex2D(const std::string & textureName, unsigned descriptorSetIndex, unsigned textureIndex, unsigned textureBindingStart) { std::string textureDecl, samplerDecl; - getTexDecl<2>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex + textureBindingStart); + getTexDecl<2>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, descriptorSetIndex, textureIndex + textureBindingStart); if (!textureDecl.empty()) { @@ -873,10 +874,10 @@ void GpuShaderText::declareTex2D(const std::string & textureName, unsigned textu } } -void GpuShaderText::declareTex3D(const std::string& textureName, unsigned textureIndex, unsigned textureBindingStart) +void GpuShaderText::declareTex3D(const std::string& textureName, unsigned descriptorSetIndex, unsigned textureIndex, unsigned textureBindingStart) { std::string textureDecl, samplerDecl; - getTexDecl<3>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, textureIndex + textureBindingStart); + getTexDecl<3>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, descriptorSetIndex, textureIndex + textureBindingStart); if (!textureDecl.empty()) { diff --git a/src/OpenColorIO/GpuShaderUtils.h b/src/OpenColorIO/GpuShaderUtils.h index 14d5cc5c73..f9ccd17ab1 100644 --- a/src/OpenColorIO/GpuShaderUtils.h +++ b/src/OpenColorIO/GpuShaderUtils.h @@ -171,11 +171,11 @@ class GpuShaderText static std::string getSamplerName(const std::string& textureName); // Declare the global texture and sampler information for a 1D texture. - void declareTex1D(const std::string& textureName, unsigned textureIndex, unsigned textureBindingStart); + void declareTex1D(const std::string& textureName, unsigned descriptorSetIndex, unsigned textureIndex, unsigned textureBindingStart); // Declare the global texture and sampler information for a 2D texture. - void declareTex2D(const std::string& textureName, unsigned textureIndex, unsigned textureBindingStart); + void declareTex2D(const std::string& textureName, unsigned descriptorSetIndex, unsigned textureIndex, unsigned textureBindingStart); // Declare the global texture and sampler information for a 3D texture. - void declareTex3D(const std::string& textureName, unsigned textureIndex, unsigned textureBindingStart); + void declareTex3D(const std::string& textureName, unsigned descriptorSetIndex, unsigned textureIndex, unsigned textureBindingStart); // Get the texture lookup call for a 1D texture. std::string sampleTex1D(const std::string& textureName, const std::string& coords) const; diff --git a/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp b/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp index 1928b264de..0acd73c102 100644 --- a/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp +++ b/src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp @@ -541,13 +541,13 @@ std::string _Add_Reach_table( if (dimensions == GpuShaderDesc::TEXTURE_1D) { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex1D(name, textureIndex, shaderCreator->getTextureBindingStart()); + ss.declareTex1D(name, shaderCreator->getDescriptorSetIndex(), textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } else { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex2D(name, textureIndex, shaderCreator->getTextureBindingStart()); + ss.declareTex2D(name, shaderCreator->getDescriptorSetIndex(), textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } @@ -838,13 +838,13 @@ std::string _Add_Cusp_table( if (dimensions == GpuShaderDesc::TEXTURE_1D) { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex1D(name, textureIndex, shaderCreator->getTextureBindingStart()); + ss.declareTex1D(name, shaderCreator->getDescriptorSetIndex(), textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } else { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex2D(name, textureIndex, shaderCreator->getTextureBindingStart()); + ss.declareTex2D(name, shaderCreator->getDescriptorSetIndex(), textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } diff --git a/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp b/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp index 9e535a1f5f..573496d653 100644 --- a/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp +++ b/src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp @@ -219,7 +219,7 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex2D(name, textureIndex, shaderCreator->getTextureBindingStart()); + ss.declareTex2D(name, shaderCreator->getDescriptorSetIndex(), textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } @@ -303,7 +303,7 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, else { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex1D(name, textureIndex, shaderCreator->getTextureBindingStart()); + ss.declareTex1D(name, shaderCreator->getDescriptorSetIndex(), textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } diff --git a/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp b/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp index db9340b53f..01423f6973 100644 --- a/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp +++ b/src/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp @@ -47,7 +47,7 @@ void GetLut3DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, ConstLut3DO { GpuShaderText ss(shaderCreator->getLanguage()); - ss.declareTex3D(name, textureIndex, shaderCreator->getTextureBindingStart()); + ss.declareTex3D(name, shaderCreator->getDescriptorSetIndex(), textureIndex, shaderCreator->getTextureBindingStart()); shaderCreator->addToTextureDeclareShaderCode(ss.string().c_str()); } From fd0fd6ad421e6c9ed0490c7f31a79177407db3ff Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Tue, 1 Jul 2025 11:16:55 +0200 Subject: [PATCH 13/19] Fixed uniform buffer array stride and size. Signed-off-by: Michael Horsch --- include/OpenColorIO/OpenColorIO.h | 6 ++++-- src/OpenColorIO/GpuShader.cpp | 21 ++++++++++++------- src/OpenColorIO/GpuShader.h | 6 ++++-- .../gradingrgbcurve/GradingRGBCurveOpGPU.cpp | 4 ++-- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/include/OpenColorIO/OpenColorIO.h b/include/OpenColorIO/OpenColorIO.h index 8d09eb0bd4..7f2bbab307 100644 --- a/include/OpenColorIO/OpenColorIO.h +++ b/include/OpenColorIO/OpenColorIO.h @@ -3332,11 +3332,13 @@ class OCIOEXPORT GpuShaderCreator virtual bool addUniform(const char * name, const SizeGetter & getSize, - const VectorFloatGetter & getVectorFloat) = 0; + const VectorFloatGetter & getVectorFloat, + const unsigned maxSize) = 0; virtual bool addUniform(const char * name, const SizeGetter & getSize, - const VectorIntGetter & getVectorInt) = 0; + const VectorIntGetter & getVectorInt, + const unsigned maxSize) = 0; /// Adds the property (used internally). void addDynamicProperty(DynamicPropertyRcPtr & prop); diff --git a/src/OpenColorIO/GpuShader.cpp b/src/OpenColorIO/GpuShader.cpp index 86d70c9775..38eda8a30e 100644 --- a/src/OpenColorIO/GpuShader.cpp +++ b/src/OpenColorIO/GpuShader.cpp @@ -57,6 +57,7 @@ constexpr size_t GPU_INT_ALIGNMENT = 4; constexpr size_t GPU_VEC3_SIZE = 12; constexpr size_t GPU_VEC3_ALIGNMENT = 16; constexpr size_t GPU_ARRAY_ALIGNMENT = 16; +constexpr size_t GPU_ARRAY_STRIDE = 16; class PrivateImpl { @@ -383,7 +384,8 @@ class PrivateImpl bool addUniform(const char * name, const GpuShaderCreator::SizeGetter & getSize, - const GpuShaderCreator::VectorFloatGetter & getVector) + const GpuShaderCreator::VectorFloatGetter & getVector, + const unsigned maxSize) { if (uniformNameUsed(name)) { @@ -392,13 +394,14 @@ class PrivateImpl } m_uniformBufferSize = alignOffset(m_uniformBufferSize, GPU_ARRAY_ALIGNMENT); m_uniforms.emplace_back(name, getSize, getVector, m_uniformBufferSize); - m_uniformBufferSize += GPU_FLOAT_SIZE * getSize(); + m_uniformBufferSize += GPU_ARRAY_STRIDE * maxSize; return true; } bool addUniform(const char * name, const GpuShaderCreator::SizeGetter & getSize, - const GpuShaderCreator::VectorIntGetter & getVectorInt) + const GpuShaderCreator::VectorIntGetter & getVectorInt, + const unsigned maxSize) { if (uniformNameUsed(name)) { @@ -407,7 +410,7 @@ class PrivateImpl } m_uniformBufferSize = alignOffset(m_uniformBufferSize, GPU_ARRAY_ALIGNMENT); m_uniforms.emplace_back(name, getSize, getVectorInt, m_uniformBufferSize); - m_uniformBufferSize += GPU_INT_SIZE * getSize(); + m_uniformBufferSize += GPU_ARRAY_STRIDE * maxSize; return true; } @@ -489,16 +492,18 @@ bool GenericGpuShaderDesc::addUniform(const char * name, const Float3Getter & ge bool GenericGpuShaderDesc::addUniform(const char * name, const SizeGetter & getSize, - const VectorFloatGetter & getFloatArray) + const VectorFloatGetter & getFloatArray, + const unsigned maxSize) { - return getImplGeneric()->addUniform(name, getSize, getFloatArray); + return getImplGeneric()->addUniform(name, getSize, getFloatArray, maxSize); } bool GenericGpuShaderDesc::addUniform(const char * name, const SizeGetter & getSize, - const VectorIntGetter & getVectorInt) + const VectorIntGetter & getVectorInt, + const unsigned maxSize) { - return getImplGeneric()->addUniform(name, getSize, getVectorInt); + return getImplGeneric()->addUniform(name, getSize, getVectorInt, maxSize); } std::size_t GenericGpuShaderDesc::getUniformBufferSize() const noexcept diff --git a/src/OpenColorIO/GpuShader.h b/src/OpenColorIO/GpuShader.h index 352d7871c1..8b099cc12f 100644 --- a/src/OpenColorIO/GpuShader.h +++ b/src/OpenColorIO/GpuShader.h @@ -41,10 +41,12 @@ class GenericGpuShaderDesc : public GpuShaderDesc bool addUniform(const char * name, const Float3Getter & getter) override; bool addUniform(const char * name, const SizeGetter & getSize, - const VectorFloatGetter & getVectorFloat) override; + const VectorFloatGetter & getVectorFloat, + const unsigned maxSize) override; bool addUniform(const char * name, const SizeGetter & getSize, - const VectorIntGetter & getVectorInt) override; + const VectorIntGetter & getVectorInt, + const unsigned maxSize) override; std::size_t getUniformBufferSize() const noexcept override; // Accessors to the 1D & 2D textures built from 1D LUT diff --git a/src/OpenColorIO/ops/gradingrgbcurve/GradingRGBCurveOpGPU.cpp b/src/OpenColorIO/ops/gradingrgbcurve/GradingRGBCurveOpGPU.cpp index fb8cf1dfe1..6093026420 100644 --- a/src/OpenColorIO/ops/gradingrgbcurve/GradingRGBCurveOpGPU.cpp +++ b/src/OpenColorIO/ops/gradingrgbcurve/GradingRGBCurveOpGPU.cpp @@ -86,7 +86,7 @@ void AddUniform(GpuShaderCreatorRcPtr & shaderCreator, const std::string & name) { // Add the uniform if it does not already exist. - if (shaderCreator->addUniform(name.c_str(), getSize, getVector)) + if (shaderCreator->addUniform(name.c_str(), getSize, getVector, maxSize)) { // Declare uniform. GpuShaderText stDecl(shaderCreator->getLanguage()); @@ -101,7 +101,7 @@ void AddUniform(GpuShaderCreatorRcPtr & shaderCreator, const std::string & name) { // Add the uniform if it does not already exist. - if (shaderCreator->addUniform(name.c_str(), getSize, getVector)) + if (shaderCreator->addUniform(name.c_str(), getSize, getVector, 8)) { // Declare uniform. GpuShaderText stDecl(shaderCreator->getLanguage()); From 8bec334cb13357a25b0d30ecc357ad94917d61f1 Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Wed, 2 Jul 2025 18:25:32 +0200 Subject: [PATCH 14/19] Fixes documentation, formatting. Adds test and py functions. Signed-off-by: Michael Horsch --- include/OpenColorIO/OpenColorIO.h | 10 ++++- src/OpenColorIO/GpuShaderDesc.cpp | 2 +- src/OpenColorIO/GpuShaderUtils.cpp | 24 ++++++++---- src/bindings/python/PyGpuShaderCreator.cpp | 9 ++++- tests/cpu/GpuShader_tests.cpp | 45 ++++++++++++++++++++++ 5 files changed, 80 insertions(+), 10 deletions(-) diff --git a/include/OpenColorIO/OpenColorIO.h b/include/OpenColorIO/OpenColorIO.h index 7f2bbab307..ab3b506cf0 100644 --- a/include/OpenColorIO/OpenColorIO.h +++ b/include/OpenColorIO/OpenColorIO.h @@ -3273,7 +3273,7 @@ class OCIOEXPORT GpuShaderCreator /** * \brief Set the descriptor set index and texture binding start index to use for the shader program. * - * \note Only supported for shading languages that use descriptor sets and texture bindings. + * \note Only supported for shading languages, such as Vulkan, that use descriptor sets and texture bindings. * * \param index The descriptor set index to use. * \param textureBindingStart The texture binding start index to use. The default index starts at 1 @@ -3330,11 +3330,19 @@ class OCIOEXPORT GpuShaderCreator virtual bool addUniform(const char * name, const Float3Getter & getFloat3) = 0; + /// The size of the vector can be smaller than the size of the corresponding + /// array that is declared in the shader. The parameter maxSize must be used + /// to pass the size of the array declared in the shader. This is important for + /// being able to calculate the correct uniform buffer offset for subsequent uniforms virtual bool addUniform(const char * name, const SizeGetter & getSize, const VectorFloatGetter & getVectorFloat, const unsigned maxSize) = 0; + /// The size of the vector can be smaller than the size of the corresponding + /// array that is declared in the shader. The parameter maxSize must be used + /// to pass the size of the array declared in the shader. This is important for + /// being able to calculate the correct uniform buffer offset for subsequent uniforms virtual bool addUniform(const char * name, const SizeGetter & getSize, const VectorIntGetter & getVectorInt, diff --git a/src/OpenColorIO/GpuShaderDesc.cpp b/src/OpenColorIO/GpuShaderDesc.cpp index 4e94e34ae3..ffa9be7407 100644 --- a/src/OpenColorIO/GpuShaderDesc.cpp +++ b/src/OpenColorIO/GpuShaderDesc.cpp @@ -334,7 +334,7 @@ void GpuShaderCreator::createShaderText(const char * shaderParameterDeclarations { getImpl()->m_shaderCode += "layout (set = "+std::to_string(getImpl()->m_descriptorSetIndex) + ", binding = 0) uniform " + - getImpl()->m_functionName + "_Parameters\n {\n"; + getImpl()->m_functionName + "_Parameters\n{\n"; } getImpl()->m_shaderCode += (shaderParameterDeclarations && *shaderParameterDeclarations) ? shaderParameterDeclarations : ""; if (getImpl()->m_language == GPU_LANGUAGE_GLSL_VK_4_6 && (shaderParameterDeclarations && *shaderParameterDeclarations)) diff --git a/src/OpenColorIO/GpuShaderUtils.cpp b/src/OpenColorIO/GpuShaderUtils.cpp index 8e9b0716b5..021d185efb 100644 --- a/src/OpenColorIO/GpuShaderUtils.cpp +++ b/src/OpenColorIO/GpuShaderUtils.cpp @@ -106,7 +106,8 @@ void getTexDecl(GpuLanguage lang, textureDecl = ""; std::ostringstream kw; - kw << "layout(set="<(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, descriptorSetIndex, textureIndex + textureBindingStart); + getTexDecl<1>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, + descriptorSetIndex, textureIndex + textureBindingStart); if (!textureDecl.empty()) { @@ -858,10 +862,13 @@ void GpuShaderText::declareTex1D(const std::string & textureName, unsigned descr } } -void GpuShaderText::declareTex2D(const std::string & textureName, unsigned descriptorSetIndex, unsigned textureIndex, unsigned textureBindingStart) +void GpuShaderText::declareTex2D(const std::string & textureName, + unsigned descriptorSetIndex, + unsigned textureIndex, unsigned textureBindingStart) { std::string textureDecl, samplerDecl; - getTexDecl<2>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, descriptorSetIndex, textureIndex + textureBindingStart); + getTexDecl<2>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, + descriptorSetIndex, textureIndex + textureBindingStart); if (!textureDecl.empty()) { @@ -874,10 +881,13 @@ void GpuShaderText::declareTex2D(const std::string & textureName, unsigned descr } } -void GpuShaderText::declareTex3D(const std::string& textureName, unsigned descriptorSetIndex, unsigned textureIndex, unsigned textureBindingStart) +void GpuShaderText::declareTex3D(const std::string& textureName, + unsigned descriptorSetIndex, + unsigned textureIndex, unsigned textureBindingStart) { std::string textureDecl, samplerDecl; - getTexDecl<3>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, descriptorSetIndex, textureIndex + textureBindingStart); + getTexDecl<3>(m_lang, textureName, getSamplerName(textureName), textureDecl, samplerDecl, + descriptorSetIndex, textureIndex + textureBindingStart); if (!textureDecl.empty()) { diff --git a/src/bindings/python/PyGpuShaderCreator.cpp b/src/bindings/python/PyGpuShaderCreator.cpp index 34846227b0..908ac1817d 100644 --- a/src/bindings/python/PyGpuShaderCreator.cpp +++ b/src/bindings/python/PyGpuShaderCreator.cpp @@ -62,6 +62,13 @@ void bindPyGpuShaderCreator(py::module & m) DOC(GpuShaderCreator, getResourcePrefix)) .def("setResourcePrefix", &GpuShaderCreator::setResourcePrefix, "prefix"_a, DOC(GpuShaderCreator, setResourcePrefix)) + .def("setDescriptorSetIndex", &GpuShaderCreator::setDescriptorSetIndex, + "index"_a, "textureBindingStart"_a, + DOC(GpuShaderCreator, setDescriptorSetIndex)) + .def("getDescriptorSetIndex", &GpuShaderCreator::getDescriptorSetIndex, + DOC(GpuShaderCreator, getDescriptorSetIndex)) + .def("getTextureBindingStart", &GpuShaderCreator::getTextureBindingStart, + DOC(GpuShaderCreator, getTextureBindingStart)) .def("getCacheID", &GpuShaderCreator::getCacheID, DOC(GpuShaderCreator, getCacheID)) .def("begin", &GpuShaderCreator::begin, "uid"_a, @@ -111,7 +118,7 @@ void bindPyGpuShaderCreator(py::module & m) "shaderCode"_a, DOC(GpuShaderCreator, addToFunctionFooterShaderCode)) .def("createShaderText", &GpuShaderCreator::createShaderText, - "shaderParameterDeclarations"_a, "shaderTextureDeclarations"_a, + "shaderParameterDeclarations"_a, "shaderTextureDeclarations"_a, "shaderHelperMethods"_a, "shaderFunctionHeader"_a, "shaderFunctionBody"_a, "shaderFunctionFooter"_a, DOC(GpuShaderCreator, createShaderText)) diff --git a/tests/cpu/GpuShader_tests.cpp b/tests/cpu/GpuShader_tests.cpp index 559e95b285..01efe9e534 100644 --- a/tests/cpu/GpuShader_tests.cpp +++ b/tests/cpu/GpuShader_tests.cpp @@ -195,6 +195,51 @@ OCIO_ADD_TEST(GpuShader, generic_shader) OCIO_CHECK_EQUAL(fragText, shaderDesc->getShaderText()); } + + { + OCIO_CHECK_NE(shaderDesc->getLanguage(), OCIO::GPU_LANGUAGE_GLSL_VK_4_6); + OCIO_CHECK_NO_THROW(shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_VK_4_6)); + OCIO_CHECK_EQUAL(shaderDesc->getLanguage(), OCIO::GPU_LANGUAGE_GLSL_VK_4_6); + + OCIO_CHECK_THROW_WHAT(shaderDesc->setDescriptorSetIndex(123, 0),OCIO::Exception, "Texture binding start index must be greater than 0."); + OCIO_CHECK_NO_THROW(shaderDesc->setDescriptorSetIndex(123, 456)); + OCIO_CHECK_EQUAL(shaderDesc->getDescriptorSetIndex(), 123); + OCIO_CHECK_EQUAL(shaderDesc->getTextureBindingStart(), 456); + + auto getSize = []() -> float { return 2; }; //simulate only 2 elements in the array + auto getArray = []() -> const float* { return nullptr; }; + const unsigned maxSize = 3; + OCIO_CHECK_NO_THROW(shaderDesc->addUniform("array", getSize, getArray, maxSize)); + OCIO_CHECK_EQUAL(shaderDesc->getUniformBufferSize(), 16 * maxSize); + + OCIO_CHECK_NO_THROW(shaderDesc->addToTextureDeclareShaderCode("layout(set=123, binding = 456) uniform sampler2D samplerName; \n")); + + OCIO_CHECK_NO_THROW(shaderDesc->finalize()); + + std::string fragText; + fragText += "layout (set = 123, binding = 0) uniform 1sd234__Parameters\n"; + fragText += "{\n"; + fragText += "\n"; + fragText += "// Declaration of all variables\n"; + fragText += "\n"; + fragText += "vec2 coords;\n"; + fragText += "\n"; + fragText += "};\n"; + fragText += "\n"; + fragText += "// Declaration of all textures\n"; + fragText += "\n"; + fragText += "layout(set=123, binding = 456) uniform sampler2D samplerName; \n"; + fragText += "\n"; + fragText += "// Declaration of all helper methods\n"; + fragText += "\n"; + fragText += "vec2 helpers() {}\n\n"; + fragText += "void func() {\n"; + fragText += " int i;\n"; + fragText += "}\n"; + + OCIO_CHECK_EQUAL(fragText, shaderDesc->getShaderText()); + + } } OCIO_ADD_TEST(GpuShader, MetalLutTest) From 27a54b1f24095647b683c73134a66a55792cb421 Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Thu, 3 Jul 2025 13:43:00 +0200 Subject: [PATCH 15/19] Added missing python bindings. Signed-off-by: Michael Horsch --- src/bindings/python/PyGpuShaderDesc.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bindings/python/PyGpuShaderDesc.cpp b/src/bindings/python/PyGpuShaderDesc.cpp index 24bb82412a..e6c9b600fc 100644 --- a/src/bindings/python/PyGpuShaderDesc.cpp +++ b/src/bindings/python/PyGpuShaderDesc.cpp @@ -107,6 +107,8 @@ void bindPyGpuShaderDesc(py::module & m) { return UniformIterator(self); }) + .def("getUniformBufferSize", &GpuShaderDesc::getUniformBufferSize, + DOC(GpuShaderDesc, getUniformBufferSize)) // 1D lut related methods .def("addTexture", [](GpuShaderDescRcPtr & self, @@ -187,6 +189,7 @@ void bindPyGpuShaderDesc(py::module & m) .def(py::init(), "data"_a) .def_readwrite("type", &GpuShaderDesc::UniformData::m_type) + .def_readwrite("bufferOffset", &GpuShaderDesc::UniformData::m_bufferOffset) .def("getDouble", [](GpuShaderDesc::UniformData & self) -> double { From fac80d4aa73c7d8474ccfb39616e93e4c17766cb Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Thu, 3 Jul 2025 14:54:23 +0200 Subject: [PATCH 16/19] Fixed Metal unit tests. Signed-off-by: Michael Horsch --- tests/cpu/GpuShader_tests.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/tests/cpu/GpuShader_tests.cpp b/tests/cpu/GpuShader_tests.cpp index 01efe9e534..c7ac914dc8 100644 --- a/tests/cpu/GpuShader_tests.cpp +++ b/tests/cpu/GpuShader_tests.cpp @@ -307,6 +307,7 @@ ocioDisplay( } + // Declaration of the OCIO shader function float4 Display(float4 inPixel) @@ -396,6 +397,7 @@ ocioDisplay( } + // Declaration of the OCIO shader function float4 Display(float4 inPixel) @@ -486,7 +488,8 @@ ocioMyMethodName( } -// Declaration of all variables + +// Declaration of all textures texture1d ocio_lut1d_0; sampler ocio_lut1d_0Sampler; @@ -594,7 +597,8 @@ ocioMyMethodName( } -// Declaration of all variables + +// Declaration of all textures texture3d ocio_lut3d_0; sampler ocio_lut3d_0Sampler; @@ -696,7 +700,8 @@ ocioOCIOMain( } -// Declaration of all variables + +// Declaration of all textures texture2d ocio_lut1d_0; sampler ocio_lut1d_0Sampler; @@ -825,7 +830,8 @@ ocioOCIOMain( } -// Declaration of all variables + +// Declaration of all textures texture1d ocio_lut1d_0; sampler ocio_lut1d_0Sampler; @@ -970,8 +976,9 @@ ocioOCIOMain( // Declaration of all variables -float ocio_exposure_contrast_exposureVal; -float ocio_exposure_contrast_gammaVal; + float ocio_exposure_contrast_exposureVal; + float ocio_exposure_contrast_gammaVal; + // Declaration of the OCIO shader function @@ -1074,6 +1081,7 @@ ocioOCIOMain( } + // Declaration of all helper methods @@ -1235,11 +1243,12 @@ ocioOCIOMain( // Declaration of all variables -int ocio_grading_rgbcurve_knotsOffsets[8]; -float ocio_grading_rgbcurve_knots[60]; -int ocio_grading_rgbcurve_coefsOffsets[8]; -float ocio_grading_rgbcurve_coefs[180]; -bool ocio_grading_rgbcurve_localBypass; + int ocio_grading_rgbcurve_knotsOffsets[8]; + float ocio_grading_rgbcurve_knots[60]; + int ocio_grading_rgbcurve_coefsOffsets[8]; + float ocio_grading_rgbcurve_coefs[180]; + bool ocio_grading_rgbcurve_localBypass; + // Declaration of all helper methods From b1ec8d1fe9ed27ce8011dea81b2e6ea58a635d95 Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Thu, 24 Jul 2025 16:54:00 +0200 Subject: [PATCH 17/19] Fixes for MyOSLShaderCreator. Signed-off-by: Michael Horsch --- tests/osl/UnitTestMain.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/osl/UnitTestMain.cpp b/tests/osl/UnitTestMain.cpp index 3a69ed3659..5e105b5715 100644 --- a/tests/osl/UnitTestMain.cpp +++ b/tests/osl/UnitTestMain.cpp @@ -56,7 +56,8 @@ class MyOSLShaderCreator final : public OCIO::GpuShaderCreator bool addUniform(const char * /*name*/, const SizeGetter & /*getSize*/, - const VectorFloatGetter & /*getVectorFloat*/) override + const VectorFloatGetter & /*getVectorFloat*/, + const unsigned /*maxSize*/) override { throw OCIO::Exception("Unsupported by OSL unit tests."); return false; @@ -64,13 +65,14 @@ class MyOSLShaderCreator final : public OCIO::GpuShaderCreator bool addUniform(const char * /*name*/, const SizeGetter & /*getSize*/, - const VectorIntGetter & /*getVectorInt*/) override + const VectorIntGetter & /*getVectorInt*/, + const unsigned /*maxSize*/) override { throw OCIO::Exception("Unsupported by OSL unit tests."); return false; } - void addTexture(const char * /*textureName*/, + unsigned addTexture(const char * /*textureName*/, const char * /*samplerName*/, unsigned /*width*/, unsigned /*height*/, @@ -80,24 +82,28 @@ class MyOSLShaderCreator final : public OCIO::GpuShaderCreator const float * /*values*/) override { throw OCIO::Exception("Unsupported by OSL unit tests."); + return 0; } - void add3DTexture(const char * /*textureName*/, + unsigned add3DTexture(const char * /*textureName*/, const char * /*samplerName*/, unsigned /*edgelen*/, OCIO::Interpolation /*interpolation*/, const float * /*values*/) override { throw OCIO::Exception("Unsupported by OSL unit tests."); + return 0; } - void createShaderText(const char * shaderDeclarations, + void createShaderText(const char * shaderParameterDeclarations, + const char * shaderTextureDeclarations, const char * shaderHelperMethods, const char * shaderFunctionHeader, const char * shaderFunctionBody, const char * shaderFunctionFooter) override { - m_shaderCode += shaderDeclarations; + m_shaderCode += shaderParameterDeclarations; + m_shaderCode += shaderTextureDeclarations; m_shaderCode += shaderHelperMethods; m_shaderCode += shaderFunctionHeader; m_shaderCode += shaderFunctionBody; From 77756ecd591e57d7408cd546a42c45a93a975912 Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Fri, 19 Sep 2025 16:06:54 +0200 Subject: [PATCH 18/19] Fixed spaces at beginning of uniform declarations. Signed-off-by: Michael Horsch --- src/OpenColorIO/GpuShaderUtils.cpp | 20 ++++++++++---------- tests/cpu/GpuShader_tests.cpp | 14 +++++++------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/OpenColorIO/GpuShaderUtils.cpp b/src/OpenColorIO/GpuShaderUtils.cpp index 021d185efb..a125fa0fd1 100644 --- a/src/OpenColorIO/GpuShaderUtils.cpp +++ b/src/OpenColorIO/GpuShaderUtils.cpp @@ -921,17 +921,17 @@ std::string GpuShaderText::sampleTex3D(const std::string& textureName, void GpuShaderText::declareUniformFloat(const std::string & uniformName) { - std::string uniformDeclString("uniform"); + std::string uniformDeclString("uniform "); if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { uniformDeclString = ""; } - newLine() << uniformDeclString << " " << floatKeyword() << " " << uniformName << ";"; + newLine() << uniformDeclString << floatKeyword() << " " << uniformName << ";"; } void GpuShaderText::declareUniformBool(const std::string & uniformName) { - std::string uniformDeclString("uniform"); + std::string uniformDeclString("uniform "); std::string boolKeyword("bool"); if (m_lang == GPU_LANGUAGE_MSL_2_0) { @@ -942,37 +942,37 @@ void GpuShaderText::declareUniformBool(const std::string & uniformName) uniformDeclString = ""; boolKeyword = "int"; } - newLine() << uniformDeclString << " " << boolKeyword << " " << uniformName << ";"; + newLine() << uniformDeclString << boolKeyword << " " << uniformName << ";"; } void GpuShaderText::declareUniformFloat3(const std::string & uniformName) { - std::string uniformDeclString("uniform"); + std::string uniformDeclString("uniform "); if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { uniformDeclString = ""; } - newLine() << uniformDeclString << " " << float3Keyword() << " " << uniformName << ";"; + newLine() << uniformDeclString << float3Keyword() << " " << uniformName << ";"; } void GpuShaderText::declareUniformArrayFloat(const std::string & uniformName, unsigned int size) { - std::string uniformDeclString("uniform"); + std::string uniformDeclString("uniform "); if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { uniformDeclString = ""; } - newLine() << uniformDeclString << " " << floatKeyword() << " " << uniformName << "[" << size << "];"; + newLine() << uniformDeclString << floatKeyword() << " " << uniformName << "[" << size << "];"; } void GpuShaderText::declareUniformArrayInt(const std::string & uniformName, unsigned int size) { - std::string uniformDeclString("uniform"); + std::string uniformDeclString("uniform "); if (m_lang == GPU_LANGUAGE_MSL_2_0 || m_lang == GPU_LANGUAGE_GLSL_VK_4_6) { uniformDeclString = ""; } - newLine() << uniformDeclString << " " << intKeyword() << " " << uniformName << "[" << size << "];"; + newLine() << uniformDeclString << intKeyword() << " " << uniformName << "[" << size << "];"; } // Keep the method private as only float & double types are expected diff --git a/tests/cpu/GpuShader_tests.cpp b/tests/cpu/GpuShader_tests.cpp index c7ac914dc8..4f102e8ffa 100644 --- a/tests/cpu/GpuShader_tests.cpp +++ b/tests/cpu/GpuShader_tests.cpp @@ -976,8 +976,8 @@ ocioOCIOMain( // Declaration of all variables - float ocio_exposure_contrast_exposureVal; - float ocio_exposure_contrast_gammaVal; +float ocio_exposure_contrast_exposureVal; +float ocio_exposure_contrast_gammaVal; // Declaration of the OCIO shader function @@ -1243,11 +1243,11 @@ ocioOCIOMain( // Declaration of all variables - int ocio_grading_rgbcurve_knotsOffsets[8]; - float ocio_grading_rgbcurve_knots[60]; - int ocio_grading_rgbcurve_coefsOffsets[8]; - float ocio_grading_rgbcurve_coefs[180]; - bool ocio_grading_rgbcurve_localBypass; +int ocio_grading_rgbcurve_knotsOffsets[8]; +float ocio_grading_rgbcurve_knots[60]; +int ocio_grading_rgbcurve_coefsOffsets[8]; +float ocio_grading_rgbcurve_coefs[180]; +bool ocio_grading_rgbcurve_localBypass; // Declaration of all helper methods From c144ca48daa8ad79387462b7a57ecc1af9c42208 Mon Sep 17 00:00:00 2001 From: Michael Horsch Date: Fri, 26 Sep 2025 14:51:31 +0200 Subject: [PATCH 19/19] Fixed Vulkan unit test. Signed-off-by: Michael Horsch --- tests/cpu/GpuShader_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cpu/GpuShader_tests.cpp b/tests/cpu/GpuShader_tests.cpp index 4f102e8ffa..610366a036 100644 --- a/tests/cpu/GpuShader_tests.cpp +++ b/tests/cpu/GpuShader_tests.cpp @@ -206,7 +206,7 @@ OCIO_ADD_TEST(GpuShader, generic_shader) OCIO_CHECK_EQUAL(shaderDesc->getDescriptorSetIndex(), 123); OCIO_CHECK_EQUAL(shaderDesc->getTextureBindingStart(), 456); - auto getSize = []() -> float { return 2; }; //simulate only 2 elements in the array + auto getSize = []() -> int { return 2; }; //simulate only 2 elements in the array auto getArray = []() -> const float* { return nullptr; }; const unsigned maxSize = 3; OCIO_CHECK_NO_THROW(shaderDesc->addUniform("array", getSize, getArray, maxSize));