From 27a8aa057c91cb22befdcf8a09e224d18dc446b1 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sun, 24 May 2026 17:38:44 +0800 Subject: [PATCH] [Feat] (MG_Impl/RenderState): implement some blend related states --- .../Renderer/VkRenderPassManager.cpp | 10 +++- .../Renderer/VkTextureManager.cpp | 28 +++++++---- .../MG_Impl/GLImpl/Exporting/Definitions.cpp | 14 +++--- .../GLImpl/RenderState/GL_RenderState.cpp | 48 +++++++++++++++++++ .../GLImpl/RenderState/GL_RenderState.h | 3 ++ 5 files changed, 87 insertions(+), 16 deletions(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp index 06bd9672..6773ff60 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp @@ -12,8 +12,16 @@ #include "MG_State/GLState/TextureState/TextureObject2D.h" #include "MG_Util/Converters/MGToStr/FramebufferEnumConverter.h" #include "MG_Util/Converters/MGToVk/TextureEnumConverter.h" +#include "MG_Util/Metrics/TextureMetrics.h" namespace MobileGL::MG_Backend::DirectVulkan { + static Float ResolveColorClearAlpha(const MG_State::GLState::ITextureObject* texture, Float requestedAlpha) { + if (texture != nullptr && MG_Util::GetBaseInternalFormatComponentCount(texture->GetFormat()) == 3) { + return 1.0f; + } + return requestedAlpha; + } + static MG_State::GLState::ITextureObject* ResolveCompleteColorAttachmentTexture( const MG_State::GLState::FramebufferObject& fbo, FramebufferAttachmentType attachmentType, @@ -516,7 +524,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { clearPayload.color.x(), clearPayload.color.y(), clearPayload.color.z(), - clearPayload.color.w() + ResolveColorClearAlpha(pending.texture, clearPayload.color.w()) }; } if ((clearPayload.mask & GL_DEPTH_BUFFER_BIT) != 0) { diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp index ea22dcf1..57c09542 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp @@ -336,13 +336,22 @@ namespace MobileGL::MG_Backend::DirectVulkan { } } - static VkComponentMapping ResolveSampledViewComponents(const MG_State::GLState::ITextureObject& texture) { + static VkComponentSwizzle ToVkSampledComponentSwizzle(TextureSwizzleParam swizzle, Bool alphaIsImplicitOne) { + if (alphaIsImplicitOne && swizzle == TextureSwizzleParam::Alpha) { + return VK_COMPONENT_SWIZZLE_ONE; + } + return ToVkComponentSwizzle(swizzle); + } + + static VkComponentMapping ResolveSampledViewComponents(const MG_State::GLState::ITextureObject& texture, + const TextureFormatInfo& formatInfo) { const auto& swizzles = texture.GetAllSwizzleParams(); + const Bool alphaIsImplicitOne = formatInfo.expandRgbToRgba; VkComponentMapping components{ - ToVkComponentSwizzle(swizzles.x()), - ToVkComponentSwizzle(swizzles.y()), - ToVkComponentSwizzle(swizzles.z()), - ToVkComponentSwizzle(swizzles.w()), + ToVkSampledComponentSwizzle(swizzles.x(), alphaIsImplicitOne), + ToVkSampledComponentSwizzle(swizzles.y(), alphaIsImplicitOne), + ToVkSampledComponentSwizzle(swizzles.z(), alphaIsImplicitOne), + ToVkSampledComponentSwizzle(swizzles.w(), alphaIsImplicitOne), }; return components; } @@ -514,7 +523,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { return perMipSampledView; } - const VkComponentMapping sampledComponents = ResolveSampledViewComponents(texture); + const TextureFormatInfo formatInfo = ResolveTextureFormatInfo(texture.GetFormat()); + const VkComponentMapping sampledComponents = ResolveSampledViewComponents(texture, formatInfo); perMipSampledView = CreateImageView(resource->image, resource->format, resource->aspect, resource->viewType, mipLevel, 1, resource->arrayLayers, &sampledComponents); if (perMipSampledView == VK_NULL_HANDLE) { @@ -962,7 +972,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { resource.fullView = VK_NULL_HANDLE; } - const VkComponentMapping sampledComponents = ResolveSampledViewComponents(texture); + const TextureFormatInfo formatInfo = ResolveTextureFormatInfo(texture.GetFormat()); + const VkComponentMapping sampledComponents = ResolveSampledViewComponents(texture, formatInfo); resource.fullView = CreateImageView(resource.image, resource.format, resource.aspect, resource.viewType, baseMipLevel, levelCount, resource.arrayLayers, &sampledComponents); if (resource.fullView == VK_NULL_HANDLE) { @@ -1143,8 +1154,9 @@ namespace MobileGL::MG_Backend::DirectVulkan { 1, ©); } + VkImageLayout uploadLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; ok = TransitionImageLayout(commandBuffer, outResource.image, - outResource.layout, + uploadLayout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, kGraphicsSampledReadStages, diff --git a/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp b/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp index 10139c38..a692f6e6 100644 --- a/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp +++ b/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp @@ -387,14 +387,14 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, GetObjectPtrLabel, const void* ptr, GLsizei DECLARE_GL_FUNCTION_STUB_HEAD(void, GetPointerv, GLenum pname, void** params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetPointerv, pname, params) DECLARE_GL_FUNCTION_HEAD(void, Enablei, GLenum target, GLuint index) DECLARE_GL_FUNCTION_END_NO_RETURN(void, Enablei, target, index) DECLARE_GL_FUNCTION_HEAD(void, Disablei, GLenum target, GLuint index) DECLARE_GL_FUNCTION_END_NO_RETURN(void, Disablei, target, index) -DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendEquationi, GLuint buf, GLenum mode) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlendEquationi, buf, mode) -DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendEquationiARB, GLuint buf, GLenum mode) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlendEquationi, buf, mode) -DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendEquationSeparatei, GLuint buf, GLenum modeRGB, GLenum modeAlpha) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlendEquationSeparatei, buf, modeRGB, modeAlpha) -DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendEquationSeparateiARB, GLuint buf, GLenum modeRGB, GLenum modeAlpha) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlendEquationSeparatei, buf, modeRGB, modeAlpha) -DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendFunci, GLuint buf, GLenum src, GLenum dst) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlendFunci, buf, src, dst) -DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendFunciARB, GLuint buf, GLenum src, GLenum dst) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlendFunci, buf, src, dst) +DECLARE_GL_FUNCTION_HEAD(void, BlendEquationi, GLuint buf, GLenum mode) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendEquationi, buf, mode) +DECLARE_GL_FUNCTION_HEAD(void, BlendEquationiARB, GLuint buf, GLenum mode) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendEquationi, buf, mode) +DECLARE_GL_FUNCTION_HEAD(void, BlendEquationSeparatei, GLuint buf, GLenum modeRGB, GLenum modeAlpha) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendEquationSeparatei, buf, modeRGB, modeAlpha) +DECLARE_GL_FUNCTION_HEAD(void, BlendEquationSeparateiARB, GLuint buf, GLenum modeRGB, GLenum modeAlpha) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendEquationSeparatei, buf, modeRGB, modeAlpha) +DECLARE_GL_FUNCTION_HEAD(void, BlendFunci, GLuint buf, GLenum src, GLenum dst) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendFunci, buf, src, dst) +DECLARE_GL_FUNCTION_HEAD(void, BlendFunciARB, GLuint buf, GLenum src, GLenum dst) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendFunci, buf, src, dst) DECLARE_GL_FUNCTION_HEAD(void, BlendFuncSeparatei, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendFuncSeparatei, buf, srcRGB, dstRGB, srcAlpha, dstAlpha) -DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendFuncSeparateiARB, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlendFuncSeparatei, buf, srcRGB, dstRGB, srcAlpha, dstAlpha) +DECLARE_GL_FUNCTION_HEAD(void, BlendFuncSeparateiARB, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendFuncSeparatei, buf, srcRGB, dstRGB, srcAlpha, dstAlpha) DECLARE_GL_FUNCTION_STUB_HEAD(void, ColorMaski, GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ColorMaski, index, r, g, b, a) DECLARE_GL_FUNCTION_HEAD(GLboolean, IsEnabledi, GLenum target, GLuint index) DECLARE_GL_FUNCTION_END(GLboolean, IsEnabledi, target, index) DECLARE_GL_FUNCTION_HEAD(void, DrawElementsBaseVertex, GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DrawElementsBaseVertex, mode, count, type, indices, basevertex) diff --git a/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp b/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp index c9c8562e..aa7c46f3 100644 --- a/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp +++ b/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp @@ -308,9 +308,45 @@ namespace MobileGL::MG_Impl::GLImpl { BlendFactor dstRGBM = MG_Util::ConvertGLEnumToBlendFactor(dstRGB); BlendFactor srcAlphaM = MG_Util::ConvertGLEnumToBlendFactor(srcAlpha); BlendFactor dstAlphaM = MG_Util::ConvertGLEnumToBlendFactor(dstAlpha); + if (srcRGBM == BlendFactor::Unknown || dstRGBM == BlendFactor::Unknown || + srcAlphaM == BlendFactor::Unknown || dstAlphaM == BlendFactor::Unknown) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeUnique("MG_Impl/GLImpl", "BlendFuncSeparatei_State", + "One of the indexed blend factor enums is not supported.")); + return; + } MG_State::pGLContext->SetBlendFuncIndexed(buf, srcRGBM, dstRGBM, srcAlphaM, dstAlphaM); } + void BlendFunci_State(GLuint buf, GLenum src, GLenum dst) { + BlendFuncSeparatei_State(buf, src, dst, src, dst); + } + + void BlendEquationSeparatei_State(GLuint buf, GLenum modeRGB, GLenum modeAlpha) { + if (buf >= MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeUnique( + "MG_Impl/GLImpl", "BlendEquationSeparatei_State", + "Buffer index " + std::to_string(buf) + " is out of range. Max supported is " + + std::to_string(MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS - 1) + ".")); + return; + } + + ::MobileGL::BlendEquation colorEquation = ::MobileGL::BlendEquation::Unknown; + if (!TryConvertBlendEquation(modeRGB, "BlendEquationSeparatei_State", colorEquation)) return; + + ::MobileGL::BlendEquation alphaEquation = ::MobileGL::BlendEquation::Unknown; + if (!TryConvertBlendEquation(modeAlpha, "BlendEquationSeparatei_State", alphaEquation)) return; + + MG_State::pGLContext->SetBlendEquationIndexed(buf, colorEquation, alphaEquation); + } + + void BlendEquationi_State(GLuint buf, GLenum mode) { + BlendEquationSeparatei_State(buf, mode, mode); + } + void Disablei_State(GLenum target, GLuint index) { auto capInput = MG_Util::ConvertGLEnumToCapabilityInput(target); if (capInput == CapabilityInput::Unknown) { @@ -340,6 +376,18 @@ namespace MobileGL::MG_Impl::GLImpl { } /* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */ + void BlendEquationi(GLuint buf, GLenum mode) { + BlendEquationi_State(buf, mode); + } + + void BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha) { + BlendEquationSeparatei_State(buf, modeRGB, modeAlpha); + } + + void BlendFunci(GLuint buf, GLenum src, GLenum dst) { + BlendFunci_State(buf, src, dst); + } + void BlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { BlendFuncSeparatei_State(buf, srcRGB, dstRGB, srcAlpha, dstAlpha); } diff --git a/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.h b/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.h index d40b629b..400909dc 100644 --- a/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.h +++ b/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.h @@ -11,6 +11,9 @@ namespace MobileGL::MG_Impl::GLImpl { /* @INSERTION_POINT:FUNCTION_DECLARATION@ */ + void BlendEquationi(GLuint buf, GLenum mode); + void BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha); + void BlendFunci(GLuint buf, GLenum src, GLenum dst); void BlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); void Disablei(GLenum target, GLuint index); void Enablei(GLenum target, GLuint index);