D3D11: Support native compressed textures

This commit is contained in:
Stenzek 2017-04-16 20:47:17 +10:00
parent f5d95dcc86
commit 2d75c2ab10
2 changed files with 64 additions and 7 deletions

View File

@ -239,6 +239,19 @@ D3D_FEATURE_LEVEL GetFeatureLevel(IDXGIAdapter* adapter)
return feat_level;
}
static bool SupportsS3TCTextures(ID3D11Device* device)
{
UINT bc1_support, bc2_support, bc3_support;
if (FAILED(device->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &bc1_support)) ||
FAILED(device->CheckFormatSupport(DXGI_FORMAT_BC2_UNORM, &bc2_support)) ||
FAILED(device->CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &bc3_support)))
{
return false;
}
return ((bc1_support & bc2_support & bc3_support) & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
}
HRESULT Create(HWND wnd)
{
hWnd = wnd;
@ -427,6 +440,7 @@ HRESULT Create(HWND wnd)
UINT format_support;
device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support);
bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
g_Config.backend_info.bSupportsST3CTextures = SupportsS3TCTextures(device);
stateman = new StateManager;
return S_OK;

View File

@ -7,6 +7,7 @@
#include <algorithm>
#include <memory>
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
@ -29,6 +30,42 @@ static std::unique_ptr<PSTextureEncoder> g_encoder;
const size_t MAX_COPY_BUFFERS = 32;
ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = {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()
{
texture->Release();
@ -41,6 +78,11 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage)
bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int level)
{
// 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);
// Create a staging/readback texture with the dimensions of the specified mip level.
u32 mip_width = std::max(config.width >> level, 1u);
u32 mip_height = std::max(config.height >> level, 1u);
@ -132,25 +174,26 @@ 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 = row_length * 4;
u32 src_pitch = GetLevelPitch(config.format, row_length);
D3D::context->UpdateSubresource(texture->GetTex(), level, nullptr, buffer, src_pitch, 0);
}
TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConfig& config)
{
DXGI_FORMAT dxgi_format = GetDXGIFormatForHostFormat(config.format);
if (config.rendertarget)
{
return new TCacheEntry(
config, D3DTexture2D::Create(
config.width, config.height, (D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET |
(int)D3D11_BIND_SHADER_RESOURCE),
D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM, 1, config.layers));
config, D3DTexture2D::Create(config.width, config.height,
(D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET |
(int)D3D11_BIND_SHADER_RESOURCE),
D3D11_USAGE_DEFAULT, dxgi_format, 1, config.layers));
}
else
{
const D3D11_TEXTURE2D_DESC texdesc =
CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, config.width, config.height, 1,
config.levels, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0);
CD3D11_TEXTURE2D_DESC(dxgi_format, config.width, config.height, 1, config.levels,
D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0);
ID3D11Texture2D* pTexture;
const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &pTexture);