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