mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-10 21:28:32 +09:00
[Fix] (MG_Backend/DirectVulkan): Vulkan backend default framebuffer initialization
This commit is contained in:
@@ -8,6 +8,9 @@
|
||||
|
||||
#include "SwapchainObject.h"
|
||||
|
||||
#include "MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h"
|
||||
#include "MG_State/GLState/TextureState/TextureObject2D.h"
|
||||
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<vulkan/vk_enum_string_helper.h>)
|
||||
#include <vulkan/vk_enum_string_helper.h>
|
||||
@@ -228,6 +231,35 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
|
||||
MGLOG_I("Swapchain created, extent = %dx%d, swapchain imageCount = %d", m_extent.width, m_extent.height,
|
||||
imageCount);
|
||||
|
||||
// Properly initialize Default FBO here
|
||||
auto* defaultFBOInfo = MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo;
|
||||
auto* colorTex = static_cast<MG_State::GLState::TextureObject2D*>(defaultFBOInfo->colorAttachment.get());
|
||||
colorTex->AllocateStorage(
|
||||
TextureUploadTarget::Texture2D, 0, {
|
||||
{(Int)createInfo.imageExtent.width, (Int)createInfo.imageExtent.height, 1},
|
||||
createInfo.imageExtent.width * (Int)createInfo.imageExtent.height * 4}); // TODO: 4 is format size
|
||||
TextureInternalFormat depthFormat = TextureInternalFormat::Depth24Stencil8;
|
||||
switch (m_depthStencilFormat) {
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT:
|
||||
depthFormat = TextureInternalFormat::Depth24Stencil8;
|
||||
break;
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
depthFormat = TextureInternalFormat::Depth32FStencil8;
|
||||
break;
|
||||
case VK_FORMAT_D32_SFLOAT:
|
||||
depthFormat = TextureInternalFormat::DepthComponent32F;
|
||||
break;
|
||||
default:
|
||||
depthFormat = TextureInternalFormat::Depth24Stencil8;
|
||||
break;
|
||||
}
|
||||
auto* depthTex = static_cast<MG_State::GLState::TextureObject2D*>(defaultFBOInfo->depthAttachment.get());
|
||||
depthTex->SetInternalFormat(depthFormat);
|
||||
depthTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {
|
||||
{(Int)createInfo.imageExtent.width, (Int)createInfo.imageExtent.height, 1},
|
||||
createInfo.imageExtent.width * createInfo.imageExtent.width * 4}); // TODO: 4 is format size
|
||||
|
||||
}
|
||||
|
||||
void SwapchainObject::CreateDepthStencilResources(VkDevice device, VkPhysicalDevice physicalDevice) {
|
||||
|
||||
@@ -475,14 +475,15 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
if (!samplerToUse) {
|
||||
return false;
|
||||
}
|
||||
VkTextureManager::TextureResource resource;
|
||||
if (!m_textureManager->SyncTextureAndGetDescriptor(*texture, resource)) {
|
||||
VkTextureManager::TextureResource* resource =
|
||||
m_textureManager->SyncTextureAndGetDescriptor(*texture);
|
||||
if (resource == nullptr) {
|
||||
return false;
|
||||
}
|
||||
outImageInfo = {
|
||||
.sampler = m_samplerManager->GetOrCreateSampler(*samplerToUse),
|
||||
.imageView = resource.view,
|
||||
.imageLayout = resource.layout,
|
||||
.imageView = resource->view,
|
||||
.imageLayout = resource->layout,
|
||||
};
|
||||
return outImageInfo.sampler != VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
Int height = 0;
|
||||
Vector<VkAttachmentDescription> attachmentDescriptions(validDrawBufCount);
|
||||
Vector<VkAttachmentReference> colorAttachmentRefs(validDrawBufCount);
|
||||
Vector<VkTextureManager::TextureResource> textureResources(validDrawBufCount);
|
||||
Vector<VkTextureManager::TextureResource*> textureResources(validDrawBufCount, nullptr);
|
||||
// This should automatically work on default & offscreen FBO
|
||||
// assuming default FBO has the right param
|
||||
for (Int i = 0; i < validDrawBufCount; ++i) {
|
||||
@@ -135,8 +135,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
if (height == 0)
|
||||
height = texture2d->GetBaseSize().y();
|
||||
|
||||
Bool ok = m_textureManager.SyncTextureAndGetDescriptor(*texture, textureResources[i]);
|
||||
MOBILEGL_ASSERT(ok, "GetOrCreateRenderPass: SyncTextureAndGetDescriptor failed at color attachment %d", i);
|
||||
textureResources[i] = m_textureManager.SyncTextureAndGetDescriptor(*texture);
|
||||
MOBILEGL_ASSERT(textureResources[i], "GetOrCreateRenderPass: SyncTextureAndGetDescriptor failed at color attachment %d", i);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -153,7 +153,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
// Depth attachment description
|
||||
auto& depthAtt = fbo.GetAttachment(FramebufferAttachmentType::Depth);
|
||||
VkAttachmentDescription depthAttachmentDescription;
|
||||
VkTextureManager::TextureResource depthTextureResource;
|
||||
VkTextureManager::TextureResource* depthTextureResource = nullptr;
|
||||
if (depthAtt.IsComplete() && depthAtt.IsTexture()) {
|
||||
auto& texture = *depthAtt.GetTexture();
|
||||
depthAttachmentDescription.format =
|
||||
@@ -167,8 +167,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
depthAttachmentDescription.finalLayout = isDefaultFbo ?
|
||||
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR :
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
Bool ok = m_textureManager.SyncTextureAndGetDescriptor(texture, depthTextureResource);
|
||||
MOBILEGL_ASSERT(ok, "GetOrCreateRenderPass: SyncTextureAndGetDescriptor failed at depth attachment");
|
||||
depthTextureResource = m_textureManager.SyncTextureAndGetDescriptor(texture);
|
||||
MOBILEGL_ASSERT(depthTextureResource, "GetOrCreateRenderPass: SyncTextureAndGetDescriptor failed at depth attachment");
|
||||
attachmentDescriptions.emplace_back(depthAttachmentDescription);
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
|
||||
Vector<VkImageView> attachmentViews(textureResources.size(), VK_NULL_HANDLE);
|
||||
for (Int i = 0; i < textureResources.size(); i++) {
|
||||
attachmentViews[i] = textureResources[i].view;
|
||||
attachmentViews[i] = textureResources[i]->view;
|
||||
}
|
||||
|
||||
// Framebuffer
|
||||
|
||||
@@ -21,7 +21,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
static inline VkDevice s_device;
|
||||
VkRenderPass renderPass = VK_NULL_HANDLE;
|
||||
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
||||
Vector<VkTextureManager::TextureResource> textureResources;
|
||||
// Should we hold pointer-to-resource here?
|
||||
Vector<VkTextureManager::TextureResource*> textureResources;
|
||||
IntVec2 extent = {0, 0};
|
||||
Uint32 subpass = 0;
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
m_commandPool != VK_NULL_HANDLE && m_graphicsQueue != VK_NULL_HANDLE,
|
||||
"VkTextureManager::Initialize failed: invalid initialization info");
|
||||
|
||||
TextureResource::s_device = m_device;
|
||||
TextureResource::s_allocator = m_allocator;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VkTextureManager::Shutdown() {
|
||||
for (auto& [_, resource] : m_textureResources) {
|
||||
DestroyTextureResource(resource);
|
||||
}
|
||||
m_textureResources.clear();
|
||||
|
||||
m_device = VK_NULL_HANDLE;
|
||||
@@ -40,25 +40,21 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
m_graphicsQueue = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
Bool VkTextureManager::SyncTextureAndGetDescriptor(MG_State::GLState::ITextureObject& texture,
|
||||
TextureResource& outTextureResource) {
|
||||
VkTextureManager::TextureResource* VkTextureManager::SyncTextureAndGetDescriptor(MG_State::GLState::ITextureObject& texture) {
|
||||
MOBILEGL_ASSERT(m_device != VK_NULL_HANDLE, "SyncTextureAndGetDescriptor: m_device == VK_NULL_HANDLE");
|
||||
|
||||
auto it = m_textureResources.find(texture.GetExternalIndex());
|
||||
auto it = m_textureResources.find(&texture);
|
||||
if (it == m_textureResources.end()) {
|
||||
TextureResource initial{};
|
||||
initial.textureExternalIndex = texture.GetExternalIndex();
|
||||
auto [insertIt, _] = m_textureResources.emplace(texture.GetExternalIndex(), initial);
|
||||
auto [insertIt, _] = m_textureResources.emplace(&texture, Move(initial));
|
||||
it = insertIt;
|
||||
}
|
||||
|
||||
if (!SyncTexture(texture, it->second)) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
outTextureResource = it->second;
|
||||
|
||||
return true;
|
||||
return &(it->second);
|
||||
}
|
||||
Bool VkTextureManager::TransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image,
|
||||
VkImageLayout& trackedLayout, VkImageLayout newLayout,
|
||||
@@ -91,6 +87,22 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return true;
|
||||
}
|
||||
|
||||
SizeT VkTextureManager::CollectGarbage() {
|
||||
m_gcCounter++;
|
||||
if (m_gcCounter != 0) {
|
||||
return 0;
|
||||
}
|
||||
SizeT count = 0;
|
||||
for (const auto& [raw, weak]: m_aliveObjects) {
|
||||
if (weak.expired()) {
|
||||
count++;
|
||||
m_textureResources.erase(raw);
|
||||
m_aliveObjects.erase(raw);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
Bool VkTextureManager::SyncTexture(MG_State::GLState::ITextureObject &texture,
|
||||
TextureResource &outResource) {
|
||||
TextureUploadTarget uploadTarget = TextureUploadTarget::Unknown;
|
||||
@@ -153,7 +165,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return true;
|
||||
}
|
||||
|
||||
DestroyTextureResource(resource);
|
||||
resource.~TextureResource();
|
||||
|
||||
VkImageCreateInfo imageInfo{};
|
||||
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
@@ -191,7 +203,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
resource.extent = {static_cast<Uint32>(texelSize.x()), static_cast<Uint32>(texelSize.y())};
|
||||
resource.mipLevels = mipLevels;
|
||||
resource.format = format;
|
||||
resource.textureExternalIndex = texture.GetExternalIndex();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -339,22 +350,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return true;
|
||||
}
|
||||
|
||||
void VkTextureManager::DestroyTextureResource(TextureResource& resource) const {
|
||||
if (m_device != VK_NULL_HANDLE && resource.view != VK_NULL_HANDLE) {
|
||||
vkDestroyImageView(m_device, resource.view, nullptr);
|
||||
}
|
||||
if (m_allocator != nullptr && resource.image != VK_NULL_HANDLE && resource.allocation != nullptr) {
|
||||
vmaDestroyImage(m_allocator, resource.image, resource.allocation);
|
||||
}
|
||||
resource.view = VK_NULL_HANDLE;
|
||||
resource.image = VK_NULL_HANDLE;
|
||||
resource.allocation = nullptr;
|
||||
resource.layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
resource.extent = {0, 0};
|
||||
resource.mipLevels = 1;
|
||||
resource.format = VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
Bool VkTextureManager::CheckMipmapCompleteness(const MG_State::GLState::ITextureObject& texture,
|
||||
TextureUploadTarget& outTarget,
|
||||
IntVec3& outTexelSize,
|
||||
@@ -416,6 +411,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
case TextureInternalFormat::SRGB8Alpha8:
|
||||
return VK_FORMAT_R8G8B8A8_SRGB;
|
||||
case TextureInternalFormat::Depth24Stencil8:
|
||||
return VK_FORMAT_D24_UNORM_S8_UINT;
|
||||
case TextureInternalFormat::Depth32FStencil8:
|
||||
return VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
case TextureInternalFormat::DepthComponent32F:
|
||||
return VK_FORMAT_D32_SFLOAT;
|
||||
default:
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
@@ -36,20 +36,51 @@ public:
|
||||
VkExtent2D extent = {0, 0};
|
||||
Uint32 mipLevels = 1;
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
Uint textureExternalIndex = 0;
|
||||
|
||||
TextureResource() {}
|
||||
TextureResource(const TextureResource&) = delete;
|
||||
TextureResource(TextureResource&& that) noexcept {
|
||||
std::swap(this->image, that.image);
|
||||
std::swap(this->allocation, that.allocation);
|
||||
std::swap(this->view, that.view);
|
||||
std::swap(this->layout, that.layout);
|
||||
std::swap(this->extent, that.extent);
|
||||
std::swap(this->mipLevels, that.mipLevels);
|
||||
std::swap(this->format, that.format);
|
||||
}
|
||||
|
||||
~TextureResource() {
|
||||
if (view != VK_NULL_HANDLE) {
|
||||
vkDestroyImageView(s_device, view, nullptr);
|
||||
}
|
||||
if (image != VK_NULL_HANDLE && allocation != nullptr) {
|
||||
vmaDestroyImage(s_allocator, image, allocation);
|
||||
}
|
||||
view = VK_NULL_HANDLE;
|
||||
image = VK_NULL_HANDLE;
|
||||
allocation = nullptr;
|
||||
layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
extent = {0, 0};
|
||||
mipLevels = 1;
|
||||
format = VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
static inline VkDevice s_device = VK_NULL_HANDLE;
|
||||
static inline VmaAllocator s_allocator = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
Bool Initialize(const InitInfo& initInfo);
|
||||
void Shutdown();
|
||||
|
||||
Bool SyncTextureAndGetDescriptor(
|
||||
MG_State::GLState::ITextureObject& texture, TextureResource& outTextureResource);
|
||||
|
||||
TextureResource* SyncTextureAndGetDescriptor(
|
||||
MG_State::GLState::ITextureObject& texture);
|
||||
|
||||
static Bool TransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout& trackedLayout,
|
||||
VkImageLayout newLayout, VkPipelineStageFlags srcStageMask,
|
||||
VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask,
|
||||
VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask);
|
||||
|
||||
SizeT CollectGarbage();
|
||||
private:
|
||||
|
||||
Bool SyncTexture(MG_State::GLState::ITextureObject &texture,
|
||||
@@ -62,7 +93,6 @@ private:
|
||||
TextureUploadTarget uploadTarget,
|
||||
TextureResource &outResource);
|
||||
Bool ExecuteCmdBufImmediate(const std::function<void(VkCommandBuffer)>& recorder) const;
|
||||
void DestroyTextureResource(TextureResource& resource) const;
|
||||
static Bool CheckMipmapCompleteness(const MG_State::GLState::ITextureObject& texture,
|
||||
TextureUploadTarget& outTarget,
|
||||
IntVec3& outTexelSize,
|
||||
@@ -77,6 +107,8 @@ private:
|
||||
VkCommandPool m_commandPool = VK_NULL_HANDLE;
|
||||
VkQueue m_graphicsQueue = VK_NULL_HANDLE;
|
||||
|
||||
UnorderedMap<Uint, TextureResource> m_textureResources;
|
||||
Uint8 m_gcCounter = 0;
|
||||
UnorderedMap<MG_State::GLState::ITextureObject*, WeakPtr<MG_State::GLState::ITextureObject>> m_aliveObjects;
|
||||
UnorderedMap<MG_State::GLState::ITextureObject*, TextureResource> m_textureResources;
|
||||
};
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
|
||||
@@ -25,15 +25,13 @@ namespace MobileGL::MG_Impl {
|
||||
auto colorTex = MakeShared<MG_State::GLState::TextureObject2D>(0);
|
||||
colorTex->SetInternalFormat(TextureInternalFormat::RGBA8);
|
||||
colorTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {{512, 512, 1}, 0});
|
||||
// colorTex->SetMipmapLevel({{512, 512, 1}, 0, false, 0, {nullptr, 0}});
|
||||
|
||||
auto depthTex = MakeShared<MG_State::GLState::TextureObject2D>(0);
|
||||
depthTex->SetInternalFormat(TextureInternalFormat::Depth32FStencil8);
|
||||
depthTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {{512, 512, 1}, 0});
|
||||
// depthTex->SetMipmapLevel({{512, 512, 1}, 0, false, 0, {nullptr, 0}});
|
||||
auto stencilTex = MakeShared<MG_State::GLState::TextureObject2D>(0);
|
||||
stencilTex->SetInternalFormat(TextureInternalFormat::Depth32FStencil8);
|
||||
stencilTex->AllocateStorage(TextureUploadTarget::Texture2D, 0, {{512, 512, 1}, 0});
|
||||
// stencilTex->SetMipmapLevel({{512, 512, 1}, 0, false, 0, {nullptr, 0}});
|
||||
fbo0->AttachTexture(FramebufferAttachmentType::Color0, colorTex);
|
||||
fbo0->AttachTexture(FramebufferAttachmentType::Depth, depthTex);
|
||||
fbo0->AttachTexture(FramebufferAttachmentType::Stencil, stencilTex);
|
||||
|
||||
Reference in New Issue
Block a user