mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-10 20:53:15 +00:00
video_core: Track renderpass scopes properly
This commit is contained in:
parent
ad10020836
commit
22b930ba5e
36 changed files with 400 additions and 166 deletions
|
@ -221,6 +221,7 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_,
|
|||
: instance{&instance_}, scheduler{&scheduler_}, info{info_},
|
||||
image{instance->GetDevice(), instance->GetAllocator()}, cpu_addr{cpu_addr},
|
||||
cpu_addr_end{cpu_addr + info.guest_size_bytes} {
|
||||
ASSERT(info.pixel_format != vk::Format::eUndefined);
|
||||
vk::ImageCreateFlags flags{vk::ImageCreateFlagBits::eMutableFormat |
|
||||
vk::ImageCreateFlagBits::eExtendedUsage};
|
||||
if (info.type == vk::ImageType::e2D && info.resources.layers >= 6 &&
|
||||
|
@ -272,7 +273,8 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_,
|
|||
Transit(vk::ImageLayout::eGeneral, vk::AccessFlagBits::eNone);
|
||||
}
|
||||
|
||||
void Image::Transit(vk::ImageLayout dst_layout, vk::Flags<vk::AccessFlagBits> dst_mask) {
|
||||
void Image::Transit(vk::ImageLayout dst_layout, vk::Flags<vk::AccessFlagBits> dst_mask,
|
||||
vk::CommandBuffer cmdbuf) {
|
||||
if (dst_layout == layout && dst_mask == access_mask) {
|
||||
return;
|
||||
}
|
||||
|
@ -300,7 +302,12 @@ void Image::Transit(vk::ImageLayout dst_layout, vk::Flags<vk::AccessFlagBits> ds
|
|||
dst_mask == vk::AccessFlagBits::eTransferWrite)
|
||||
? vk::PipelineStageFlagBits::eTransfer
|
||||
: vk::PipelineStageFlagBits::eAllGraphics | vk::PipelineStageFlagBits::eComputeShader;
|
||||
const auto cmdbuf = scheduler->CommandBuffer();
|
||||
|
||||
if (!cmdbuf) {
|
||||
// When using external cmdbuf you are responsible for ending rp.
|
||||
scheduler->EndRendering();
|
||||
cmdbuf = scheduler->CommandBuffer();
|
||||
}
|
||||
cmdbuf.pipelineBarrier(pl_stage, dst_pl_stage, vk::DependencyFlagBits::eByRegion, {}, {},
|
||||
barrier);
|
||||
|
||||
|
@ -310,6 +317,7 @@ void Image::Transit(vk::ImageLayout dst_layout, vk::Flags<vk::AccessFlagBits> ds
|
|||
}
|
||||
|
||||
void Image::Upload(vk::Buffer buffer, u64 offset) {
|
||||
scheduler->EndRendering();
|
||||
Transit(vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits::eTransferWrite);
|
||||
|
||||
// Copy to the image.
|
||||
|
@ -318,7 +326,7 @@ void Image::Upload(vk::Buffer buffer, u64 offset) {
|
|||
.bufferRowLength = info.pitch,
|
||||
.bufferImageHeight = info.size.height,
|
||||
.imageSubresource{
|
||||
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||
.aspectMask = aspect_mask,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
|
|
|
@ -132,7 +132,8 @@ struct Image {
|
|||
return image_view_ids[std::distance(image_view_infos.begin(), it)];
|
||||
}
|
||||
|
||||
void Transit(vk::ImageLayout dst_layout, vk::Flags<vk::AccessFlagBits> dst_mask);
|
||||
void Transit(vk::ImageLayout dst_layout, vk::Flags<vk::AccessFlagBits> dst_mask,
|
||||
vk::CommandBuffer cmdbuf = {});
|
||||
void Upload(vk::Buffer buffer, u64 offset);
|
||||
|
||||
const Vulkan::Instance* instance;
|
||||
|
|
|
@ -80,8 +80,10 @@ ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info
|
|||
|
||||
// When sampling D32 texture from shader, the T# specifies R32 Float format so adjust it.
|
||||
vk::Format format = info.format;
|
||||
vk::ImageAspectFlags aspect = image.aspect_mask;
|
||||
if (image.aspect_mask & vk::ImageAspectFlagBits::eDepth && format == vk::Format::eR32Sfloat) {
|
||||
format = vk::Format::eD32Sfloat;
|
||||
format = image.info.pixel_format;
|
||||
aspect = vk::ImageAspectFlagBits::eDepth;
|
||||
}
|
||||
|
||||
const vk::ImageViewCreateInfo image_view_ci = {
|
||||
|
@ -91,7 +93,7 @@ ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info
|
|||
.format = format,
|
||||
.components = info.mapping,
|
||||
.subresourceRange{
|
||||
.aspectMask = image.aspect_mask,
|
||||
.aspectMask = aspect,
|
||||
.baseMipLevel = 0U,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
|
|
|
@ -116,10 +116,15 @@ Image& TextureCache::FindImage(const ImageInfo& info, VAddr cpu_address, bool re
|
|||
std::unique_lock lock{m_page_table};
|
||||
boost::container::small_vector<ImageId, 2> image_ids;
|
||||
ForEachImageInRegion(cpu_address, info.guest_size_bytes, [&](ImageId image_id, Image& image) {
|
||||
if (image.cpu_addr == cpu_address && image.info.size.width == info.size.width &&
|
||||
image.info.IsDepthStencil() == info.IsDepthStencil()) {
|
||||
image_ids.push_back(image_id);
|
||||
// Address and width must match.
|
||||
if (image.cpu_addr != cpu_address || image.info.size.width != info.size.width) {
|
||||
return;
|
||||
}
|
||||
if (info.IsDepthStencil() != image.info.IsDepthStencil() &&
|
||||
info.pixel_format != vk::Format::eR32Sfloat) {
|
||||
return;
|
||||
}
|
||||
image_ids.push_back(image_id);
|
||||
});
|
||||
|
||||
ASSERT_MSG(image_ids.size() <= 1, "Overlapping images not allowed!");
|
||||
|
@ -129,7 +134,7 @@ Image& TextureCache::FindImage(const ImageInfo& info, VAddr cpu_address, bool re
|
|||
image_id = slot_images.insert(instance, scheduler, info, cpu_address);
|
||||
RegisterImage(image_id);
|
||||
} else {
|
||||
image_id = image_ids[0];
|
||||
image_id = image_ids.size() > 1 ? image_ids[1] : image_ids[0];
|
||||
}
|
||||
|
||||
RegisterMeta(info, image_id);
|
||||
|
@ -163,11 +168,11 @@ ImageView& TextureCache::RegisterImageView(Image& image, const ImageViewInfo& vi
|
|||
return slot_image_views[view_id];
|
||||
}
|
||||
|
||||
ImageView& TextureCache::FindImageView(const AmdGpu::Image& desc, bool is_storage) {
|
||||
ImageView& TextureCache::FindImageView(const AmdGpu::Image& desc, bool is_storage, bool is_depth) {
|
||||
const ImageInfo info{desc};
|
||||
Image& image = FindImage(info, desc.Address());
|
||||
|
||||
if (is_storage) {
|
||||
if (is_storage || is_depth) {
|
||||
image.Transit(vk::ImageLayout::eGeneral, vk::AccessFlagBits::eShaderWrite);
|
||||
image.info.usage.storage = true;
|
||||
} else {
|
||||
|
@ -202,7 +207,7 @@ ImageView& TextureCache::DepthTarget(const AmdGpu::Liverpool::DepthBuffer& buffe
|
|||
auto& image = FindImage(info, buffer.Address(), false);
|
||||
image.flags &= ~ImageFlagBits::CpuModified;
|
||||
|
||||
image.Transit(vk::ImageLayout::eDepthStencilAttachmentOptimal,
|
||||
image.Transit(vk::ImageLayout::eGeneral,
|
||||
vk::AccessFlagBits::eDepthStencilAttachmentWrite |
|
||||
vk::AccessFlagBits::eDepthStencilAttachmentRead);
|
||||
|
||||
|
@ -261,6 +266,8 @@ void TextureCache::RefreshImage(Image& image) {
|
|||
.imageExtent = {width, height, 1},
|
||||
};
|
||||
|
||||
scheduler.EndRendering();
|
||||
|
||||
const auto cmdbuf = scheduler.CommandBuffer();
|
||||
image.Transit(vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits::eTransferWrite);
|
||||
|
||||
|
|
|
@ -52,7 +52,8 @@ public:
|
|||
bool refresh_on_create = true);
|
||||
|
||||
/// Retrieves an image view with the properties of the specified image descriptor.
|
||||
[[nodiscard]] ImageView& FindImageView(const AmdGpu::Image& image, bool is_storage);
|
||||
[[nodiscard]] ImageView& FindImageView(const AmdGpu::Image& image, bool is_storage,
|
||||
bool is_depth);
|
||||
|
||||
/// Retrieves the render target with specified properties
|
||||
[[nodiscard]] ImageView& RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
||||
|
|
|
@ -231,7 +231,7 @@ static constexpr vk::BufferUsageFlags StagingFlags = vk::BufferUsageFlagBits::eT
|
|||
|
||||
TileManager::TileManager(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler)
|
||||
: instance{instance}, scheduler{scheduler},
|
||||
staging{instance, scheduler, StagingFlags, 64_MB, Vulkan::BufferType::Upload} {
|
||||
staging{instance, scheduler, StagingFlags, 128_MB, Vulkan::BufferType::Upload} {
|
||||
|
||||
static const std::array detiler_shaders{
|
||||
HostShaders::DETILE_M8X1_COMP, HostShaders::DETILE_M8X2_COMP,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue