incomplete fix

This commit is contained in:
Asuka 2022-07-10 06:16:30 +08:00
parent 30636e91a8
commit 9203064f5c
10 changed files with 169 additions and 118 deletions

View file

@ -171,8 +171,6 @@ namespace sce::Gnm
VkImageTiling tiling,
VkImageLayout layout)
{
SceTexture texture;
GnmImageCreateInfo info;
info.tsharp = tsharp;
info.usage = usage;
@ -182,13 +180,10 @@ namespace sce::Gnm
info.layout = layout;
info.memoryType = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
m_factory.createImage(info, texture);
m_tracker.track(texture);
m_initializer->initTexture(texture.image, tsharp);
uint32_t slot = computeResourceBinding(
gcnProgramTypeFromVkStage(stage), startRegister);
SceTexture texture = getResourceTexture(info);
auto progType = gcnProgramTypeFromVkStage(stage);
uint32_t slot = computeResourceBinding(progType,
startRegister);
m_context->bindResourceView(slot, texture.imageView, nullptr);
}
@ -198,6 +193,9 @@ namespace sce::Gnm
uint32_t startRegister,
VkPipelineStageFlags2 stage)
{
// Samplers are cached internally
// in resource factory
Rc<VltSampler> sampler = nullptr;
m_factory.createSampler(ssharp, sampler);
@ -349,7 +347,8 @@ namespace sce::Gnm
auto type = resource->type();
if (type.any(SceResourceType::Texture,
SceResourceType::RenderTarget,
SceResourceType::DepthRenderTarget))
SceResourceType::DepthRenderTarget) &&
!type.test(SceResourceType::Buffer))
{
// An image backend buffer,
// we create and fill the buffer,
@ -390,6 +389,64 @@ namespace sce::Gnm
return result;
}
SceTexture GnmCommandBuffer::getResourceTexture(
const GnmImageCreateInfo& info)
{
SceTexture result = {};
const auto& tsharp = info.tsharp;
void* memory = tsharp->getBaseAddress();
auto resource = m_tracker.find(memory);
if (resource != nullptr)
{
auto type = resource->type();
if (type.test(SceResourceType::Buffer) &&
!type.test(SceResourceType::Texture))
{
m_factory.createImage(info, result);
m_initializer->initTexture(result.image, tsharp);
resource->setTexture(result);
resource->setTransform(SceTransformFlag::GpuUpload);
}
else if (type.test(SceResourceType::RenderTarget) &&
!type.test(SceResourceType::Texture))
{
const auto& target = resource->renderTarget();
result.image = target.image;
result.imageView = target.imageView;
result.texture = *tsharp;
resource->setTexture(result);
}
else if (type.test(SceResourceType::DepthRenderTarget) &&
!type.test(SceResourceType::Texture))
{
const auto& target = resource->depthRenderTarget();
result.image = target.image;
result.imageView = target.imageView;
result.texture = *tsharp;
resource->setTexture(result);
}
else
{
result = resource->texture();
}
}
else
{
// create a fresh new texture,
// initialize and track it
m_factory.createImage(info, result);
m_initializer->initTexture(result.image, tsharp);
m_tracker.track(result);
}
return result;
}
GcnBufferMeta GnmCommandBuffer::populateBufferMeta(
const Buffer* vsharp)
{
@ -444,4 +501,6 @@ namespace sce::Gnm
return m_shaderModules.getShaderModule(key, code);
}
} // namespace sce::Gnm

View file

