/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2018 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ #ifndef XENIA_GPU_D3D12_TEXTURE_CACHE_H_ #define XENIA_GPU_D3D12_TEXTURE_CACHE_H_ #include "xenia/gpu/register_file.h" #include "xenia/gpu/xenos.h" #include "xenia/ui/d3d12/d3d12_api.h" namespace xe { namespace gpu { namespace d3d12 { class D3D12CommandProcessor; // Manages host copies of guest textures, performing untiling, format and endian // conversion of textures stored in the shared memory, and also handling // invalidation. // // Mipmaps are treated the following way, according to the GPU hang message // found in game executables explaining the valid usage of BaseAddress when // streaming the largest LOD (it says games should not use 0 as the base address // when the largest LOD isn't loaded, but rather, either allocate a valid // address for it or make it the same as MipAddress): // - If the texture has a base address, but no mip address, it's not mipmapped - // the host texture has only the largest level too. // - If the texture has different non-zero base address and mip address, a host // texture with mip_max_level+1 mipmaps is created - mip_min_level is ignored // and treated purely as sampler state because there are tfetch instructions // working directly with LOD values - including fetching with an explicit LOD. // However, the max level is not ignored because any mip count can be // specified when creating a texture, and another texture may be placed after // the last one. // - If the texture has a mip address, but the base address is 0 or the same as // the mip address, a mipmapped texture is created, but min/max LOD is clamped // to the lower bound of 1 - the game is expected to do that anyway until the // largest LOD is loaded. // TODO(Triang3l): Check if there are any games with BaseAddress==MipAddress // but min or max LOD being 0, especially check Modern Warfare 2/3. // TODO(Triang3l): Attach the largest LOD to existing textures with a valid // MipAddress but no BaseAddress to save memory because textures are streamed // this way anyway. class TextureCache { public: TextureCache(D3D12CommandProcessor* command_processor, RegisterFile* register_file); ~TextureCache(); void Shutdown(); void ClearCache(); void WriteTextureSRV(uint32_t fetch_constant, TextureDimension shader_dimension, D3D12_CPU_DESCRIPTOR_HANDLE handle); void WriteSampler(uint32_t fetch_constant, D3D12_CPU_DESCRIPTOR_HANDLE handle); private: D3D12CommandProcessor* command_processor_; RegisterFile* register_file_; }; } // namespace d3d12 } // namespace gpu } // namespace xe #endif // XENIA_GPU_D3D12_TEXTURE_CACHE_H_