mirror of
https://github.com/Inori/GPCS4.git
synced 2024-05-20 05:00:52 -04:00
adjust image layout
This commit is contained in:
parent
9203064f5c
commit
aafab46347
|
@ -168,8 +168,7 @@ namespace sce::Gnm
|
|||
VkImageUsageFlags usage,
|
||||
VkPipelineStageFlags2 stage,
|
||||
VkAccessFlagBits2 access,
|
||||
VkImageTiling tiling,
|
||||
VkImageLayout layout)
|
||||
VkImageTiling tiling)
|
||||
{
|
||||
GnmImageCreateInfo info;
|
||||
info.tsharp = tsharp;
|
||||
|
@ -177,7 +176,6 @@ namespace sce::Gnm
|
|||
info.stage = stage | VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
info.access = access;
|
||||
info.tiling = tiling;
|
||||
info.layout = layout;
|
||||
info.memoryType = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
SceTexture texture = getResourceTexture(info);
|
||||
|
@ -254,8 +252,7 @@ namespace sce::Gnm
|
|||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
stage,
|
||||
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
VK_IMAGE_TILING_OPTIMAL);
|
||||
|
||||
updateMetaTextureInfo(stage, res.startRegister, false, tsharp);
|
||||
}
|
||||
|
@ -270,8 +267,7 @@ namespace sce::Gnm
|
|||
VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
stage,
|
||||
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_GENERAL);
|
||||
VK_IMAGE_TILING_OPTIMAL);
|
||||
|
||||
updateMetaTextureInfo(stage, res.startRegister, false, tsharp);
|
||||
}
|
||||
|
|
|
@ -454,8 +454,7 @@ namespace sce::Gnm
|
|||
VkImageUsageFlags usage,
|
||||
VkPipelineStageFlags2 stage,
|
||||
VkAccessFlagBits2 access,
|
||||
VkImageTiling tiling,
|
||||
VkImageLayout layout);
|
||||
VkImageTiling tiling);
|
||||
|
||||
void bindResourceSampler(
|
||||
const Sampler* ssharp,
|
||||
|
|
|
@ -650,28 +650,6 @@ namespace sce::Gnm
|
|||
void GnmCommandBufferDraw::waitUntilSafeForRendering(uint32_t videoOutHandle, uint32_t displayBufferIndex)
|
||||
{
|
||||
// This cmd blocks command processor until the specified display buffer is no longer displayed.
|
||||
// should we call vkAcquireNextImageKHR here to implement it?
|
||||
// or should we create a new render target image and then bilt to swapchain like DXVK does?
|
||||
|
||||
// get render target from swapchain
|
||||
auto& videoOut = GPU().videoOutGet(videoOutHandle);
|
||||
auto dispBuffer = videoOut.getDisplayBuffer(displayBufferIndex);
|
||||
|
||||
auto res = m_tracker.find(dispBuffer.address);
|
||||
if (res)
|
||||
{
|
||||
auto& image = res->renderTarget().image;
|
||||
auto range = res->renderTarget().imageView->imageSubresources();
|
||||
m_context->transformImage(
|
||||
image,
|
||||
range,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
0,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void GnmCommandBufferDraw::prepareFlip()
|
||||
|
@ -1425,7 +1403,7 @@ namespace sce::Gnm
|
|||
|
||||
result.color[slot] = VltAttachment{
|
||||
targetView,
|
||||
targetView->imageInfo().layout
|
||||
VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1436,7 +1414,7 @@ namespace sce::Gnm
|
|||
|
||||
result.depth = VltAttachment{
|
||||
depthView,
|
||||
depthView->imageInfo().layout
|
||||
VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ namespace sce::Gnm
|
|||
VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
|
||||
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
imageInfo.layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
imageInfo.layout = optimizeLayout(imageInfo.usage);
|
||||
|
||||
VltImageViewCreateInfo viewInfo;
|
||||
viewInfo.type = VK_IMAGE_VIEW_TYPE_2D;
|
||||
|
@ -225,7 +225,7 @@ namespace sce::Gnm
|
|||
imageInfo.stages = createInfo.stage;
|
||||
imageInfo.access = createInfo.access;
|
||||
imageInfo.tiling = createInfo.tiling;
|
||||
imageInfo.layout = createInfo.layout;
|
||||
imageInfo.layout = optimizeLayout(imageInfo.usage);
|
||||
|
||||
VltImageViewCreateInfo viewInfo;
|
||||
viewInfo.type = cvt::convertTextureTypeView(textureType);
|
||||
|
@ -327,6 +327,39 @@ namespace sce::Gnm
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
VkImageLayout GnmResourceFactory::optimizeLayout(VkImageUsageFlags usage)
|
||||
{
|
||||
const VkImageUsageFlags usageFlags = usage;
|
||||
|
||||
// Filter out unnecessary flags. Transfer operations
|
||||
// are handled by the backend in a transparent manner.
|
||||
usage &= ~(VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
|
||||
|
||||
// If the image is used only as an attachment, we never
|
||||
// have to transform the image back to a different layout
|
||||
if (usage == VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
||||
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
if (usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
||||
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
usage &= ~(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
|
||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
|
||||
// If the image is used for reading but not as a storage
|
||||
// image, we can optimize the image for texture access
|
||||
if (usage == VK_IMAGE_USAGE_SAMPLED_BIT)
|
||||
{
|
||||
return usageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
|
||||
? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
|
||||
: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
|
||||
// Otherwise, we have to stick with the default layout
|
||||
return VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
|
||||
|
||||
} // namespace sce::Gnm
|
|
@ -45,7 +45,6 @@ namespace sce
|
|||
VkPipelineStageFlags2 stage;
|
||||
VkAccessFlagBits2 access;
|
||||
VkImageTiling tiling;
|
||||
VkImageLayout layout;
|
||||
VkMemoryPropertyFlags memoryType;
|
||||
};
|
||||
|
||||
|
@ -79,6 +78,8 @@ namespace sce
|
|||
vlt::Rc<vlt::VltSampler> createSampler(
|
||||
const Sampler* ssharp);
|
||||
|
||||
VkImageLayout optimizeLayout(VkImageUsageFlags usage);
|
||||
|
||||
private:
|
||||
vlt::VltDevice* m_device;
|
||||
vlt::VltDebugUtil m_debugUtil;
|
||||
|
|
|
@ -54,15 +54,6 @@ namespace sce
|
|||
// Get the render target which is draw to by commands from game.
|
||||
auto& target = m_renderTargets[index];
|
||||
|
||||
// Transform render target to SHADER_READ layout
|
||||
// so that we can copy it to swapchain.
|
||||
// Note that the content must be preserved.
|
||||
m_context->transformImage(
|
||||
target.image,
|
||||
target.image->getAvailableSubresources(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
// Record draw commands to copy render target image to swapchain image.
|
||||
m_blitter->presentImage(m_context.ptr(),
|
||||
m_imageViews.at(imageIndex), VkRect2D(),
|
||||
|
@ -227,4 +218,51 @@ namespace sce
|
|||
}
|
||||
}
|
||||
|
||||
void SceSwapchain::transitionImageLayout()
|
||||
{
|
||||
// Transition swapchain image's layout to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR.
|
||||
// Because we are using dynamic rendering, the layout can not be
|
||||
// transformed implicitly.
|
||||
PresenterInfo info = m_presenter->info();
|
||||
|
||||
VltImageCreateInfo imageInfo;
|
||||
imageInfo.type = VK_IMAGE_TYPE_2D;
|
||||
imageInfo.format = info.format.format;
|
||||
imageInfo.flags = 0;
|
||||
imageInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT;
|
||||
imageInfo.extent = { info.imageExtent.width, info.imageExtent.height, 1 };
|
||||
imageInfo.numLayers = 1;
|
||||
imageInfo.mipLevels = 1;
|
||||
imageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
imageInfo.stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
imageInfo.access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
imageInfo.layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
|
||||
auto& device = m_device.device;
|
||||
m_context->beginRecording(
|
||||
device->createCommandList(VltQueueType::Graphics));
|
||||
|
||||
for (uint32_t i = 0; i < info.imageCount; i++)
|
||||
{
|
||||
VkImage imageHandle = m_presenter->getImage(i).image;
|
||||
|
||||
Rc<VltImage> image =
|
||||
m_device.device->createImageFromVkImage(imageInfo, imageHandle);
|
||||
|
||||
m_context->transformImage(image,
|
||||
image->getAvailableSubresources(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
image->info().layout);
|
||||
}
|
||||
|
||||
device->submitCommandList(
|
||||
m_context->endRecording(),
|
||||
VK_NULL_HANDLE,
|
||||
VK_NULL_HANDLE);
|
||||
|
||||
device->syncSubmission();
|
||||
}
|
||||
|
||||
|
||||
} // namespace sce
|
|
@ -53,6 +53,8 @@ namespace sce
|
|||
|
||||
void createSwapImageViews();
|
||||
|
||||
void transitionImageLayout();
|
||||
|
||||
private:
|
||||
SceSwapchainDevice m_device;
|
||||
|
||||
|
|
|
@ -165,11 +165,6 @@ namespace sce
|
|||
|
||||
ctx->clearRenderTarget(
|
||||
dstView, VK_IMAGE_ASPECT_COLOR_BIT, VkClearValue());
|
||||
ctx->transformImage(
|
||||
dstView->image(),
|
||||
dstView->subresources(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
|
||||
ctx->bindResourceSampler(BindingIds::Image, m_samplerPresent);
|
||||
ctx->bindResourceView(BindingIds::Image, srcView, nullptr);
|
||||
|
|
|
@ -1388,8 +1388,6 @@ namespace sce::vlt
|
|||
if (!m_flags.test(VltContextFlag::GpRenderingActive) &&
|
||||
framebuffer != nullptr)
|
||||
{
|
||||
framebuffer->prepareLayout(this);
|
||||
|
||||
m_execBarriers.recordCommands(m_cmd);
|
||||
|
||||
const VltFramebufferSize fbSize = framebuffer->size();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "VltContext.h"
|
||||
#include "VltImage.h"
|
||||
#include "VltSampler.h"
|
||||
|
||||
namespace sce::vlt
|
||||
{
|
||||
|
@ -112,70 +113,6 @@ namespace sce::vlt
|
|||
return VltFramebufferSize{ extent.width, extent.height, layers };
|
||||
}
|
||||
|
||||
void VltFramebuffer::prepareLayout(VltContext* ctx)
|
||||
{
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
|
||||
{
|
||||
auto& colorView = m_renderTargets.color[i].view;
|
||||
if (colorView == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto& colorImage = colorView->image();
|
||||
if (colorImage->info().layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ctx->transformImage(colorImage,
|
||||
colorImage->getAvailableSubresources(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
|
||||
auto& depthView = m_renderTargets.depth.view;
|
||||
if (depthView != nullptr)
|
||||
{
|
||||
auto& depthImage = depthView->image();
|
||||
if (depthImage->info().layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL)
|
||||
{
|
||||
ctx->transformImage(depthImage,
|
||||
depthImage->getAvailableSubresources(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VltFramebuffer::restoreLayout(VltContext* ctx)
|
||||
{
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
|
||||
{
|
||||
auto& colorView = m_renderTargets.color[i].view;
|
||||
if (colorView == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto& colorImage = colorView->image();
|
||||
ctx->transformImage(colorImage,
|
||||
colorImage->getAvailableSubresources(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
colorImage->info().layout);
|
||||
}
|
||||
|
||||
auto& depthView = m_renderTargets.depth.view;
|
||||
if (depthView != nullptr)
|
||||
{
|
||||
auto& depthImage = depthView->image();
|
||||
ctx->transformImage(depthImage,
|
||||
depthImage->getAvailableSubresources(),
|
||||
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
|
||||
depthImage->info().layout);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t VltFramebuffer::findAttachment(
|
||||
const Rc<VltImageView>& view) const
|
||||
{
|
||||
|
|
|
@ -149,16 +149,6 @@ namespace sce::vlt
|
|||
&m_depthAttachment : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Transform attachment images to rendering-ready layout.
|
||||
*/
|
||||
void prepareLayout(VltContext* ctx);
|
||||
|
||||
/**
|
||||
* \brief Restore attachment images to its' original layout
|
||||
*/
|
||||
void restoreLayout(VltContext* ctx);
|
||||
|
||||
/**
|
||||
* \brief Checks whether the framebuffer's targets match
|
||||
*
|
||||
|
|
|
@ -125,7 +125,6 @@ namespace sce::vlt
|
|||
m_device(device),
|
||||
m_info(info), m_image({ image })
|
||||
{
|
||||
|
||||
m_viewFormats.resize(info.viewFormatCount);
|
||||
for (uint32_t i = 0; i < info.viewFormatCount; i++)
|
||||
m_viewFormats[i] = info.viewFormats[i];
|
||||
|
|
Loading…
Reference in a new issue