Commit 47bb4933 by Geoff Lang Committed by Commit Bot

Implement CopyTexture functions for uint texture formats.

BUG=angleproject:1932 Change-Id: I6474237cbb82b59a0bd40c1b9b9e2455952d3755 Reviewed-on: https://chromium-review.googlesource.com/600510 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 553590a5
......@@ -67,9 +67,11 @@ class BlitGL : angle::NonCopyable
gl::Error copySubTexture(const gl::Context *context,
TextureGL *source,
size_t sourceLevel,
GLenum sourceComponentType,
TextureGL *dest,
GLenum destTarget,
size_t destLevel,
GLenum destComponentType,
const gl::Extents &sourceSize,
const gl::Rectangle &sourceArea,
const gl::Offset &destOffset,
......@@ -110,8 +112,11 @@ class BlitGL : angle::NonCopyable
enum class BlitProgramType
{
FLOAT_TO_FLOAT,
FLOAT_TO_UINT,
UINT_TO_UINT,
};
static BlitProgramType getBlitProgramType(GLenum sourceComponentType, GLenum destComponentType);
gl::Error getBlitProgram(BlitProgramType type, BlitProgram **program);
std::map<BlitProgramType, BlitProgram> mBlitPrograms;
......
......@@ -88,7 +88,8 @@ LevelInfoGL GetLevelInfo(GLenum originalInternalFormat, GLenum destinationIntern
{
GLenum originalFormat = gl::GetUnsizedFormat(originalInternalFormat);
GLenum destinationFormat = gl::GetUnsizedFormat(destinationInternalFormat);
return LevelInfoGL(originalFormat, GetDepthStencilWorkaround(originalFormat),
return LevelInfoGL(originalFormat, destinationInternalFormat,
GetDepthStencilWorkaround(originalFormat),
GetLUMAWorkaroundInfo(originalFormat, destinationFormat));
}
......@@ -113,14 +114,16 @@ LUMAWorkaroundGL::LUMAWorkaroundGL(bool enabled_, GLenum workaroundFormat_)
{
}
LevelInfoGL::LevelInfoGL() : LevelInfoGL(GL_NONE, false, LUMAWorkaroundGL())
LevelInfoGL::LevelInfoGL() : LevelInfoGL(GL_NONE, GL_NONE, false, LUMAWorkaroundGL())
{
}
LevelInfoGL::LevelInfoGL(GLenum sourceFormat_,
GLenum nativeInternalFormat_,
bool depthStencilWorkaround_,
const LUMAWorkaroundGL &lumaWorkaround_)
: sourceFormat(sourceFormat_),
nativeInternalFormat(nativeInternalFormat_),
depthStencilWorkaround(depthStencilWorkaround_),
lumaWorkaround(lumaWorkaround_)
{
......@@ -715,8 +718,8 @@ gl::Error TextureGL::copyTexture(const gl::Context *context,
gl::GetUnsizedFormat(internalFormat), type);
return copySubTextureHelper(context, target, level, gl::Offset(0, 0, 0), sourceLevel,
sourceArea, internalFormat, unpackFlipY, unpackPremultiplyAlpha,
unpackUnmultiplyAlpha, source);
sourceArea, gl::GetUnsizedFormat(internalFormat), type, unpackFlipY,
unpackPremultiplyAlpha, unpackUnmultiplyAlpha, source);
}
gl::Error TextureGL::copySubTexture(const gl::Context *context,
......@@ -730,10 +733,10 @@ gl::Error TextureGL::copySubTexture(const gl::Context *context,
bool unpackUnmultiplyAlpha,
const gl::Texture *source)
{
GLenum destFormat = mState.getImageDesc(target, level).format.info->format;
const gl::InternalFormat &destFormatInfo = *mState.getImageDesc(target, level).format.info;
return copySubTextureHelper(context, target, level, destOffset, sourceLevel, sourceArea,
destFormat, unpackFlipY, unpackPremultiplyAlpha,
unpackUnmultiplyAlpha, source);
destFormatInfo.format, destFormatInfo.type, unpackFlipY,
unpackPremultiplyAlpha, unpackUnmultiplyAlpha, source);
}
gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
......@@ -743,6 +746,7 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
size_t sourceLevel,
const gl::Rectangle &sourceArea,
GLenum destFormat,
GLenum destType,
bool unpackFlipY,
bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha,
......@@ -762,19 +766,31 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
(sourceFormat == destFormat && sourceFormat != GL_BGRA_EXT) ||
(sourceFormat == GL_RGBA && destFormat == GL_RGB);
GLenum sourceComponentType = sourceImageDesc.format.info->componentType;
GLenum destComponentType = gl::GetInternalFormatInfo(destFormat, destType).componentType;
if (source->getTarget() == GL_TEXTURE_2D && !unpackFlipY &&
unpackPremultiplyAlpha == unpackUnmultiplyAlpha && !needsLumaWorkaround &&
sourceFormatContainSupersetOfDestFormat)
sourceFormatContainSupersetOfDestFormat && sourceComponentType == destComponentType)
{
return mBlitter->copyTexSubImage(sourceGL, sourceLevel, this, target, level, sourceArea,
destOffset);
}
// We can't use copyTexSubImage, do a manual copy
return mBlitter->copySubTexture(context, sourceGL, sourceLevel, this, target, level,
sourceImageDesc.size, sourceArea, destOffset,
needsLumaWorkaround, sourceLevelInfo.sourceFormat, unpackFlipY,
unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
// Check if the destination is renderable and copy on the GPU
const LevelInfoGL &destLevelInfo = getLevelInfo(target, level);
if (nativegl::SupportsNativeRendering(mFunctions, target, destLevelInfo.nativeInternalFormat))
{
return mBlitter->copySubTexture(context, sourceGL, sourceLevel, sourceComponentType, this,
target, level, destComponentType, sourceImageDesc.size,
sourceArea, destOffset, needsLumaWorkaround,
sourceLevelInfo.sourceFormat, unpackFlipY,
unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
}
// Fall back to CPU-readback
UNIMPLEMENTED();
return gl::NoError();
}
gl::Error TextureGL::setStorage(const gl::Context *context,
......
......@@ -37,6 +37,9 @@ struct LevelInfoGL
// Format of the data used in this mip level.
GLenum sourceFormat;
// Internal format used for the native call to define this texture
GLenum nativeInternalFormat;
// If this mip level requires sampler-state re-writing so that only a red channel is exposed.
bool depthStencilWorkaround;
......@@ -45,6 +48,7 @@ struct LevelInfoGL
LevelInfoGL();
LevelInfoGL(GLenum sourceFormat,
GLenum nativeInternalFormat,
bool depthStencilWorkaround,
const LUMAWorkaroundGL &lumaWorkaround);
};
......@@ -134,6 +138,7 @@ class TextureGL : public TextureImpl
size_t sourceLevel,
const gl::Rectangle &sourceArea,
GLenum destFormat,
GLenum destType,
bool unpackFlipY,
bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha,
......
......@@ -1120,6 +1120,26 @@ bool SupportsOcclusionQueries(const FunctionsGL *functions)
functions->isAtLeastGLES(gl::Version(3, 0)) ||
functions->hasGLESExtension("GL_EXT_occlusion_query_boolean");
}
bool SupportsNativeRendering(const FunctionsGL *functions, GLenum target, GLenum internalFormat)
{
// Some desktop drivers allow rendering to formats that are not required by the spec, this is
// exposed through the GL_FRAMEBUFFER_RENDERABLE query.
if (functions->isAtLeastGL(gl::Version(4, 3)) ||
functions->hasGLExtension("GL_ARB_internalformat_query2"))
{
GLint framebufferRenderable = GL_FALSE;
functions->getInternalformativ(target, internalFormat, GL_FRAMEBUFFER_RENDERABLE, 1,
&framebufferRenderable);
return framebufferRenderable != GL_FALSE;
}
else
{
const nativegl::InternalFormat &nativeInfo =
nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
return nativegl_gl::MeetsRequirements(functions, nativeInfo.framebufferAttachment);
}
}
}
bool CanMapBufferForRead(const FunctionsGL *functions)
......
......@@ -60,6 +60,7 @@ namespace nativegl
{
bool SupportsFenceSync(const FunctionsGL *functions);
bool SupportsOcclusionQueries(const FunctionsGL *functions);
bool SupportsNativeRendering(const FunctionsGL *functions, GLenum target, GLenum internalFormat);
}
bool CanMapBufferForRead(const FunctionsGL *functions);
......
......@@ -1260,13 +1260,6 @@ TEST_P(CopyTextureTestES3, ES3UintFormats)
return;
}
if (IsOpenGL() || IsOpenGLES())
{
std::cout << "Test on OpenGL and OpenGLES because not all formats are implemented yet."
<< std::endl;
return;
}
using GLColor32U = std::tuple<GLuint, GLuint, GLuint, GLuint>;
auto testOutput = [this](GLuint texture, const GLColor32U &expectedColor) {
......@@ -1350,12 +1343,22 @@ TEST_P(CopyTextureTestES3, ES3UintFormats)
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI,
GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 128));
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 32, 1));
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
GL_UNSIGNED_BYTE, false, true, false, GLColor32U(64, 32, 16, 1));
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGB8UI,
GL_UNSIGNED_BYTE, false, false, true, GLColor32U(255, 128, 64, 1));
if (IsOpenGL() || IsOpenGLES())
{
std::cout << "Skipping GL_RGB8UI because it is not implemented yet." << std::endl;
}
else
{
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
GL_RGB8UI, GL_UNSIGNED_BYTE, false, false, false,
GLColor32U(128, 64, 32, 1));
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
GL_RGB8UI, GL_UNSIGNED_BYTE, false, true, false,
GLColor32U(64, 32, 16, 1));
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128),
GL_RGB8UI, GL_UNSIGNED_BYTE, false, false, true,
GLColor32U(255, 128, 64, 1));
}
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RG8UI,
GL_UNSIGNED_BYTE, false, false, false, GLColor32U(128, 64, 0, 1));
......
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