Support BGRA texture by remapping the internal format to RGBA.
The format is still passed as BGRA to the driver so that the data can be
properly unpacked.
BUG=angleproject:884
Change-Id: I767626c818ce1a3c5a4739f07aa623bf8a9ae377
Reviewed-on: https://chromium-review.googlesource.com/273162
Reviewed-by: Brandon Jones <bajones@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/gl/RenderbufferGL.cpp b/src/libANGLE/renderer/gl/RenderbufferGL.cpp
index 358da74..a5877f6 100644
--- a/src/libANGLE/renderer/gl/RenderbufferGL.cpp
+++ b/src/libANGLE/renderer/gl/RenderbufferGL.cpp
@@ -13,6 +13,7 @@
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/formatutilsgl.h"
#include "libANGLE/renderer/gl/renderergl_utils.h"
namespace rx
@@ -38,14 +39,19 @@
gl::Error RenderbufferGL::setStorage(GLenum internalformat, size_t width, size_t height)
{
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
- mFunctions->renderbufferStorage(GL_RENDERBUFFER, internalformat, width, height);
+
+ const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(internalformat, mFunctions->standard);
+ mFunctions->renderbufferStorage(GL_RENDERBUFFER, nativeInternalFormatInfo.internalFormat, width, height);
+
return gl::Error(GL_NO_ERROR);
}
gl::Error RenderbufferGL::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height)
{
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
- mFunctions->renderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalformat, width, height);
+
+ const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(internalformat, mFunctions->standard);
+ mFunctions->renderbufferStorageMultisample(GL_RENDERBUFFER, samples, nativeInternalFormatInfo.internalFormat, width, height);
const gl::TextureCaps &formatCaps = mTextureCaps.get(internalformat);
if (samples > formatCaps.getMaxSamples())
diff --git a/src/libANGLE/renderer/gl/TextureGL.cpp b/src/libANGLE/renderer/gl/TextureGL.cpp
index 91b3f5e..e113ab6 100644
--- a/src/libANGLE/renderer/gl/TextureGL.cpp
+++ b/src/libANGLE/renderer/gl/TextureGL.cpp
@@ -17,6 +17,7 @@
#include "libANGLE/renderer/gl/FramebufferGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/formatutilsgl.h"
namespace rx
{
@@ -92,15 +93,17 @@
SetUnpackStateForTexImage(mStateManager, unpack);
+ const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(internalFormat, mFunctions->standard);
+
mStateManager->bindTexture(mTextureType, mTextureID);
if (UseTexImage2D(mTextureType))
{
ASSERT(size.depth == 1);
- mFunctions->texImage2D(target, level, internalFormat, size.width, size.height, 0, format, type, pixels);
+ mFunctions->texImage2D(target, level, nativeInternalFormatInfo.internalFormat, size.width, size.height, 0, format, type, pixels);
}
else if (UseTexImage3D(mTextureType))
{
- mFunctions->texImage3D(target, level, internalFormat, size.width, size.height, size.depth, 0, format, type, pixels);
+ mFunctions->texImage3D(target, level, nativeInternalFormatInfo.internalFormat, size.width, size.height, size.depth, 0, format, type, pixels);
}
else
{
@@ -143,15 +146,17 @@
SetUnpackStateForTexImage(mStateManager, unpack);
+ const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(internalFormat, mFunctions->standard);
+
mStateManager->bindTexture(mTextureType, mTextureID);
if (UseTexImage2D(mTextureType))
{
ASSERT(size.depth == 1);
- mFunctions->compressedTexImage2D(target, level, internalFormat, size.width, size.height, 0, imageSize, pixels);
+ mFunctions->compressedTexImage2D(target, level, nativeInternalFormatInfo.internalFormat, size.width, size.height, 0, imageSize, pixels);
}
else if (UseTexImage3D(mTextureType))
{
- mFunctions->compressedTexImage3D(target, level, internalFormat, size.width, size.height, size.depth, 0,
+ mFunctions->compressedTexImage3D(target, level, nativeInternalFormatInfo.internalFormat, size.width, size.height, size.depth, 0,
imageSize, pixels);
}
else
@@ -169,17 +174,19 @@
SetUnpackStateForTexImage(mStateManager, unpack);
+ const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(format, mFunctions->standard);
+
mStateManager->bindTexture(mTextureType, mTextureID);
if (UseTexImage2D(mTextureType))
{
ASSERT(area.z == 0 && area.depth == 1);
- mFunctions->compressedTexSubImage2D(target, level, area.x, area.y, area.width, area.height, format, imageSize,
+ mFunctions->compressedTexSubImage2D(target, level, area.x, area.y, area.width, area.height, nativeInternalFormatInfo.internalFormat, imageSize,
pixels);
}
else if (UseTexImage3D(mTextureType))
{
mFunctions->compressedTexSubImage3D(target, level, area.x, area.y, area.z, area.width, area.height, area.depth,
- format, imageSize, pixels);
+ nativeInternalFormatInfo.internalFormat, imageSize, pixels);
}
else
{
@@ -192,6 +199,8 @@
gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
const gl::Framebuffer *source)
{
+ const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(internalFormat, mFunctions->standard);
+
const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
mStateManager->bindTexture(mTextureType, mTextureID);
@@ -199,7 +208,7 @@
if (UseTexImage2D(mTextureType))
{
- mFunctions->copyTexImage2D(target, level, internalFormat, sourceArea.x, sourceArea.y,
+ mFunctions->copyTexImage2D(target, level, nativeInternalFormatInfo.internalFormat, sourceArea.x, sourceArea.y,
sourceArea.width, sourceArea.height, 0);
}
else
@@ -242,13 +251,15 @@
// TODO: emulate texture storage with TexImage calls if on GL version <4.2 or the
// ARB_texture_storage extension is not available.
+ const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(internalFormat, mFunctions->standard);
+
mStateManager->bindTexture(mTextureType, mTextureID);
if (UseTexImage2D(mTextureType))
{
ASSERT(size.depth == 1);
if (mFunctions->texStorage2D)
{
- mFunctions->texStorage2D(target, levels, internalFormat, size.width, size.height);
+ mFunctions->texStorage2D(target, levels, nativeInternalFormatInfo.internalFormat, size.width, size.height);
}
else
{
@@ -271,12 +282,12 @@
if (internalFormatInfo.compressed)
{
size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height);
- mFunctions->compressedTexImage2D(target, level, internalFormat, levelSize.width, levelSize.height,
+ mFunctions->compressedTexImage2D(target, level, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height,
0, dataSize, nullptr);
}
else
{
- mFunctions->texImage2D(target, level, internalFormat, levelSize.width, levelSize.height,
+ mFunctions->texImage2D(target, level, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height,
0, internalFormatInfo.format, internalFormatInfo.type, nullptr);
}
}
@@ -287,12 +298,12 @@
if (internalFormatInfo.compressed)
{
size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height);
- mFunctions->compressedTexImage2D(face, level, internalFormat, levelSize.width, levelSize.height,
+ mFunctions->compressedTexImage2D(face, level, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height,
0, dataSize, nullptr);
}
else
{
- mFunctions->texImage2D(face, level, internalFormat, levelSize.width, levelSize.height,
+ mFunctions->texImage2D(face, level, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height,
0, internalFormatInfo.format, internalFormatInfo.type, nullptr);
}
}
@@ -308,7 +319,7 @@
{
if (mFunctions->texStorage3D)
{
- mFunctions->texStorage3D(target, levels, internalFormat, size.width, size.height, size.depth);
+ mFunctions->texStorage3D(target, levels, nativeInternalFormatInfo.internalFormat, size.width, size.height, size.depth);
}
else
{
@@ -329,12 +340,12 @@
if (internalFormatInfo.compressed)
{
size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height) * levelSize.depth;
- mFunctions->compressedTexImage3D(target, i, internalFormat, levelSize.width, levelSize.height, levelSize.depth,
+ mFunctions->compressedTexImage3D(target, i, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height, levelSize.depth,
0, dataSize, nullptr);
}
else
{
- mFunctions->texImage3D(target, i, internalFormat, levelSize.width, levelSize.height, levelSize.depth,
+ mFunctions->texImage3D(target, i, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height, levelSize.depth,
0, internalFormatInfo.format, internalFormatInfo.type, nullptr);
}
}
diff --git a/src/libANGLE/renderer/gl/formatutilsgl.cpp b/src/libANGLE/renderer/gl/formatutilsgl.cpp
index 4ef4b3a..6f0fe7f 100644
--- a/src/libANGLE/renderer/gl/formatutilsgl.cpp
+++ b/src/libANGLE/renderer/gl/formatutilsgl.cpp
@@ -9,7 +9,6 @@
#include "libANGLE/renderer/gl/formatutilsgl.h"
-#include <map>
#include <limits>
#include "common/string_utils.h"
@@ -20,6 +19,52 @@
namespace nativegl
{
+typedef std::map<GLenum, GLenum> InternalFormatConversionMap;
+
+static InternalFormatConversionMap BuildGLInternalFormatConversionMap()
+{
+ InternalFormatConversionMap map;
+
+ map[GL_BGRA8_EXT] = GL_RGBA8;
+ map[GL_BGRA_EXT] = GL_RGBA;
+
+ return map;
+}
+
+static InternalFormatConversionMap BuildGLESInternalFormatConversionMap()
+{
+ InternalFormatConversionMap map;
+
+ return map;
+}
+
+static const InternalFormatConversionMap &GetInternalFormatConversionMap(StandardGL standard)
+{
+ if (standard == STANDARD_GL_DESKTOP)
+ {
+ static const InternalFormatConversionMap map = BuildGLInternalFormatConversionMap();
+ return map;
+ }
+ else if (standard == STANDARD_GL_ES)
+ {
+ static const InternalFormatConversionMap map = BuildGLESInternalFormatConversionMap();
+ return map;
+ }
+ else
+ {
+ UNREACHABLE();
+ static const InternalFormatConversionMap map;
+ return map;
+ }
+}
+
+static GLenum GetConvertedInternalFormat(GLenum format, StandardGL standard)
+{
+ const InternalFormatConversionMap &map = GetInternalFormatConversionMap(standard);
+ auto iter = map.find(format);
+ return iter != map.end() ? iter->second : format;
+}
+
SupportRequirement::SupportRequirement()
: version(std::numeric_limits<GLuint>::max(), std::numeric_limits<GLuint>::max()),
versionExtensions(),
@@ -109,10 +154,12 @@
const SupportRequirement &esTexture, const SupportRequirement &esFilter, const SupportRequirement &esRender)
{
InternalFormatInfo formatInfo;
+ formatInfo.glInfo.internalFormat = GetConvertedInternalFormat(internalFormat, STANDARD_GL_DESKTOP);
formatInfo.glInfo.texture = desktopTexture;
formatInfo.glInfo.filter = desktopFilter;
formatInfo.glInfo.renderbuffer = desktopRender;
formatInfo.glInfo.framebufferAttachment = desktopRender;
+ formatInfo.glesInfo.internalFormat = GetConvertedInternalFormat(internalFormat, STANDARD_GL_ES);
formatInfo.glesInfo.texture = esTexture;
formatInfo.glesInfo.filter = esTexture;
formatInfo.glesInfo.renderbuffer = esFilter;
@@ -181,8 +228,8 @@
InsertFormatMapping(&map, GL_SRGB_ALPHA, VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), Always(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), VersionOrExts(3, 0, "GL_EXT_texture_sRGB"), Always(), VersionOrExts(3, 0, "GL_EXT_texture_sRGB"));
// From GL_EXT_texture_format_BGRA8888
- InsertFormatMapping(&map, GL_BGRA8_EXT, Never(), Never(), Never(), ExtsOnly("GL_EXT_texture_format_BGRA8888"), Always(), ExtsOnly("GL_EXT_texture_format_BGRA8888"));
- InsertFormatMapping(&map, GL_BGRA_EXT, Never(), Never(), Never(), ExtsOnly("GL_EXT_texture_format_BGRA8888"), Always(), ExtsOnly("GL_EXT_texture_format_BGRA8888"));
+ InsertFormatMapping(&map, GL_BGRA8_EXT, VersionOrExts(1, 2, "GL_EXT_bgra"), Always(), VersionOrExts(1, 2, "GL_EXT_bgra"), ExtsOnly("GL_EXT_texture_format_BGRA8888"), Always(), ExtsOnly("GL_EXT_texture_format_BGRA8888"));
+ InsertFormatMapping(&map, GL_BGRA_EXT, VersionOrExts(1, 2, "GL_EXT_bgra"), Always(), VersionOrExts(1, 2, "GL_EXT_bgra"), ExtsOnly("GL_EXT_texture_format_BGRA8888"), Always(), ExtsOnly("GL_EXT_texture_format_BGRA8888"));
// Floating point formats
// | Format | OpenGL texture support | Filter | OpenGL render support | OpenGL ES texture support | Filter | OpenGL ES render support |
diff --git a/src/libANGLE/renderer/gl/formatutilsgl.h b/src/libANGLE/renderer/gl/formatutilsgl.h
index dc5ab7f..7c4360f 100644
--- a/src/libANGLE/renderer/gl/formatutilsgl.h
+++ b/src/libANGLE/renderer/gl/formatutilsgl.h
@@ -10,6 +10,7 @@
#ifndef LIBANGLE_RENDERER_GL_FORMATUTILSGL_H_
#define LIBANGLE_RENDERER_GL_FORMATUTILSGL_H_
+#include <map>
#include <string>
#include <vector>
@@ -41,6 +42,9 @@
{
InternalFormat();
+ // Internal format to use for the native texture
+ GLenum internalFormat;
+
SupportRequirement texture;
SupportRequirement filter;
SupportRequirement renderbuffer;