Skip to content

Commit

Permalink
Merge branch 'shadps4-emu:main' into Main
Browse files Browse the repository at this point in the history
  • Loading branch information
diegolix29 authored Sep 23, 2024
2 parents 75ea7a2 + cd7268a commit c639a4b
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/video_core/buffer_cache/buffer_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace VideoCore {
static constexpr size_t NumVertexBuffers = 32;
static constexpr size_t GdsBufferSize = 64_KB;
static constexpr size_t StagingBufferSize = 1_GB;
static constexpr size_t UboStreamBufferSize = 128_MB;
static constexpr size_t UboStreamBufferSize = 64_MB;

BufferCache::BufferCache(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_,
const AmdGpu::Liverpool* liverpool_, TextureCache& texture_cache_,
Expand Down
2 changes: 1 addition & 1 deletion src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
buffer_barriers.emplace_back(*barrier);
}
if (desc.is_written) {
texture_cache.MarkWritten(address, size);
texture_cache.InvalidateMemoryFromGPU(address, size);
}
}
set_writes.push_back({
Expand Down
2 changes: 1 addition & 1 deletion src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
buffer_barriers.emplace_back(*barrier);
}
if (desc.is_written) {
texture_cache.MarkWritten(address, size);
texture_cache.InvalidateMemoryFromGPU(address, size);
}
}
set_writes.push_back({
Expand Down
10 changes: 4 additions & 6 deletions src/video_core/texture_cache/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@

#include "common/enum.h"
#include "common/types.h"
#include "core/libraries/videoout/buffer.h"
#include "video_core/amdgpu/liverpool.h"
#include "video_core/amdgpu/resource.h"
#include "video_core/renderer_vulkan/vk_common.h"
#include "video_core/texture_cache/image_info.h"
#include "video_core/texture_cache/image_view.h"
#include "video_core/texture_cache/types.h"

#include <optional>

Expand All @@ -26,7 +22,9 @@ VK_DEFINE_HANDLE(VmaAllocator)
namespace VideoCore {

enum ImageFlagBits : u32 {
CpuModified = 1 << 2, ///< Contents have been modified from the CPU
CpuDirty = 1 << 1, ///< Contents have been modified from the CPU
GpuDirty = 1 << 2, ///< Contents have been modified from the GPU (valid data in buffer cache)
Dirty = CpuDirty | GpuDirty,
GpuModified = 1 << 3, ///< Contents have been modified from the GPU
Tracked = 1 << 4, ///< Writes and reads are being hooked from the CPU
Registered = 1 << 6, ///< True when the image is registered
Expand Down Expand Up @@ -108,7 +106,7 @@ struct Image {
ImageInfo info;
UniqueImage image;
vk::ImageAspectFlags aspect_mask = vk::ImageAspectFlagBits::eColor;
ImageFlagBits flags = ImageFlagBits::CpuModified;
ImageFlagBits flags = ImageFlagBits::Dirty;
VAddr cpu_addr = 0;
VAddr cpu_addr_end = 0;
std::vector<ImageViewInfo> image_view_infos;
Expand Down
41 changes: 20 additions & 21 deletions src/video_core/texture_cache/texture_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,23 @@ void TextureCache::InvalidateMemory(VAddr address, size_t size) {
std::scoped_lock lock{mutex};
ForEachImageInRegion(address, size, [&](ImageId image_id, Image& image) {
// Ensure image is reuploaded when accessed again.
image.flags |= ImageFlagBits::CpuModified;
image.flags |= ImageFlagBits::CpuDirty;
// Untrack image, so the range is unprotected and the guest can write freely.
UntrackImage(image_id);
});
}

void TextureCache::MarkWritten(VAddr address, size_t max_size) {
static constexpr FindFlags find_flags =
FindFlags::NoCreate | FindFlags::RelaxDim | FindFlags::RelaxFmt | FindFlags::RelaxSize;
ImageInfo info{};
info.guest_address = address;
info.guest_size_bytes = max_size;
const ImageId image_id = FindImage(info, find_flags);
if (!image_id) {
return;
}
// Ensure image is copied when accessed again.
slot_images[image_id].flags |= ImageFlagBits::CpuModified;
void TextureCache::InvalidateMemoryFromGPU(VAddr address, size_t max_size) {
std::scoped_lock lock{mutex};
ForEachImageInRegion(address, max_size, [&](ImageId image_id, Image& image) {
// Only consider images that match base address.
// TODO: Maybe also consider subresources
if (image.info.guest_address != address) {
return;
}
// Ensure image is reuploaded when accessed again.
image.flags |= ImageFlagBits::GpuDirty;
});
}

void TextureCache::UnmapMemory(VAddr cpu_addr, size_t size) {
Expand Down Expand Up @@ -189,7 +188,7 @@ ImageId TextureCache::ExpandImage(const ImageInfo& info, ImageId image_id) {
FreeImage(image_id);

TrackImage(new_image_id);
new_image.flags &= ~ImageFlagBits::CpuModified;
new_image.flags &= ~ImageFlagBits::Dirty;
return new_image_id;
}

Expand Down Expand Up @@ -325,7 +324,7 @@ ImageView& TextureCache::FindDepthTarget(const ImageInfo& image_info,
const ImageId image_id = FindImage(image_info);
Image& image = slot_images[image_id];
image.flags |= ImageFlagBits::GpuModified;
image.flags &= ~ImageFlagBits::CpuModified;
image.flags &= ~ImageFlagBits::Dirty;
image.aspect_mask = vk::ImageAspectFlagBits::eDepth;

const bool has_stencil = image_info.usage.stencil;
Expand Down Expand Up @@ -362,11 +361,9 @@ ImageView& TextureCache::FindDepthTarget(const ImageInfo& image_info,
}

void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_scheduler /*= nullptr*/) {
if (False(image.flags & ImageFlagBits::CpuModified)) {
if (False(image.flags & ImageFlagBits::Dirty)) {
return;
}
// Mark image as validated.
image.flags &= ~ImageFlagBits::CpuModified;

const auto& num_layers = image.info.resources.layers;
const auto& num_mips = image.info.resources.levels;
Expand All @@ -380,9 +377,10 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule
image.info.props.is_volume ? std::max(image.info.size.depth >> m, 1u) : 1u;
const auto& [mip_size, mip_pitch, mip_height, mip_ofs] = image.info.mips_layout[m];

// Protect GPU modified resources from accidental reuploads.
if (True(image.flags & ImageFlagBits::GpuModified) &&
!buffer_cache.IsRegionGpuModified(image.info.guest_address + mip_ofs, mip_size)) {
// Protect GPU modified resources from accidental CPU reuploads.
const bool is_gpu_modified = True(image.flags & ImageFlagBits::GpuModified);
const bool is_gpu_dirty = True(image.flags & ImageFlagBits::GpuDirty);
if (is_gpu_modified && !is_gpu_dirty) {
const u8* addr = std::bit_cast<u8*>(image.info.guest_address);
const u64 hash = XXH3_64bits(addr + mip_ofs, mip_size);
if (image.mip_hashes[m] == hash) {
Expand Down Expand Up @@ -438,6 +436,7 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule
}

cmdbuf.copyBufferToImage(buffer, image.image, vk::ImageLayout::eTransferDstOptimal, image_copy);
image.flags &= ~ImageFlagBits::Dirty;
}

vk::Sampler TextureCache::GetSampler(const AmdGpu::Sampler& sampler) {
Expand Down
2 changes: 1 addition & 1 deletion src/video_core/texture_cache/texture_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class TextureCache {
void InvalidateMemory(VAddr address, size_t size);

/// Marks an image as dirty if it exists at the provided address.
void MarkWritten(VAddr address, size_t max_size);
void InvalidateMemoryFromGPU(VAddr address, size_t max_size);

/// Evicts any images that overlap the unmapped range.
void UnmapMemory(VAddr cpu_addr, size_t size);
Expand Down

0 comments on commit c639a4b

Please sign in to comment.