@ -470,13 +470,15 @@ namespace sce::Gnm
void commitComputeState(
GnmShaderContext& ctx);
ShaderStage getShaderStage(
VkPipelineStageFlags pipeStage);
SceBuffer getResourceBuffer(
const GnmBufferCreateInfo& info);
SceTexture getResourceTexture(
const GnmImageCreateInfo& info);
virtual void updateMetaBufferInfo(
VkPipelineStageFlags stage,
uint32_t startRegister,

View file

@ -97,6 +97,7 @@ namespace sce::Gnm
const RenderTarget* target,
SceRenderTarget& targetImage)
{
VltImageCreateInfo imageInfo;
imageInfo.type = VK_IMAGE_TYPE_2D;
imageInfo.format = cvt::convertDataFormat(target->getDataFormat());
@ -105,11 +106,23 @@ namespace sce::Gnm
imageInfo.extent = { target->getWidth(), target->getHeight(), 1 };
imageInfo.numLayers = 1;
imageInfo.mipLevels = 1;
imageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
imageInfo.stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
imageInfo.access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
imageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT;
imageInfo.stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_TRANSFER_BIT;
imageInfo.access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_TRANSFER_READ_BIT |
VK_ACCESS_TRANSFER_WRITE_BIT;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.layout = VK_IMAGE_LAYOUT_GENERAL;
VltImageViewCreateInfo viewInfo;
viewInfo.type = VK_IMAGE_VIEW_TYPE_2D;

View file

@ -5,12 +5,11 @@
#include "GnmDataFormat.h"
#include "GnmRegInfo.h"
#include "GnmSharpBuffer.h"
#include "UtilBit.h"
namespace sce::Gnm
{
class alignas(16) Sampler
class Sampler
{
public:
enum
@ -24,12 +23,12 @@ namespace sce::Gnm
bool operator==(const Sampler& other) const
{
return util::bit::bcmpeq(this, &other);
return !std::memcmp(this, &other, sizeof(Sampler));
}
bool operator!=(const Sampler& other) const
{
return !util::bit::bcmpeq(this, &other);
return std::memcmp(this, &other, sizeof(Sampler));
}
const SSharpBuffer& getSsharp() const

View file

@ -5,6 +5,16 @@ using namespace sce::vlt;
namespace sce::Gnm
{
size_t GnmSamplerHash::operator()(const Sampler& object) const
{
VltHashState state;
state.add(object.m_regs[0]);
state.add(object.m_regs[1]);
state.add(object.m_regs[2]);
state.add(object.m_regs[3]);
return state;
}
GnmSamplerCache::GnmSamplerCache()
{
}
@ -33,14 +43,4 @@ namespace sce::Gnm
m_samplers.emplace(ssharp, sampler);
}
size_t GnmSamplerHash::operator()(const Sampler& object) const
{
VltHashState state;
state.add(object.m_regs[0]);
state.add(object.m_regs[1]);
state.add(object.m_regs[2]);
state.add(object.m_regs[3]);
return state;
}
} // namespace sce::Gnm

View file

@ -24,7 +24,6 @@ namespace sce::Gnm
/**
* \brief Sampler cache
*
*/
class GnmSamplerCache
{

View file

@ -225,27 +225,8 @@ namespace sce::vlt
VkImageLayout srcLayout,
VkImageLayout dstLayout)
{
this->transformImage(
dstImage,
dstSubresources,
srcLayout,
dstImage->info().stages,
dstImage->info().access,
dstLayout,
dstImage->info().stages,
dstImage->info().access);
}
this->endRendering();
void VltContext::transformImage(
const Rc<VltImage>& dstImage,
const VkImageSubresourceRange& dstSubresources,
VkImageLayout srcLayout,
VkPipelineStageFlags2 srcStages,
VkAccessFlags2 srcAccess,
VkImageLayout dstLayout,
VkPipelineStageFlags2 dstStages,
VkAccessFlags2 dstAccess)
{
if (srcLayout != dstLayout)
{
m_execBarriers.recordCommands(m_cmd);
@ -253,11 +234,11 @@ namespace sce::vlt
m_execBarriers.accessImage(
dstImage, dstSubresources,
srcLayout,
srcStages,
srcAccess,
dstImage->info().stages,
dstImage->info().access,
dstLayout,
dstStages,
dstAccess);
dstImage->info().stages,
dstImage->info().access);
m_cmd->trackResource<VltAccess::Write>(dstImage);
}
@ -1407,6 +1388,8 @@ namespace sce::vlt
if (!m_flags.test(VltContextFlag::GpRenderingActive) &&
framebuffer != nullptr)
{
framebuffer->prepareLayout(this);
m_execBarriers.recordCommands(m_cmd);
const VltFramebufferSize fbSize = framebuffer->size();
@ -1679,7 +1662,9 @@ namespace sce::vlt
}
// Allocate and update descriptor set
auto& set = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ? m_gpSet : m_cpSet;
auto& set = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
? m_gpSet
: m_cpSet;
if (layout->bindingCount())
{
@ -1956,9 +1941,6 @@ namespace sce::vlt
m_flags.clr(VltContextFlag::GpDirtyFramebufferState);
}
framebuffer->prepareRenderingLayout(m_execAcquires);
m_execAcquires.recordCommands(m_cmd);
m_flags.clr(VltContextFlag::GpDirtyFramebuffer);
}

View file

@ -479,21 +479,6 @@ namespace sce::vlt
VkImageLayout dstLayout);
/**
* \brief Transforms image subresource layouts
*
* Note the internal image info layout is not changed.
*/
void transformImage(
const Rc<VltImage>& dstImage,
const VkImageSubresourceRange& dstSubresources,
VkImageLayout srcLayout,
VkPipelineStageFlags2 srcStages,
VkAccessFlags2 srcAccess,
VkImageLayout dstLayout,
VkPipelineStageFlags2 dstStages,
VkAccessFlags2 dstAccess);
/**
* \brief Copies data from one buffer to another
*
* \param [in] dstBuffer Destination buffer

View file

@ -1,6 +1,6 @@
#include "VltFramebuffer.h"
#include "VltBarrier.h"
#include "VltContext.h"
#include "VltImage.h"
namespace sce::vlt
@ -112,36 +112,26 @@ namespace sce::vlt
return VltFramebufferSize{ extent.width, extent.height, layers };
}
void VltFramebuffer::prepareRenderingLayout(VltBarrierSet& barrier)
void VltFramebuffer::prepareLayout(VltContext* ctx)
{
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
{
auto& colorView = m_renderTargets.color[i].view;
if (colorView != nullptr)
if (colorView == nullptr)
{
auto& colorImage = colorView->image();
if (colorImage->info().layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
{
continue;
}
VkImageSubresourceRange subresources;
subresources.aspectMask = colorImage->formatInfo()->aspectMask;
subresources.baseArrayLayer = 0;
subresources.baseMipLevel = 0;
subresources.layerCount = colorImage->info().numLayers;
subresources.levelCount = colorImage->info().mipLevels;
barrier.accessImage(
colorImage,
subresources,
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);
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;
@ -150,26 +140,42 @@ namespace sce::vlt
auto& depthImage = depthView->image();
if (depthImage->info().layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL)
{
VkImageSubresourceRange subresources;
subresources.aspectMask = depthImage->formatInfo()->aspectMask;
subresources.baseArrayLayer = 0;
subresources.baseMipLevel = 0;
subresources.layerCount = depthImage->info().numLayers;
subresources.levelCount = depthImage->info().mipLevels;
barrier.accessImage(
depthImage,
subresources,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
0,
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
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
{
@ -221,4 +227,6 @@ namespace sce::vlt
}
}
} // namespace sce::vlt

View file

@ -7,7 +7,7 @@
namespace sce::vlt
{
class VltBarrierSet;
class VltContext;
/**
* \brief Attachment
@ -151,9 +151,13 @@ namespace sce::vlt
/**
* \brief Transform attachment images to rendering-ready layout.
*
*/
void prepareRenderingLayout(VltBarrierSet& barrier);
void prepareLayout(VltContext* ctx);
/**
* \brief Restore attachment images to its' original layout
*/
void restoreLayout(VltContext* ctx);
/**
* \brief Checks whether the framebuffer's targets match