From ecfa70284e8e3a7fae45f0b09881c130b270985c Mon Sep 17 00:00:00 2001 From: Triang3l Date: Sat, 22 Sep 2018 19:22:57 +0300 Subject: [PATCH] [D3D12] Treat gamma/as_16 EDRAM formats the same as their base formats --- src/xenia/gpu/d3d12/render_target_cache.cc | 20 ++++++++++++++++++-- src/xenia/gpu/d3d12/render_target_cache.h | 4 ++++ src/xenia/gpu/d3d12/texture_cache.h | 3 ++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/xenia/gpu/d3d12/render_target_cache.cc b/src/xenia/gpu/d3d12/render_target_cache.cc index 26db1bd1e..18e1f3271 100644 --- a/src/xenia/gpu/d3d12/render_target_cache.cc +++ b/src/xenia/gpu/d3d12/render_target_cache.cc @@ -437,7 +437,8 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { for (uint32_t i = 0; i < 4; ++i) { enabled[i] = (color_mask & (0xF << (i * 4))) != 0; edram_bases[i] = std::min(rb_color_info[i] & 0xFFF, 2048u); - formats[i] = (rb_color_info[i] >> 16) & 0xF; + formats[i] = uint32_t(GetBaseColorFormat( + ColorRenderTargetFormat((rb_color_info[i] >> 16) & 0xF))); formats_are_64bpp[i] = IsColorFormat64bpp(ColorRenderTargetFormat(formats[i])); } @@ -844,7 +845,8 @@ bool RenderTargetCache::Resolve(SharedMemory* shared_memory, break; } surface_edram_base = rb_color_info & 0xFFF; - surface_format = (rb_color_info >> 16) & 0xF; + surface_format = uint32_t(GetBaseColorFormat( + ColorRenderTargetFormat((rb_color_info >> 16) & 0xF))); } // Get the resolve region since both copying and clearing need it. @@ -1683,6 +1685,20 @@ void RenderTargetCache::UnbindRenderTargets() { void RenderTargetCache::EndFrame() { UnbindRenderTargets(); } +ColorRenderTargetFormat RenderTargetCache::GetBaseColorFormat( + ColorRenderTargetFormat format) { + switch (format) { + case ColorRenderTargetFormat::k_8_8_8_8_GAMMA: + return ColorRenderTargetFormat::k_8_8_8_8; + case ColorRenderTargetFormat::k_2_10_10_10_AS_16_16_16_16: + return ColorRenderTargetFormat::k_2_10_10_10; + case ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: + return ColorRenderTargetFormat::k_2_10_10_10_FLOAT; + default: + return format; + } +} + DXGI_FORMAT RenderTargetCache::GetColorDXGIFormat( ColorRenderTargetFormat format) { switch (format) { diff --git a/src/xenia/gpu/d3d12/render_target_cache.h b/src/xenia/gpu/d3d12/render_target_cache.h index 121b001db..f2846f45a 100644 --- a/src/xenia/gpu/d3d12/render_target_cache.h +++ b/src/xenia/gpu/d3d12/render_target_cache.h @@ -229,6 +229,10 @@ class RenderTargetCache { void UnbindRenderTargets(); void EndFrame(); + // Totally necessary to rely on the base format - Too Human switches between + // 2_10_10_10_FLOAT and 2_10_10_10_FLOAT_AS_16_16_16_16 every draw. + static ColorRenderTargetFormat GetBaseColorFormat( + ColorRenderTargetFormat format); static inline bool IsColorFormat64bpp(ColorRenderTargetFormat format) { return format == ColorRenderTargetFormat::k_16_16_16_16 || format == ColorRenderTargetFormat::k_16_16_16_16_FLOAT || diff --git a/src/xenia/gpu/d3d12/texture_cache.h b/src/xenia/gpu/d3d12/texture_cache.h index 1ec36477a..a4e239456 100644 --- a/src/xenia/gpu/d3d12/texture_cache.h +++ b/src/xenia/gpu/d3d12/texture_cache.h @@ -142,7 +142,8 @@ class TextureCache { TileMode tile_mode; // Uncompression info for when the regular host format for this texture is // block-compressed, but the size is not block-aligned, and thus such - // texture cannot be created in Direct3D on PC and needs decompression. + // texture cannot be created in Direct3D on PC and needs decompression, + // however, such textures are common, for instance, in Halo 3. DXGI_FORMAT dxgi_format_uncompressed; LoadMode decompress_mode; };