mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 20:28:32 +09:00
[Fix] (MG_Backend/DirectVulkan): track image layout naively
This commit is contained in:
@@ -20,6 +20,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
m_swapchainObject(swapchainObject) {
|
||||
RenderPassEntry::s_device = m_device;
|
||||
s_clearManager = &m_clearManager;
|
||||
s_textureManager = &m_textureManager;
|
||||
}
|
||||
|
||||
VkRenderPassManager::~VkRenderPassManager() {}
|
||||
@@ -120,6 +121,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
Vector<VkAttachmentDescription> attachmentDescriptions(validDrawBufCount);
|
||||
Vector<VkAttachmentReference> colorAttachmentRefs(validDrawBufCount);
|
||||
Vector<PendingClearAttachmentInfo> pendingClearAttachments;
|
||||
Vector<TrackedAttachmentLayoutInfo> trackedAttachmentLayouts;
|
||||
auto& textureResources = RenderPassEntry::s_textureResourcesScratch;
|
||||
textureResources.clear();
|
||||
textureResources.resize(validDrawBufCount, nullptr);
|
||||
@@ -184,6 +186,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
MOBILEGL_ASSERT(hasClear || textureResources[i]->layout != VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
"GetOrCreateRenderPass: color attachment textureId=%d has undefined tracked layout with LOAD_OP_LOAD (attachment=%d)",
|
||||
texture->GetExternalIndex(), i);
|
||||
trackedAttachmentLayouts.emplace_back(TrackedAttachmentLayoutInfo {
|
||||
.texture = texture,
|
||||
.finalLayout = desc.finalLayout,
|
||||
});
|
||||
attachmentViews[i] = textureResources[i]->view;
|
||||
}
|
||||
|
||||
@@ -249,6 +255,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
MOBILEGL_ASSERT(clearDepth || clearStencil || depthTextureResource->layout != VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
"GetOrCreateRenderPass: depth attachment textureId=%d has undefined tracked layout with LOAD_OP_LOAD",
|
||||
texture.GetExternalIndex());
|
||||
trackedAttachmentLayouts.emplace_back(TrackedAttachmentLayoutInfo {
|
||||
.texture = &texture,
|
||||
.finalLayout = depthAttachmentDescription.finalLayout,
|
||||
});
|
||||
textureResources.emplace_back(depthTextureResource);
|
||||
attachmentViews.emplace_back(depthTextureResource->view);
|
||||
if (width == 0 || height == 0) {
|
||||
@@ -308,6 +318,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
framebuffer,
|
||||
compatibilityHash,
|
||||
Move(pendingClearAttachments),
|
||||
Move(trackedAttachmentLayouts),
|
||||
static_cast<Uint32>(attachmentViews.size()),
|
||||
extent,
|
||||
1 };
|
||||
@@ -367,7 +378,14 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
|
||||
Bool VkRenderPassManager::EndRenderPass(VkCommandBuffer commandBuffer) {
|
||||
auto* activeRenderPass = s_activeRenderPass;
|
||||
vkCmdEndRenderPass(commandBuffer);
|
||||
if (activeRenderPass != nullptr && !activeRenderPass->trackedAttachmentLayouts.empty()) {
|
||||
MOBILEGL_ASSERT(s_textureManager != nullptr, "EndRenderPass: texture manager is null");
|
||||
for (const auto& trackedAttachment : activeRenderPass->trackedAttachmentLayouts) {
|
||||
s_textureManager->UpdateTrackedImageLayout(trackedAttachment.texture, trackedAttachment.finalLayout);
|
||||
}
|
||||
}
|
||||
s_activeRenderPass = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,11 +18,17 @@
|
||||
#include <Includes.h>
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
|
||||
struct PendingClearAttachmentInfo {
|
||||
Uint32 attachmentIndex = 0;
|
||||
MG_State::GLState::ITextureObject* texture = nullptr;
|
||||
};
|
||||
|
||||
struct TrackedAttachmentLayoutInfo {
|
||||
MG_State::GLState::ITextureObject* texture = nullptr;
|
||||
VkImageLayout finalLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
};
|
||||
|
||||
struct RenderPassEntry {
|
||||
static inline VkDevice s_device;
|
||||
static inline Vector<VkTextureManager::TextureResource*> s_textureResourcesScratch;
|
||||
@@ -30,6 +36,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
||||
Uint64 compatibilityHash = 0;
|
||||
Vector<PendingClearAttachmentInfo> pendingClearAttachments;
|
||||
Vector<TrackedAttachmentLayoutInfo> trackedAttachmentLayouts;
|
||||
Uint32 attachmentCount = 0;
|
||||
IntVec2 extent = {0, 0};
|
||||
Uint32 subpass = 0;
|
||||
@@ -41,6 +48,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
std::swap(framebuffer, that.framebuffer);
|
||||
std::swap(compatibilityHash, that.compatibilityHash);
|
||||
std::swap(pendingClearAttachments, that.pendingClearAttachments);
|
||||
std::swap(trackedAttachmentLayouts, that.trackedAttachmentLayouts);
|
||||
std::swap(attachmentCount, that.attachmentCount);
|
||||
std::swap(extent, that.extent);
|
||||
std::swap(subpass, that.subpass);
|
||||
@@ -50,12 +58,14 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
VkFramebuffer framebuffer,
|
||||
Uint64 compatibilityHash,
|
||||
const Vector<PendingClearAttachmentInfo>& pendingClearAttachments,
|
||||
const Vector<TrackedAttachmentLayoutInfo>& trackedAttachmentLayouts,
|
||||
Uint32 attachmentCount,
|
||||
IntVec2 extent, int subpass):
|
||||
renderPass(renderpass),
|
||||
framebuffer(framebuffer),
|
||||
compatibilityHash(compatibilityHash),
|
||||
pendingClearAttachments(Move(pendingClearAttachments)),
|
||||
trackedAttachmentLayouts(Move(trackedAttachmentLayouts)),
|
||||
attachmentCount(attachmentCount),
|
||||
extent(extent),
|
||||
subpass(subpass)
|
||||
@@ -70,9 +80,13 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
}
|
||||
|
||||
Bool CompatibleWith(const RenderPassEntry& that) {
|
||||
Bool CompatibleWith(const RenderPassEntry& that) const {
|
||||
return this->compatibilityHash == that.compatibilityHash;
|
||||
}
|
||||
|
||||
Bool CompatibleWith(Uint64 compatibilityHash) const {
|
||||
return this->compatibilityHash == compatibilityHash;
|
||||
}
|
||||
};
|
||||
|
||||
class VkRenderPassManager {
|
||||
@@ -104,5 +118,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
static inline XXH64_state_t* m_hashState = XXH64_createState();
|
||||
static inline RenderPassEntry* s_activeRenderPass = nullptr;
|
||||
static inline VkClearManager* s_clearManager = nullptr;
|
||||
static inline VkTextureManager* s_textureManager = nullptr;
|
||||
};
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
|
||||
@@ -58,6 +58,17 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
void VkTextureManager::UpdateTrackedImageLayout(MG_State::GLState::ITextureObject* texture, VkImageLayout newLayout) {
|
||||
MOBILEGL_ASSERT(texture != nullptr, "UpdateTrackedImageLayout: texture is null");
|
||||
auto it = m_textureResources.find(texture);
|
||||
MOBILEGL_ASSERT(it != m_textureResources.end(),
|
||||
"UpdateTrackedImageLayout: textureId=%d has no tracked resource", texture->GetExternalIndex());
|
||||
MOBILEGL_ASSERT(it->second.image != VK_NULL_HANDLE,
|
||||
"UpdateTrackedImageLayout: textureId=%d has null image", texture->GetExternalIndex());
|
||||
it->second.layout = newLayout;
|
||||
}
|
||||
|
||||
Bool VkTextureManager::TransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image,
|
||||
VkImageLayout& trackedLayout, VkImageLayout newLayout,
|
||||
VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
|
||||
TextureResource* SyncTextureAndGetDescriptor(
|
||||
MG_State::GLState::ITextureObject& texture);
|
||||
void UpdateTrackedImageLayout(MG_State::GLState::ITextureObject* texture, VkImageLayout newLayout);
|
||||
|
||||
static Bool TransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout& trackedLayout,
|
||||
VkImageLayout newLayout, VkPipelineStageFlags srcStageMask,
|
||||
|
||||
Reference in New Issue
Block a user