mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Fix] (MG_Backend/DirectVulkan): fixing Vulkan backend initialization
This commit is contained in:
@@ -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(),
|
||||
|
||||
@@ -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__)
|
||||
|
||||
Reference in New Issue
Block a user