[Fix] (MG_Backend/DirectVulkan): fixing Vulkan backend initialization

This commit is contained in:
2026-03-01 22:39:30 +08:00
parent 43f2043478
commit 6f8c76f06c
6 changed files with 71 additions and 17 deletions
@@ -115,6 +115,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
case TextureTarget::Texture2D: { case TextureTarget::Texture2D: {
auto* texture2d = auto* texture2d =
static_cast<MG_State::GLState::TextureObject2D*>(texture); static_cast<MG_State::GLState::TextureObject2D*>(texture);
desc.flags = 0;
desc.format = desc.format =
MG_Util::ConvertTextureInternalFormatToVkEnum( MG_Util::ConvertTextureInternalFormatToVkEnum(
texture2d->GetFormat()); texture2d->GetFormat());
@@ -156,6 +157,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
VkTextureManager::TextureResource* depthTextureResource = nullptr; VkTextureManager::TextureResource* depthTextureResource = nullptr;
if (depthAtt.IsComplete() && depthAtt.IsTexture()) { if (depthAtt.IsComplete() && depthAtt.IsTexture()) {
auto& texture = *depthAtt.GetTexture(); auto& texture = *depthAtt.GetTexture();
depthAttachmentDescription.flags = 0;
depthAttachmentDescription.format = depthAttachmentDescription.format =
MG_Util::ConvertTextureInternalFormatToVkEnum(texture.GetFormat()); MG_Util::ConvertTextureInternalFormatToVkEnum(texture.GetFormat());
depthAttachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT; depthAttachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT;
@@ -170,6 +172,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
depthTextureResource = m_textureManager.SyncTextureAndGetDescriptor(texture); depthTextureResource = m_textureManager.SyncTextureAndGetDescriptor(texture);
MOBILEGL_ASSERT(depthTextureResource, "GetOrCreateRenderPass: SyncTextureAndGetDescriptor failed at depth attachment"); MOBILEGL_ASSERT(depthTextureResource, "GetOrCreateRenderPass: SyncTextureAndGetDescriptor failed at depth attachment");
attachmentDescriptions.emplace_back(depthAttachmentDescription); attachmentDescriptions.emplace_back(depthAttachmentDescription);
textureResources.emplace_back(depthTextureResource);
} }
// Depth attachment ref // Depth attachment ref
@@ -224,14 +227,14 @@ namespace MobileGL::MG_Backend::DirectVulkan {
VkFramebuffer framebuffer = VK_NULL_HANDLE; VkFramebuffer framebuffer = VK_NULL_HANDLE;
VK_VERIFY(vkCreateFramebuffer(m_device, &framebufferCreateInfo, nullptr, &framebuffer)); VK_VERIFY(vkCreateFramebuffer(m_device, &framebufferCreateInfo, nullptr, &framebuffer));
IntVec2 extent = {width, height}; IntVec2 extent = {width, height};
m_renderPasses[hash] = { renderPass, framebuffer, Move(textureResources), extent, 1 }; RenderPassEntry renderPassEntry {
return m_renderPasses[hash]; renderPass, framebuffer, Move(textureResources), extent, 1 };
auto [insertedIt, _] = m_renderPasses.emplace(hash, Move(renderPassEntry));
return insertedIt->second;
} }
Bool VkRenderPassManager::BeginRenderPass(VkCommandBuffer commandBuffer, RenderPassEntry& renderPassEntry) { Bool VkRenderPassManager::BeginRenderPass(VkCommandBuffer commandBuffer, RenderPassEntry& renderPassEntry) {
// TODO: Transition all the attachments into proper layout before starting the render pass // TODO: Transition all the attachments into proper layout before starting the render pass
VkRenderPassBeginInfo renderPassBeginInfo; VkRenderPassBeginInfo renderPassBeginInfo;
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.pNext = nullptr; renderPassBeginInfo.pNext = nullptr;
@@ -242,12 +245,13 @@ namespace MobileGL::MG_Backend::DirectVulkan {
(Uint32)renderPassEntry.extent.x(), (Uint32)renderPassEntry.extent.y() }; (Uint32)renderPassEntry.extent.x(), (Uint32)renderPassEntry.extent.y() };
// TODO: should query proper clear color // TODO: should query proper clear color
VkClearValue clearValue; VkClearValue defaultClearValue;
clearValue.color = { 0.0f, 0.0f, 0.0f, 1.0f }; defaultClearValue.color = { 0.0f, 0.0f, 0.0f, 1.0f };
clearValue.depthStencil = { 1.0f, 0 }; defaultClearValue.depthStencil = { 1.0f, 0 };
Vector<VkClearValue> clearValue(renderPassEntry.textureResources.size(), defaultClearValue);
renderPassBeginInfo.clearValueCount = 1; renderPassBeginInfo.clearValueCount = clearValue.size();
renderPassBeginInfo.pClearValues = &clearValue; renderPassBeginInfo.pClearValues = clearValue.data();
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
@@ -26,6 +26,27 @@ namespace MobileGL::MG_Backend::DirectVulkan {
IntVec2 extent = {0, 0}; IntVec2 extent = {0, 0};
Uint32 subpass = 0; Uint32 subpass = 0;
RenderPassEntry() = default;
RenderPassEntry(const RenderPassEntry&) = delete;
RenderPassEntry(RenderPassEntry&& that) noexcept {
std::swap(renderPass, that.renderPass);
std::swap(framebuffer, that.framebuffer);
std::swap(textureResources, that.textureResources);
std::swap(extent, that.extent);
std::swap(subpass, that.subpass);
}
RenderPassEntry(
VkRenderPass renderpass,
VkFramebuffer framebuffer,
const std::vector<VkTextureManager::TextureResource*>& textureResources,
IntVec2 extent, int subpass):
renderPass(renderpass),
framebuffer(framebuffer),
textureResources(Move(textureResources)),
extent(extent),
subpass(subpass)
{}
~RenderPassEntry() { ~RenderPassEntry() {
if (renderPass != VK_NULL_HANDLE) { if (renderPass != VK_NULL_HANDLE) {
vkDestroyRenderPass(s_device, renderPass, nullptr); vkDestroyRenderPass(s_device, renderPass, nullptr);
@@ -167,6 +167,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
resource.~TextureResource(); resource.~TextureResource();
auto aspect = GetAspectMaskForFormat(format);
VkImageCreateInfo imageInfo{}; VkImageCreateInfo imageInfo{};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.imageType = VK_IMAGE_TYPE_2D; imageInfo.imageType = VK_IMAGE_TYPE_2D;
@@ -178,7 +180,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
imageInfo.format = format; imageInfo.format = format;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; imageInfo.usage =
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
((aspect & VK_IMAGE_ASPECT_COLOR_BIT) ?
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT : 0) |
((aspect & VK_IMAGE_ASPECT_DEPTH_BIT || aspect & VK_IMAGE_ASPECT_STENCIL_BIT) ?
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0);
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VmaAllocationCreateInfo allocationInfo{}; VmaAllocationCreateInfo allocationInfo{};
@@ -192,7 +199,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
viewInfo.image = resource.image; viewInfo.image = resource.image;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = format; viewInfo.format = format;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; viewInfo.subresourceRange.aspectMask = aspect;
viewInfo.subresourceRange.baseMipLevel = 0; viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = mipLevels; viewInfo.subresourceRange.levelCount = mipLevels;
viewInfo.subresourceRange.baseArrayLayer = 0; viewInfo.subresourceRange.baseArrayLayer = 0;
@@ -203,6 +210,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
resource.extent = {static_cast<Uint32>(texelSize.x()), static_cast<Uint32>(texelSize.y())}; resource.extent = {static_cast<Uint32>(texelSize.x()), static_cast<Uint32>(texelSize.y())};
resource.mipLevels = mipLevels; resource.mipLevels = mipLevels;
resource.format = format; resource.format = format;
resource.aspect = viewInfo.subresourceRange.aspectMask;
return true; return true;
} }
@@ -270,6 +278,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
// TODO: Could be uploaded asynchronously? // TODO: Could be uploaded asynchronously?
const Bool ok = ExecuteCmdBufImmediate([&](VkCommandBuffer commandBuffer) { const Bool ok = ExecuteCmdBufImmediate([&](VkCommandBuffer commandBuffer) {
const VkImageAspectFlags aspectMask = GetAspectMaskForFormat(outResource.format);
Bool ok = TransitionImageLayout(commandBuffer, outResource.image, Bool ok = TransitionImageLayout(commandBuffer, outResource.image,
outResource.layout, outResource.layout,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
@@ -277,7 +286,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
outResource.layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ? VK_ACCESS_SHADER_READ_BIT : 0, outResource.layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ? VK_ACCESS_SHADER_READ_BIT : 0,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT); aspectMask);
MOBILEGL_ASSERT(ok, "TransitionImageLayout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL failed"); MOBILEGL_ASSERT(ok, "TransitionImageLayout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL failed");
for (const auto& item : uploadItems) { for (const auto& item : uploadItems) {
@@ -285,7 +294,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
copy.bufferOffset = item.offset; copy.bufferOffset = item.offset;
copy.bufferRowLength = 0; copy.bufferRowLength = 0;
copy.bufferImageHeight = 0; copy.bufferImageHeight = 0;
copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; copy.imageSubresource.aspectMask = aspectMask;
copy.imageSubresource.mipLevel = item.level; copy.imageSubresource.mipLevel = item.level;
copy.imageSubresource.baseArrayLayer = 0; copy.imageSubresource.baseArrayLayer = 0;
copy.imageSubresource.layerCount = 1; copy.imageSubresource.layerCount = 1;
@@ -302,7 +311,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_ASPECT_COLOR_BIT); aspectMask);
MOBILEGL_ASSERT(ok, "TransitionImageLayout to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL failed"); MOBILEGL_ASSERT(ok, "TransitionImageLayout to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL failed");
outResource.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; outResource.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
return ok; return ok;
@@ -421,4 +430,21 @@ namespace MobileGL::MG_Backend::DirectVulkan {
return VK_FORMAT_UNDEFINED; return VK_FORMAT_UNDEFINED;
} }
} }
VkImageAspectFlags VkTextureManager::GetAspectMaskForFormat(VkFormat format) {
switch (format) {
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_X8_D24_UNORM_PACK32:
case VK_FORMAT_D32_SFLOAT:
return VK_IMAGE_ASPECT_DEPTH_BIT;
case VK_FORMAT_S8_UINT:
return VK_IMAGE_ASPECT_STENCIL_BIT;
case VK_FORMAT_D16_UNORM_S8_UINT:
case VK_FORMAT_D24_UNORM_S8_UINT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
default:
return VK_IMAGE_ASPECT_COLOR_BIT;
}
}
} // namespace MobileGL::MG_Backend::DirectVulkan } // namespace MobileGL::MG_Backend::DirectVulkan
@@ -36,8 +36,9 @@ public:
VkExtent2D extent = {0, 0}; VkExtent2D extent = {0, 0};
Uint32 mipLevels = 1; Uint32 mipLevels = 1;
VkFormat format = VK_FORMAT_UNDEFINED; VkFormat format = VK_FORMAT_UNDEFINED;
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_NONE;
TextureResource() {} TextureResource() = default;
TextureResource(const TextureResource&) = delete; TextureResource(const TextureResource&) = delete;
TextureResource(TextureResource&& that) noexcept { TextureResource(TextureResource&& that) noexcept {
std::swap(this->image, that.image); std::swap(this->image, that.image);
@@ -100,6 +101,7 @@ private:
Uint32& outMipLevelCount); Uint32& outMipLevelCount);
static Uint32 GetUploadMipLevelCount(const MG_State::GLState::TextureObjectMipmap& texture, TextureUploadTarget target); static Uint32 GetUploadMipLevelCount(const MG_State::GLState::TextureObjectMipmap& texture, TextureUploadTarget target);
static VkFormat GetVkFormat(TextureInternalFormat format); static VkFormat GetVkFormat(TextureInternalFormat format);
static VkImageAspectFlags GetAspectMaskForFormat(VkFormat format);
VkDevice m_device = VK_NULL_HANDLE; VkDevice m_device = VK_NULL_HANDLE;
VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE; VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE;
@@ -463,7 +463,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
auto vertexInputHash = m_vertexInputStateFactory->ComputeHash(vao); auto vertexInputHash = m_vertexInputStateFactory->ComputeHash(vao);
auto& vis = m_vertexInputStateFactory->GetOrCreateVertexInputState(vao); auto& vis = m_vertexInputStateFactory->GetOrCreateVertexInputState(vao);
auto pipelineLayout = m_uniformDescriptorBinder->GetOrCreatePipelineLayout(program); auto pipelineLayout = m_uniformDescriptorBinder->GetOrCreatePipelineLayout(program);
auto renderPassEntry = m_renderPassManager->GetOrCreateRenderPass(drawFbo); auto& renderPassEntry = m_renderPassManager->GetOrCreateRenderPass(drawFbo);
auto depthTestEnabled = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::DepthTest); auto depthTestEnabled = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::DepthTest);
BlendFactor srcRGB = BlendFactor::One; BlendFactor srcRGB = BlendFactor::One;
BlendFactor dstRGB = BlendFactor::Zero; BlendFactor dstRGB = BlendFactor::Zero;
@@ -477,7 +477,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
.vertexInputHash = vertexInputHash, .vertexInputHash = vertexInputHash,
.pipelineLayout = pipelineLayout, .pipelineLayout = pipelineLayout,
.renderPass = renderPassEntry.renderPass, .renderPass = renderPassEntry.renderPass,
.subpass = renderPassEntry.subpass, .subpass = 0,
.topology = toVkTopology(mode), .topology = toVkTopology(mode),
.depthTestEnable = depthTestEnabled, .depthTestEnable = depthTestEnabled,
.depthWriteEnable = depthTestEnabled && MG_State::pGLContext->GetDepthMask(), .depthWriteEnable = depthTestEnabled && MG_State::pGLContext->GetDepthMask(),
+1
View File
@@ -97,6 +97,7 @@ namespace MobileGL {
#if MOBILEGL_LOG_ENABLE_CONSOLE #if MOBILEGL_LOG_ENABLE_CONSOLE
std::fwrite(out.c_str(), 1, out.size(), stdout); std::fwrite(out.c_str(), 1, out.size(), stdout);
fflush(stdout);
#endif #endif
#if MOBILEGL_LOG_ENABLE_ANDROID && defined(__ANDROID__) #if MOBILEGL_LOG_ENABLE_ANDROID && defined(__ANDROID__)