mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Chore] (MG_Backend/DirectVulkan): remove "transition" stuff in VkRenderTargetManager
This commit is contained in:
@@ -481,13 +481,21 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_framebufferManager->Transition(commandBuffer,
|
||||
VkRenderTargetManager::TransitionResource::OffscreenColorTexture,
|
||||
VkRenderTargetManager::TransitionUsage::ShaderRead,
|
||||
texture->GetExternalIndex())) {
|
||||
VkImageView offscreenView = VK_NULL_HANDLE;
|
||||
if (m_framebufferManager->GetOffscreenColorViewByTexture(texture->GetExternalIndex(), offscreenView) &&
|
||||
offscreenView != VK_NULL_HANDLE) {
|
||||
VkImageView offscreenView = VK_NULL_HANDLE;
|
||||
VkImage offscreenImage = VK_NULL_HANDLE;
|
||||
VkImageLayout* offscreenLayout = nullptr;
|
||||
if (m_framebufferManager->GetOffscreenColorTargetStateByTexture(texture->GetExternalIndex(), offscreenView,
|
||||
offscreenImage, offscreenLayout) &&
|
||||
offscreenView != VK_NULL_HANDLE && offscreenLayout != nullptr) {
|
||||
const Bool fromUndefined = (*offscreenLayout == VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
if (VkTextureManager::TransitionImageLayout(
|
||||
commandBuffer, offscreenImage, *offscreenLayout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
fromUndefined
|
||||
? VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
|
||||
: (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT),
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
fromUndefined ? 0 : (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT),
|
||||
VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT)) {
|
||||
VkDescriptorImageInfo sampledInfo{};
|
||||
if (!m_textureManager->SyncTextureAndGetDescriptor(*texture, sampledInfo)) {
|
||||
return false;
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
#include "VkRenderTargetManager.h"
|
||||
|
||||
#include "VkTextureManager.h"
|
||||
|
||||
#include <MG_State/GLState/RenderbufferState/RenderbufferObject.h>
|
||||
#include <MG_State/GLState/TextureState/TextureEnum.h>
|
||||
|
||||
@@ -48,128 +46,41 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return RecreateOffscreenColorTarget(target, glFbo, colorAttachment, objectVersion);
|
||||
}
|
||||
|
||||
Bool VkRenderTargetManager::Transition(VkCommandBuffer commandBuffer, TransitionResource resource,
|
||||
TransitionUsage usage, Uint externalIndex) {
|
||||
auto resolveDepthStencilAspectMask = [](VkFormat format) {
|
||||
VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
if (format == VK_FORMAT_D24_UNORM_S8_UINT || format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
|
||||
aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
return aspectMask;
|
||||
};
|
||||
|
||||
if (resource == TransitionResource::OffscreenColorTexture) {
|
||||
if (usage != TransitionUsage::ShaderRead) {
|
||||
MGLOG_W("VkFramebufferManager::Transition skipped: unsupported usage %d for texture %u",
|
||||
static_cast<Int>(usage), externalIndex);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& [_, target] : m_offscreenColorTargets) {
|
||||
if (target.colorTextureExternalIndex != externalIndex || target.image == VK_NULL_HANDLE) {
|
||||
continue;
|
||||
}
|
||||
const Bool fromUndefined = (target.layout == VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
return VkTextureManager::TransitionImageLayout(
|
||||
commandBuffer, target.image, target.layout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
fromUndefined
|
||||
? VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
|
||||
: (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT),
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
fromUndefined ? 0 : (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT),
|
||||
VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it = m_offscreenColorTargets.find(externalIndex);
|
||||
Bool VkRenderTargetManager::GetOffscreenRenderSurfaceState(Uint glFboExternalIndex, VkImage& outColorImage,
|
||||
VkImageLayout*& outColorLayout,
|
||||
VkImage& outDepthStencilImage,
|
||||
VkImageLayout*& outDepthStencilLayout,
|
||||
VkFormat& outDepthStencilFormat) {
|
||||
auto it = m_offscreenColorTargets.find(glFboExternalIndex);
|
||||
if (it == m_offscreenColorTargets.end()) {
|
||||
MGLOG_W("VkFramebufferManager::Transition skipped: FBO %u not found", externalIndex);
|
||||
return false;
|
||||
}
|
||||
auto& target = it->second;
|
||||
|
||||
if (resource == TransitionResource::OffscreenColor) {
|
||||
switch (usage) {
|
||||
case TransitionUsage::Attachment: {
|
||||
if (!VkTextureManager::TransitionImageLayout(
|
||||
commandBuffer, target.image, target.layout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT)) {
|
||||
return false;
|
||||
}
|
||||
if (target.depthStencilImage == VK_NULL_HANDLE) {
|
||||
return true;
|
||||
}
|
||||
const VkImageAspectFlags aspectMask = resolveDepthStencilAspectMask(target.depthStencilFormat);
|
||||
return VkTextureManager::TransitionImageLayout(
|
||||
commandBuffer, target.depthStencilImage, target.depthStencilLayout,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0,
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
aspectMask);
|
||||
}
|
||||
case TransitionUsage::TransferSrc:
|
||||
return VkTextureManager::TransitionImageLayout(commandBuffer, target.image, target.layout,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
case TransitionUsage::TransferDst:
|
||||
return VkTextureManager::TransitionImageLayout(commandBuffer, target.image, target.layout,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
case TransitionUsage::General:
|
||||
return VkTextureManager::TransitionImageLayout(commandBuffer, target.image, target.layout, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||
VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
case TransitionUsage::ShaderRead:
|
||||
return VkTextureManager::TransitionImageLayout(commandBuffer, target.image, target.layout,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
0, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (target.image == VK_NULL_HANDLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resource == TransitionResource::OffscreenDepthStencil) {
|
||||
if (target.depthStencilImage == VK_NULL_HANDLE) {
|
||||
return false;
|
||||
}
|
||||
const VkImageAspectFlags aspectMask = resolveDepthStencilAspectMask(target.depthStencilFormat);
|
||||
switch (usage) {
|
||||
case TransitionUsage::TransferSrc:
|
||||
return VkTextureManager::TransitionImageLayout(commandBuffer, target.depthStencilImage, target.depthStencilLayout,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, aspectMask);
|
||||
case TransitionUsage::TransferDst:
|
||||
return VkTextureManager::TransitionImageLayout(commandBuffer, target.depthStencilImage, target.depthStencilLayout,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, aspectMask);
|
||||
case TransitionUsage::General:
|
||||
return VkTextureManager::TransitionImageLayout(commandBuffer, target.depthStencilImage, target.depthStencilLayout,
|
||||
VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||
VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, aspectMask);
|
||||
case TransitionUsage::Attachment:
|
||||
return VkTextureManager::TransitionImageLayout(
|
||||
commandBuffer, target.depthStencilImage, target.depthStencilLayout,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0,
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
aspectMask);
|
||||
case TransitionUsage::ShaderRead:
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
outColorImage = target.image;
|
||||
outColorLayout = &target.layout;
|
||||
outDepthStencilImage = target.depthStencilImage;
|
||||
outDepthStencilLayout = &target.depthStencilLayout;
|
||||
outDepthStencilFormat = target.depthStencilFormat;
|
||||
return true;
|
||||
}
|
||||
|
||||
Bool VkRenderTargetManager::GetOffscreenColorTargetStateByTexture(Uint textureExternalIndex,
|
||||
VkImageView& outImageView, VkImage& outImage,
|
||||
VkImageLayout*& outLayout) {
|
||||
for (auto& [_, target] : m_offscreenColorTargets) {
|
||||
if (target.colorTextureExternalIndex != textureExternalIndex || target.image == VK_NULL_HANDLE ||
|
||||
target.imageView == VK_NULL_HANDLE) {
|
||||
continue;
|
||||
}
|
||||
outImageView = target.imageView;
|
||||
outImage = target.image;
|
||||
outLayout = &target.layout;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,20 +16,6 @@
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
class VkRenderTargetManager {
|
||||
public:
|
||||
enum class TransitionResource {
|
||||
OffscreenColor,
|
||||
OffscreenDepthStencil,
|
||||
OffscreenColorTexture
|
||||
};
|
||||
|
||||
enum class TransitionUsage {
|
||||
Attachment,
|
||||
TransferSrc,
|
||||
TransferDst,
|
||||
General,
|
||||
ShaderRead
|
||||
};
|
||||
|
||||
struct InitInfo {
|
||||
VkDevice device = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||
@@ -43,8 +29,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
void Shutdown();
|
||||
|
||||
Bool EnsureOffscreenColorTarget(Uint glFboExternalIndex, const MG_State::GLState::FramebufferObject& glFbo);
|
||||
Bool Transition(VkCommandBuffer commandBuffer, TransitionResource resource, TransitionUsage usage,
|
||||
Uint externalIndex);
|
||||
Bool GetOffscreenRenderSurfaceState(Uint glFboExternalIndex, VkImage& outColorImage,
|
||||
VkImageLayout*& outColorLayout, VkImage& outDepthStencilImage,
|
||||
VkImageLayout*& outDepthStencilLayout,
|
||||
VkFormat& outDepthStencilFormat);
|
||||
Bool GetOffscreenColorTargetStateByTexture(Uint textureExternalIndex, VkImageView& outImageView,
|
||||
VkImage& outImage, VkImageLayout*& outLayout);
|
||||
Bool GetOffscreenColorViewByTexture(Uint textureExternalIndex, VkImageView& outImageView) const;
|
||||
Bool GetOffscreenRenderSurface(Uint glFboExternalIndex, VkImageView& outColorView, VkFormat& outColorFormat,
|
||||
VkImageView& outDepthStencilView, VkFormat& outDepthStencilFormat,
|
||||
|
||||
@@ -480,13 +480,45 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_framebufferManager->Transition(commandBuffer, VkRenderTargetManager::TransitionResource::OffscreenColor,
|
||||
VkRenderTargetManager::TransitionUsage::Attachment,
|
||||
drawFboExternalIndex)) {
|
||||
VkImage offscreenColorImage = VK_NULL_HANDLE;
|
||||
VkImageLayout* offscreenColorLayout = nullptr;
|
||||
VkImage offscreenDepthStencilImage = VK_NULL_HANDLE;
|
||||
VkImageLayout* offscreenDepthStencilLayout = nullptr;
|
||||
VkFormat offscreenDepthStencilStateFormat = VK_FORMAT_UNDEFINED;
|
||||
if (!m_framebufferManager->GetOffscreenRenderSurfaceState(
|
||||
drawFboExternalIndex, offscreenColorImage, offscreenColorLayout, offscreenDepthStencilImage,
|
||||
offscreenDepthStencilLayout, offscreenDepthStencilStateFormat) ||
|
||||
offscreenColorLayout == nullptr) {
|
||||
MGLOG_D("EnsureFrameRecordingStarted skipped: failed to transition offscreen FBO %u for attachment",
|
||||
drawFboExternalIndex);
|
||||
return;
|
||||
}
|
||||
if (!VkTextureManager::TransitionImageLayout(
|
||||
commandBuffer, offscreenColorImage, *offscreenColorLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT)) {
|
||||
MGLOG_D("EnsureFrameRecordingStarted skipped: failed to transition offscreen color for FBO %u",
|
||||
drawFboExternalIndex);
|
||||
return;
|
||||
}
|
||||
if (offscreenDepthStencilImage != VK_NULL_HANDLE && offscreenDepthStencilLayout != nullptr) {
|
||||
VkImageAspectFlags depthStencilAspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
if (offscreenDepthStencilStateFormat == VK_FORMAT_D24_UNORM_S8_UINT ||
|
||||
offscreenDepthStencilStateFormat == VK_FORMAT_D32_SFLOAT_S8_UINT) {
|
||||
depthStencilAspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
if (!VkTextureManager::TransitionImageLayout(
|
||||
commandBuffer, offscreenDepthStencilImage, *offscreenDepthStencilLayout,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0,
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
depthStencilAspectMask)) {
|
||||
MGLOG_D("EnsureFrameRecordingStarted skipped: failed to transition offscreen depth/stencil for FBO %u",
|
||||
drawFboExternalIndex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_renderPassManager->BeginRenderPass(commandBuffer, offscreenRenderPass, offscreenFramebuffer,
|
||||
offscreenExtent);
|
||||
m_isMainRenderPassActive = true;
|
||||
@@ -1226,12 +1258,40 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
offscreenFramebuffer, offscreenExtent, offscreenDepthStencilFormat)) {
|
||||
return false;
|
||||
}
|
||||
if (!m_framebufferManager->Transition(commandBuffer,
|
||||
VkRenderTargetManager::TransitionResource::OffscreenColor,
|
||||
VkRenderTargetManager::TransitionUsage::Attachment,
|
||||
targetFboExternalIndex)) {
|
||||
VkImage offscreenColorImage = VK_NULL_HANDLE;
|
||||
VkImageLayout* offscreenColorLayout = nullptr;
|
||||
VkImage offscreenDepthStencilImage = VK_NULL_HANDLE;
|
||||
VkImageLayout* offscreenDepthStencilLayout = nullptr;
|
||||
VkFormat offscreenDepthStencilStateFormat = VK_FORMAT_UNDEFINED;
|
||||
if (!m_framebufferManager->GetOffscreenRenderSurfaceState(
|
||||
targetFboExternalIndex, offscreenColorImage, offscreenColorLayout, offscreenDepthStencilImage,
|
||||
offscreenDepthStencilLayout, offscreenDepthStencilStateFormat) ||
|
||||
offscreenColorLayout == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (!VkTextureManager::TransitionImageLayout(
|
||||
commandBuffer, offscreenColorImage, *offscreenColorLayout,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT)) {
|
||||
return false;
|
||||
}
|
||||
if (offscreenDepthStencilImage != VK_NULL_HANDLE && offscreenDepthStencilLayout != nullptr) {
|
||||
VkImageAspectFlags depthStencilAspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
if (offscreenDepthStencilStateFormat == VK_FORMAT_D24_UNORM_S8_UINT ||
|
||||
offscreenDepthStencilStateFormat == VK_FORMAT_D32_SFLOAT_S8_UINT) {
|
||||
depthStencilAspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
if (!VkTextureManager::TransitionImageLayout(
|
||||
commandBuffer, offscreenDepthStencilImage, *offscreenDepthStencilLayout,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0,
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
depthStencilAspectMask)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const auto swapchainOldLayout = m_swapchainObject.GetImageLayout(m_imageIndexAcquired);
|
||||
if (swapchainOldLayout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR &&
|
||||
|
||||
Reference in New Issue
Block a user