Commit a7b35c33 by Olli Etuaho Committed by Commit Bot

Add helpers for multiview framebuffer init

Multiview tests now use common helpers to create textures for multiview framebuffers and often also to attach the textures to the framebuffers. The tests now rely on uploaded texture data to initialize the buffers instead of clearing the framebuffers with glClear. BUG=angleproject:2765 TEST=angle_end2end_tests Change-Id: I7d6d63add5943cab610ab888045d5b0f8ba29215 Reviewed-on: https://chromium-review.googlesource.com/1184712Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 5fea1b76
...@@ -73,10 +73,10 @@ class FramebufferMultiviewSideBySideClearTest : public FramebufferMultiviewTest ...@@ -73,10 +73,10 @@ class FramebufferMultiviewSideBySideClearTest : public FramebufferMultiviewTest
void initializeFBOs(size_t numColorBuffers, bool stencil, bool depth) void initializeFBOs(size_t numColorBuffers, bool stencil, bool depth)
{ {
const std::vector<GLenum> &drawBuffers = GetDrawBufferRange(2); ASSERT(mColorTex.empty() && mDepthStencilTex == 0u && mDepthTex == 0u);
const std::vector<GLenum> &drawBuffers = GetDrawBufferRange(numColorBuffers);
// Generate textures. // Generate textures.
// Generate textures.
mColorTex.resize(numColorBuffers); mColorTex.resize(numColorBuffers);
glGenTextures(mColorTex.size(), mColorTex.data()); glGenTextures(mColorTex.size(), mColorTex.data());
if (stencil) if (stencil)
...@@ -88,24 +88,8 @@ class FramebufferMultiviewSideBySideClearTest : public FramebufferMultiviewTest ...@@ -88,24 +88,8 @@ class FramebufferMultiviewSideBySideClearTest : public FramebufferMultiviewTest
glGenTextures(1, &mDepthTex); glGenTextures(1, &mDepthTex);
} }
for (size_t i = 0u; i < numColorBuffers; ++i) CreateMultiviewBackingTextures(GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE, 2, 2, 2,
{ mColorTex, mDepthTex, mDepthStencilTex);
glBindTexture(GL_TEXTURE_2D, mColorTex[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
}
if (stencil)
{
glBindTexture(GL_TEXTURE_2D, mDepthStencilTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 4, 2, 0, GL_DEPTH_STENCIL,
GL_UNSIGNED_INT_24_8, nullptr);
}
else if (depth)
{
glBindTexture(GL_TEXTURE_2D, mDepthTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 4, 2, 0, GL_DEPTH_COMPONENT,
GL_FLOAT, nullptr);
}
glGenFramebuffers(1, &mMultiviewFBO); glGenFramebuffers(1, &mMultiviewFBO);
glGenFramebuffers(1, &mNonMultiviewFBO); glGenFramebuffers(1, &mNonMultiviewFBO);
...@@ -228,6 +212,7 @@ class FramebufferMultiviewLayeredClearTest : public FramebufferMultiviewTest ...@@ -228,6 +212,7 @@ class FramebufferMultiviewLayeredClearTest : public FramebufferMultiviewTest
bool stencil, bool stencil,
bool depth) bool depth)
{ {
ASSERT(mColorTex.empty() && mDepthStencilTex == 0u && mDepthTex == 0u);
ASSERT(baseViewIndex + numViews <= numLayers); ASSERT(baseViewIndex + numViews <= numLayers);
// Generate textures. // Generate textures.
...@@ -242,56 +227,22 @@ class FramebufferMultiviewLayeredClearTest : public FramebufferMultiviewTest ...@@ -242,56 +227,22 @@ class FramebufferMultiviewLayeredClearTest : public FramebufferMultiviewTest
glGenTextures(1, &mDepthTex); glGenTextures(1, &mDepthTex);
} }
for (int i = 0; i < numColorAttachments; ++i) CreateMultiviewBackingTextures(GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE, width, height,
{ numLayers, mColorTex, mDepthTex, mDepthStencilTex);
glBindTexture(GL_TEXTURE_2D_ARRAY, mColorTex[i]);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, width, height, numLayers, 0, GL_RGBA,
GL_UNSIGNED_BYTE, nullptr);
}
if (stencil)
{
glBindTexture(GL_TEXTURE_2D_ARRAY, mDepthStencilTex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH24_STENCIL8, width, height, numLayers, 0,
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
}
else if (depth)
{
glBindTexture(GL_TEXTURE_2D_ARRAY, mDepthTex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, width, height, numLayers, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
}
glGenFramebuffers(1, &mMultiviewFBO); glGenFramebuffers(1, &mMultiviewFBO);
// Generate multiview FBO and attach textures. // Generate multiview FBO and attach textures.
glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO); glBindFramebuffer(GL_FRAMEBUFFER, mMultiviewFBO);
for (int i = 0; i < numColorAttachments; ++i) AttachMultiviewTextures(GL_FRAMEBUFFER, GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE, width,
{ numViews, baseViewIndex, mColorTex, mDepthTex, mDepthStencilTex);
glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER,
static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i),
mColorTex[i], 0, baseViewIndex, numViews);
}
if (stencil)
{
glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
mDepthStencilTex, 0, baseViewIndex, numViews);
}
else if (depth)
{
glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
mDepthTex, 0, baseViewIndex, numViews);
}
const auto &drawBuffers = GetDrawBufferRange(numColorAttachments); const auto &drawBuffers = GetDrawBufferRange(numColorAttachments);
glDrawBuffers(numColorAttachments, drawBuffers.data()); glDrawBuffers(numColorAttachments, drawBuffers.data());
mNonMultiviewFBO.resize(numLayers);
glGenFramebuffers(mNonMultiviewFBO.size(), mNonMultiviewFBO.data());
// Generate non-multiview FBOs and attach textures. // Generate non-multiview FBOs and attach textures.
mNonMultiviewFBO.resize(numLayers); mNonMultiviewFBO.resize(numLayers);
glGenFramebuffers(mNonMultiviewFBO.size(), mNonMultiviewFBO.data());
for (int i = 0; i < numLayers; ++i) for (int i = 0; i < numLayers; ++i)
{ {
glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]); glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]);
...@@ -311,9 +262,6 @@ class FramebufferMultiviewLayeredClearTest : public FramebufferMultiviewTest ...@@ -311,9 +262,6 @@ class FramebufferMultiviewLayeredClearTest : public FramebufferMultiviewTest
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mDepthTex, 0, i); glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mDepthTex, 0, i);
} }
glDrawBuffers(numColorAttachments, drawBuffers.data()); glDrawBuffers(numColorAttachments, drawBuffers.data());
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
} }
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
...@@ -1184,10 +1132,10 @@ TEST_P(FramebufferMultiviewLayeredClearTest, ColorBufferClear) ...@@ -1184,10 +1132,10 @@ TEST_P(FramebufferMultiviewLayeredClearTest, ColorBufferClear)
glClearColor(0, 1, 0, 1); glClearColor(0, 1, 0, 1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0));
EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0));
EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0));
EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0));
} }
// Test that glClearBufferfv can be used to clear individual color buffers of a layered FBO. // Test that glClearBufferfv can be used to clear individual color buffers of a layered FBO.
...@@ -1202,7 +1150,7 @@ TEST_P(FramebufferMultiviewLayeredClearTest, ClearIndividualColorBuffer) ...@@ -1202,7 +1150,7 @@ TEST_P(FramebufferMultiviewLayeredClearTest, ClearIndividualColorBuffer)
for (int layer = 0; layer < 4; ++layer) for (int layer = 0; layer < 4; ++layer)
{ {
GLenum colorAttachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i); GLenum colorAttachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i);
EXPECT_EQ(GLColor::red, getLayerColor(layer, colorAttachment)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(layer, colorAttachment));
} }
} }
...@@ -1214,15 +1162,15 @@ TEST_P(FramebufferMultiviewLayeredClearTest, ClearIndividualColorBuffer) ...@@ -1214,15 +1162,15 @@ TEST_P(FramebufferMultiviewLayeredClearTest, ClearIndividualColorBuffer)
float clearValues1[4] = {0.f, 1.f, 0.f, 1.f}; float clearValues1[4] = {0.f, 1.f, 0.f, 1.f};
glClearBufferfv(GL_COLOR, 1, clearValues1); glClearBufferfv(GL_COLOR, 1, clearValues1);
EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0));
EXPECT_EQ(GLColor::blue, getLayerColor(1, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::blue, getLayerColor(1, GL_COLOR_ATTACHMENT0));
EXPECT_EQ(GLColor::blue, getLayerColor(2, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::blue, getLayerColor(2, GL_COLOR_ATTACHMENT0));
EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0));
EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT1)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT1));
EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT1)); EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT1));
EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT1)); EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT1));
EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT1)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT1));
} }
// Test that glClearBufferfi clears the contents of the stencil buffer for only the attached layers // Test that glClearBufferfi clears the contents of the stencil buffer for only the attached layers
...@@ -1300,10 +1248,10 @@ TEST_P(FramebufferMultiviewLayeredClearTest, UnmodifiedDetachedTexture) ...@@ -1300,10 +1248,10 @@ TEST_P(FramebufferMultiviewLayeredClearTest, UnmodifiedDetachedTexture)
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
{ {
GLenum colorAttachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i); GLenum colorAttachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i);
EXPECT_EQ(GLColor::red, getLayerColor(0, colorAttachment)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, colorAttachment));
EXPECT_EQ(GLColor::green, getLayerColor(1, colorAttachment)); EXPECT_EQ(GLColor::green, getLayerColor(1, colorAttachment));
EXPECT_EQ(GLColor::green, getLayerColor(2, colorAttachment)); EXPECT_EQ(GLColor::green, getLayerColor(2, colorAttachment));
EXPECT_EQ(GLColor::red, getLayerColor(3, colorAttachment)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, colorAttachment));
} }
// Detach and clear again. // Detach and clear again.
...@@ -1313,16 +1261,16 @@ TEST_P(FramebufferMultiviewLayeredClearTest, UnmodifiedDetachedTexture) ...@@ -1313,16 +1261,16 @@ TEST_P(FramebufferMultiviewLayeredClearTest, UnmodifiedDetachedTexture)
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
// Check that color attachment 0 is modified. // Check that color attachment 0 is modified.
EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0));
EXPECT_EQ(GLColor::yellow, getLayerColor(1, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::yellow, getLayerColor(1, GL_COLOR_ATTACHMENT0));
EXPECT_EQ(GLColor::yellow, getLayerColor(2, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::yellow, getLayerColor(2, GL_COLOR_ATTACHMENT0));
EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0));
// Check that color attachment 1 is unmodified. // Check that color attachment 1 is unmodified.
EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT1)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT1));
EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT1)); EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT1));
EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT1)); EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT1));
EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT1)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT1));
} }
// Test that glClear clears only the contents within the scissor rectangle of the attached layers. // Test that glClear clears only the contents within the scissor rectangle of the attached layers.
...@@ -1340,17 +1288,17 @@ TEST_P(FramebufferMultiviewLayeredClearTest, ScissoredClear) ...@@ -1340,17 +1288,17 @@ TEST_P(FramebufferMultiviewLayeredClearTest, ScissoredClear)
glClearColor(0, 1, 0, 1); glClearColor(0, 1, 0, 1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0, 0, 0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0, 0, 0));
EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0, 1, 0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(0, GL_COLOR_ATTACHMENT0, 1, 0));
EXPECT_EQ(GLColor::red, getLayerColor(1, GL_COLOR_ATTACHMENT0, 0, 0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(1, GL_COLOR_ATTACHMENT0, 0, 0));
EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0, 1, 0)); EXPECT_EQ(GLColor::green, getLayerColor(1, GL_COLOR_ATTACHMENT0, 1, 0));
EXPECT_EQ(GLColor::red, getLayerColor(2, GL_COLOR_ATTACHMENT0, 0, 0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(2, GL_COLOR_ATTACHMENT0, 0, 0));
EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0, 1, 0)); EXPECT_EQ(GLColor::green, getLayerColor(2, GL_COLOR_ATTACHMENT0, 1, 0));
EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT0, 0, 0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0, 0, 0));
EXPECT_EQ(GLColor::red, getLayerColor(3, GL_COLOR_ATTACHMENT0, 1, 0)); EXPECT_EQ(GLColor::transparentBlack, getLayerColor(3, GL_COLOR_ATTACHMENT0, 1, 0));
} }
// Test that glClearBufferfi clears the contents of the stencil buffer for only the attached layers // Test that glClearBufferfi clears the contents of the stencil buffer for only the attached layers
...@@ -1404,10 +1352,10 @@ TEST_P(FramebufferMultiviewLayeredClearTest, ScissoredClearBufferfi) ...@@ -1404,10 +1352,10 @@ TEST_P(FramebufferMultiviewLayeredClearTest, ScissoredClearBufferfi)
// the test. // the test.
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_EQUAL, 0x00, 0xFF); glStencilFunc(GL_EQUAL, 0x00, 0xFF);
glUniform3f(mColorUniformLoc, 0.0f, 1.0f, 0.0f);
for (size_t i = 0u; i < mNonMultiviewFBO.size(); ++i) for (size_t i = 0u; i < mNonMultiviewFBO.size(); ++i)
{ {
glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]); glBindFramebuffer(GL_FRAMEBUFFER, mNonMultiviewFBO[i]);
glUniform3f(mColorUniformLoc, 0.0f, 1.0f, 0.0f);
drawQuad(program, "vPos", 0.0f, 1.0f, true); drawQuad(program, "vPos", 0.0f, 1.0f, true);
} }
EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0, 0, 0)); EXPECT_EQ(GLColor::red, getLayerColor(0, GL_COLOR_ATTACHMENT0, 0, 0));
......
...@@ -101,78 +101,16 @@ class MultiviewFramebufferTestBase : public MultiviewTestBase ...@@ -101,78 +101,16 @@ class MultiviewFramebufferTestBase : public MultiviewTestBase
glGenTextures(1, &mColorTexture); glGenTextures(1, &mColorTexture);
glGenTextures(1, &mDepthTexture); glGenTextures(1, &mDepthTexture);
// Create color and depth textures. CreateMultiviewBackingTextures(mMultiviewLayout, viewWidth, height, numLayers,
switch (mMultiviewLayout) mColorTexture, mDepthTexture, 0u);
{
case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE:
{
int textureWidth = viewWidth * numViews;
glBindTexture(GL_TEXTURE_2D, mColorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, mDepthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, textureWidth, height, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
glBindTexture(GL_TEXTURE_2D, 0);
break;
}
case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
glBindTexture(GL_TEXTURE_2D_ARRAY, mColorTexture);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, viewWidth, height, numLayers, 0,
GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D_ARRAY, mDepthTexture);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, viewWidth, height,
numLayers, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
break;
default:
UNREACHABLE();
}
ASSERT_GL_NO_ERROR();
glGenFramebuffers(1, &mDrawFramebuffer); glGenFramebuffers(1, &mDrawFramebuffer);
// Create draw framebuffer to be used for multiview rendering. // Create draw framebuffer to be used for multiview rendering.
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawFramebuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawFramebuffer);
switch (mMultiviewLayout) AttachMultiviewTextures(GL_DRAW_FRAMEBUFFER, mMultiviewLayout, viewWidth, numViews,
{ baseViewIndex, mColorTexture, mDepthTexture, 0u);
case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE:
{
std::vector<GLint> viewportOffsets(numViews * 2);
for (int i = 0u; i < numViews; ++i)
{
viewportOffsets[i * 2] = i * viewWidth;
viewportOffsets[i * 2 + 1] = 0;
}
glFramebufferTextureMultiviewSideBySideANGLE(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0, mColorTexture, 0,
numViews, &viewportOffsets[0]);
glFramebufferTextureMultiviewSideBySideANGLE(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT, mDepthTexture, 0,
numViews, &viewportOffsets[0]);
break;
}
case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
glFramebufferTextureMultiviewLayeredANGLE(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
mColorTexture, 0, baseViewIndex,
numViews);
glFramebufferTextureMultiviewLayeredANGLE(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
mDepthTexture, 0, baseViewIndex,
numViews);
break;
default:
UNREACHABLE();
}
GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, DrawBuffers);
ASSERT_GL_NO_ERROR();
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)); ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
// Create read framebuffer to be used to retrieve the pixel information for testing // Create read framebuffer to be used to retrieve the pixel information for testing
...@@ -193,15 +131,12 @@ class MultiviewFramebufferTestBase : public MultiviewTestBase ...@@ -193,15 +131,12 @@ class MultiviewFramebufferTestBase : public MultiviewTestBase
glGenFramebuffers(mReadFramebuffer.size(), mReadFramebuffer.data()); glGenFramebuffers(mReadFramebuffer.size(), mReadFramebuffer.data());
for (int i = 0; i < numLayers; ++i) for (int i = 0; i < numLayers; ++i)
{ {
glBindFramebuffer(GL_FRAMEBUFFER, mReadFramebuffer[i]); glBindFramebuffer(GL_READ_FRAMEBUFFER, mReadFramebuffer[i]);
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mColorTexture, glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
0, i); mColorTexture, 0, i);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE,
glCheckFramebufferStatus(GL_READ_FRAMEBUFFER)); glCheckFramebufferStatus(GL_READ_FRAMEBUFFER));
} }
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawFramebuffer);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -215,8 +150,6 @@ class MultiviewFramebufferTestBase : public MultiviewTestBase ...@@ -215,8 +150,6 @@ class MultiviewFramebufferTestBase : public MultiviewTestBase
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, viewWidth, height); glScissor(0, 0, viewWidth, height);
} }
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
void updateFBOs(int viewWidth, int height, int numViews) void updateFBOs(int viewWidth, int height, int numViews)
...@@ -231,6 +164,7 @@ class MultiviewFramebufferTestBase : public MultiviewTestBase ...@@ -231,6 +164,7 @@ class MultiviewFramebufferTestBase : public MultiviewTestBase
switch (mMultiviewLayout) switch (mMultiviewLayout)
{ {
case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE: case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE:
glBindFramebuffer(GL_READ_FRAMEBUFFER, mReadFramebuffer[0]);
return ReadColor(view * mViewWidth + x, y); return ReadColor(view * mViewWidth + x, y);
case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE: case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
ASSERT(static_cast<size_t>(view) < mReadFramebuffer.size()); ASSERT(static_cast<size_t>(view) < mReadFramebuffer.size());
...@@ -346,10 +280,10 @@ class MultiviewRenderDualViewTest : public MultiviewRenderTest ...@@ -346,10 +280,10 @@ class MultiviewRenderDualViewTest : public MultiviewRenderTest
void checkOutput() void checkOutput()
{ {
EXPECT_EQ(GLColor::black, GetViewColor(0, 0, 0)); EXPECT_EQ(GLColor::transparentBlack, GetViewColor(0, 0, 0));
EXPECT_EQ(GLColor::green, GetViewColor(1, 0, 0)); EXPECT_EQ(GLColor::green, GetViewColor(1, 0, 0));
EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1)); EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1));
EXPECT_EQ(GLColor::black, GetViewColor(1, 0, 1)); EXPECT_EQ(GLColor::transparentBlack, GetViewColor(1, 0, 1));
} }
GLuint mProgram; GLuint mProgram;
...@@ -464,7 +398,8 @@ class MultiviewRenderPrimitiveTest : public MultiviewRenderTest ...@@ -464,7 +398,8 @@ class MultiviewRenderPrimitiveTest : public MultiviewRenderTest
{ {
size_t flatIndex = size_t flatIndex =
static_cast<size_t>(view * mViewWidth * mViewHeight + mViewWidth * h + w); static_cast<size_t>(view * mViewWidth * mViewHeight + mViewWidth * h + w);
EXPECT_EQ(GLColor(0, expectedGreenChannelData[flatIndex], 0, 255), EXPECT_EQ(GLColor(0, expectedGreenChannelData[flatIndex], 0,
expectedGreenChannelData[flatIndex]),
GetViewColor(w, h, view)); GetViewColor(w, h, view));
} }
} }
...@@ -996,7 +931,7 @@ TEST_P(MultiviewRenderTest, DrawArraysFourViews) ...@@ -996,7 +931,7 @@ TEST_P(MultiviewRenderTest, DrawArraysFourViews)
} }
else else
{ {
EXPECT_EQ(GLColor::black, GetViewColor(j, 0, i)); EXPECT_EQ(GLColor::transparentBlack, GetViewColor(j, 0, i));
} }
} }
} }
...@@ -1056,7 +991,8 @@ TEST_P(MultiviewRenderTest, DrawArraysInstanced) ...@@ -1056,7 +991,8 @@ TEST_P(MultiviewRenderTest, DrawArraysInstanced)
{ {
for (int x = 0; x < 2; ++x) for (int x = 0; x < 2; ++x)
{ {
EXPECT_EQ(GLColor(0, expectedGreenChannel[view][y][x], 0, 255), EXPECT_EQ(GLColor(0, expectedGreenChannel[view][y][x], 0,
expectedGreenChannel[view][y][x]),
GetViewColor(x, y, view)); GetViewColor(x, y, view));
} }
} }
...@@ -1145,7 +1081,8 @@ TEST_P(MultiviewRenderTest, AttribDivisor) ...@@ -1145,7 +1081,8 @@ TEST_P(MultiviewRenderTest, AttribDivisor)
{ {
for (int col = 0; col < 4; ++col) for (int col = 0; col < 4; ++col)
{ {
EXPECT_EQ(GLColor(0, expectedGreenChannel[view][row][col], 0, 255), EXPECT_EQ(GLColor(0, expectedGreenChannel[view][row][col], 0,
expectedGreenChannel[view][row][col]),
GetViewColor(col, row, view)); GetViewColor(col, row, view));
} }
} }
...@@ -1812,9 +1749,9 @@ TEST_P(MultiviewSideBySideRenderTest, NoLeakingFragments) ...@@ -1812,9 +1749,9 @@ TEST_P(MultiviewSideBySideRenderTest, NoLeakingFragments)
{ {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_POINTS, 0, 2); glDrawArrays(GL_POINTS, 0, 2);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::red); EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::red);
EXPECT_PIXEL_COLOR_EQ(2, 0, GLColor::black); EXPECT_PIXEL_COLOR_EQ(2, 0, GLColor::transparentBlack);
EXPECT_PIXEL_COLOR_EQ(3, 0, GLColor::green); EXPECT_PIXEL_COLOR_EQ(3, 0, GLColor::green);
} }
...@@ -1823,9 +1760,9 @@ TEST_P(MultiviewSideBySideRenderTest, NoLeakingFragments) ...@@ -1823,9 +1760,9 @@ TEST_P(MultiviewSideBySideRenderTest, NoLeakingFragments)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLineWidth(10.f); glLineWidth(10.f);
glDrawArrays(GL_LINES, 0, 2); glDrawArrays(GL_LINES, 0, 2);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::red); EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::red);
EXPECT_PIXEL_COLOR_EQ(2, 0, GLColor::black); EXPECT_PIXEL_COLOR_EQ(2, 0, GLColor::transparentBlack);
EXPECT_PIXEL_COLOR_EQ(3, 0, GLColor::green); EXPECT_PIXEL_COLOR_EQ(3, 0, GLColor::green);
} }
} }
...@@ -2027,7 +1964,7 @@ TEST_P(MultiviewRenderTest, DivisorUpdatedOnProgramChange) ...@@ -2027,7 +1964,7 @@ TEST_P(MultiviewRenderTest, DivisorUpdatedOnProgramChange)
} }
for (int j = numViews; j < 4; ++j) for (int j = numViews; j < 4; ++j)
{ {
EXPECT_EQ(GLColor::black, GetViewColor(j, 0, view)); EXPECT_EQ(GLColor::transparentBlack, GetViewColor(j, 0, view));
} }
} }
......
...@@ -40,6 +40,171 @@ GLuint CreateSimplePassthroughProgram(int numViews) ...@@ -40,6 +40,171 @@ GLuint CreateSimplePassthroughProgram(int numViews)
return CompileProgram(vsSource, fsSource); return CompileProgram(vsSource, fsSource);
} }
void CreateMultiviewBackingTextures(GLenum multiviewLayout,
int viewWidth,
int height,
int numLayers,
std::vector<GLuint> colorTextures,
GLuint depthTexture,
GLuint depthStencilTexture)
{
// The same zero data is used to initialize both color and depth/stencil textures.
std::vector<GLubyte> textureData;
textureData.resize(viewWidth * height * numLayers * 4, 0u);
// Create color and depth textures.
switch (multiviewLayout)
{
case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE:
{
int textureWidth = viewWidth * numLayers;
for (auto colorTexture : colorTextures)
{
glBindTexture(GL_TEXTURE_2D, colorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, textureData.data());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
if (depthTexture != 0)
{
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, textureWidth, height, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, textureData.data());
}
if (depthStencilTexture != 0)
{
glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, textureWidth, height, 0,
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, textureData.data());
}
glBindTexture(GL_TEXTURE_2D, 0);
break;
}
case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
for (auto colorTexture : colorTextures)
{
glBindTexture(GL_TEXTURE_2D_ARRAY, colorTexture);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, viewWidth, height, numLayers, 0,
GL_RGBA, GL_UNSIGNED_BYTE, textureData.data());
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
if (depthTexture != 0)
{
glBindTexture(GL_TEXTURE_2D_ARRAY, depthTexture);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, viewWidth, height,
numLayers, 0, GL_DEPTH_COMPONENT, GL_FLOAT, textureData.data());
}
if (depthStencilTexture != 0)
{
glBindTexture(GL_TEXTURE_2D_ARRAY, depthStencilTexture);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH24_STENCIL8, viewWidth, height,
numLayers, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
textureData.data());
}
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
break;
default:
UNREACHABLE();
}
ASSERT_GL_NO_ERROR();
}
void CreateMultiviewBackingTextures(GLenum multiviewLayout,
int viewWidth,
int height,
int numLayers,
GLuint colorTexture,
GLuint depthTexture,
GLuint depthStencilTexture)
{
ASSERT(colorTexture != 0u);
std::vector<GLuint> colorTextures(1, colorTexture);
CreateMultiviewBackingTextures(multiviewLayout, viewWidth, height, numLayers, colorTextures,
depthTexture, depthStencilTexture);
}
void AttachMultiviewTextures(GLenum target,
GLenum multiviewLayout,
int viewWidth,
int numViews,
int baseViewIndex,
std::vector<GLuint> colorTextures,
GLuint depthTexture,
GLuint depthStencilTexture)
{
ASSERT(multiviewLayout == GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE || (baseViewIndex == 0));
ASSERT(depthTexture == 0u || depthStencilTexture == 0u);
switch (multiviewLayout)
{
case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE:
{
std::vector<GLint> viewportOffsets(numViews * 2);
for (int i = 0u; i < numViews; ++i)
{
viewportOffsets[i * 2] = i * viewWidth;
viewportOffsets[i * 2 + 1] = 0;
}
for (size_t i = 0; i < colorTextures.size(); ++i)
{
glFramebufferTextureMultiviewSideBySideANGLE(target, GL_COLOR_ATTACHMENT0 + i,
colorTextures[i], 0, numViews,
viewportOffsets.data());
}
if (depthTexture)
{
glFramebufferTextureMultiviewSideBySideANGLE(
target, GL_DEPTH_ATTACHMENT, depthTexture, 0, numViews, viewportOffsets.data());
}
if (depthStencilTexture)
{
glFramebufferTextureMultiviewSideBySideANGLE(target, GL_DEPTH_STENCIL_ATTACHMENT,
depthStencilTexture, 0, numViews,
viewportOffsets.data());
}
break;
}
case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
for (size_t i = 0; i < colorTextures.size(); ++i)
{
glFramebufferTextureMultiviewLayeredANGLE(
target, GL_COLOR_ATTACHMENT0 + i, colorTextures[i], 0, baseViewIndex, numViews);
}
if (depthTexture)
{
glFramebufferTextureMultiviewLayeredANGLE(target, GL_DEPTH_ATTACHMENT, depthTexture,
0, baseViewIndex, numViews);
}
if (depthStencilTexture)
{
glFramebufferTextureMultiviewLayeredANGLE(target, GL_DEPTH_STENCIL_ATTACHMENT,
depthStencilTexture, 0, baseViewIndex,
numViews);
}
break;
default:
UNREACHABLE();
}
}
void AttachMultiviewTextures(GLenum target,
GLenum multiviewLayout,
int viewWidth,
int numViews,
int baseViewIndex,
GLuint colorTexture,
GLuint depthTexture,
GLuint depthStencilTexture)
{
ASSERT(colorTexture != 0u);
std::vector<GLuint> colorTextures(1, colorTexture);
AttachMultiviewTextures(target, multiviewLayout, viewWidth, numViews, baseViewIndex,
colorTextures, depthTexture, depthStencilTexture);
}
std::ostream &operator<<(std::ostream &os, const MultiviewImplementationParams &params) std::ostream &operator<<(std::ostream &os, const MultiviewImplementationParams &params)
{ {
const PlatformParameters &base = static_cast<const PlatformParameters &>(params); const PlatformParameters &base = static_cast<const PlatformParameters &>(params);
......
...@@ -19,6 +19,46 @@ namespace angle ...@@ -19,6 +19,46 @@ namespace angle
// fragments. // fragments.
GLuint CreateSimplePassthroughProgram(int numViews); GLuint CreateSimplePassthroughProgram(int numViews);
// Create a set of textures to use for multiview rendering. If multiviewLayout is
// GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE, then 2D textures are created. If multiviewLayout is
// GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE, then 2D texture arrays are created. Texture ids should be
// created beforehand. If depthTexture or stencilTexture is 0, it will not be initialized.
void CreateMultiviewBackingTextures(GLenum multiviewLayout,
int viewWidth,
int height,
int numLayers,
std::vector<GLuint> colorTextures,
GLuint depthTexture,
GLuint depthStencilTexture);
void CreateMultiviewBackingTextures(GLenum multiviewLayout,
int viewWidth,
int height,
int numLayers,
GLuint colorTexture,
GLuint depthTexture,
GLuint depthStencilTexture);
// Attach multiview textures to the framebuffer denoted by target. If there are multiple color
// textures they get attached to different color attachments starting from 0. If multiviewLayout is
// GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE, then the viewport offsets are set so that the views
// are tightly packed inside the attachments.
void AttachMultiviewTextures(GLenum target,
GLenum multiviewLayout,
int viewWidth,
int numViews,
int baseViewIndex,
std::vector<GLuint> colorTextures,
GLuint depthTexture,
GLuint depthStencilTexture);
void AttachMultiviewTextures(GLenum target,
GLenum multiviewLayout,
int viewWidth,
int numViews,
int baseViewIndex,
GLuint colorTexture,
GLuint depthTexture,
GLuint depthStencilTexture);
struct MultiviewImplementationParams : public PlatformParameters struct MultiviewImplementationParams : public PlatformParameters
{ {
MultiviewImplementationParams(GLint majorVersion, MultiviewImplementationParams(GLint majorVersion,
......
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