HiresTextures: Support loading BC7 (BPTC) from DDS files

This commit is contained in:
Stenzek 2017-07-27 22:00:04 +10:00
parent d18988f41e
commit 63305e9173
15 changed files with 44 additions and 2 deletions

View File

@ -239,6 +239,16 @@ static bool SupportsS3TCTextures(ID3D11Device* dev)
return ((bc1_support & bc2_support & bc3_support) & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0; return ((bc1_support & bc2_support & bc3_support) & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
} }
static bool SupportsBPTCTextures(ID3D11Device* dev)
{
// Currently, we only care about BC7. This could be extended to BC6H in the future.
UINT bc7_support;
if (FAILED(dev->CheckFormatSupport(DXGI_FORMAT_BC7_UNORM, &bc7_support)))
return false;
return (bc7_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
}
HRESULT Create(HWND wnd) HRESULT Create(HWND wnd)
{ {
hWnd = wnd; hWnd = wnd;
@ -420,6 +430,7 @@ HRESULT Create(HWND wnd)
device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support); device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support);
bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0; bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
g_Config.backend_info.bSupportsST3CTextures = SupportsS3TCTextures(device); g_Config.backend_info.bSupportsST3CTextures = SupportsS3TCTextures(device);
g_Config.backend_info.bSupportsBPTCTextures = SupportsBPTCTextures(device);
stateman = new StateManager; stateman = new StateManager;
return S_OK; return S_OK;

View File

@ -37,6 +37,8 @@ DXGI_FORMAT GetDXGIFormatForHostFormat(AbstractTextureFormat format)
return DXGI_FORMAT_BC2_UNORM; return DXGI_FORMAT_BC2_UNORM;
case AbstractTextureFormat::DXT5: case AbstractTextureFormat::DXT5:
return DXGI_FORMAT_BC3_UNORM; return DXGI_FORMAT_BC3_UNORM;
case AbstractTextureFormat::BPTC:
return DXGI_FORMAT_BC7_UNORM;
case AbstractTextureFormat::RGBA8: case AbstractTextureFormat::RGBA8:
default: default:
return DXGI_FORMAT_R8G8B8A8_UNORM; return DXGI_FORMAT_R8G8B8A8_UNORM;

View File

@ -80,6 +80,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsST3CTextures = false; g_Config.backend_info.bSupportsST3CTextures = false;
g_Config.backend_info.bSupportsBitfield = false; g_Config.backend_info.bSupportsBitfield = false;
g_Config.backend_info.bSupportsDynamicSamplerIndexing = false; g_Config.backend_info.bSupportsDynamicSamplerIndexing = false;
g_Config.backend_info.bSupportsBPTCTextures = false;
IDXGIFactory* factory; IDXGIFactory* factory;
IDXGIAdapter* ad; IDXGIAdapter* ad;

View File

@ -46,6 +46,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsInternalResolutionFrameDumps = false; g_Config.backend_info.bSupportsInternalResolutionFrameDumps = false;
g_Config.backend_info.bSupportsGPUTextureDecoding = false; g_Config.backend_info.bSupportsGPUTextureDecoding = false;
g_Config.backend_info.bSupportsST3CTextures = false; g_Config.backend_info.bSupportsST3CTextures = false;
g_Config.backend_info.bSupportsBPTCTextures = false;
// aamodes: We only support 1 sample, so no MSAA // aamodes: We only support 1 sample, so no MSAA
g_Config.backend_info.Adapters.clear(); g_Config.backend_info.Adapters.clear();

View File

@ -33,6 +33,8 @@ GLenum GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool st
return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
case AbstractTextureFormat::DXT5: case AbstractTextureFormat::DXT5:
return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
case AbstractTextureFormat::BPTC:
return GL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
case AbstractTextureFormat::RGBA8: case AbstractTextureFormat::RGBA8:
default: default:
return storage ? GL_RGBA8 : GL_RGBA; return storage ? GL_RGBA8 : GL_RGBA;

View File

@ -477,6 +477,8 @@ Renderer::Renderer()
g_Config.backend_info.bSupportsComputeShaders = GLExtensions::Supports("GL_ARB_compute_shader"); g_Config.backend_info.bSupportsComputeShaders = GLExtensions::Supports("GL_ARB_compute_shader");
g_Config.backend_info.bSupportsST3CTextures = g_Config.backend_info.bSupportsST3CTextures =
GLExtensions::Supports("GL_EXT_texture_compression_s3tc"); GLExtensions::Supports("GL_EXT_texture_compression_s3tc");
g_Config.backend_info.bSupportsBPTCTextures =
GLExtensions::Supports("GL_ARB_texture_compression_bptc");
if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGLES3) if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGLES3)
{ {

View File

@ -104,6 +104,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsClipControl = true; g_Config.backend_info.bSupportsClipControl = true;
g_Config.backend_info.bSupportsDepthClamp = true; g_Config.backend_info.bSupportsDepthClamp = true;
g_Config.backend_info.bSupportsST3CTextures = false; g_Config.backend_info.bSupportsST3CTextures = false;
g_Config.backend_info.bSupportsBPTCTextures = false;
g_Config.backend_info.Adapters.clear(); g_Config.backend_info.Adapters.clear();

View File

@ -121,6 +121,7 @@ void VideoSoftware::InitBackendInfo()
g_Config.backend_info.bSupportsInternalResolutionFrameDumps = false; g_Config.backend_info.bSupportsInternalResolutionFrameDumps = false;
g_Config.backend_info.bSupportsGPUTextureDecoding = false; g_Config.backend_info.bSupportsGPUTextureDecoding = false;
g_Config.backend_info.bSupportsST3CTextures = false; g_Config.backend_info.bSupportsST3CTextures = false;
g_Config.backend_info.bSupportsBPTCTextures = false;
// aamodes // aamodes
g_Config.backend_info.AAModes = {1}; g_Config.backend_info.AAModes = {1};

View File

@ -61,6 +61,7 @@ bool IsCompressedFormat(VkFormat format)
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
case VK_FORMAT_BC2_UNORM_BLOCK: case VK_FORMAT_BC2_UNORM_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK: case VK_FORMAT_BC3_UNORM_BLOCK:
case VK_FORMAT_BC7_UNORM_BLOCK:
return true; return true;
default: default:
@ -102,6 +103,9 @@ VkFormat GetVkFormatForHostTextureFormat(AbstractTextureFormat format)
case AbstractTextureFormat::DXT5: case AbstractTextureFormat::DXT5:
return VK_FORMAT_BC3_UNORM_BLOCK; return VK_FORMAT_BC3_UNORM_BLOCK;
case AbstractTextureFormat::BPTC:
return VK_FORMAT_BC7_UNORM_BLOCK;
case AbstractTextureFormat::RGBA8: case AbstractTextureFormat::RGBA8:
default: default:
return VK_FORMAT_R8G8B8A8_UNORM; return VK_FORMAT_R8G8B8A8_UNORM;
@ -130,6 +134,7 @@ u32 GetTexelSize(VkFormat format)
case VK_FORMAT_BC2_UNORM_BLOCK: case VK_FORMAT_BC2_UNORM_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK: case VK_FORMAT_BC3_UNORM_BLOCK:
case VK_FORMAT_BC7_UNORM_BLOCK:
return 16; return 16;
default: default:
@ -145,6 +150,7 @@ u32 GetBlockSize(VkFormat format)
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
case VK_FORMAT_BC2_UNORM_BLOCK: case VK_FORMAT_BC2_UNORM_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK: case VK_FORMAT_BC3_UNORM_BLOCK:
case VK_FORMAT_BC7_UNORM_BLOCK:
return 4; return 4;
default: default:

View File

@ -248,6 +248,7 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config)
config->backend_info.bSupportsSSAA = false; // Dependent on features. config->backend_info.bSupportsSSAA = false; // Dependent on features.
config->backend_info.bSupportsDepthClamp = false; // Dependent on features. config->backend_info.bSupportsDepthClamp = false; // Dependent on features.
config->backend_info.bSupportsST3CTextures = false; // Dependent on features. config->backend_info.bSupportsST3CTextures = false; // Dependent on features.
config->backend_info.bSupportsBPTCTextures = false; // Dependent on features.
config->backend_info.bSupportsReversedDepthRange = false; // No support yet due to driver bugs. config->backend_info.bSupportsReversedDepthRange = false; // No support yet due to driver bugs.
} }
@ -287,7 +288,9 @@ void VulkanContext::PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalD
(features.depthClamp == VK_TRUE && features.shaderClipDistance == VK_TRUE); (features.depthClamp == VK_TRUE && features.shaderClipDistance == VK_TRUE);
// textureCompressionBC implies BC1 through BC7, which is a superset of DXT1/3/5, which we need. // textureCompressionBC implies BC1 through BC7, which is a superset of DXT1/3/5, which we need.
config->backend_info.bSupportsST3CTextures = features.textureCompressionBC == VK_TRUE; const bool supports_bc = features.textureCompressionBC == VK_TRUE;
config->backend_info.bSupportsST3CTextures = supports_bc;
config->backend_info.bSupportsBPTCTextures = supports_bc;
// Our usage of primitive restart appears to be broken on AMD's binary drivers. // Our usage of primitive restart appears to be broken on AMD's binary drivers.
// Seems to be fine on GCN Gen 1-2, unconfirmed on GCN Gen 3, causes driver resets on GCN Gen 4. // Seems to be fine on GCN Gen 1-2, unconfirmed on GCN Gen 3, causes driver resets on GCN Gen 4.

