Commit fd216c41 by Geoff Lang

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/273162Reviewed-by: 's avatarBrandon Jones <bajones@chromium.org> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 6683032d
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/formatutilsgl.h"
#include "libANGLE/renderer/gl/renderergl_utils.h" #include "libANGLE/renderer/gl/renderergl_utils.h"
namespace rx namespace rx
...@@ -38,14 +39,19 @@ RenderbufferGL::~RenderbufferGL() ...@@ -38,14 +39,19 @@ RenderbufferGL::~RenderbufferGL()
gl::Error RenderbufferGL::setStorage(GLenum internalformat, size_t width, size_t height) gl::Error RenderbufferGL::setStorage(GLenum internalformat, size_t width, size_t height)
{ {
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID); 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); return gl::Error(GL_NO_ERROR);
} }
gl::Error RenderbufferGL::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) gl::Error RenderbufferGL::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height)
{ {
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID); 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); const gl::TextureCaps &formatCaps = mTextureCaps.get(internalformat);
if (samples > formatCaps.getMaxSamples()) if (samples > formatCaps.getMaxSamples())
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "libANGLE/renderer/gl/FramebufferGL.h" #include "libANGLE/renderer/gl/FramebufferGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/formatutilsgl.h"
namespace rx namespace rx
{ {
...@@ -92,15 +93,17 @@ gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat ...@@ -92,15 +93,17 @@ gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat
SetUnpackStateForTexImage(mStateManager, unpack); SetUnpackStateForTexImage(mStateManager, unpack);
const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(internalFormat, mFunctions->standard);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mTextureType, mTextureID);
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mTextureType))
{ {
ASSERT(size.depth == 1); 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)) 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 else
{ {
...@@ -143,15 +146,17 @@ gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum inte ...@@ -143,15 +146,17 @@ gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum inte
SetUnpackStateForTexImage(mStateManager, unpack); SetUnpackStateForTexImage(mStateManager, unpack);
const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(internalFormat, mFunctions->standard);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mTextureType, mTextureID);
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mTextureType))
{ {
ASSERT(size.depth == 1); 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)) 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); imageSize, pixels);
} }
else else
...@@ -169,17 +174,19 @@ gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl ...@@ -169,17 +174,19 @@ gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl
SetUnpackStateForTexImage(mStateManager, unpack); SetUnpackStateForTexImage(mStateManager, unpack);
const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(format, mFunctions->standard);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mTextureType, mTextureID);
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mTextureType))
{ {
ASSERT(area.z == 0 && area.depth == 1); 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); pixels);
} }
else if (UseTexImage3D(mTextureType)) else if (UseTexImage3D(mTextureType))
{ {
mFunctions->compressedTexSubImage3D(target, level, area.x, area.y, area.z, area.width, area.height, area.depth, mFunctions->compressedTexSubImage3D(target, level, area.x, area.y, area.z, area.width, area.height, area.depth,
format, imageSize, pixels); nativeInternalFormatInfo.internalFormat, imageSize, pixels);
} }
else else
{ {
...@@ -192,6 +199,8 @@ gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl ...@@ -192,6 +199,8 @@ gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl
gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
const gl::Framebuffer *source) const gl::Framebuffer *source)
{ {
const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(internalFormat, mFunctions->standard);
const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source); const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mTextureType, mTextureID);
...@@ -199,7 +208,7 @@ gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle ...@@ -199,7 +208,7 @@ gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle
if (UseTexImage2D(mTextureType)) 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); sourceArea.width, sourceArea.height, 0);
} }
else else
...@@ -242,13 +251,15 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor ...@@ -242,13 +251,15 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
// TODO: emulate texture storage with TexImage calls if on GL version <4.2 or the // TODO: emulate texture storage with TexImage calls if on GL version <4.2 or the
// ARB_texture_storage extension is not available. // ARB_texture_storage extension is not available.
const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(internalFormat, mFunctions->standard);
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mTextureType, mTextureID);
if (UseTexImage2D(mTextureType)) if (UseTexImage2D(mTextureType))
{ {
ASSERT(size.depth == 1); ASSERT(size.depth == 1);
if (mFunctions->texStorage2D) if (mFunctions->texStorage2D)
{ {
mFunctions->texStorage2D(target, levels, internalFormat, size.width, size.height); mFunctions->texStorage2D(target, levels, nativeInternalFormatInfo.internalFormat, size.width, size.height);
} }
else else
{ {
...@@ -271,12 +282,12 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor ...@@ -271,12 +282,12 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
if (internalFormatInfo.compressed) if (internalFormatInfo.compressed)
{ {
size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height); 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); 0, dataSize, nullptr);
} }
else 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); 0, internalFormatInfo.format, internalFormatInfo.type, nullptr);
} }
} }
...@@ -287,12 +298,12 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor ...@@ -287,12 +298,12 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
if (internalFormatInfo.compressed) if (internalFormatInfo.compressed)
{ {
size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height); 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); 0, dataSize, nullptr);
} }
else 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); 0, internalFormatInfo.format, internalFormatInfo.type, nullptr);
} }
} }
...@@ -308,7 +319,7 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor ...@@ -308,7 +319,7 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
{ {
if (mFunctions->texStorage3D) 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 else
{ {
...@@ -329,12 +340,12 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor ...@@ -329,12 +340,12 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
if (internalFormatInfo.compressed) if (internalFormatInfo.compressed)
{ {
size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height) * levelSize.depth; 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); 0, dataSize, nullptr);
} }
else 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); 0, internalFormatInfo.format, internalFormatInfo.type, nullptr);
} }
} }
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include "libANGLE/renderer/gl/formatutilsgl.h" #include "libANGLE/renderer/gl/formatutilsgl.h"
#include <map>
#include <limits> #include <limits>
#include "common/string_utils.h" #include "common/string_utils.h"
...@@ -20,6 +19,52 @@ namespace rx ...@@ -20,6 +19,52 @@ namespace rx
namespace nativegl 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() SupportRequirement::SupportRequirement()
: version(std::numeric_limits<GLuint>::max(), std::numeric_limits<GLuint>::max()), : version(std::numeric_limits<GLuint>::max(), std::numeric_limits<GLuint>::max()),
versionExtensions(), versionExtensions(),
...@@ -109,10 +154,12 @@ static inline void InsertFormatMapping(InternalFormatInfoMap *map, GLenum intern ...@@ -109,10 +154,12 @@ static inline void InsertFormatMapping(InternalFormatInfoMap *map, GLenum intern
const SupportRequirement &esTexture, const SupportRequirement &esFilter, const SupportRequirement &esRender) const SupportRequirement &esTexture, const SupportRequirement &esFilter, const SupportRequirement &esRender)
{ {
InternalFormatInfo formatInfo; InternalFormatInfo formatInfo;
formatInfo.glInfo.internalFormat = GetConvertedInternalFormat(internalFormat, STANDARD_GL_DESKTOP);
formatInfo.glInfo.texture = desktopTexture; formatInfo.glInfo.texture = desktopTexture;
formatInfo.glInfo.filter = desktopFilter; formatInfo.glInfo.filter = desktopFilter;
formatInfo.glInfo.renderbuffer = desktopRender; formatInfo.glInfo.renderbuffer = desktopRender;
formatInfo.glInfo.framebufferAttachment = desktopRender; formatInfo.glInfo.framebufferAttachment = desktopRender;
formatInfo.glesInfo.internalFormat = GetConvertedInternalFormat(internalFormat, STANDARD_GL_ES);
formatInfo.glesInfo.texture = esTexture; formatInfo.glesInfo.texture = esTexture;
formatInfo.glesInfo.filter = esTexture; formatInfo.glesInfo.filter = esTexture;
formatInfo.glesInfo.renderbuffer = esFilter; formatInfo.glesInfo.renderbuffer = esFilter;
...@@ -181,8 +228,8 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() ...@@ -181,8 +228,8 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap()
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")); 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 // 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_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, Never(), Never(), Never(), 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 // Floating point formats
// | Format | OpenGL texture support | Filter | OpenGL render support | OpenGL ES texture support | Filter | OpenGL ES render support | // | Format | OpenGL texture support | Filter | OpenGL render support | OpenGL ES texture support | Filter | OpenGL ES render support |
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#ifndef LIBANGLE_RENDERER_GL_FORMATUTILSGL_H_ #ifndef LIBANGLE_RENDERER_GL_FORMATUTILSGL_H_
#define LIBANGLE_RENDERER_GL_FORMATUTILSGL_H_ #define LIBANGLE_RENDERER_GL_FORMATUTILSGL_H_
#include <map>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -41,6 +42,9 @@ struct InternalFormat ...@@ -41,6 +42,9 @@ struct InternalFormat
{ {
InternalFormat(); InternalFormat();
// Internal format to use for the native texture
GLenum internalFormat;
SupportRequirement texture; SupportRequirement texture;
SupportRequirement filter; SupportRequirement filter;
SupportRequirement renderbuffer; SupportRequirement renderbuffer;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment