From a96b5111e68ecae4266fe8997007e68af681c596 Mon Sep 17 00:00:00 2001 From: nmzik Date: Thu, 16 Jul 2026 22:42:06 +0200 Subject: [PATCH] Refactor buffer image write classification --- src/graphics/host_gpu/renderer/imageInfo.h | 66 ++++--- .../host_gpu/renderer/textureCache.cpp | 90 ++++----- src/graphics/host_gpu/renderer/tiler.cpp | 4 +- src/graphics/host_gpu/utils.cpp | 4 +- tests/ShaderRecompilerComputeTests.cpp | 171 +++++++++--------- 5 files changed, 172 insertions(+), 163 deletions(-) diff --git a/src/graphics/host_gpu/renderer/imageInfo.h b/src/graphics/host_gpu/renderer/imageInfo.h index 65a998881..d347df43a 100644 --- a/src/graphics/host_gpu/renderer/imageInfo.h +++ b/src/graphics/host_gpu/renderer/imageInfo.h @@ -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, diff --git a/src/graphics/host_gpu/renderer/textureCache.cpp b/src/graphics/host_gpu/renderer/textureCache.cpp index 9d9b9d89b..f709679fd 100644 --- a/src/graphics/host_gpu/renderer/textureCache.cpp +++ b/src/graphics/host_gpu/renderer/textureCache.cpp @@ -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(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) { diff --git a/src/graphics/host_gpu/renderer/tiler.cpp b/src/graphics/host_gpu/renderer/tiler.cpp index 5284efc4c..b9fdef0d2 100644 --- a/src/graphics/host_gpu/renderer/tiler.cpp +++ b/src/graphics/host_gpu/renderer/tiler.cpp @@ -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", diff --git a/src/graphics/host_gpu/utils.cpp b/src/graphics/host_gpu/utils.cpp index 1a95ea632..9c6f7267f 100644 --- a/src/graphics/host_gpu/utils.cpp +++ b/src/graphics/host_gpu/utils.cpp @@ -26,8 +26,8 @@ std::vector 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 regions(layers); diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 34d324ecc..678634bde 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -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;