mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Chore] (MG_Backend/DirectVulkan): move ClearAttachmentsOnActiveRenderPass to VulkanRenderer
This commit is contained in:
@@ -302,13 +302,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
Bool VkRenderPassManager::TryClearPendingAttachmentsOnActiveRenderPass(
|
Bool VkRenderPassManager::TryClearPendingAttachmentsOnActiveRenderPass(
|
||||||
VkCommandBuffer commandBuffer,
|
VkCommandBuffer commandBuffer,
|
||||||
const RenderPassEntry& compatibleRenderPassEntry) {
|
const RenderPassEntry& compatibleRenderPassEntry) {
|
||||||
if (!s_activeRenderPass || !s_clearManager) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (s_activeRenderPass->compatibilityHash != compatibleRenderPassEntry.compatibilityHash) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkClearRect clearRect{};
|
VkClearRect clearRect{};
|
||||||
clearRect.rect.offset = {0, 0};
|
clearRect.rect.offset = {0, 0};
|
||||||
clearRect.rect.extent = {
|
clearRect.rect.extent = {
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
vkDestroyFramebuffer(s_device, framebuffer, nullptr);
|
vkDestroyFramebuffer(s_device, framebuffer, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool CompatibleWith(const RenderPassEntry& that) {
|
||||||
|
return this->compatibilityHash == that.compatibilityHash;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class VkRenderPassManager {
|
class VkRenderPassManager {
|
||||||
|
|||||||
@@ -392,23 +392,19 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
const auto& drawFbo =
|
const auto& drawFbo =
|
||||||
MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject();
|
MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject();
|
||||||
|
|
||||||
// Begin render pass
|
// Begin render pass, and handle clear
|
||||||
// TODO: properly deal with clear
|
|
||||||
auto& renderPassEntry = m_renderPassManager->GetOrCreateRenderPass(*drawFbo, m_imageIndexAcquired);
|
auto& renderPassEntry = m_renderPassManager->GetOrCreateRenderPass(*drawFbo, m_imageIndexAcquired);
|
||||||
auto* activeRenderPass = VkRenderPassManager::GetActiveRenderPass();
|
auto* activeRenderPass = VkRenderPassManager::GetActiveRenderPass();
|
||||||
if (activeRenderPass != &renderPassEntry) {
|
|
||||||
if (activeRenderPass &&
|
if (activeRenderPass && (activeRenderPass == &renderPassEntry || activeRenderPass->CompatibleWith(renderPassEntry))) {
|
||||||
VkRenderPassManager::TryClearPendingAttachmentsOnActiveRenderPass(frame.commandBuffer, renderPassEntry)) {
|
ClearAttachmentsOnActiveRenderPass(frame.commandBuffer, renderPassEntry);
|
||||||
// Keep the current compatible render pass open and clear inside it.
|
|
||||||
} else {
|
|
||||||
if (activeRenderPass) {
|
|
||||||
VkRenderPassManager::EndRenderPass(frame.commandBuffer);
|
|
||||||
}
|
|
||||||
Bool ok = VkRenderPassManager::BeginRenderPass(frame.commandBuffer, renderPassEntry);
|
|
||||||
MOBILEGL_ASSERT(ok, "%s: BeginRenderPass failed", __func__);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// We probably already have one compatible render pass running. Keep going.
|
// No active render pass or active one not compatible.
|
||||||
|
// Restart a new render pass
|
||||||
|
if (activeRenderPass)
|
||||||
|
VkRenderPassManager::EndRenderPass(frame.commandBuffer);
|
||||||
|
Bool ok = VkRenderPassManager::BeginRenderPass(frame.commandBuffer, renderPassEntry);
|
||||||
|
MOBILEGL_ASSERT(ok, "%s: BeginRenderPass failed", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& vao = *MG_State::pGLContext->GetBoundVertexArray();
|
const auto& vao = *MG_State::pGLContext->GetBoundVertexArray();
|
||||||
@@ -1140,4 +1136,54 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
Bool VulkanRenderer::IsDrawIndirectCountExtensionEnabled() const {
|
Bool VulkanRenderer::IsDrawIndirectCountExtensionEnabled() const {
|
||||||
return m_drawIndirectCountExtensionEnabled;
|
return m_drawIndirectCountExtensionEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanRenderer::ClearAttachmentsOnActiveRenderPass(VkCommandBuffer commandBuffer,
|
||||||
|
const RenderPassEntry &compatibleRenderPassEntry) {
|
||||||
|
auto* activeRenderPass = VkRenderPassManager::GetActiveRenderPass();
|
||||||
|
MOBILEGL_ASSERT(activeRenderPass, "No render pass active");
|
||||||
|
VkClearRect clearRect{};
|
||||||
|
clearRect.rect.offset = {0, 0};
|
||||||
|
clearRect.rect.extent = {
|
||||||
|
static_cast<Uint32>(activeRenderPass->extent.x()),
|
||||||
|
static_cast<Uint32>(activeRenderPass->extent.y())
|
||||||
|
};
|
||||||
|
clearRect.baseArrayLayer = 0;
|
||||||
|
clearRect.layerCount = 1;
|
||||||
|
|
||||||
|
for (const auto& pending : compatibleRenderPassEntry.pendingClearAttachments) {
|
||||||
|
if (!pending.texture) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearAttachmentPayload clearPayload{};
|
||||||
|
if (!m_clearManager->GetPendingClear(pending.texture, clearPayload)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkClearAttachment clearAttachment{};
|
||||||
|
clearAttachment.clearValue.depthStencil = {1.0f, 0};
|
||||||
|
if (clearPayload.attachmentType >= FramebufferAttachmentType::Color0 &&
|
||||||
|
clearPayload.attachmentType <= FramebufferAttachmentType::Color31) {
|
||||||
|
clearAttachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
clearAttachment.colorAttachment = pending.attachmentIndex;
|
||||||
|
clearAttachment.clearValue.color = {
|
||||||
|
clearPayload.color.x(),
|
||||||
|
clearPayload.color.y(),
|
||||||
|
clearPayload.color.z(),
|
||||||
|
clearPayload.color.w()
|
||||||
|
};
|
||||||
|
} else if (clearPayload.attachmentType == FramebufferAttachmentType::Depth) {
|
||||||
|
clearAttachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
|
clearAttachment.clearValue.depthStencil.depth = clearPayload.depth;
|
||||||
|
} else if (clearPayload.attachmentType == FramebufferAttachmentType::Stencil) {
|
||||||
|
clearAttachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||||
|
clearAttachment.clearValue.depthStencil.stencil = clearPayload.stencil;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
vkCmdClearAttachments(commandBuffer, 1, &clearAttachment, 1, &clearRect);
|
||||||
|
m_clearManager->PopPendingClear(pending.texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
void SetupDraw(FrameContext::FrameData& frame, GLenum mode, Flags<DrawSetupAspect> aspects);
|
void SetupDraw(FrameContext::FrameData& frame, GLenum mode, Flags<DrawSetupAspect> aspects);
|
||||||
|
void ClearAttachmentsOnActiveRenderPass(VkCommandBuffer commandBuffer,
|
||||||
|
const RenderPassEntry& compatibleRenderPassEntry);
|
||||||
|
|
||||||
void Clear(GLbitfield mask);
|
void Clear(GLbitfield mask);
|
||||||
void DrawArrays(const DrawArrayCmd& payload);
|
void DrawArrays(const DrawArrayCmd& payload);
|
||||||
@@ -116,8 +118,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
VkCommandPool m_commandPool = VK_NULL_HANDLE;
|
VkCommandPool m_commandPool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
RenderPassEntry* m_activeRenderPass = nullptr;
|
|
||||||
|
|
||||||
Vector<VkBufferObject> m_frameVertexUploadBuffers;
|
Vector<VkBufferObject> m_frameVertexUploadBuffers;
|
||||||
Vector<VkDeviceSize> m_frameVertexUploadHeads;
|
Vector<VkDeviceSize> m_frameVertexUploadHeads;
|
||||||
Vector<VkBufferObject> m_frameIndexUploadBuffers;
|
Vector<VkBufferObject> m_frameIndexUploadBuffers;
|
||||||
|
|||||||
Reference in New Issue
Block a user