summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/TextureCache.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@users.noreply.github.com>2017-04-30 00:44:06 +1000
committerGitHub <noreply@github.com>2017-04-30 00:44:06 +1000
commita2cba6d72f049e86460491c875353584e167d613 (patch)
tree91f077a0bb9cd269f73937f843a4922f5812dcc9 /Source/Core/VideoBackends/OGL/TextureCache.cpp
parentda880c2a987e6553bec34a7a23ca6aff46bbede7 (diff)
parentcc851c41c11bdc1c192003021df6dc3c2d2b74fb (diff)
Merge pull request #5279 from stenzek/compressed-custom-textures
Native compressed custom texture support
Diffstat (limited to 'Source/Core/VideoBackends/OGL/TextureCache.cpp')
-rw-r--r--Source/Core/VideoBackends/OGL/TextureCache.cpp94
1 files changed, 82 insertions, 12 deletions
diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp
index 3bf1342809..2031d7e220 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,48 @@ bool SaveTexture(const std::string& filename, u32 textarget, u32 tex, int virtua
return TextureToPng(data.data(), width * 4, filename, width, height, true);
}
+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 +172,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 +191,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_(!IsCompressedHostTextureFormat(config.format));
if (!g_ogl_config.bSupportsTextureStorage)
{
for (u32 level = 0; level < config.levels; level++)
@@ -202,8 +253,8 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase*
g_renderer->RestoreAPIState();
}
-void TextureCache::TCacheEntry::Load(const u8* buffer, u32 width, u32 height, u32 expanded_width,
- u32 level)
+void TextureCache::TCacheEntry::Load(u32 level, u32 width, u32 height, u32 row_length,
+ const u8* buffer, size_t buffer_size)
{
if (level >= config.levels)
PanicAlert("Texture only has %d levels, can't update level %d", config.levels, level);
@@ -216,21 +267,40 @@ void TextureCache::TCacheEntry::Load(const u8* buffer, u32 width, u32 height, u3
glActiveTexture(GL_TEXTURE9);
glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
- if (expanded_width != width)
- glPixelStorei(GL_UNPACK_ROW_LENGTH, expanded_width);
+ 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 (IsCompressedHostTextureFormat(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 (expanded_width != width)
+ if (row_length != width)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
TextureCache::SetStage();