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 ...@@ -67,9 +67,11 @@ class BlitGL : angle::NonCopyable
gl::Error copySubTexture(const gl::Context *context, gl::Error copySubTexture(const gl::Context *context,
TextureGL *source, TextureGL *source,
size_t sourceLevel, size_t sourceLevel,
GLenum sourceComponentType,
TextureGL *dest, TextureGL *dest,
GLenum destTarget, GLenum destTarget,
size_t destLevel, size_t destLevel,
GLenum destComponentType,
const gl::Extents &sourceSize, const gl::Extents &sourceSize,
const gl::Rectangle &sourceArea, const gl::Rectangle &sourceArea,
const gl::Offset &destOffset, const gl::Offset &destOffset,
...@@ -110,8 +112,11 @@ class BlitGL : angle::NonCopyable ...@@ -110,8 +112,11 @@ class BlitGL : angle::NonCopyable
enum class BlitProgramType enum class BlitProgramType
{ {
FLOAT_TO_FLOAT, FLOAT_TO_FLOAT,
FLOAT_TO_UINT,
UINT_TO_UINT,
}; };
static BlitProgramType getBlitProgramType(GLenum sourceComponentType, GLenum destComponentType);
gl::Error getBlitProgram(BlitProgramType type, BlitProgram **program); gl::Error getBlitProgram(BlitProgramType type, BlitProgram **program);
std::map<BlitProgramType, BlitProgram> mBlitPrograms; std::map<BlitProgramType, BlitProgram> mBlitPrograms;
......
...@@ -88,7 +88,8 @@ LevelInfoGL GetLevelInfo(GLenum originalInternalFormat, GLenum destinationIntern ...@@ -88,7 +88,8 @@ LevelInfoGL GetLevelInfo(GLenum originalInternalFormat, GLenum destinationIntern
{ {
GLenum originalFormat = gl::GetUnsizedFormat(originalInternalFormat); GLenum originalFormat = gl::GetUnsizedFormat(originalInternalFormat);
GLenum destinationFormat = gl::GetUnsizedFormat(destinationInternalFormat); GLenum destinationFormat = gl::GetUnsizedFormat(destinationInternalFormat);
return LevelInfoGL(originalFormat, GetDepthStencilWorkaround(originalFormat), return LevelInfoGL(originalFormat, destinationInternalFormat,
GetDepthStencilWorkaround(originalFormat),
GetLUMAWorkaroundInfo(originalFormat, destinationFormat)); GetLUMAWorkaroundInfo(originalFormat, destinationFormat));
} }
...@@ -113,14 +114,16 @@ LUMAWorkaroundGL::LUMAWorkaroundGL(bool enabled_, GLenum workaroundFormat_) ...@@ -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_, LevelInfoGL::LevelInfoGL(GLenum sourceFormat_,
GLenum nativeInternalFormat_,
bool depthStencilWorkaround_, bool depthStencilWorkaround_,
const LUMAWorkaroundGL &lumaWorkaround_) const LUMAWorkaroundGL &lumaWorkaround_)
: sourceFormat(sourceFormat_), : sourceFormat(sourceFormat_),
nativeInternalFormat(nativeInternalFormat_),
depthStencilWorkaround(depthStencilWorkaround_), depthStencilWorkaround(depthStencilWorkaround_),
lumaWorkaround(lumaWorkaround_) lumaWorkaround(lumaWorkaround_)
{ {
...@@ -715,8 +718,8 @@ gl::Error TextureGL::copyTexture(const gl::Context *context, ...@@ -715,8 +718,8 @@ gl::Error TextureGL::copyTexture(const gl::Context *context,
gl::GetUnsizedFormat(internalFormat), type); gl::GetUnsizedFormat(internalFormat), type);
return copySubTextureHelper(context, target, level, gl::Offset(0, 0, 0), sourceLevel, return copySubTextureHelper(context, target, level, gl::Offset(0, 0, 0), sourceLevel,
sourceArea, internalFormat, unpackFlipY, unpackPremultiplyAlpha, sourceArea, gl::GetUnsizedFormat(internalFormat), type, unpackFlipY,
unpackUnmultiplyAlpha, source); unpackPremultiplyAlpha, unpackUnmultiplyAlpha, source);
} }
gl::Error TextureGL::copySubTexture(const gl::Context *context, gl::Error TextureGL::copySubTexture(const gl::Context *context,
...@@ -730,10 +733,10 @@ gl::Error TextureGL::copySubTexture(const gl::Context *context, ...@@ -730,10 +733,10 @@ gl::Error TextureGL::copySubTexture(const gl::Context *context,
bool unpackUnmultiplyAlpha, bool unpackUnmultiplyAlpha,
const gl::Texture *source) 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, return copySubTextureHelper(context, target, level, destOffset, sourceLevel, sourceArea,
destFormat, unpackFlipY, unpackPremultiplyAlpha, destFormatInfo.format, destFormatInfo.type, unpackFlipY,
unpackUnmultiplyAlpha, source); unpackPremultiplyAlpha, unpackUnmultiplyAlpha, source);
} }
gl::Error TextureGL::copySubTextureHelper(const gl::Context *context, gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
...@@ -743,6 +746,7 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context, ...@@ -743,6 +746,7 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
size_t sourceLevel, size_t sourceLevel,
const gl::Rectangle &sourceArea, const gl::Rectangle &sourceArea,
GLenum destFormat, GLenum destFormat,
GLenum destType,
bool unpackFlipY, bool unpackFlipY,
bool unpackPremultiplyAlpha, bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha, bool unpackUnmultiplyAlpha,
...@@ -762,19 +766,31 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context, ...@@ -762,19 +766,31 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
(sourceFormat == destFormat && sourceFormat != GL_BGRA_EXT) || (sourceFormat == destFormat && sourceFormat != GL_BGRA_EXT) ||
(sourceFormat == GL_RGBA && destFormat == GL_RGB); (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 && if (source->getTarget() == GL_TEXTURE_2D && !unpackFlipY &&
unpackPremultiplyAlpha == unpackUnmultiplyAlpha && !needsLumaWorkaround && unpackPremultiplyAlpha == unpackUnmultiplyAlpha && !needsLumaWorkaround &&
sourceFormatContainSupersetOfDestFormat) sourceFormatContainSupersetOfDestFormat && sourceComponentType == destComponentType)
{ {
return mBlitter->copyTexSubImage(sourceGL, sourceLevel, this, target, level, sourceArea, return mBlitter->copyTexSubImage(sourceGL, sourceLevel, this, target, level, sourceArea,
destOffset); destOffset);
} }
// We can't use copyTexSubImage, do a manual copy // Check if the destination is renderable and copy on the GPU
return mBlitter->copySubTexture(context, sourceGL, sourceLevel, this, target, level, const LevelInfoGL &destLevelInfo = getLevelInfo(target, level);
sourceImageDesc.size, sourceArea, destOffset, if (nativegl::SupportsNativeRendering(mFunctions, target, destLevelInfo.nativeInternalFormat))
needsLumaWorkaround, sourceLevelInfo.sourceFormat, unpackFlipY, {
unpackPremultiplyAlpha, unpackUnmultiplyAlpha); 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, gl::Error TextureGL::setStorage(const gl::Context *context,
......
...@@ -37,6 +37,9 @@ struct LevelInfoGL ...@@ -37,6 +37,9 @@ struct LevelInfoGL
// Format of the data used in this mip level. // Format of the data used in this mip level.
GLenum sourceFormat; 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. // If this mip level requires sampler-state re-writing so that only a red channel is exposed.
bool depthStencilWorkaround; bool depthStencilWorkaround;
...@@ -45,6 +48,7 @@ struct LevelInfoGL ...@@ -45,6 +48,7 @@ struct LevelInfoGL
LevelInfoGL(); LevelInfoGL();
LevelInfoGL(GLenum sourceFormat, LevelInfoGL(GLenum sourceFormat,
GLenum nativeInternalFormat,
bool depthStencilWorkaround, bool depthStencilWorkaround,
const LUMAWorkaroundGL &lumaWorkaround); const LUMAWorkaroundGL &lumaWorkaround);
}; };
...@@ -134,6 +138,7 @@ class TextureGL : public TextureImpl ...@@ -134,6 +138,7 @@ class TextureGL : public TextureImpl
size_t sourceLevel, size_t sourceLevel,
const gl::Rectangle &sourceArea, const gl::Rectangle &sourceArea,
GLenum destFormat, GLenum destFormat,
GLenum destType,
bool unpackFlipY, bool unpackFlipY,
bool unpackPremultiplyAlpha, bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha, bool unpackUnmultiplyAlpha,
......
...@@ -1120,6 +1120,26 @@ bool SupportsOcclusionQueries(const FunctionsGL *functions) ...@@ -1120,6 +1120,26 @@ bool SupportsOcclusionQueries(const FunctionsGL *functions)
functions->isAtLeastGLES(gl::Version(3, 0)) || functions->isAtLeastGLES(gl::Version(3, 0)) ||
functions->hasGLESExtension("GL_EXT_occlusion_query_boolean"); 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) bool CanMapBufferForRead(const FunctionsGL *functions)
......
...@@ -60,6 +60,7 @@ namespace nativegl ...@@ -60,6 +60,7 @@ namespace nativegl
{ {
bool SupportsFenceSync(const FunctionsGL *functions); bool SupportsFenceSync(const FunctionsGL *functions);
bool SupportsOcclusionQueries(const FunctionsGL *functions); bool SupportsOcclusionQueries(const FunctionsGL *functions);
bool SupportsNativeRendering(const FunctionsGL *functions, GLenum target, GLenum internalFormat);
} }
bool CanMapBufferForRead(const FunctionsGL *functions); bool CanMapBufferForRead(const FunctionsGL *functions);
......
...@@ -1260,13 +1260,6 @@ TEST_P(CopyTextureTestES3, ES3UintFormats) ...@@ -1260,13 +1260,6 @@ TEST_P(CopyTextureTestES3, ES3UintFormats)
return; 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>; using GLColor32U = std::tuple<GLuint, GLuint, GLuint, GLuint>;
auto testOutput = [this](GLuint texture, const GLColor32U &expectedColor) { auto testOutput = [this](GLuint texture, const GLColor32U &expectedColor) {
...@@ -1350,12 +1343,22 @@ TEST_P(CopyTextureTestES3, ES3UintFormats) ...@@ -1350,12 +1343,22 @@ TEST_P(CopyTextureTestES3, ES3UintFormats)
testCopyCombination(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GLColor(128, 64, 32, 128), GL_RGBA8UI, 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)); 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, if (IsOpenGL() || IsOpenGLES())
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, std::cout << "Skipping GL_RGB8UI because it is not implemented yet." << std::endl;
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, else
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_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, 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)); 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