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