diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineFactory.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineFactory.h index 54039081..842aa10f 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineFactory.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineFactory.h @@ -24,7 +24,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkRenderPass renderPass = VK_NULL_HANDLE; Uint32 subpass = 0; VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - VkCullModeFlags cullMode = VK_CULL_MODE_NONE; + VkCullModeFlags cullMode = VK_CULL_MODE_BACK_BIT; VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE; Bool depthTestEnable = false; Bool depthWriteEnable = false; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp index 4a30f9ea..ad1f254b 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp @@ -364,7 +364,6 @@ namespace MobileGL::MG_Backend::DirectVulkan { } auto& entry = m_cache[hash]; - entry.device = m_device; entry.hash = hash; auto& shaders = program.GetAttachedShaders(); auto& spirv = program.GetGeneratedSpirv(); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.h index 15ddc913..b44358cd 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.h @@ -26,39 +26,35 @@ namespace MobileGL::MG_Backend::DirectVulkan { }; using CompileOptionFlags = Flags; using HashType = Uint64; - struct BackendProgramObject { + struct VkProgramObject { HashType hash = 0; - VkDevice device = VK_NULL_HANDLE; Vector stages; Vector modules; + static inline VkDevice s_device = VK_NULL_HANDLE; - BackendProgramObject() = default; - BackendProgramObject(const BackendProgramObject&) = delete; - BackendProgramObject& operator=(const BackendProgramObject&) = delete; - BackendProgramObject(BackendProgramObject&& other) noexcept { + VkProgramObject() = default; + VkProgramObject(const VkProgramObject&) = delete; + VkProgramObject& operator=(const VkProgramObject&) = delete; + VkProgramObject(VkProgramObject&& other) noexcept { hash = other.hash; - device = other.device; stages = std::move(other.stages); modules = std::move(other.modules); other.hash = 0; - other.device = VK_NULL_HANDLE; } - BackendProgramObject& operator=(BackendProgramObject&& other) noexcept { + VkProgramObject& operator=(VkProgramObject&& other) noexcept { if (this == &other) { return *this; } DestroyModules(); stages.clear(); hash = other.hash; - device = other.device; stages = std::move(other.stages); modules = std::move(other.modules); other.hash = 0; - other.device = VK_NULL_HANDLE; return *this; } - ~BackendProgramObject() { + ~VkProgramObject() { DestroyModules(); stages.clear(); } @@ -66,8 +62,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { private: void DestroyModules() { for (auto module : modules) { - if (module != VK_NULL_HANDLE && device != VK_NULL_HANDLE) { - vkDestroyShaderModule(device, module, nullptr); + if (module != VK_NULL_HANDLE && s_device != VK_NULL_HANDLE) { + vkDestroyShaderModule(s_device, module, nullptr); } } modules.clear(); @@ -75,7 +71,9 @@ namespace MobileGL::MG_Backend::DirectVulkan { }; explicit ProgramFactory(VkDevice device, const VulkanRendererConfig& config) - : m_device(device), m_config(config) {} + : m_device(device), m_config(config) { + VkProgramObject::s_device = device; + } ~ProgramFactory(); ProgramFactory(const ProgramFactory&) = delete; @@ -87,7 +85,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { private: VkDevice m_device = VK_NULL_HANDLE; - UnorderedMap m_cache; + UnorderedMap m_cache; const VulkanRendererConfig& m_config; static inline XXH64_state_t* m_hashState = XXH64_createState(); }; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index 71bdbd75..6d7b1db6 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -337,6 +337,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const MG_State::GLState::VertexArrayObject& vao, const MG_State::GLState::FramebufferObject& drawFbo) { ProgramFactory::CompileOptionFlags transformFlags = GetShaderTransformFlags(m_swapchainObject.GetPreTransform()); + Bool invertClockwise = transformFlags & ProgramFactory::CompileOptionBit::PositionYFlip; auto& stages = m_programFactory->GetOrCreatePipelineShaderStages(program, transformFlags); if (stages.empty()) { MGLOG_D("GetOrCreatePipeline skipped: program has no shader stages"); @@ -364,10 +365,9 @@ namespace MobileGL::MG_Backend::DirectVulkan { .renderPass = renderPassEntry.renderPass, .subpass = 0, .topology = MG_Util::ConvertPrimitiveModeToVkEnum(mode), -// .cullMode = cullFaceEnabled -// ? MG_Util::ConvertCullFaceModeToVkEnum(MG_State::pGLContext->GetCullFaceMode()) -// : VK_CULL_MODE_NONE, - .cullMode = VK_CULL_MODE_NONE, + .cullMode = cullFaceEnabled + ? MG_Util::ConvertCullFaceModeToVkEnum(MG_State::pGLContext->GetCullFaceMode(), invertClockwise) + : VK_CULL_MODE_NONE, .frontFace = VK_FRONT_FACE_CLOCKWISE, .depthTestEnable = depthTestEnabled, .depthWriteEnable = depthTestEnabled && MG_State::pGLContext->GetDepthMask(), @@ -389,17 +389,23 @@ namespace MobileGL::MG_Backend::DirectVulkan { } void VulkanRenderer::SetupDraw(FrameContext::FrameData& frame, GLenum mode, Flags aspects) { + // Prepare render pass + const auto& drawFbo = + MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); + auto& renderPassEntry = m_renderPassManager->GetOrCreateRenderPass(*drawFbo, m_imageIndexAcquired); + + // Prepare pipeline + const auto& vao = *MG_State::pGLContext->GetBoundVertexArray(); + const auto& program = *MG_State::pGLContext->GetCurrentProgram(); + auto pipeline = GetOrCreatePipeline(mode, program, vao, *drawFbo); + // Begin command recording if not yet if (!frame.isCommandRecording) { m_frameContext.BeginCommandRecording(); m_uniformDescriptorBinder->BeginFrame(m_frameContext.GetCurrentFrameIndex()); } - const auto& drawFbo = - MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject(); - // Begin render pass, and handle clear - auto& renderPassEntry = m_renderPassManager->GetOrCreateRenderPass(*drawFbo, m_imageIndexAcquired); auto* activeRenderPass = VkRenderPassManager::GetActiveRenderPass(); if (activeRenderPass && (activeRenderPass == &renderPassEntry || activeRenderPass->CompatibleWith(renderPassEntry))) { @@ -413,9 +419,6 @@ namespace MobileGL::MG_Backend::DirectVulkan { MOBILEGL_ASSERT(ok, "%s: BeginRenderPass failed", __func__); } - const auto& vao = *MG_State::pGLContext->GetBoundVertexArray(); - const auto& program = *MG_State::pGLContext->GetCurrentProgram(); - auto pipeline = GetOrCreatePipeline(mode, program, vao, *drawFbo); vkCmdBindPipeline(frame.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); m_uniformDescriptorBinder->BindProgramUniformBuffers(frame.commandBuffer, program, diff --git a/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.cpp index e7b3ffce..f59145ce 100644 --- a/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.cpp @@ -31,12 +31,12 @@ namespace MobileGL { } } - VkCullModeFlags ConvertCullFaceModeToVkEnum(CullFaceMode v) { + VkCullModeFlags ConvertCullFaceModeToVkEnum(CullFaceMode v, Bool invertClockwise) { switch (v) { case CullFaceMode::Front: - return VK_CULL_MODE_FRONT_BIT; + return invertClockwise ? VK_CULL_MODE_BACK_BIT : VK_CULL_MODE_FRONT_BIT; case CullFaceMode::Back: - return VK_CULL_MODE_BACK_BIT; + return invertClockwise ? VK_CULL_MODE_FRONT_BIT : VK_CULL_MODE_BACK_BIT; case CullFaceMode::FrontAndBack: return VK_CULL_MODE_FRONT_AND_BACK; case CullFaceMode::Unknown: diff --git a/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.h b/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.h index ecc5fead..abe436be 100644 --- a/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.h +++ b/MobileGL/MG_Util/Converters/MGToVk/RenderStateEnumConverter.h @@ -13,7 +13,7 @@ namespace MobileGL { namespace MG_Util { VkPrimitiveTopology ConvertPrimitiveModeToVkEnum(GLenum mode); - VkCullModeFlags ConvertCullFaceModeToVkEnum(CullFaceMode value); + VkCullModeFlags ConvertCullFaceModeToVkEnum(CullFaceMode value, Bool invertClockwise = false); VkCompareOp ConvertDepthTestFuncToVkEnum(DepthTestFunc value); VkBlendFactor ConvertBlendFactorToVkEnum(BlendFactor value); } // namespace MG_Util