diff options
| author | Stenzek <stenzek@users.noreply.github.com> | 2017-04-30 00:44:06 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-04-30 00:44:06 +1000 |
| commit | a2cba6d72f049e86460491c875353584e167d613 (patch) | |
| tree | 91f077a0bb9cd269f73937f843a4922f5812dcc9 /Source/Core/VideoBackends/OGL/TextureCache.cpp | |
| parent | da880c2a987e6553bec34a7a23ca6aff46bbede7 (diff) | |
| parent | cc851c41c11bdc1c192003021df6dc3c2d2b74fb (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.cpp | 94 |
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(); |
