mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Fix] (MG_Backend/DirectVulkan): get ImageView from swapchain when creating render pass for default FBO
This commit is contained in:
@@ -14,8 +14,10 @@
|
|||||||
|
|
||||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||||
VkRenderPassManager::VkRenderPassManager(VkDevice device,
|
VkRenderPassManager::VkRenderPassManager(VkDevice device,
|
||||||
const VulkanRendererConfig& config, VkClearManager& clearManager, VkTextureManager& textureManager):
|
const VulkanRendererConfig& config, VkClearManager& clearManager, VkTextureManager& textureManager,
|
||||||
m_device(device), m_config(config), m_clearManager(clearManager), m_textureManager(textureManager) {
|
const SwapchainObject& swapchainObject):
|
||||||
|
m_device(device), m_config(config), m_clearManager(clearManager), m_textureManager(textureManager),
|
||||||
|
m_swapchainObject(swapchainObject) {
|
||||||
RenderPassEntry::s_device = m_device;
|
RenderPassEntry::s_device = m_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,8 +31,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkRenderPassManager::HashType VkRenderPassManager::ComputeHash(
|
VkRenderPassManager::HashType VkRenderPassManager::ComputeHash(
|
||||||
const MG_State::GLState::FramebufferObject& fbo) const {
|
const MG_State::GLState::FramebufferObject& fbo, Uint32 swapchainImageIndex) const {
|
||||||
XXHASH_VERIFY(XXH64_reset(m_hashState, m_config.CacheVersion));
|
XXHASH_VERIFY(XXH64_reset(m_hashState, m_config.CacheVersion));
|
||||||
|
const Bool isDefaultFbo = (&fbo == MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO.get());
|
||||||
|
if (isDefaultFbo) {
|
||||||
|
XXHASH_VERIFY(XXH64_update(m_hashState, &swapchainImageIndex, sizeof(swapchainImageIndex)));
|
||||||
|
}
|
||||||
auto& drawBuffers = fbo.GetDrawBuffers();
|
auto& drawBuffers = fbo.GetDrawBuffers();
|
||||||
XXHASH_VERIFY(XXH64_update(m_hashState, drawBuffers.data(), drawBuffers.size() * sizeof(drawBuffers[0])));
|
XXHASH_VERIFY(XXH64_update(m_hashState, drawBuffers.data(), drawBuffers.size() * sizeof(drawBuffers[0])));
|
||||||
auto readBuffer = fbo.GetReadBuffer();
|
auto readBuffer = fbo.GetReadBuffer();
|
||||||
@@ -75,9 +81,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return XXH64_digest(m_hashState);
|
return XXH64_digest(m_hashState);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderPassEntry& VkRenderPassManager::GetOrCreateRenderPass(const MG_State::GLState::FramebufferObject& fbo) {
|
RenderPassEntry& VkRenderPassManager::GetOrCreateRenderPass(const MG_State::GLState::FramebufferObject& fbo,
|
||||||
|
Uint32 swapchainImageIndex) {
|
||||||
// retrieve from cache first
|
// retrieve from cache first
|
||||||
auto hash = ComputeHash(fbo);
|
auto hash = ComputeHash(fbo, swapchainImageIndex);
|
||||||
auto it = m_renderPasses.find(hash);
|
auto it = m_renderPasses.find(hash);
|
||||||
if (it != m_renderPasses.end())
|
if (it != m_renderPasses.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
@@ -97,6 +104,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
Vector<VkAttachmentDescription> attachmentDescriptions(validDrawBufCount);
|
Vector<VkAttachmentDescription> attachmentDescriptions(validDrawBufCount);
|
||||||
Vector<VkAttachmentReference> colorAttachmentRefs(validDrawBufCount);
|
Vector<VkAttachmentReference> colorAttachmentRefs(validDrawBufCount);
|
||||||
Vector<VkTextureManager::TextureResource*> textureResources(validDrawBufCount, nullptr);
|
Vector<VkTextureManager::TextureResource*> textureResources(validDrawBufCount, nullptr);
|
||||||
|
Vector<VkImageView> attachmentViews(validDrawBufCount, VK_NULL_HANDLE);
|
||||||
// This should automatically work on default & offscreen FBO
|
// This should automatically work on default & offscreen FBO
|
||||||
// assuming default FBO has the right param
|
// assuming default FBO has the right param
|
||||||
for (Int i = 0; i < validDrawBufCount; ++i) {
|
for (Int i = 0; i < validDrawBufCount; ++i) {
|
||||||
@@ -136,8 +144,17 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
if (height == 0)
|
if (height == 0)
|
||||||
height = texture2d->GetBaseSize().y();
|
height = texture2d->GetBaseSize().y();
|
||||||
|
|
||||||
textureResources[i] = m_textureManager.SyncTextureAndGetDescriptor(*texture);
|
if (isDefaultFbo) {
|
||||||
MOBILEGL_ASSERT(textureResources[i], "GetOrCreateRenderPass: SyncTextureAndGetDescriptor failed at color attachment %d", i);
|
const auto& swapchainViews = m_swapchainObject.GetImageViews();
|
||||||
|
MOBILEGL_ASSERT(swapchainImageIndex < swapchainViews.size(),
|
||||||
|
"GetOrCreateRenderPass: swapchain image index out of range");
|
||||||
|
attachmentViews[i] = swapchainViews[swapchainImageIndex];
|
||||||
|
} else {
|
||||||
|
textureResources[i] = m_textureManager.SyncTextureAndGetDescriptor(*texture);
|
||||||
|
MOBILEGL_ASSERT(textureResources[i],
|
||||||
|
"GetOrCreateRenderPass: SyncTextureAndGetDescriptor failed at color attachment %d", i);
|
||||||
|
attachmentViews[i] = textureResources[i]->view;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -166,13 +183,17 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
depthAttachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
depthAttachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
depthAttachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
depthAttachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
depthAttachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
depthAttachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
depthAttachmentDescription.finalLayout = isDefaultFbo ?
|
depthAttachmentDescription.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR :
|
if (isDefaultFbo) {
|
||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
attachmentViews.emplace_back(m_swapchainObject.GetDepthStencilImageView(swapchainImageIndex));
|
||||||
depthTextureResource = m_textureManager.SyncTextureAndGetDescriptor(texture);
|
} else {
|
||||||
MOBILEGL_ASSERT(depthTextureResource, "GetOrCreateRenderPass: SyncTextureAndGetDescriptor failed at depth attachment");
|
depthTextureResource = m_textureManager.SyncTextureAndGetDescriptor(texture);
|
||||||
|
MOBILEGL_ASSERT(depthTextureResource,
|
||||||
|
"GetOrCreateRenderPass: SyncTextureAndGetDescriptor failed at depth attachment");
|
||||||
|
textureResources.emplace_back(depthTextureResource);
|
||||||
|
attachmentViews.emplace_back(depthTextureResource->view);
|
||||||
|
}
|
||||||
attachmentDescriptions.emplace_back(depthAttachmentDescription);
|
attachmentDescriptions.emplace_back(depthAttachmentDescription);
|
||||||
textureResources.emplace_back(depthTextureResource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Depth attachment ref
|
// Depth attachment ref
|
||||||
@@ -208,11 +229,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
VkRenderPass renderPass = VK_NULL_HANDLE;
|
VkRenderPass renderPass = VK_NULL_HANDLE;
|
||||||
VK_VERIFY(vkCreateRenderPass(m_device, &renderPassCreateInfo, nullptr, &renderPass));
|
VK_VERIFY(vkCreateRenderPass(m_device, &renderPassCreateInfo, nullptr, &renderPass));
|
||||||
|
|
||||||
Vector<VkImageView> attachmentViews(textureResources.size(), VK_NULL_HANDLE);
|
|
||||||
for (Int i = 0; i < textureResources.size(); i++) {
|
|
||||||
attachmentViews[i] = textureResources[i]->view;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Framebuffer
|
// Framebuffer
|
||||||
VkFramebufferCreateInfo framebufferCreateInfo;
|
VkFramebufferCreateInfo framebufferCreateInfo;
|
||||||
framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
@@ -228,7 +244,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
VK_VERIFY(vkCreateFramebuffer(m_device, &framebufferCreateInfo, nullptr, &framebuffer));
|
VK_VERIFY(vkCreateFramebuffer(m_device, &framebufferCreateInfo, nullptr, &framebuffer));
|
||||||
IntVec2 extent = {width, height};
|
IntVec2 extent = {width, height};
|
||||||
RenderPassEntry renderPassEntry {
|
RenderPassEntry renderPassEntry {
|
||||||
renderPass, framebuffer, Move(textureResources), extent, 1 };
|
renderPass, framebuffer, Move(textureResources), static_cast<Uint32>(attachmentViews.size()), extent, 1 };
|
||||||
auto [insertedIt, _] = m_renderPasses.emplace(hash, Move(renderPassEntry));
|
auto [insertedIt, _] = m_renderPasses.emplace(hash, Move(renderPassEntry));
|
||||||
return insertedIt->second;
|
return insertedIt->second;
|
||||||
}
|
}
|
||||||
@@ -248,7 +264,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
VkClearValue defaultClearValue;
|
VkClearValue defaultClearValue;
|
||||||
defaultClearValue.color = { 0.0f, 0.0f, 0.0f, 1.0f };
|
defaultClearValue.color = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||||
defaultClearValue.depthStencil = { 1.0f, 0 };
|
defaultClearValue.depthStencil = { 1.0f, 0 };
|
||||||
Vector<VkClearValue> clearValue(renderPassEntry.textureResources.size(), defaultClearValue);
|
Vector<VkClearValue> clearValue(renderPassEntry.attachmentCount, defaultClearValue);
|
||||||
|
|
||||||
renderPassBeginInfo.clearValueCount = clearValue.size();
|
renderPassBeginInfo.clearValueCount = clearValue.size();
|
||||||
renderPassBeginInfo.pClearValues = clearValue.data();
|
renderPassBeginInfo.pClearValues = clearValue.data();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "SwapchainObject.h"
|
||||||
#include "VkClearManager.h"
|
#include "VkClearManager.h"
|
||||||
#include "VkTextureManager.h"
|
#include "VkTextureManager.h"
|
||||||
#include "../VkIncludes.h"
|
#include "../VkIncludes.h"
|
||||||
@@ -23,6 +24,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
||||||
// Should we hold pointer-to-resource here?
|
// Should we hold pointer-to-resource here?
|
||||||
Vector<VkTextureManager::TextureResource*> textureResources;
|
Vector<VkTextureManager::TextureResource*> textureResources;
|
||||||
|
Uint32 attachmentCount = 0;
|
||||||
IntVec2 extent = {0, 0};
|
IntVec2 extent = {0, 0};
|
||||||
Uint32 subpass = 0;
|
Uint32 subpass = 0;
|
||||||
|
|
||||||
@@ -32,6 +34,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
std::swap(renderPass, that.renderPass);
|
std::swap(renderPass, that.renderPass);
|
||||||
std::swap(framebuffer, that.framebuffer);
|
std::swap(framebuffer, that.framebuffer);
|
||||||
std::swap(textureResources, that.textureResources);
|
std::swap(textureResources, that.textureResources);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -39,10 +42,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
VkRenderPass renderpass,
|
VkRenderPass renderpass,
|
||||||
VkFramebuffer framebuffer,
|
VkFramebuffer framebuffer,
|
||||||
const std::vector<VkTextureManager::TextureResource*>& textureResources,
|
const std::vector<VkTextureManager::TextureResource*>& textureResources,
|
||||||
|
Uint32 attachmentCount,
|
||||||
IntVec2 extent, int subpass):
|
IntVec2 extent, int subpass):
|
||||||
renderPass(renderpass),
|
renderPass(renderpass),
|
||||||
framebuffer(framebuffer),
|
framebuffer(framebuffer),
|
||||||
textureResources(Move(textureResources)),
|
textureResources(Move(textureResources)),
|
||||||
|
attachmentCount(attachmentCount),
|
||||||
extent(extent),
|
extent(extent),
|
||||||
subpass(subpass)
|
subpass(subpass)
|
||||||
{}
|
{}
|
||||||
@@ -61,14 +66,15 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
public:
|
public:
|
||||||
using HashType = Uint64;
|
using HashType = Uint64;
|
||||||
VkRenderPassManager(VkDevice device,
|
VkRenderPassManager(VkDevice device,
|
||||||
const VulkanRendererConfig& config, VkClearManager& clearManager, VkTextureManager& textureManager);
|
const VulkanRendererConfig& config, VkClearManager& clearManager, VkTextureManager& textureManager,
|
||||||
|
const SwapchainObject& swapchainObject);
|
||||||
~VkRenderPassManager();
|
~VkRenderPassManager();
|
||||||
|
|
||||||
Bool Initialize();
|
Bool Initialize();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
HashType ComputeHash(const MG_State::GLState::FramebufferObject& fbo) const;
|
HashType ComputeHash(const MG_State::GLState::FramebufferObject& fbo, Uint32 swapchainImageIndex) const;
|
||||||
RenderPassEntry& GetOrCreateRenderPass(const MG_State::GLState::FramebufferObject& fbo);
|
RenderPassEntry& GetOrCreateRenderPass(const MG_State::GLState::FramebufferObject& fbo, Uint32 swapchainImageIndex);
|
||||||
static Bool BeginRenderPass(VkCommandBuffer commandBuffer, RenderPassEntry& renderPassEntry);
|
static Bool BeginRenderPass(VkCommandBuffer commandBuffer, RenderPassEntry& renderPassEntry);
|
||||||
static Bool EndRenderPass(VkCommandBuffer commandBuffer);
|
static Bool EndRenderPass(VkCommandBuffer commandBuffer);
|
||||||
static RenderPassEntry* GetActiveRenderPass();
|
static RenderPassEntry* GetActiveRenderPass();
|
||||||
@@ -77,6 +83,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
const VulkanRendererConfig& m_config;
|
const VulkanRendererConfig& m_config;
|
||||||
VkClearManager& m_clearManager;
|
VkClearManager& m_clearManager;
|
||||||
VkTextureManager& m_textureManager;
|
VkTextureManager& m_textureManager;
|
||||||
|
const SwapchainObject& m_swapchainObject;
|
||||||
UnorderedMap<Uint64, RenderPassEntry> m_renderPasses;
|
UnorderedMap<Uint64, RenderPassEntry> m_renderPasses;
|
||||||
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;
|
||||||
|
|||||||
@@ -112,7 +112,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
MOBILEGL_ASSERT(m_clearManager != nullptr, "VkClearManager creation failed.");
|
MOBILEGL_ASSERT(m_clearManager != nullptr, "VkClearManager creation failed.");
|
||||||
succeeded = m_clearManager->Initialize();
|
succeeded = m_clearManager->Initialize();
|
||||||
MOBILEGL_ASSERT(succeeded, "VkClearManager initialization failed.");
|
MOBILEGL_ASSERT(succeeded, "VkClearManager initialization failed.");
|
||||||
m_renderPassManager = MakeUnique<VkRenderPassManager>(m_device, m_config, *m_clearManager, *m_textureManager);
|
m_renderPassManager =
|
||||||
|
MakeUnique<VkRenderPassManager>(m_device, m_config, *m_clearManager, *m_textureManager, m_swapchainObject);
|
||||||
MOBILEGL_ASSERT(m_renderPassManager != nullptr, "VkRenderPassManager creation failed.");
|
MOBILEGL_ASSERT(m_renderPassManager != nullptr, "VkRenderPassManager creation failed.");
|
||||||
succeeded = m_renderPassManager->Initialize();
|
succeeded = m_renderPassManager->Initialize();
|
||||||
MOBILEGL_ASSERT(succeeded, "VkRenderPassManager initialization failed.");
|
MOBILEGL_ASSERT(succeeded, "VkRenderPassManager initialization failed.");
|
||||||
@@ -463,7 +464,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, m_imageIndexAcquired);
|
||||||
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;
|
||||||
@@ -505,11 +506,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
m_uniformDescriptorBinder->BeginFrame(m_frameContext.GetCurrentFrameIndex());
|
m_uniformDescriptorBinder->BeginFrame(m_frameContext.GetCurrentFrameIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& drawFbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject();
|
const auto& drawFbo =
|
||||||
|
MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject();
|
||||||
|
|
||||||
// Begin render pass
|
// Begin render pass
|
||||||
// TODO: properly deal with clear
|
// TODO: properly deal with clear
|
||||||
auto& renderPassEntry = m_renderPassManager->GetOrCreateRenderPass(*drawFbo);
|
auto& renderPassEntry = m_renderPassManager->GetOrCreateRenderPass(*drawFbo, m_imageIndexAcquired);
|
||||||
auto* activeRenderPass = VkRenderPassManager::GetActiveRenderPass();
|
auto* activeRenderPass = VkRenderPassManager::GetActiveRenderPass();
|
||||||
if (activeRenderPass != &renderPassEntry) {
|
if (activeRenderPass != &renderPassEntry) {
|
||||||
if (activeRenderPass) {
|
if (activeRenderPass) {
|
||||||
|
|||||||
Reference in New Issue
Block a user