Support blitFramebuffer to and from IOSurface-backed textures.

Extend validation to allow texture rectangle-backed textures as
blitFramebuffer sources and destinations.

Add end-to-end test covering this functionality, and run the
IOSurfaceClientBufferTests against both ES2 and ES3.

Bug: angleproject:3669
Change-Id: I7b8815a2c98072c12de45717afbba9e9b29ba253
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1694483
Commit-Queue: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Kenneth Russell 2019-07-09 20:30:45 -07:00 коммит произвёл Commit Bot
Родитель 8db211bc8d
Коммит cbdf8616f9
4 изменённых файлов: 96 добавлений и 9 удалений

Просмотреть файл

@ -178,12 +178,6 @@ GLuint FramebufferAttachment::id() const
return mResource->getId();
}
const ImageIndex &FramebufferAttachment::getTextureImageIndex() const
{
ASSERT(type() == GL_TEXTURE);
return mTarget.textureIndex();
}
TextureTarget FramebufferAttachment::cubeMapFace() const
{
ASSERT(mType == GL_TEXTURE);

Просмотреть файл

@ -216,6 +216,12 @@ class FramebufferAttachmentObject : public angle::Subject
virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0;
};
inline const ImageIndex &FramebufferAttachment::getTextureImageIndex() const
{
ASSERT(type() == GL_TEXTURE);
return mTarget.textureIndex();
}
inline Extents FramebufferAttachment::getSize() const
{
ASSERT(mResource);

Просмотреть файл

@ -2671,7 +2671,9 @@ bool ValidateBlitFramebufferANGLE(Context *context,
if (readColorAttachment && drawColorAttachment)
{
if (!(readColorAttachment->type() == GL_TEXTURE &&
readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
(readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D ||
readColorAttachment->getTextureImageIndex().getType() ==
TextureType::Rectangle)) &&
readColorAttachment->type() != GL_RENDERBUFFER &&
readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
{
@ -2688,7 +2690,9 @@ bool ValidateBlitFramebufferANGLE(Context *context,
if (attachment)
{
if (!(attachment->type() == GL_TEXTURE &&
attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
(attachment->getTextureImageIndex().getType() == TextureType::_2D ||
attachment->getTextureImageIndex().getType() ==
TextureType::Rectangle)) &&
attachment->type() != GL_RENDERBUFFER &&
attachment->type() != GL_FRAMEBUFFER_DEFAULT)
{

Просмотреть файл

@ -241,6 +241,74 @@ class IOSurfaceClientBufferTest : public ANGLETest
ASSERT_GL_NO_ERROR();
}
void doBlitTest(bool ioSurfaceIsSource, int width, int height)
{
// Create IOSurface and bind it to a texture.
ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(width, height, 'BGRA', 4);
EGLSurface pbuffer;
GLTexture texture;
bindIOSurfaceToTexture(ioSurface, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, &pbuffer,
&texture);
GLFramebuffer iosurfaceFbo;
glBindFramebuffer(GL_FRAMEBUFFER, iosurfaceFbo);
EXPECT_GL_NO_ERROR();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ANGLE,
texture, 0);
EXPECT_GL_NO_ERROR();
EXPECT_GLENUM_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE);
EXPECT_GL_NO_ERROR();
// Create another framebuffer with a regular renderbuffer.
GLFramebuffer fbo;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
EXPECT_GL_NO_ERROR();
GLRenderbuffer rbo;
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
EXPECT_GL_NO_ERROR();
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
EXPECT_GL_NO_ERROR();
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
EXPECT_GL_NO_ERROR();
EXPECT_GLENUM_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE);
EXPECT_GL_NO_ERROR();
glBindRenderbuffer(GL_RENDERBUFFER, 0);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
EXPECT_GL_NO_ERROR();
// Choose which is going to be the source and destination.
GLFramebuffer &src = ioSurfaceIsSource ? iosurfaceFbo : fbo;
GLFramebuffer &dst = ioSurfaceIsSource ? fbo : iosurfaceFbo;
// Clear source to known color.
glBindFramebuffer(GL_FRAMEBUFFER, src);
glClearColor(1.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 4.0f / 255.0f);
EXPECT_GL_NO_ERROR();
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_GL_NO_ERROR();
// Blit to destination.
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, dst);
glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT,
GL_NEAREST);
// Read back from destination.
glBindFramebuffer(GL_FRAMEBUFFER, dst);
GLColor expectedColor(1, 2, 3, 4);
EXPECT_PIXEL_COLOR_EQ(0, 0, expectedColor);
// Unbind pbuffer and check content.
EGLBoolean result = eglReleaseTexImage(mDisplay, pbuffer, EGL_BACK_BUFFER);
EXPECT_EGL_TRUE(result);
EXPECT_EGL_SUCCESS();
result = eglDestroySurface(mDisplay, pbuffer);
EXPECT_EGL_TRUE(result);
EXPECT_EGL_SUCCESS();
}
EGLConfig mConfig;
EGLDisplay mDisplay;
};
@ -302,6 +370,9 @@ TEST_P(IOSurfaceClientBufferTest, ReadFromR8IOSurface)
// Test using R16 IOSurfaces for rendering
TEST_P(IOSurfaceClientBufferTest, RenderToR16IOSurface)
{
// This test only works on ES3.
ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
// HACK(cwallez@chromium.org) 'L016' doesn't seem to be an official pixel format but it works
// sooooooo let's test using it
ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'L016', 2);
@ -314,6 +385,18 @@ TEST_P(IOSurfaceClientBufferTest, RenderToR16IOSurface)
// TODO(cwallez@chromium.org): Test using RGBA half float IOSurfaces ('RGhA')
// Test blitting from IOSurface
TEST_P(IOSurfaceClientBufferTest, BlitFromIOSurface)
{
doBlitTest(true, 2, 2);
}
// Test blitting to IOSurface
TEST_P(IOSurfaceClientBufferTest, BlitToIOSurface)
{
doBlitTest(false, 2, 2);
}
// Test the validation errors for missing attributes for eglCreatePbufferFromClientBuffer with
// IOSurface
TEST_P(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes)
@ -726,4 +809,4 @@ TEST_P(IOSurfaceClientBufferTest, MakeCurrent)
// TODO(cwallez@chromium.org): Test setting width and height to less than the IOSurface's work as
// expected.
ANGLE_INSTANTIATE_TEST(IOSurfaceClientBufferTest, ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(IOSurfaceClientBufferTest, ES2_OPENGL(), ES3_OPENGL());