summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/TextureCache.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2017-04-16 20:34:02 +1000
committerStenzek <stenzek@gmail.com>2017-04-29 00:44:34 +1000
commitf5d95dcc861031dac4de98d95117afe1c43b166c (patch)
treeece38c0490ba5456512463fc4ba3136170c63907 /Source/Core/VideoBackends/OGL/TextureCache.cpp
parent12bde06dc32be06493738ff1eabdc4b6d0783594 (diff)
OGL: Use native compressed textures on supported drivers
Diffstat (limited to 'Source/Core/VideoBackends/OGL/TextureCache.cpp')
-rw-r--r--Source/Core/VideoBackends/OGL/TextureCache.cpp89
1 files changed, 82 insertions, 7 deletions
diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp
index e49483a593..05261f1d33 100644
--- a/Source/Core/VideoBackends/OGL/TextureCache.cpp
+++ b/Source/Core/VideoBackends/OGL/TextureCache.cpp
@@ -11,6 +11,7 @@
#include <memory>
#include <vector>
+#include "Common/Assert.h"
#include "Common/GL/GLInterfaceBase.h"
#include "Common/MsgHandler.h"
#include "Common/StringUtil.h"
@@ -87,6 +88,53 @@ bool SaveTexture(const std::string& filename, u32 textarget, u32 tex, int virtua
return TextureToPng(data.data(), width * 4, filename, width, height, true);
}
+static bool IsCompressedTextureFormat(HostTextureFormat format)
+{
+ return format >= HostTextureFormat::DXT1 && format <= HostTextureFormat::DXT5;
+}
+
+static GLenum GetGLInternalFormatForTextureFormat(HostTextureFormat format, bool storage)
+{
+ switch (format)
+ {
+ case HostTextureFormat::DXT1:
+ return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ case HostTextureFormat::DXT3:
+ return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ case HostTextureFormat::DXT5:
+ return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+ case HostTextureFormat::RGBA8:
+ default:
+ return storage ? GL_RGBA8 : GL_RGBA;
+ }
+}
+
+static GLenum GetGLFormatForTextureFormat(HostTextureFormat format)
+{
+ switch (format)
+ {
+ case HostTextureFormat::RGBA8:
+ return GL_RGBA;
+
+ // Compressed texture formats don't use this parameter.
+ default:
+ return GL_UNSIGNED_BYTE;
+ }
+}
+
+static GLenum GetGLTypeForTextureFormat(HostTextureFormat format)
+{
+ switch (format)
+ {
+ case HostTextureFormat::RGBA8:
+ return GL_UNSIGNED_BYTE;
+
+ // Compressed texture formats don't use this parameter.
+ default:
+ return GL_UNSIGNED_BYTE;
+ }
+}
+
TextureCache::TCacheEntry::~TCacheEntry()
{
if (texture)
@@ -129,6 +177,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);
+
return SaveTexture(filename, GL_TEXTURE_2D_ARRAY, texture, config.width, config.height, level);
}
@@ -143,12 +196,15 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConf
if (g_ogl_config.bSupportsTextureStorage)
{
- glTexStorage3D(GL_TEXTURE_2D_ARRAY, config.levels, GL_RGBA8, config.width, config.height,
- config.layers);
+ GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(config.format, true);
+ glTexStorage3D(GL_TEXTURE_2D_ARRAY, config.levels, gl_internal_format, config.width,
+ config.height, config.layers);
}
if (config.rendertarget)
{
+ // We can't render to compressed formats.
+ _assert_(!IsCompressedTextureFormat(config.format));
if (!g_ogl_config.bSupportsTextureStorage)
{
for (u32 level = 0; level < config.levels; level++)
@@ -219,15 +275,34 @@ void TextureCache::TCacheEntry::Load(u32 level, u32 width, u32 height, u32 row_l
if (row_length != width)
glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
- if (g_ogl_config.bSupportsTextureStorage)
+ GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(config.format, false);
+ if (IsCompressedTextureFormat(config.format))
{
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, 0, width, height, 1, GL_RGBA,
- GL_UNSIGNED_BYTE, buffer);
+ if (g_ogl_config.bSupportsTextureStorage)
+ {
+ glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, 0, width, height, 1,
+ gl_internal_format, static_cast<GLsizei>(buffer_size), buffer);
+ }
+ else
+ {
+ glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, level, gl_internal_format, width, height, 1, 0,
+ static_cast<GLsizei>(buffer_size), buffer);
+ }
}
else
{
- glTexImage3D(GL_TEXTURE_2D_ARRAY, level, GL_RGBA, width, height, 1, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, buffer);
+ GLenum gl_format = GetGLFormatForTextureFormat(config.format);
+ GLenum gl_type = GetGLTypeForTextureFormat(config.format);
+ if (g_ogl_config.bSupportsTextureStorage)
+ {
+ glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, 0, width, height, 1, gl_format, gl_type,
+ buffer);
+ }
+ else
+ {
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, level, gl_internal_format, width, height, 1, 0, gl_format,
+ gl_type, buffer);
+ }
}
if (row_length != width)