76 lines
3.1 KiB
C++
76 lines
3.1 KiB
C++
/**
|
|
******************************************************************************
|
|
* 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_
|