diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj
index 4c8d2f1b61..5af496cc9f 100644
--- a/Source/Core/Common/Common.vcxproj
+++ b/Source/Core/Common/Common.vcxproj
@@ -89,6 +89,7 @@
+
diff --git a/Source/Core/Common/Common.vcxproj.filters b/Source/Core/Common/Common.vcxproj.filters
index 10aa2c9d36..161557ddc0 100644
--- a/Source/Core/Common/Common.vcxproj.filters
+++ b/Source/Core/Common/Common.vcxproj.filters
@@ -254,6 +254,9 @@
+
+ GL\GLExtensions
+
diff --git a/Source/Core/Common/GL/GLExtensions/ARB_texture_compression_bptc.h b/Source/Core/Common/GL/GLExtensions/ARB_texture_compression_bptc.h
new file mode 100644
index 0000000000..f5c27538e2
--- /dev/null
+++ b/Source/Core/Common/GL/GLExtensions/ARB_texture_compression_bptc.h
@@ -0,0 +1,29 @@
+/*
+** Copyright (c) 2013-2015 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#include "Common/GL/GLExtensions/gl_common.h"
+
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
diff --git a/Source/Core/Common/GL/GLExtensions/GLExtensions.h b/Source/Core/Common/GL/GLExtensions/GLExtensions.h
index 7745d78e60..2c0364da48 100644
--- a/Source/Core/Common/GL/GLExtensions/GLExtensions.h
+++ b/Source/Core/Common/GL/GLExtensions/GLExtensions.h
@@ -25,6 +25,7 @@
#include "Common/GL/GLExtensions/ARB_shader_image_load_store.h"
#include "Common/GL/GLExtensions/ARB_shader_storage_buffer_object.h"
#include "Common/GL/GLExtensions/ARB_sync.h"
+#include "Common/GL/GLExtensions/ARB_texture_compression_bptc.h"
#include "Common/GL/GLExtensions/ARB_texture_multisample.h"
#include "Common/GL/GLExtensions/ARB_texture_storage.h"
#include "Common/GL/GLExtensions/ARB_texture_storage_multisample.h"
diff --git a/Source/Core/VideoBackends/D3D/D3DBase.cpp b/Source/Core/VideoBackends/D3D/D3DBase.cpp
index cab8c628e6..4bcd81bac9 100644
--- a/Source/Core/VideoBackends/D3D/D3DBase.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DBase.cpp
@@ -239,6 +239,16 @@ static bool SupportsS3TCTextures(ID3D11Device* dev)
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)
{
hWnd = wnd;
@@ -420,6 +430,7 @@ HRESULT Create(HWND wnd)
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);
+ g_Config.backend_info.bSupportsBPTCTextures = SupportsBPTCTextures(device);
stateman = new StateManager;
return S_OK;
diff --git a/Source/Core/VideoBackends/D3D/DXTexture.cpp b/Source/Core/VideoBackends/D3D/DXTexture.cpp
index 765438d679..c8c5ef6105 100644
--- a/Source/Core/VideoBackends/D3D/DXTexture.cpp
+++ b/Source/Core/VideoBackends/D3D/DXTexture.cpp
@@ -37,6 +37,8 @@ DXGI_FORMAT GetDXGIFormatForHostFormat(AbstractTextureFormat format)
return DXGI_FORMAT_BC2_UNORM;
case AbstractTextureFormat::DXT5:
return DXGI_FORMAT_BC3_UNORM;
+ case AbstractTextureFormat::BPTC:
+ return DXGI_FORMAT_BC7_UNORM;
case AbstractTextureFormat::RGBA8:
default:
return DXGI_FORMAT_R8G8B8A8_UNORM;
diff --git a/Source/Core/VideoBackends/D3D/main.cpp b/Source/Core/VideoBackends/D3D/main.cpp
index ffa15a601c..791bced398 100644
--- a/Source/Core/VideoBackends/D3D/main.cpp
+++ b/Source/Core/VideoBackends/D3D/main.cpp
@@ -80,6 +80,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsST3CTextures = false;
g_Config.backend_info.bSupportsBitfield = false;
g_Config.backend_info.bSupportsDynamicSamplerIndexing = false;
+ g_Config.backend_info.bSupportsBPTCTextures = false;
IDXGIFactory* factory;
IDXGIAdapter* ad;
diff --git a/Source/Core/VideoBackends/Null/NullBackend.cpp b/Source/Core/VideoBackends/Null/NullBackend.cpp
index bcbbd1aaab..2a52fe7172 100644
--- a/Source/Core/VideoBackends/Null/NullBackend.cpp
+++ b/Source/Core/VideoBackends/Null/NullBackend.cpp
@@ -46,6 +46,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsInternalResolutionFrameDumps = false;
g_Config.backend_info.bSupportsGPUTextureDecoding = false;
g_Config.backend_info.bSupportsST3CTextures = false;
+ g_Config.backend_info.bSupportsBPTCTextures = false;
// aamodes: We only support 1 sample, so no MSAA
g_Config.backend_info.Adapters.clear();
diff --git a/Source/Core/VideoBackends/OGL/OGLTexture.cpp b/Source/Core/VideoBackends/OGL/OGLTexture.cpp
index 242e19888e..8569e9b8b0 100644
--- a/Source/Core/VideoBackends/OGL/OGLTexture.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLTexture.cpp
@@ -33,6 +33,8 @@ GLenum GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool st
return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
case AbstractTextureFormat::DXT5:
return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+ case AbstractTextureFormat::BPTC:
+ return GL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
case AbstractTextureFormat::RGBA8:
default:
return storage ? GL_RGBA8 : GL_RGBA;
diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp
index b8a14869d0..8d02053fcc 100644
--- a/Source/Core/VideoBackends/OGL/Render.cpp
+++ b/Source/Core/VideoBackends/OGL/Render.cpp
@@ -477,6 +477,8 @@ Renderer::Renderer()
g_Config.backend_info.bSupportsComputeShaders = GLExtensions::Supports("GL_ARB_compute_shader");
g_Config.backend_info.bSupportsST3CTextures =
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)
{
diff --git a/Source/Core/VideoBackends/OGL/main.cpp b/Source/Core/VideoBackends/OGL/main.cpp
index c00782ee70..4b3a7a5daf 100644
--- a/Source/Core/VideoBackends/OGL/main.cpp
+++ b/Source/Core/VideoBackends/OGL/main.cpp
@@ -104,6 +104,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsClipControl = true;
g_Config.backend_info.bSupportsDepthClamp = true;
g_Config.backend_info.bSupportsST3CTextures = false;
+ g_Config.backend_info.bSupportsBPTCTextures = false;
g_Config.backend_info.Adapters.clear();
diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp
index 9c822ca34c..910de9697d 100644
--- a/Source/Core/VideoBackends/Software/SWmain.cpp
+++ b/Source/Core/VideoBackends/Software/SWmain.cpp
@@ -121,6 +121,7 @@ void VideoSoftware::InitBackendInfo()
g_Config.backend_info.bSupportsInternalResolutionFrameDumps = false;
g_Config.backend_info.bSupportsGPUTextureDecoding = false;
g_Config.backend_info.bSupportsST3CTextures = false;
+ g_Config.backend_info.bSupportsBPTCTextures = false;
// aamodes
g_Config.backend_info.AAModes = {1};
diff --git a/Source/Core/VideoBackends/Vulkan/Util.cpp b/Source/Core/VideoBackends/Vulkan/Util.cpp
index fc5b2ec8dc..e377bb32cf 100644
--- a/Source/Core/VideoBackends/Vulkan/Util.cpp
+++ b/Source/Core/VideoBackends/Vulkan/Util.cpp
@@ -61,6 +61,7 @@ bool IsCompressedFormat(VkFormat format)
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
case VK_FORMAT_BC2_UNORM_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK:
+ case VK_FORMAT_BC7_UNORM_BLOCK:
return true;
default:
@@ -102,6 +103,9 @@ VkFormat GetVkFormatForHostTextureFormat(AbstractTextureFormat format)
case AbstractTextureFormat::DXT5:
return VK_FORMAT_BC3_UNORM_BLOCK;
+ case AbstractTextureFormat::BPTC:
+ return VK_FORMAT_BC7_UNORM_BLOCK;
+
case AbstractTextureFormat::RGBA8:
default:
return VK_FORMAT_R8G8B8A8_UNORM;
@@ -130,6 +134,7 @@ u32 GetTexelSize(VkFormat format)
case VK_FORMAT_BC2_UNORM_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK:
+ case VK_FORMAT_BC7_UNORM_BLOCK:
return 16;
default:
@@ -145,6 +150,7 @@ u32 GetBlockSize(VkFormat format)
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
case VK_FORMAT_BC2_UNORM_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK:
+ case VK_FORMAT_BC7_UNORM_BLOCK:
return 4;
default:
diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
index af9e249833..8bb7a5088e 100644
--- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
@@ -248,6 +248,7 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config)
config->backend_info.bSupportsSSAA = false; // Dependent on features.
config->backend_info.bSupportsDepthClamp = 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.
}
@@ -287,7 +288,9 @@ void VulkanContext::PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalD
(features.depthClamp == VK_TRUE && features.shaderClipDistance == VK_TRUE);
// 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.
// Seems to be fine on GCN Gen 1-2, unconfirmed on GCN Gen 3, causes driver resets on GCN Gen 4.
diff --git a/Source/Core/VideoCommon/AbstractTexture.cpp b/Source/Core/VideoCommon/AbstractTexture.cpp
index b756651640..18f9c72064 100644
--- a/Source/Core/VideoCommon/AbstractTexture.cpp
+++ b/Source/Core/VideoCommon/AbstractTexture.cpp
@@ -31,6 +31,7 @@ size_t AbstractTexture::CalculateHostTextureLevelPitch(AbstractTextureFormat for
return static_cast(std::max(1u, row_length / 4)) * 8;
case AbstractTextureFormat::DXT3:
case AbstractTextureFormat::DXT5:
+ case AbstractTextureFormat::BPTC:
return static_cast(std::max(1u, row_length / 4)) * 16;
case AbstractTextureFormat::RGBA8:
default:
diff --git a/Source/Core/VideoCommon/HiresTextures_DDSLoader.cpp b/Source/Core/VideoCommon/HiresTextures_DDSLoader.cpp
index 5b9bbeced9..003a59664f 100644
--- a/Source/Core/VideoCommon/HiresTextures_DDSLoader.cpp
+++ b/Source/Core/VideoCommon/HiresTextures_DDSLoader.cpp
@@ -319,6 +319,14 @@ bool ParseDDSHeader(File::IOFile& file, DDSLoadInfo* info)
info->bytes_per_block = 16;
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
{
// Leave all remaining formats to SOIL.
diff --git a/Source/Core/VideoCommon/TextureConfig.h b/Source/Core/VideoCommon/TextureConfig.h
index 27a0c935a1..7a9ac08bcc 100644
--- a/Source/Core/VideoCommon/TextureConfig.h
+++ b/Source/Core/VideoCommon/TextureConfig.h
@@ -15,7 +15,8 @@ enum class AbstractTextureFormat : u32
RGBA8,
DXT1,
DXT3,
- DXT5
+ DXT5,
+ BPTC
};
struct TextureConfig
diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp
index e643937764..9caab54603 100644
--- a/Source/Core/VideoCommon/VideoConfig.cpp
+++ b/Source/Core/VideoCommon/VideoConfig.cpp
@@ -38,6 +38,7 @@ VideoConfig::VideoConfig()
backend_info.bSupportsMultithreading = false;
backend_info.bSupportsInternalResolutionFrameDumps = false;
backend_info.bSupportsST3CTextures = false;
+ backend_info.bSupportsBPTCTextures = false;
bEnableValidationLayer = false;
bBackendMultithreading = true;
diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h
index b7044d9cf8..499ab1c88a 100644
--- a/Source/Core/VideoCommon/VideoConfig.h
+++ b/Source/Core/VideoCommon/VideoConfig.h
@@ -232,6 +232,7 @@ struct VideoConfig final
bool bSupportsST3CTextures;
bool bSupportsBitfield; // Needed by UberShaders, so must stay in VideoCommon
bool bSupportsDynamicSamplerIndexing; // Needed by UberShaders, so must stay in VideoCommon
+ bool bSupportsBPTCTextures;
} backend_info;
// Utility