Commit e5285d29 by Martin Radev Committed by Commit Bot

Handle ANGLE_multiview state queries

The patch extends glGetIntegerv and glGetFramebufferAttachmentParameteriv logic to handle the new tokens from the ANGLE_multiview extension. BUG=angleproject:2062 TEST=angle_end2end_tests Change-Id: Ide145279cd7b58cd03502458d7d3a1a0f5e9e86d Reviewed-on: https://chromium-review.googlesource.com/573780Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 6170bef8
...@@ -1522,6 +1522,11 @@ void Context::getIntegervImpl(GLenum pname, GLint *params) ...@@ -1522,6 +1522,11 @@ void Context::getIntegervImpl(GLenum pname, GLint *params)
*params = mExtensions.maxLabelLength; *params = mExtensions.maxLabelLength;
break; break;
// GL_ANGLE_multiview
case GL_MAX_VIEWS_ANGLE:
*params = mExtensions.maxViews;
break;
// GL_EXT_disjoint_timer_query // GL_EXT_disjoint_timer_query
case GL_GPU_DISJOINT_EXT: case GL_GPU_DISJOINT_EXT:
*params = mImplementation->getGPUDisjoint(); *params = mImplementation->getGPUDisjoint();
......
...@@ -514,6 +514,13 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign ...@@ -514,6 +514,13 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign
return true; return true;
} }
if (getExtensions().multiview && pname == GL_MAX_VIEWS_ANGLE)
{
*type = GL_INT;
*numParams = 1;
return true;
}
if (getClientVersion() < Version(3, 0)) if (getClientVersion() < Version(3, 0))
{ {
return false; return false;
......
...@@ -51,7 +51,12 @@ FramebufferAttachment::Target &FramebufferAttachment::Target::operator=(const Ta ...@@ -51,7 +51,12 @@ FramebufferAttachment::Target &FramebufferAttachment::Target::operator=(const Ta
////// FramebufferAttachment Implementation ////// ////// FramebufferAttachment Implementation //////
FramebufferAttachment::FramebufferAttachment() FramebufferAttachment::FramebufferAttachment()
: mType(GL_NONE), mResource(nullptr) : mType(GL_NONE),
mResource(nullptr),
mNumViews(1),
mMultiviewLayout(GL_NONE),
mBaseViewIndex(0),
mViewportOffsets(1u)
{ {
} }
...@@ -60,7 +65,11 @@ FramebufferAttachment::FramebufferAttachment(const Context *context, ...@@ -60,7 +65,11 @@ FramebufferAttachment::FramebufferAttachment(const Context *context,
GLenum binding, GLenum binding,
const ImageIndex &textureIndex, const ImageIndex &textureIndex,
FramebufferAttachmentObject *resource) FramebufferAttachmentObject *resource)
: mResource(nullptr) : mResource(nullptr),
mNumViews(1),
mMultiviewLayout(GL_NONE),
mBaseViewIndex(0),
mViewportOffsets(1u)
{ {
attach(context, type, binding, textureIndex, resource); attach(context, type, binding, textureIndex, resource);
} }
...@@ -76,6 +85,10 @@ FramebufferAttachment &FramebufferAttachment::operator=(FramebufferAttachment && ...@@ -76,6 +85,10 @@ FramebufferAttachment &FramebufferAttachment::operator=(FramebufferAttachment &&
std::swap(mType, other.mType); std::swap(mType, other.mType);
std::swap(mTarget, other.mTarget); std::swap(mTarget, other.mTarget);
std::swap(mResource, other.mResource); std::swap(mResource, other.mResource);
std::swap(mNumViews, other.mNumViews);
std::swap(mMultiviewLayout, other.mMultiviewLayout);
std::swap(mBaseViewIndex, other.mBaseViewIndex);
std::swap(mViewportOffsets, other.mViewportOffsets);
return *this; return *this;
} }
...@@ -92,6 +105,11 @@ void FramebufferAttachment::detach(const Context *context) ...@@ -92,6 +105,11 @@ void FramebufferAttachment::detach(const Context *context)
mResource->onDetach(context); mResource->onDetach(context);
mResource = nullptr; mResource = nullptr;
} }
mNumViews = 1;
mMultiviewLayout = GL_NONE;
mBaseViewIndex = 0;
mViewportOffsets.resize(1u);
mViewportOffsets[0] = Offset();
// not technically necessary, could omit for performance // not technically necessary, could omit for performance
mTarget = Target(); mTarget = Target();
...@@ -199,6 +217,26 @@ GLint FramebufferAttachment::layer() const ...@@ -199,6 +217,26 @@ GLint FramebufferAttachment::layer() const
return 0; return 0;
} }
GLint FramebufferAttachment::getNumViews() const
{
return mNumViews;
}
GLenum FramebufferAttachment::getMultiviewLayout() const
{
return mMultiviewLayout;
}
GLint FramebufferAttachment::getBaseViewIndex() const
{
return mBaseViewIndex;
}
const std::vector<Offset> &FramebufferAttachment::getMultiviewViewportOffsets() const
{
return mViewportOffsets;
}
Texture *FramebufferAttachment::getTexture() const Texture *FramebufferAttachment::getTexture() const
{ {
return rx::GetAs<Texture>(mResource); return rx::GetAs<Texture>(mResource);
...@@ -221,7 +259,9 @@ FramebufferAttachmentObject *FramebufferAttachment::getResource() const ...@@ -221,7 +259,9 @@ FramebufferAttachmentObject *FramebufferAttachment::getResource() const
bool FramebufferAttachment::operator==(const FramebufferAttachment &other) const bool FramebufferAttachment::operator==(const FramebufferAttachment &other) const
{ {
if (mResource != other.mResource || mType != other.mType) if (mResource != other.mResource || mType != other.mType || mNumViews != other.mNumViews ||
mMultiviewLayout != other.mMultiviewLayout || mBaseViewIndex != other.mBaseViewIndex ||
mViewportOffsets != other.mViewportOffsets)
{ {
return false; return false;
} }
......
...@@ -93,6 +93,10 @@ class FramebufferAttachment final ...@@ -93,6 +93,10 @@ class FramebufferAttachment final
GLenum cubeMapFace() const; GLenum cubeMapFace() const;
GLint mipLevel() const; GLint mipLevel() const;
GLint layer() const; GLint layer() const;
GLint getNumViews() const;
GLenum getMultiviewLayout() const;
GLint getBaseViewIndex() const;
const std::vector<Offset> &getMultiviewViewportOffsets() const;
// The size of the underlying resource the attachment points to. The 'depth' value will // The size of the underlying resource the attachment points to. The 'depth' value will
// correspond to a 3D texture depth or the layer count of a 2D array texture. For Surfaces and // correspond to a 3D texture depth or the layer count of a 2D array texture. For Surfaces and
...@@ -150,6 +154,10 @@ class FramebufferAttachment final ...@@ -150,6 +154,10 @@ class FramebufferAttachment final
GLenum mType; GLenum mType;
Target mTarget; Target mTarget;
FramebufferAttachmentObject *mResource; FramebufferAttachmentObject *mResource;
GLint mNumViews;
GLenum mMultiviewLayout;
GLint mBaseViewIndex;
std::vector<Offset> mViewportOffsets;
}; };
// A base class for objects that FBO Attachments may point to. // A base class for objects that FBO Attachments may point to.
......
...@@ -216,6 +216,16 @@ bool Box::operator!=(const Box &other) const ...@@ -216,6 +216,16 @@ bool Box::operator!=(const Box &other) const
return !(*this == other); return !(*this == other);
} }
bool operator==(const Offset &a, const Offset &b)
{
return a.x == b.x && a.y == b.y && a.z == b.z;
}
bool operator!=(const Offset &a, const Offset &b)
{
return !(a == b);
}
bool operator==(const Extents &lhs, const Extents &rhs) bool operator==(const Extents &lhs, const Extents &rhs)
{ {
return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depth == rhs.depth; return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depth == rhs.depth;
......
...@@ -78,6 +78,9 @@ struct Offset ...@@ -78,6 +78,9 @@ struct Offset
Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) { } Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) { }
}; };
bool operator==(const Offset &a, const Offset &b);
bool operator!=(const Offset &a, const Offset &b);
struct Extents struct Extents
{ {
int width; int width;
......
...@@ -530,6 +530,29 @@ void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer, ...@@ -530,6 +530,29 @@ void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
*params = attachmentObject->layer(); *params = attachmentObject->layer();
break; break;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
*params = attachmentObject->getNumViews();
break;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
*params = static_cast<GLint>(attachmentObject->getMultiviewLayout());
break;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
*params = attachmentObject->getBaseViewIndex();
break;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
{
const std::vector<Offset> &offsets = attachmentObject->getMultiviewViewportOffsets();
for (size_t i = 0u; i < offsets.size(); ++i)
{
params[i * 2u] = offsets[i].x;
params[i * 2u + 1u] = offsets[i].y;
}
}
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
......
...@@ -3954,12 +3954,6 @@ bool ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context, ...@@ -3954,12 +3954,6 @@ bool ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context,
GLenum pname, GLenum pname,
GLsizei *numParams) GLsizei *numParams)
{ {
// Only one parameter is returned from glGetFramebufferAttachmentParameteriv
if (numParams)
{
*numParams = 1;
}
if (!ValidFramebufferTarget(target)) if (!ValidFramebufferTarget(target))
{ {
context->handleError(InvalidEnum()); context->handleError(InvalidEnum());
...@@ -3976,6 +3970,17 @@ bool ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context, ...@@ -3976,6 +3970,17 @@ bool ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context,
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
break; break;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
if (clientVersion < 3 || !context->getExtensions().multiview)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
return false;
}
break;
case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
if (clientVersion < 3 && !context->getExtensions().sRGB) if (clientVersion < 3 && !context->getExtensions().sRGB)
{ {
...@@ -4178,6 +4183,22 @@ bool ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context, ...@@ -4178,6 +4183,22 @@ bool ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context,
} }
} }
if (numParams)
{
if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
{
// Only when the viewport offsets are queried we can have a varying number of output
// parameters.
const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1;
*numParams = numViews * 2;
}
else
{
// For all other queries we can have only one output parameter.
*numParams = 1;
}
}
return true; return true;
} }
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
'<(angle_path)/src/tests/gl_tests/FenceSyncTests.cpp', '<(angle_path)/src/tests/gl_tests/FenceSyncTests.cpp',
'<(angle_path)/src/tests/gl_tests/FloatingPointSurfaceTest.cpp', '<(angle_path)/src/tests/gl_tests/FloatingPointSurfaceTest.cpp',
'<(angle_path)/src/tests/gl_tests/FramebufferMixedSamplesTest.cpp', '<(angle_path)/src/tests/gl_tests/FramebufferMixedSamplesTest.cpp',
'<(angle_path)/src/tests/gl_tests/FramebufferMultiviewTest.cpp',
'<(angle_path)/src/tests/gl_tests/FramebufferRenderMipmapTest.cpp', '<(angle_path)/src/tests/gl_tests/FramebufferRenderMipmapTest.cpp',
'<(angle_path)/src/tests/gl_tests/FramebufferTest.cpp', '<(angle_path)/src/tests/gl_tests/FramebufferTest.cpp',
'<(angle_path)/src/tests/gl_tests/GLSLTest.cpp', '<(angle_path)/src/tests/gl_tests/GLSLTest.cpp',
......
//
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Framebuffer multiview tests:
// The tests modify and examine the multiview state.
//
#include "test_utils/ANGLETest.h"
using namespace angle;
class FramebufferMultiviewTest : public ANGLETest
{
protected:
FramebufferMultiviewTest() : mFramebuffer(0), mTexture(0)
{
setWindowWidth(128);
setWindowHeight(128);
setWebGLCompatibilityEnabled(true);
}
void SetUp() override
{
ANGLETest::SetUp();
glGenFramebuffers(1, &mFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
glGenTextures(1, &mTexture);
glBindTexture(GL_TEXTURE_2D, mTexture);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA16F, 1, 1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
glRequestExtensionANGLE = reinterpret_cast<PFNGLREQUESTEXTENSIONANGLEPROC>(
eglGetProcAddress("glRequestExtensionANGLE"));
}
void TearDown() override
{
if (mTexture != 0)
{
glDeleteTextures(1, &mTexture);
mTexture = 0;
}
if (mFramebuffer != 0)
{
glDeleteFramebuffers(1, &mFramebuffer);
mFramebuffer = 0;
}
ANGLETest::TearDown();
}
GLuint mFramebuffer;
GLuint mTexture;
PFNGLREQUESTEXTENSIONANGLEPROC glRequestExtensionANGLE = nullptr;
};
// Test that the framebuffer tokens introduced by ANGLE_multiview can be used query the framebuffer
// state and that their corresponding default values are correctly set.
TEST_P(FramebufferMultiviewTest, DefaultState)
{
if (extensionRequestable("GL_ANGLE_multiview"))
{
glRequestExtensionANGLE("GL_ANGLE_multiview");
}
if (!extensionEnabled("GL_ANGLE_multiview"))
{
std::cout << "Test skipped due to missing GL_ANGLE_multiview." << std::endl;
return;
}
GLint numViews = -1;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
&numViews);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(1, numViews);
GLint baseViewIndex = -1;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE,
&baseViewIndex);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(0, baseViewIndex);
GLint multiviewLayout = GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE,
&multiviewLayout);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(GL_NONE, multiviewLayout);
GLint viewportOffsets[2] = {-1, -1};
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE,
&viewportOffsets[0]);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(0, viewportOffsets[0]);
EXPECT_EQ(0, viewportOffsets[1]);
}
// Test that without having the ANGLE_multiview extension, querying for the framebuffer state using
// the ANGLE_multiview tokens results in an INVALID_ENUM error.
TEST_P(FramebufferMultiviewTest, NegativeFramebufferStateQueries)
{
GLint numViews = -1;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
&numViews);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
GLint baseViewIndex = -1;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE,
&baseViewIndex);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
GLint multiviewLayout = GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE,
&multiviewLayout);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
GLint viewportOffsets[2] = {-1, -1};
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE,
&viewportOffsets[0]);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
ANGLE_INSTANTIATE_TEST(FramebufferMultiviewTest, ES3_OPENGL());
\ No newline at end of file
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