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 @@
#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 @@ RenderbufferGL::~RenderbufferGL()
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())
......
......@@ -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 @@ gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat
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 @@ gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum inte
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 @@ gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl
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::setCompressedSubImage(GLenum target, size_t level, const gl
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 @@ gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle
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 @@ 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
// 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 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
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 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
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 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
{
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 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
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);
}
}
......
......@@ -9,7 +9,6 @@
#include "libANGLE/renderer/gl/formatutilsgl.h"
#include <map>
#include <limits>
#include "common/string_utils.h"
......@@ -20,6 +19,52 @@ namespace rx
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 @@ static inline void InsertFormatMapping(InternalFormatInfoMap *map, GLenum intern
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 @@ 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"));
// 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 |
......
......@@ -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 @@ struct InternalFormat
{
InternalFormat();
// Internal format to use for the native texture
GLenum internalFormat;
SupportRequirement texture;
SupportRequirement filter;
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