Commit f410e81a by Geoff Lang Committed by Angle LUCI CQ

GL: Implement multisampled_render_to_texture

Bug: angleproject:2894, angleproject:5988 Change-Id: I17b55f0655d32d9f41cb55a0467b93a00fba751b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2841084 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent f97b8193
......@@ -549,6 +549,11 @@ struct FeaturesGL : FeatureSetBase
"Switching framebuffers without a flush can lead to "
"crashes on Intel 9th Generation GPU Macs.",
&members, "http://crbug.com/1181068"};
Feature disableMultisampledRenderToTexture = {
"disable_mutlisampled_render_to_texture", FeatureCategory::OpenGLWorkarounds,
"Many drivers have bugs when using GL_EXT_multisampled_render_to_texture", &members,
"http://anglebug.com/2894"};
};
inline FeaturesGL::FeaturesGL() = default;
......
......@@ -4,15 +4,15 @@
"src/libANGLE/renderer/angle_format.py":
"74d6c9842128293118ccf128aeae896a",
"src/libANGLE/renderer/gl/DispatchTableGL_autogen.cpp":
"54a5c8b87d54114ee61a4c535931ea48",
"06399dbfa161982f60b0af04e3cf9ffb",
"src/libANGLE/renderer/gl/DispatchTableGL_autogen.h":
"e41b2685228feb5c20b5c1400837c055",
"3115c293d6612d10498a1063b8cebe1a",
"src/libANGLE/renderer/gl/generate_gl_dispatch_table.py":
"d133c757b44279ad205183c9c9c9b598",
"src/libANGLE/renderer/gl/gl_bindings_data.json":
"6f46f537e07b457850c060ef0c7b76c5",
"6aa7c139ca0717d08e46bf86e1bf85a2",
"src/libANGLE/renderer/gl/null_functions.cpp":
"8504f1659630d3b629029f8afd4acc28",
"684b33717a2ac64b1fa415acc33896f9",
"src/libANGLE/renderer/gl/null_functions.h":
"76931f9f5d0235a8ce16d15fa2443c65"
"19352d6beb033161490c4b37918acf17"
}
\ No newline at end of file
......@@ -994,6 +994,7 @@ void DispatchTableGL::initProcsDesktopGL(const gl::Version &version,
if (extensions.count("GL_EXT_framebuffer_multisample") != 0)
{
ASSIGN("glRenderbufferStorageMultisampleEXT", renderbufferStorageMultisample);
ASSIGN("glRenderbufferStorageMultisampleEXT", renderbufferStorageMultisampleEXT);
}
if (extensions.count("GL_EXT_framebuffer_object") != 0)
......@@ -2037,7 +2038,9 @@ void DispatchTableGL::initProcsGLES(const gl::Version &version,
if (extensions.count("GL_EXT_multisampled_render_to_texture") != 0)
{
ASSIGN("glFramebufferTexture2DMultisampleEXT", framebufferTexture2DMultisampleEXT);
ASSIGN("glRenderbufferStorageMultisampleEXT", renderbufferStorageMultisample);
ASSIGN("glRenderbufferStorageMultisampleEXT", renderbufferStorageMultisampleEXT);
}
if (extensions.count("GL_EXT_multiview_draw_buffers") != 0)
......@@ -2109,6 +2112,12 @@ void DispatchTableGL::initProcsGLES(const gl::Version &version,
ASSIGN("glTextureViewEXT", textureView);
}
if (extensions.count("GL_IMG_multisampled_render_to_texture") != 0)
{
ASSIGN("glFramebufferTexture2DMultisampleIMG", framebufferTexture2DMultisampleIMG);
ASSIGN("glRenderbufferStorageMultisampleIMG", renderbufferStorageMultisampleIMG);
}
if (extensions.count("GL_KHR_debug") != 0)
{
ASSIGN("glDebugMessageCallbackKHR", debugMessageCallback);
......@@ -3772,6 +3781,7 @@ void DispatchTableGL::initProcsDesktopGLNULL(const gl::Version &version,
if (extensions.count("GL_EXT_framebuffer_multisample") != 0)
{
renderbufferStorageMultisample = &glRenderbufferStorageMultisampleNULL;
renderbufferStorageMultisampleEXT = &glRenderbufferStorageMultisampleEXTNULL;
}
if (extensions.count("GL_EXT_framebuffer_object") != 0)
......@@ -4814,7 +4824,9 @@ void DispatchTableGL::initProcsGLESNULL(const gl::Version &version,
if (extensions.count("GL_EXT_multisampled_render_to_texture") != 0)
{
framebufferTexture2DMultisampleEXT = &glFramebufferTexture2DMultisampleEXTNULL;
renderbufferStorageMultisample = &glRenderbufferStorageMultisampleNULL;
renderbufferStorageMultisampleEXT = &glRenderbufferStorageMultisampleEXTNULL;
}
if (extensions.count("GL_EXT_multiview_draw_buffers") != 0)
......@@ -4886,6 +4898,12 @@ void DispatchTableGL::initProcsGLESNULL(const gl::Version &version,
textureView = &glTextureViewNULL;
}
if (extensions.count("GL_IMG_multisampled_render_to_texture") != 0)
{
framebufferTexture2DMultisampleIMG = &glFramebufferTexture2DMultisampleIMGNULL;
renderbufferStorageMultisampleIMG = &glRenderbufferStorageMultisampleIMGNULL;
}
if (extensions.count("GL_KHR_debug") != 0)
{
debugMessageCallback = &glDebugMessageCallbackNULL;
......
......@@ -770,6 +770,10 @@ class DispatchTableGL : angle::NonCopyable
PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC importMemoryWin32HandleEXT = nullptr;
PFNGLIMPORTMEMORYWIN32NAMEEXTPROC importMemoryWin32NameEXT = nullptr;
// GL_EXT_multisampled_render_to_texture
PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC framebufferTexture2DMultisampleEXT = nullptr;
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC renderbufferStorageMultisampleEXT = nullptr;
// GL_EXT_semaphore
PFNGLDELETESEMAPHORESEXTPROC deleteSemaphoresEXT = nullptr;
PFNGLGENSEMAPHORESEXTPROC genSemaphoresEXT = nullptr;
......@@ -790,6 +794,10 @@ class DispatchTableGL : angle::NonCopyable
PFNGLTEXBUFFEREXTPROC texBufferEXT = nullptr;
PFNGLTEXBUFFERRANGEEXTPROC texBufferRangeEXT = nullptr;
// GL_IMG_multisampled_render_to_texture
PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC framebufferTexture2DMultisampleIMG = nullptr;
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC renderbufferStorageMultisampleIMG = nullptr;
// GL_KHR_parallel_shader_compile
PFNGLMAXSHADERCOMPILERTHREADSKHRPROC maxShaderCompilerThreadsKHR = nullptr;
......
......@@ -90,10 +90,31 @@ void BindFramebufferAttachment(const FunctionsGL *functions,
texture->getType() == TextureType::Rectangle ||
texture->getType() == TextureType::External)
{
functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint,
ToGLenum(texture->getType()),
if (attachment->isRenderToTexture())
{
if (functions->framebufferTexture2DMultisampleEXT)
{
functions->framebufferTexture2DMultisampleEXT(
GL_FRAMEBUFFER, attachmentPoint, ToGLenum(texture->getType()),
textureGL->getTextureID(), attachment->mipLevel(),
attachment->getSamples());
}
else
{
ASSERT(functions->framebufferTexture2DMultisampleIMG);
functions->framebufferTexture2DMultisampleIMG(
GL_FRAMEBUFFER, attachmentPoint, ToGLenum(texture->getType()),
textureGL->getTextureID(), attachment->mipLevel(),
attachment->getSamples());
}
}
else
{
functions->framebufferTexture2D(
GL_FRAMEBUFFER, attachmentPoint, ToGLenum(texture->getType()),
textureGL->getTextureID(), attachment->mipLevel());
}
}
else if (attachment->isLayered())
{
TextureType textureType = texture->getType();
......
......@@ -68,10 +68,6 @@ angle::Result RenderbufferGL::setStorageMultisample(const gl::Context *context,
GLsizei height,
gl::MultisamplingMode mode)
{
// Note: GL_EXT_multisampled_render_to_texture is not supported in the GL backend.
// http://anglebug.com/2894
ASSERT(mode == gl::MultisamplingMode::Regular);
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const angle::FeaturesGL &features = GetFeaturesGL(context);
......@@ -80,9 +76,32 @@ angle::Result RenderbufferGL::setStorageMultisample(const gl::Context *context,
nativegl::RenderbufferFormat renderbufferFormat =
nativegl::GetRenderbufferFormat(functions, features, internalformat);
if (mode == gl::MultisamplingMode::Regular)
{
ANGLE_GL_TRY_ALWAYS_CHECK(context, functions->renderbufferStorageMultisample(
GL_RENDERBUFFER, samples,
renderbufferFormat.internalFormat, width, height));
}
else
{
ASSERT(mode == gl::MultisamplingMode::MultisampledRenderToTexture);
if (functions->renderbufferStorageMultisampleEXT)
{
ANGLE_GL_TRY_ALWAYS_CHECK(
context,
functions->renderbufferStorageMultisampleEXT(
GL_RENDERBUFFER, samples, renderbufferFormat.internalFormat, width, height));
}
else
{
ASSERT(functions->renderbufferStorageMultisampleIMG);
ANGLE_GL_TRY_ALWAYS_CHECK(
context, functions->renderbufferStorageMultisample(
context,
functions->renderbufferStorageMultisampleIMG(
GL_RENDERBUFFER, samples, renderbufferFormat.internalFormat, width, height));
}
}
mNativeInternalFormat = renderbufferFormat.internalFormat;
......
......@@ -1957,6 +1957,34 @@ typedef void(INTERNAL_GL_APIENTRY *PFNGLBLITFRAMEBUFFERNVPROC)(GLint srcX0,
GLbitfield mask,
GLenum filter);
// GL_EXT_multisampled_render_to_texture
typedef void(INTERNAL_GL_APIENTRY *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(
GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height);
typedef void(INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)(GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level,
GLsizei samples);
// GL_IMG_multisampled_render_to_texture
typedef void(INTERNAL_GL_APIENTRY *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC)(
GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height);
typedef void(INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC)(GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level,
GLsizei samples);
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_FUNCTIONSGLTYPEDEFS_H_
......@@ -854,5 +854,17 @@
"GL_NV_framebuffer_blit":
[
"BlitFramebufferNV"
],
"GL_IMG_multisampled_render_to_texture":
[
"RenderbufferStorageMultisampleIMG",
"FramebufferTexture2DMultisampleIMG"
],
"GL_EXT_multisampled_render_to_texture":
[
"RenderbufferStorageMultisampleEXT",
"FramebufferTexture2DMultisampleEXT"
]
}
......@@ -838,6 +838,22 @@ void INTERNAL_GL_APIENTRY glFramebufferTexture2DNULL(GLenum target,
GLint level)
{}
void INTERNAL_GL_APIENTRY glFramebufferTexture2DMultisampleEXTNULL(GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level,
GLsizei samples)
{}
void INTERNAL_GL_APIENTRY glFramebufferTexture2DMultisampleIMGNULL(GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level,
GLsizei samples)
{}
void INTERNAL_GL_APIENTRY glFramebufferTexture3DNULL(GLenum target,
GLenum attachment,
GLenum textarget,
......@@ -2248,6 +2264,20 @@ void INTERNAL_GL_APIENTRY glRenderbufferStorageMultisampleNULL(GLenum target,
GLsizei height)
{}
void INTERNAL_GL_APIENTRY glRenderbufferStorageMultisampleEXTNULL(GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height)
{}
void INTERNAL_GL_APIENTRY glRenderbufferStorageMultisampleIMGNULL(GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height)
{}
void INTERNAL_GL_APIENTRY glResumeTransformFeedbackNULL() {}
void INTERNAL_GL_APIENTRY glSampleCoverageNULL(GLfloat value, GLboolean invert) {}
......
......@@ -568,6 +568,18 @@ void INTERNAL_GL_APIENTRY glFramebufferTexture2DNULL(GLenum target,
GLenum textarget,
GLuint texture,
GLint level);
void INTERNAL_GL_APIENTRY glFramebufferTexture2DMultisampleEXTNULL(GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level,
GLsizei samples);
void INTERNAL_GL_APIENTRY glFramebufferTexture2DMultisampleIMGNULL(GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level,
GLsizei samples);
void INTERNAL_GL_APIENTRY glFramebufferTexture3DNULL(GLenum target,
GLenum attachment,
GLenum textarget,
......@@ -1421,6 +1433,16 @@ void INTERNAL_GL_APIENTRY glRenderbufferStorageMultisampleNULL(GLenum target,
GLenum internalformat,
GLsizei width,
GLsizei height);
void INTERNAL_GL_APIENTRY glRenderbufferStorageMultisampleEXTNULL(GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height);
void INTERNAL_GL_APIENTRY glRenderbufferStorageMultisampleIMGNULL(GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height);
void INTERNAL_GL_APIENTRY glResumeTransformFeedbackNULL();
void INTERNAL_GL_APIENTRY glSampleCoverageNULL(GLfloat value, GLboolean invert);
void INTERNAL_GL_APIENTRY glSampleMaskiNULL(GLuint maskNumber, GLbitfield mask);
......
......@@ -118,12 +118,24 @@ bool IsAdreno42xOr3xx(const FunctionsGL *functions)
return number != 0 && getAdrenoNumber(functions) < 430;
}
bool IsAdreno4xx(const FunctionsGL *functions)
{
int number = getAdrenoNumber(functions);
return number != 0 && number >= 400 && number < 500;
}
bool IsAdreno5xxOrOlder(const FunctionsGL *functions)
{
int number = getAdrenoNumber(functions);
return number != 0 && number < 600;
}
bool IsAdreno5xx(const FunctionsGL *functions)
{
int number = getAdrenoNumber(functions);
return number != 0 && number >= 500 && number < 600;
}
bool IsMaliT8xxOrOlder(const FunctionsGL *functions)
{
int number = getMaliTNumber(functions);
......@@ -1383,6 +1395,14 @@ void GenerateCaps(const FunctionsGL *functions,
extensions->framebufferBlitANGLE =
extensions->framebufferBlitNV || functions->hasGLESExtension("GL_ANGLE_framebuffer_blit");
extensions->framebufferMultisample = extensions->framebufferBlitANGLE && caps->maxSamples > 0;
extensions->multisampledRenderToTexture =
!features.disableMultisampledRenderToTexture.enabled &&
(functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture") ||
functions->hasGLESExtension("GL_IMG_multisampled_render_to_texture"));
extensions->multisampledRenderToTexture2 =
!features.disableMultisampledRenderToTexture.enabled &&
extensions->multisampledRenderToTexture &&
functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture2");
extensions->standardDerivativesOES = functions->isAtLeastGL(gl::Version(2, 0)) ||
functions->hasGLExtension("GL_ARB_fragment_shader") ||
functions->hasGLESExtension("GL_OES_standard_derivatives");
......@@ -2114,6 +2134,31 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
// http://crbug.com/1181068 and http://crbug.com/783979
ANGLE_FEATURE_CONDITION(features, flushOnFramebufferChange,
IsApple() && Has9thGenIntelGPU(systemInfo));
// Disable GL_EXT_multisampled_render_to_texture on a bunch of different configurations:
// http://crbug.com/490379
// http://crbug.com/767913
bool isAdreno4xxOnAndroidLessThan51 =
IsAndroid() && IsAdreno4xx(functions) && GetAndroidSdkLevel() < 22;
// http://crbug.com/612474
bool isAdreno4xxOnAndroid70 =
IsAndroid() && IsAdreno4xx(functions) && GetAndroidSdkLevel() == 24;
bool isAdreno5xxOnAndroidLessThan70 =
IsAndroid() && IsAdreno5xx(functions) && GetAndroidSdkLevel() < 24;
// http://crbug.com/663811
bool isAdreno5xxOnAndroid71 =
IsAndroid() && IsAdreno5xx(functions) && GetAndroidSdkLevel() == 25;
// http://crbug.com/594016
bool isLinuxVivante = IsLinux() && IsVivante(device);
ANGLE_FEATURE_CONDITION(features, disableMultisampledRenderToTexture,
isAdreno4xxOnAndroidLessThan51 || isAdreno4xxOnAndroid70 ||
isAdreno5xxOnAndroidLessThan70 || isAdreno5xxOnAndroid71 ||
isLinuxVivante);
}
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
......
......@@ -44,9 +44,9 @@
5981 PIXEL4ORXL GLES : MipmapTest.RenderOntoLevelZeroAfterGenerateMipmap/* = SKIP
5981 PIXEL4ORXL GLES : MipmapTest.TextureCubeGeneralLevelZero/* = SKIP
5981 PIXEL4ORXL GLES : MipmapTest.TextureCubeRenderToLevelZero/* = SKIP
5995 PIXEL4ORXL GLES : MultisampledRenderToTextureES3Test.BlitFramebufferTest/* = FAIL
5995 PIXEL4ORXL GLES : MultisampledRenderToTextureES3Test.ClearThenMaskedClearFramebufferTest/* = FAIL
5995 PIXEL4ORXL GLES : MultisampledRenderToTextureES3Test.RenderbufferBlitFramebufferTest/* = FAIL
2894 PIXEL4ORXL GLES : MultisampledRenderToTextureES3Test.BlitFramebufferTest/* = SKIP
2894 PIXEL4ORXL GLES : MultisampledRenderToTextureES3Test.ClearThenMaskedClearFramebufferTest/* = SKIP
2894 PIXEL4ORXL GLES : MultisampledRenderToTextureES3Test.RenderbufferBlitFramebufferTest/* = SKIP
5981 PIXEL4ORXL GLES : MultithreadingTestES3.MultithreadFenceTexImage/* = SKIP
5981 PIXEL4ORXL GLES : PbufferTest.ClearAndBindTexImageSrgb/* = SKIP
5981 PIXEL4ORXL GLES : ReadPixelsPBOTest.ExistingDataPreserved/* = SKIP
......
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