mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
D3D12: Support native compressed textures
This commit is contained in:
@ -33,6 +33,42 @@ static u32 s_efb_copy_last_cbuf_id = UINT_MAX;
|
||||
static ID3D12Resource* s_texture_cache_entry_readback_buffer = nullptr;
|
||||
static size_t s_texture_cache_entry_readback_buffer_size = 0;
|
||||
|
||||
static u32 GetLevelPitch(HostTextureFormat format, u32 row_length)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case HostTextureFormat::DXT1:
|
||||
return row_length / 4 * 8;
|
||||
|
||||
case HostTextureFormat::DXT3:
|
||||
case HostTextureFormat::DXT5:
|
||||
return row_length / 4 * 16;
|
||||
|
||||
case HostTextureFormat::RGBA8:
|
||||
default:
|
||||
return row_length * 4;
|
||||
}
|
||||
}
|
||||
|
||||
static DXGI_FORMAT GetDXGIFormatForHostFormat(HostTextureFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case HostTextureFormat::DXT1:
|
||||
return DXGI_FORMAT_BC1_UNORM;
|
||||
|
||||
case HostTextureFormat::DXT3:
|
||||
return DXGI_FORMAT_BC2_UNORM;
|
||||
|
||||
case HostTextureFormat::DXT5:
|
||||
return DXGI_FORMAT_BC3_UNORM;
|
||||
|
||||
case HostTextureFormat::RGBA8:
|
||||
default:
|
||||
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
}
|
||||
}
|
||||
|
||||
TextureCache::TCacheEntry::~TCacheEntry()
|
||||
{
|
||||
m_texture->Release();
|
||||
@ -51,6 +87,11 @@ bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int l
|
||||
Common::AlignUp(level_width * sizeof(u32), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
size_t required_readback_buffer_size = level_pitch * level_height;
|
||||
|
||||
// We can't dump compressed textures currently (it would mean drawing them to a RGBA8
|
||||
// framebuffer, and saving that). TextureCache does not call Save for custom textures
|
||||
// anyway, so this is fine for now.
|
||||
_assert_(config.format == HostTextureFormat::RGBA8);
|
||||
|
||||
// Check if the current readback buffer is large enough
|
||||
if (required_readback_buffer_size > s_texture_cache_entry_readback_buffer_size)
|
||||
{
|
||||
@ -178,19 +219,20 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase*
|
||||
void TextureCache::TCacheEntry::Load(u32 level, u32 width, u32 height, u32 row_length,
|
||||
const u8* buffer, size_t buffer_size)
|
||||
{
|
||||
u32 src_pitch = 4 * row_length;
|
||||
u32 src_pitch = GetLevelPitch(config.format, row_length);
|
||||
D3D::ReplaceRGBATexture2D(m_texture->GetTex12(), buffer, width, height, src_pitch, level,
|
||||
m_texture->GetResourceUsageState());
|
||||
}
|
||||
|
||||
TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConfig& config)
|
||||
{
|
||||
DXGI_FORMAT dxgi_format = GetDXGIFormatForHostFormat(config.format);
|
||||
if (config.rendertarget)
|
||||
{
|
||||
D3DTexture2D* texture =
|
||||
D3DTexture2D::Create(config.width, config.height,
|
||||
TEXTURE_BIND_FLAG_SHADER_RESOURCE | TEXTURE_BIND_FLAG_RENDER_TARGET,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM, 1, config.layers);
|
||||
dxgi_format, 1, config.layers);
|
||||
|
||||
TCacheEntry* entry = new TCacheEntry(config, texture);
|
||||
|
||||
@ -204,8 +246,8 @@ TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntry
|
||||
{
|
||||
ID3D12Resource* texture_resource = nullptr;
|
||||
|
||||
D3D12_RESOURCE_DESC texture_resource_desc = CD3DX12_RESOURCE_DESC::Tex2D(
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM, config.width, config.height, 1, config.levels);
|
||||
D3D12_RESOURCE_DESC texture_resource_desc =
|
||||
CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, config.width, config.height, 1, config.levels);
|
||||
|
||||
CheckHR(D3D::device12->CreateCommittedResource(
|
||||
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE,
|
||||
|
Reference in New Issue
Block a user