mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 16:02:37 +00:00
Refactor buffer image write classification
This commit is contained in:
1 parent
41114be8da
commit
a96b5111e6
5 files changed
+172
-163
No files matched your search
@@ -189,9 +189,26 @@ enum class SampledOverlap : uint8_t { None, ReadOnlyAlias, Unsupported };
|
||||
enum class StorageSampledOverlap : uint8_t { None, ExactImage, Unsupported };
|
||||
enum class StorageImageOverlap : uint8_t { None, RetireSampled, PageNeighbor, Unsupported };
|
||||
enum class HostWriteOverlap : uint8_t { None, InvalidateImage, Unsupported };
|
||||
enum class BufferImageAlias : uint8_t { None, VideoOutWrite, RenderTargetWrite, Unsupported };
|
||||
enum class BufferImageBinding : uint8_t { Texture, VideoOut, RenderTarget, Unsupported };
|
||||
enum class BufferImageWrite : uint8_t {
|
||||
None,
|
||||
InvalidateTexture,
|
||||
InvalidateVideoOut,
|
||||
SynchronizeRenderTarget,
|
||||
Unsupported
|
||||
};
|
||||
enum class MetaImageOverlap : uint8_t { RetainSampled, RetireTarget, Unsupported };
|
||||
|
||||
[[nodiscard]] inline constexpr bool IsSupportedRenderTargetElementSize(uint32_t size) noexcept {
|
||||
switch (size) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr DepthTransitionSource
|
||||
SelectDepthTransitionSource(bool depth_load_clear, bool sampled_native_available,
|
||||
bool sampled_cpu_dirty, bool sampled_buffer_modified,
|
||||
@@ -401,38 +418,31 @@ ClassifyHostWriteOverlap(uint64_t write_address, uint64_t write_size, uint64_t i
|
||||
: HostWriteOverlap::Unsupported;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool IsSampledBufferWriteTransition(uint64_t buffer_address,
|
||||
uint64_t buffer_size,
|
||||
uint64_t image_address,
|
||||
uint64_t image_size,
|
||||
bool image_gpu_modified) {
|
||||
[[nodiscard]] inline BufferImageWrite
|
||||
ClassifyBufferImageWrite(uint64_t buffer_address, uint64_t buffer_size, uint64_t image_address,
|
||||
uint64_t image_size, BufferImageBinding binding, bool image_gpu_modified,
|
||||
bool buffer_formatted) {
|
||||
if (!ImagePageRangesOverlap(buffer_address, buffer_size, image_address, image_size)) {
|
||||
return false;
|
||||
return BufferImageWrite::None;
|
||||
}
|
||||
const bool exact = buffer_address == image_address && buffer_size == image_size;
|
||||
const bool page_aligned = ((buffer_address | buffer_size) & (TRACKER_PAGE_SIZE - 1)) == 0;
|
||||
return exact && page_aligned && !image_gpu_modified;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline BufferImageAlias
|
||||
ClassifyBufferImageAlias(uint64_t buffer_address, uint64_t buffer_size, uint64_t image_address,
|
||||
uint64_t image_size, bool video_out, bool render_target,
|
||||
bool image_gpu_modified, bool buffer_written, bool buffer_formatted) {
|
||||
if (!ImagePageRangesOverlap(buffer_address, buffer_size, image_address, image_size)) {
|
||||
return BufferImageAlias::None;
|
||||
switch (binding) {
|
||||
case BufferImageBinding::Texture:
|
||||
return exact && page_aligned && !image_gpu_modified
|
||||
? BufferImageWrite::InvalidateTexture
|
||||
: BufferImageWrite::Unsupported;
|
||||
case BufferImageBinding::VideoOut:
|
||||
return exact && buffer_formatted && !image_gpu_modified
|
||||
? BufferImageWrite::InvalidateVideoOut
|
||||
: BufferImageWrite::Unsupported;
|
||||
case BufferImageBinding::RenderTarget:
|
||||
return exact && page_aligned && buffer_formatted && image_gpu_modified
|
||||
? BufferImageWrite::SynchronizeRenderTarget
|
||||
: BufferImageWrite::Unsupported;
|
||||
case BufferImageBinding::Unsupported: return BufferImageWrite::Unsupported;
|
||||
}
|
||||
const bool exact = buffer_address == image_address && buffer_size == image_size;
|
||||
if (!exact || !buffer_written || !buffer_formatted) {
|
||||
return BufferImageAlias::Unsupported;
|
||||
}
|
||||
if (video_out && !render_target && !image_gpu_modified) {
|
||||
return BufferImageAlias::VideoOutWrite;
|
||||
}
|
||||
const bool page_aligned = ((buffer_address | buffer_size) & (TRACKER_PAGE_SIZE - 1)) == 0;
|
||||
if (render_target && !video_out && image_gpu_modified && page_aligned) {
|
||||
return BufferImageAlias::RenderTargetWrite;
|
||||
}
|
||||
return BufferImageAlias::Unsupported;
|
||||
return BufferImageWrite::Unsupported;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline DepthOverlap ClassifyDepthOverlap(const ImageInfo& sampled,
|
||||
|
||||
@@ -128,6 +128,16 @@ struct TextureCache::CachedImage {
|
||||
[[nodiscard]] uint32_t RangeCount() const {
|
||||
return kind == Kind::DepthTarget && depth.stencil_address != 0 ? 2u : 1u;
|
||||
}
|
||||
[[nodiscard]] BufferImageBinding BufferBinding() const {
|
||||
switch (kind) {
|
||||
case Kind::Texture: return BufferImageBinding::Texture;
|
||||
case Kind::RenderTarget: return BufferImageBinding::RenderTarget;
|
||||
case Kind::VideoOut: return BufferImageBinding::VideoOut;
|
||||
case Kind::StorageTexture:
|
||||
case Kind::DepthTarget: return BufferImageBinding::Unsupported;
|
||||
}
|
||||
return BufferImageBinding::Unsupported;
|
||||
}
|
||||
[[nodiscard]] uint64_t Address(uint32_t index = 0) const {
|
||||
if (index >= RangeCount()) {
|
||||
EXIT("TextureCache: image address range index out of bounds, index=%u count=%u\n",
|
||||
@@ -445,8 +455,7 @@ struct TextureCache::ReadbackWorker {
|
||||
if (linear_size > slice_size || cached.image->format != info.format ||
|
||||
cached.image->extent.width != info.width ||
|
||||
cached.image->extent.height != info.height ||
|
||||
(tiled && info.bytes_per_element != 1 && info.bytes_per_element != 2 &&
|
||||
info.bytes_per_element != 4 && info.bytes_per_element != 8) ||
|
||||
(tiled && !IsSupportedRenderTargetElementSize(info.bytes_per_element)) ||
|
||||
meta_overlap || buffer_overlap) {
|
||||
EXIT("TextureCache: color-image readback storage is unsupported, addr=0x%016" PRIx64
|
||||
" size=0x%016" PRIx64 " linear=0x%016" PRIx64
|
||||
@@ -3097,20 +3106,24 @@ void TextureCache::SynchronizeRenderTargetToBufferLocked(CachedImage& cached) {
|
||||
exact.size <= UINT64_MAX / target.layers &&
|
||||
exact.size * target.layers == target.size;
|
||||
const bool exact_tiled = tiled && exact.align == 65536 && layered_size;
|
||||
if (cached.kind != CachedImage::Kind::RenderTarget || !cached.gpu_modified ||
|
||||
cached.buffer_modified || cached.ctx == nullptr || cached.image == nullptr ||
|
||||
(!linear && !exact_tiled) || target.address == 0 || target.size == 0 || target.width == 0 ||
|
||||
target.height == 0 || target.pitch < target.width || target.bytes_per_element == 0 ||
|
||||
target.layers == 0 || target.size % target.layers != 0 || target.size > UINT32_MAX ||
|
||||
target.levels != 1 || cached.image->layers != target.layers ||
|
||||
rows > (UINT64_MAX - target.width) / target.pitch) {
|
||||
const bool valid_cache = cached.kind == CachedImage::Kind::RenderTarget &&
|
||||
cached.gpu_modified && !cached.buffer_modified &&
|
||||
cached.ctx != nullptr && cached.image != nullptr;
|
||||
const bool valid_target =
|
||||
target.address != 0 && target.size != 0 && target.width != 0 && target.height != 0 &&
|
||||
target.pitch >= target.width && target.bytes_per_element != 0 && target.layers != 0 &&
|
||||
target.size % target.layers == 0 && target.size <= UINT32_MAX && target.levels == 1 &&
|
||||
rows <= (UINT64_MAX - target.width) / target.pitch;
|
||||
const bool valid_image = cached.image != nullptr && cached.image->layers == target.layers;
|
||||
if (!valid_cache || !valid_target || (!linear && !exact_tiled) || !valid_image) {
|
||||
EXIT("TextureCache: unsupported render-target buffer synchronization, "
|
||||
"addr=0x%016" PRIx64 " size=0x%016" PRIx64
|
||||
" extent=%ux%u pitch=%u bpe=%u levels=%u layers=%u/%u tile=%u"
|
||||
" gpu_modified=%d buffer_modified=%d\n",
|
||||
target.address, target.size, target.width, target.height, target.pitch,
|
||||
target.bytes_per_element, target.levels, target.layers, cached.image->layers,
|
||||
target.tile_mode, cached.gpu_modified, cached.buffer_modified);
|
||||
target.bytes_per_element, target.levels, target.layers,
|
||||
cached.image == nullptr ? 0 : cached.image->layers, target.tile_mode,
|
||||
cached.gpu_modified, cached.buffer_modified);
|
||||
}
|
||||
const auto linear_elements = rows * target.pitch + target.width;
|
||||
if (linear_elements > UINT64_MAX / target.bytes_per_element) {
|
||||
@@ -3121,8 +3134,7 @@ void TextureCache::SynchronizeRenderTargetToBufferLocked(CachedImage& cached) {
|
||||
if (linear_size > slice_size || cached.image->format != target.format ||
|
||||
cached.image->extent.width != target.width ||
|
||||
cached.image->extent.height != target.height ||
|
||||
(tiled && target.bytes_per_element != 1 && target.bytes_per_element != 2 &&
|
||||
target.bytes_per_element != 4 && target.bytes_per_element != 8) ||
|
||||
(tiled && !IsSupportedRenderTargetElementSize(target.bytes_per_element)) ||
|
||||
HasMetaOverlapLocked(target.address, target.size)) {
|
||||
EXIT("TextureCache: render-target buffer synchronization storage mismatch, "
|
||||
"addr=0x%016" PRIx64 " size=0x%016" PRIx64 " linear=0x%016" PRIx64 "\n",
|
||||
@@ -3184,24 +3196,18 @@ bool TextureCache::InvalidateMemoryFromGPU(uint64_t vaddr, uint64_t size,
|
||||
m_metadata_tracker.UntrackMemory(it->first, it->second.size);
|
||||
it = m_surface_metas.erase(it);
|
||||
}
|
||||
auto match = m_images.end();
|
||||
BufferImageAlias action = BufferImageAlias::None;
|
||||
bool sampled_write = false;
|
||||
auto match = m_images.end();
|
||||
BufferImageWrite action = BufferImageWrite::None;
|
||||
for (auto it = m_images.begin(); it != m_images.end(); ++it) {
|
||||
auto& cached = **it;
|
||||
if (!cached.OverlapsRange(vaddr, size, false)) {
|
||||
continue;
|
||||
}
|
||||
const auto alias =
|
||||
ClassifyBufferImageAlias(vaddr, size, cached.Address(), cached.Size(),
|
||||
cached.kind == CachedImage::Kind::VideoOut,
|
||||
cached.kind == CachedImage::Kind::RenderTarget,
|
||||
cached.gpu_modified, true, formatted_buffer_write);
|
||||
const bool sampled = cached.kind == CachedImage::Kind::Texture &&
|
||||
IsSampledBufferWriteTransition(vaddr, size, cached.Address(),
|
||||
cached.Size(), cached.gpu_modified);
|
||||
if (match != m_images.end() || (!sampled && alias != BufferImageAlias::VideoOutWrite &&
|
||||
alias != BufferImageAlias::RenderTargetWrite)) {
|
||||
const auto next = ClassifyBufferImageWrite(vaddr, size, cached.Address(), cached.Size(),
|
||||
cached.BufferBinding(), cached.gpu_modified,
|
||||
formatted_buffer_write);
|
||||
if (match != m_images.end() || next == BufferImageWrite::None ||
|
||||
next == BufferImageWrite::Unsupported) {
|
||||
EXIT("TextureCache: unsupported GPU invalidation alias, addr=0x%016" PRIx64
|
||||
" size=0x%016" PRIx64 " cached_kind=%u cached=0x%016" PRIx64 "+0x%016" PRIx64
|
||||
" gpu_modified=%d buffer_modified=%d formatted=%d ambiguous=%d\n",
|
||||
@@ -3209,29 +3215,25 @@ bool TextureCache::InvalidateMemoryFromGPU(uint64_t vaddr, uint64_t size,
|
||||
cached.gpu_modified, cached.buffer_modified, formatted_buffer_write,
|
||||
match != m_images.end());
|
||||
}
|
||||
match = it;
|
||||
action = sampled ? BufferImageAlias::None : alias;
|
||||
sampled_write = sampled;
|
||||
match = it;
|
||||
action = next;
|
||||
}
|
||||
if (match == m_images.end()) {
|
||||
return false;
|
||||
}
|
||||
if (sampled_write) {
|
||||
(**match).buffer_modified = true;
|
||||
return true;
|
||||
auto& cached = **match;
|
||||
switch (action) {
|
||||
case BufferImageWrite::InvalidateTexture:
|
||||
case BufferImageWrite::InvalidateVideoOut: cached.buffer_modified = true; return true;
|
||||
case BufferImageWrite::SynchronizeRenderTarget:
|
||||
SynchronizeRenderTargetToBufferLocked(cached);
|
||||
return true;
|
||||
case BufferImageWrite::None:
|
||||
case BufferImageWrite::Unsupported:
|
||||
EXIT("TextureCache: invalid GPU invalidation action %u\n",
|
||||
static_cast<uint32_t>(action));
|
||||
}
|
||||
if (action == BufferImageAlias::VideoOutWrite) {
|
||||
auto& cached = **match;
|
||||
cached.buffer_modified = true;
|
||||
return true;
|
||||
}
|
||||
if (action == BufferImageAlias::RenderTargetWrite) {
|
||||
SynchronizeRenderTargetToBufferLocked(**match);
|
||||
return true;
|
||||
}
|
||||
m_memory_tracker.UntrackMemory(vaddr, size);
|
||||
m_images.erase(match);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
DepthStencilVulkanImage* TextureCache::FindDepthTargetByRange(uint64_t vaddr, uint64_t size) {
|
||||
|
||||
@@ -166,13 +166,11 @@ void Tiler::DetileStencil(GraphicContext* ctx, DepthStencilVulkanImage* image,
|
||||
}
|
||||
|
||||
void Tiler::TileImage(void* dst, const void* src, const RenderTargetInfo& info) const {
|
||||
const bool supported_element = info.bytes_per_element == 1 || info.bytes_per_element == 2 ||
|
||||
info.bytes_per_element == 4 || info.bytes_per_element == 8;
|
||||
if (dst == nullptr || src == nullptr || info.address == 0 || info.size == 0 ||
|
||||
info.width == 0 || info.height == 0 || info.pitch < info.width ||
|
||||
info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget) ||
|
||||
info.levels != 1 || info.layers == 0 || info.size % info.layers != 0 ||
|
||||
!supported_element) {
|
||||
!IsSupportedRenderTargetElementSize(info.bytes_per_element)) {
|
||||
EXIT("Tiler: unsupported render-target tile, dst=%p src=%p "
|
||||
"addr=0x%016" PRIx64 "+0x%016" PRIx64
|
||||
" extent=%ux%u pitch=%u levels=%u tile=%u bpe=%u\n",
|
||||
|
||||
@@ -26,8 +26,8 @@ std::vector<ImageBufferCopy> MakeLayeredImageBufferCopies(uint32_t layers, uint6
|
||||
uint32_t pitch, uint32_t width,
|
||||
uint32_t height,
|
||||
VkImageAspectFlags aspect) {
|
||||
if (layers == 0 || slice_size == 0 || slice_size > UINT32_MAX ||
|
||||
slice_size > UINT32_MAX / layers || pitch < width || width == 0 || height == 0) {
|
||||
if (layers == 0 || slice_size == 0 || slice_size > UINT32_MAX / layers || pitch < width ||
|
||||
width == 0 || height == 0) {
|
||||
EXIT("invalid layered image-buffer copy layout\n");
|
||||
}
|
||||
std::vector<ImageBufferCopy> regions(layers);
|
||||
|
||||
@@ -10254,7 +10254,92 @@ void CheckMetadataReuseDescriptors() {
|
||||
std::printf("[host] %-32s ok\n", "MetadataReuseDescriptors");
|
||||
}
|
||||
|
||||
void CheckBufferImageWrites() {
|
||||
constexpr uint64_t sampled = 0xe80e0000ull;
|
||||
constexpr uint64_t sampled_size = 0x870000ull;
|
||||
constexpr uint64_t video = 0x1000c10000ull;
|
||||
constexpr uint64_t video_size = 0x1fe0000ull;
|
||||
constexpr uint64_t target = 0x1158d80000ull;
|
||||
constexpr uint64_t target_size = 0x870000ull;
|
||||
struct Case {
|
||||
const char *name;
|
||||
uint64_t buffer_address;
|
||||
uint64_t buffer_size;
|
||||
uint64_t image_address;
|
||||
uint64_t image_size;
|
||||
BufferImageBinding binding;
|
||||
bool gpu_modified;
|
||||
bool formatted;
|
||||
BufferImageWrite expected;
|
||||
};
|
||||
constexpr std::array cases{
|
||||
Case{"sampled exact", sampled, sampled_size, sampled, sampled_size,
|
||||
BufferImageBinding::Texture, false, false,
|
||||
BufferImageWrite::InvalidateTexture},
|
||||
Case{"sampled partial", sampled, sampled_size - TRACKER_PAGE_SIZE,
|
||||
sampled, sampled_size, BufferImageBinding::Texture, false, false,
|
||||
BufferImageWrite::Unsupported},
|
||||
Case{"sampled unaligned", sampled + 1, sampled_size, sampled + 1,
|
||||
sampled_size, BufferImageBinding::Texture, false, false,
|
||||
BufferImageWrite::Unsupported},
|
||||
Case{"sampled GPU-owned", sampled, sampled_size, sampled, sampled_size,
|
||||
BufferImageBinding::Texture, true, false,
|
||||
BufferImageWrite::Unsupported},
|
||||
Case{"sampled disjoint", sampled, sampled_size, sampled + sampled_size,
|
||||
sampled_size, BufferImageBinding::Texture, false, false,
|
||||
BufferImageWrite::None},
|
||||
Case{"video exact", video, video_size, video, video_size,
|
||||
BufferImageBinding::VideoOut, false, true,
|
||||
BufferImageWrite::InvalidateVideoOut},
|
||||
Case{"video disjoint", video, video_size, video + video_size, video_size,
|
||||
BufferImageBinding::VideoOut, false, true, BufferImageWrite::None},
|
||||
Case{"video partial", video, video_size - 4, video, video_size,
|
||||
BufferImageBinding::VideoOut, false, true,
|
||||
BufferImageWrite::Unsupported},
|
||||
Case{"video wrong binding", video, video_size, video, video_size,
|
||||
BufferImageBinding::Unsupported, false, true,
|
||||
BufferImageWrite::Unsupported},
|
||||
Case{"video GPU-owned", video, video_size, video, video_size,
|
||||
BufferImageBinding::VideoOut, true, true,
|
||||
BufferImageWrite::Unsupported},
|
||||
Case{"video unformatted", video, video_size, video, video_size,
|
||||
BufferImageBinding::VideoOut, false, false,
|
||||
BufferImageWrite::Unsupported},
|
||||
Case{"target exact", target, target_size, target, target_size,
|
||||
BufferImageBinding::RenderTarget, true, true,
|
||||
BufferImageWrite::SynchronizeRenderTarget},
|
||||
Case{"target partial", target, target_size - 4, target, target_size,
|
||||
BufferImageBinding::RenderTarget, true, true,
|
||||
BufferImageWrite::Unsupported},
|
||||
Case{"target CPU-owned", target, target_size, target, target_size,
|
||||
BufferImageBinding::RenderTarget, false, true,
|
||||
BufferImageWrite::Unsupported},
|
||||
Case{"target unformatted", target, target_size, target, target_size,
|
||||
BufferImageBinding::RenderTarget, true, false,
|
||||
BufferImageWrite::Unsupported},
|
||||
Case{"target unaligned", target + 0x100, target_size, target + 0x100,
|
||||
target_size, BufferImageBinding::RenderTarget, true, true,
|
||||
BufferImageWrite::Unsupported},
|
||||
};
|
||||
for (const auto &test : cases) {
|
||||
const auto actual = ClassifyBufferImageWrite(
|
||||
test.buffer_address, test.buffer_size, test.image_address,
|
||||
test.image_size, test.binding, test.gpu_modified, test.formatted);
|
||||
Require("BufferImageWrite", test.name, actual == test.expected,
|
||||
"buffer/image write classification mismatch");
|
||||
}
|
||||
|
||||
TileSizeAlign storage{};
|
||||
Require("BufferImageWrite", "target layout",
|
||||
TileGetRenderTargetPitch(1920, 4) == 1920 &&
|
||||
TileGetRenderTargetSize(1920, 1080, 1920, 4, &storage) &&
|
||||
storage.align == 0x10000 && storage.size == target_size,
|
||||
"render-target write fixture has an invalid tiled layout");
|
||||
std::printf("[host] %-32s ok\n", "BufferImageWrite");
|
||||
}
|
||||
|
||||
void CheckImageOverlapResolution() {
|
||||
CheckBufferImageWrites();
|
||||
VideoOutPixelFormatInfo video_format {};
|
||||
Require("ImageOverlapResolution", "existing video-out formats",
|
||||
DecodeVideoOutPixelFormat(0x8000000022000000ull, &video_format) &&
|
||||
@@ -10393,24 +10478,6 @@ void CheckImageOverlapResolution() {
|
||||
ClassifySampledOverlap(separate_page, page_left, false, true) ==
|
||||
SampledOverlap::None,
|
||||
"sampled images on separate pages were aliased");
|
||||
constexpr uint64_t sampled_buffer_address = 0xe80e0000ull;
|
||||
constexpr uint64_t sampled_buffer_size = 0x870000ull;
|
||||
Require("ImageOverlapResolution", "sampled buffer write transition",
|
||||
IsSampledBufferWriteTransition(
|
||||
sampled_buffer_address, sampled_buffer_size,
|
||||
sampled_buffer_address, sampled_buffer_size, false),
|
||||
"exact page-aligned clean sampled image did not accept a buffer writer");
|
||||
Require("ImageOverlapResolution", "sampled buffer write guards",
|
||||
!IsSampledBufferWriteTransition(
|
||||
sampled_buffer_address, sampled_buffer_size - TRACKER_PAGE_SIZE,
|
||||
sampled_buffer_address, sampled_buffer_size, false) &&
|
||||
!IsSampledBufferWriteTransition(
|
||||
sampled_buffer_address + 1, sampled_buffer_size,
|
||||
sampled_buffer_address + 1, sampled_buffer_size, false) &&
|
||||
!IsSampledBufferWriteTransition(
|
||||
sampled_buffer_address, sampled_buffer_size,
|
||||
sampled_buffer_address, sampled_buffer_size, true),
|
||||
"partial, unaligned, or GPU-owned sampled image accepted a buffer writer");
|
||||
constexpr uint64_t edge_target_address = 0x108ad00100ull;
|
||||
constexpr uint64_t edge_target_size = 0x1fa400;
|
||||
constexpr uint64_t edge_fault_address = edge_target_address + edge_target_size + 0x1b8;
|
||||
@@ -10494,35 +10561,6 @@ void CheckImageOverlapResolution() {
|
||||
HostWriteOverlap::None,
|
||||
"host-backed fill aliased a sampled image on another page");
|
||||
|
||||
constexpr uint64_t video_address = 0x1000c10000ull;
|
||||
constexpr uint64_t video_size = 0x1fe0000ull;
|
||||
Require("ImageOverlapResolution", "formatted video-out write",
|
||||
ClassifyBufferImageAlias(video_address, video_size, video_address,
|
||||
video_size, true, false, false, true, true) ==
|
||||
BufferImageAlias::VideoOutWrite,
|
||||
"exact formatted video-out buffer write was rejected");
|
||||
Require("ImageOverlapResolution", "video-out alias guards",
|
||||
ClassifyBufferImageAlias(video_address, video_size,
|
||||
video_address + video_size, video_size, true,
|
||||
false, false, true, true) == BufferImageAlias::None &&
|
||||
ClassifyBufferImageAlias(video_address, video_size - 4,
|
||||
video_address, video_size, true, false, false,
|
||||
true, true) ==
|
||||
BufferImageAlias::Unsupported &&
|
||||
ClassifyBufferImageAlias(video_address, video_size, video_address,
|
||||
video_size, false, false, false, true, true) ==
|
||||
BufferImageAlias::Unsupported &&
|
||||
ClassifyBufferImageAlias(video_address, video_size, video_address,
|
||||
video_size, true, false, true, true, true) ==
|
||||
BufferImageAlias::Unsupported &&
|
||||
ClassifyBufferImageAlias(video_address, video_size, video_address,
|
||||
video_size, true, false, false, false, true) ==
|
||||
BufferImageAlias::Unsupported &&
|
||||
ClassifyBufferImageAlias(video_address, video_size, video_address,
|
||||
video_size, true, false, false, true, false) ==
|
||||
BufferImageAlias::Unsupported,
|
||||
"unsupported video-out buffer alias was admitted");
|
||||
|
||||
constexpr uint64_t video_metadata = 0x1020c10000ull;
|
||||
Require("ImageOverlapResolution", "video-out DCC 256/64/64",
|
||||
ClassifyVideoOutCompression(true, video_metadata, 0x208u, 0) ==
|
||||
@@ -10647,45 +10685,6 @@ void CheckImageOverlapResolution() {
|
||||
d16_depth.size),
|
||||
"partial, offset, HTile-backed, or D16 depth clear was admitted");
|
||||
|
||||
constexpr uint64_t target_buffer_address = 0x1158d80000ull;
|
||||
constexpr uint64_t target_buffer_size = 0x870000ull;
|
||||
TileSizeAlign target_storage{};
|
||||
Require("ImageOverlapResolution", "formatted render-target write",
|
||||
TileGetRenderTargetPitch(1920, 4) == 1920 &&
|
||||
TileGetRenderTargetSize(1920, 1080, 1920, 4, &target_storage) &&
|
||||
target_storage.align == 0x10000 &&
|
||||
target_storage.size == target_buffer_size &&
|
||||
ClassifyBufferImageAlias(target_buffer_address, target_buffer_size,
|
||||
target_buffer_address, target_buffer_size,
|
||||
false, true, true, true, true) ==
|
||||
BufferImageAlias::RenderTargetWrite,
|
||||
"exact GPU-owned render target was not admitted for formatted buffer synchronization");
|
||||
Require("ImageOverlapResolution", "render-target buffer alias guards",
|
||||
ClassifyBufferImageAlias(target_buffer_address,
|
||||
target_buffer_size - 4,
|
||||
target_buffer_address, target_buffer_size,
|
||||
false, true, true, true, true) ==
|
||||
BufferImageAlias::Unsupported &&
|
||||
ClassifyBufferImageAlias(target_buffer_address, target_buffer_size,
|
||||
target_buffer_address, target_buffer_size,
|
||||
false, true, false, true, true) ==
|
||||
BufferImageAlias::Unsupported &&
|
||||
ClassifyBufferImageAlias(target_buffer_address, target_buffer_size,
|
||||
target_buffer_address, target_buffer_size,
|
||||
false, true, true, false, true) ==
|
||||
BufferImageAlias::Unsupported &&
|
||||
ClassifyBufferImageAlias(target_buffer_address, target_buffer_size,
|
||||
target_buffer_address, target_buffer_size,
|
||||
false, true, true, true, false) ==
|
||||
BufferImageAlias::Unsupported &&
|
||||
ClassifyBufferImageAlias(target_buffer_address + 0x100,
|
||||
target_buffer_size,
|
||||
target_buffer_address + 0x100,
|
||||
target_buffer_size,
|
||||
false, true, true, true, true) ==
|
||||
BufferImageAlias::Unsupported,
|
||||
"unsupported render-target buffer alias was admitted");
|
||||
|
||||
RenderTargetInfo target{};
|
||||
target.address = sampled.address;
|
||||
target.size = sampled.size;
|
||||
|
||||
Reference in new issue
Block a user