diff --git a/MobileGL/MG_Pipe/MGPipeValueTypes.h b/MobileGL/MG_Pipe/MGPipeValueTypes.h index 19b2785e..a6d50c4e 100644 --- a/MobileGL/MG_Pipe/MGPipeValueTypes.h +++ b/MobileGL/MG_Pipe/MGPipeValueTypes.h @@ -50,6 +50,9 @@ namespace MobileGL { OneMinusSrc1Color, Src1Alpha, OneMinusSrc1Alpha, + // GL_SRC_ALPHA_SATURATE: (f, f, f, 1) with f = min(As, 1 - Ad). Legal as a source and a + // destination factor in desktop GL. Appended so the values above keep their encoding. + SrcAlphaSaturate, BlendFactorCount, Unknown = -1 }; diff --git a/MobileGL/MG_Test/State/RenderStateTest.cpp b/MobileGL/MG_Test/State/RenderStateTest.cpp index 0f883a34..a8d23a2b 100644 --- a/MobileGL/MG_Test/State/RenderStateTest.cpp +++ b/MobileGL/MG_Test/State/RenderStateTest.cpp @@ -104,6 +104,23 @@ TEST_F(RenderStateTest, IndexedBlendTogglesStillWork) { EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR); } +TEST_F(RenderStateTest, SrcAlphaSaturateIsAcceptedAsSourceAndDestinationFactor) { + // Desktop GL takes GL_SRC_ALPHA_SATURATE for all four factors (KHR-GL30.api.coverage). + MG_Impl::GLImpl::BlendFuncSeparate(GL_SRC_ALPHA_SATURATE, GL_SRC_ALPHA_SATURATE, GL_SRC_ALPHA_SATURATE, + GL_SRC_ALPHA_SATURATE); + EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR); + for (const GLenum pname : {GL_BLEND_SRC_RGB, GL_BLEND_DST_RGB, GL_BLEND_SRC_ALPHA, GL_BLEND_DST_ALPHA}) { + GLint value = 0; + MG_Impl::GLImpl::GetIntegerv(pname, &value); + EXPECT_EQ(value, GL_SRC_ALPHA_SATURATE) << "pname " << pname; + } + + MG_Impl::GLImpl::BlendFunci(1, GL_SRC_ALPHA_SATURATE, GL_SRC_ALPHA_SATURATE); + EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR); + MG_Impl::GLImpl::BlendFunc(GL_ONE, GL_ZERO); + EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR); +} + // --------------------------------------------------------------------------------------------- // ARB_viewport_array: indexed viewport / scissor / depth-range state // --------------------------------------------------------------------------------------------- diff --git a/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.cpp b/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.cpp index 51218e6f..9f8a31db 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.cpp @@ -48,6 +48,8 @@ namespace MobileGL { return BlendFactor::Src1Alpha; case GL_ONE_MINUS_SRC1_ALPHA: return BlendFactor::OneMinusSrc1Alpha; + case GL_SRC_ALPHA_SATURATE: + return BlendFactor::SrcAlphaSaturate; default: return BlendFactor::Unknown; } diff --git a/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.cpp index 5004bc30..150f9aab 100644 --- a/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.cpp @@ -49,6 +49,8 @@ namespace MobileGL { return GL_SRC1_ALPHA; case BlendFactor::OneMinusSrc1Alpha: return GL_ONE_MINUS_SRC1_ALPHA; + case BlendFactor::SrcAlphaSaturate: + return GL_SRC_ALPHA_SATURATE; default: return GL_UNKNOWN_MGL; } diff --git a/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.cpp index 8952a039..e9a04edb 100644 --- a/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.cpp @@ -48,6 +48,8 @@ namespace MobileGL { return "Src1Alpha"; case BlendFactor::OneMinusSrc1Alpha: return "OneMinusSrc1Alpha"; + case BlendFactor::SrcAlphaSaturate: + return "SrcAlphaSaturate"; default: return "Unknown"; } diff --git a/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.cpp index 23806611..235ffc74 100644 --- a/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.cpp @@ -200,6 +200,8 @@ namespace MobileGL { return VK_BLEND_FACTOR_SRC1_ALPHA; case BlendFactor::OneMinusSrc1Alpha: return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA; + case BlendFactor::SrcAlphaSaturate: + return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE; default: return VK_BLEND_FACTOR_ONE; }