View File

@ -31,6 +31,7 @@ size_t AbstractTexture::CalculateHostTextureLevelPitch(AbstractTextureFormat for
return static_cast<size_t>(std::max(1u, row_length / 4)) * 8; return static_cast<size_t>(std::max(1u, row_length / 4)) * 8;
case AbstractTextureFormat::DXT3: case AbstractTextureFormat::DXT3:
case AbstractTextureFormat::DXT5: case AbstractTextureFormat::DXT5:
case AbstractTextureFormat::BPTC:
return static_cast<size_t>(std::max(1u, row_length / 4)) * 16; return static_cast<size_t>(std::max(1u, row_length / 4)) * 16;
case AbstractTextureFormat::RGBA8: case AbstractTextureFormat::RGBA8:
default: default:

View File

@ -319,6 +319,14 @@ bool ParseDDSHeader(File::IOFile& file, DDSLoadInfo* info)
info->bytes_per_block = 16; info->bytes_per_block = 16;
needs_s3tc = true; needs_s3tc = true;
} }
else if (dxt10_format == 98)
{
info->format = AbstractTextureFormat::BPTC;
info->block_size = 4;
info->bytes_per_block = 16;
if (!g_ActiveConfig.backend_info.bSupportsBPTCTextures)
return false;
}
else else
{ {
// Leave all remaining formats to SOIL. // Leave all remaining formats to SOIL.

View File

@ -15,7 +15,8 @@ enum class AbstractTextureFormat : u32
RGBA8, RGBA8,
DXT1, DXT1,
DXT3, DXT3,
DXT5 DXT5,
BPTC
}; };
struct TextureConfig struct TextureConfig

View File

@ -38,6 +38,7 @@ VideoConfig::VideoConfig()
backend_info.bSupportsMultithreading = false; backend_info.bSupportsMultithreading = false;
backend_info.bSupportsInternalResolutionFrameDumps = false; backend_info.bSupportsInternalResolutionFrameDumps = false;
backend_info.bSupportsST3CTextures = false; backend_info.bSupportsST3CTextures = false;
backend_info.bSupportsBPTCTextures = false;
bEnableValidationLayer = false; bEnableValidationLayer = false;
bBackendMultithreading = true; bBackendMultithreading = true;

View File

@ -236,6 +236,7 @@ struct VideoConfig final
bool bSupportsST3CTextures; bool bSupportsST3CTextures;
bool bSupportsBitfield; // Needed by UberShaders, so must stay in VideoCommon bool bSupportsBitfield; // Needed by UberShaders, so must stay in VideoCommon
bool bSupportsDynamicSamplerIndexing; // Needed by UberShaders, so must stay in VideoCommon bool bSupportsDynamicSamplerIndexing; // Needed by UberShaders, so must stay in VideoCommon
bool bSupportsBPTCTextures;
} backend_info; } backend_info;
// Utility // Utility