Commit b11ad26b by Geoff Lang

Implement FenceNVGL.

BUG=angleproject:888 Change-Id: Iea6993fe5459cf829f4bd23b0df5e223f22903f5 Reviewed-on: https://chromium-review.googlesource.com/264989Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 7d433ddc
......@@ -32,16 +32,9 @@ FenceNV::~FenceNV()
SafeDelete(mFence);
}
GLboolean FenceNV::isFence() const
Error FenceNV::set(GLenum condition)
{
// GL_NV_fence spec:
// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
return (mIsSet ? GL_TRUE : GL_FALSE);
}
Error FenceNV::setFence(GLenum condition)
{
Error error = mFence->set();
Error error = mFence->set(condition);
if (error.isError())
{
return error;
......@@ -54,10 +47,10 @@ Error FenceNV::setFence(GLenum condition)
return Error(GL_NO_ERROR);
}
Error FenceNV::testFence(GLboolean *outResult)
Error FenceNV::test(GLboolean *outResult)
{
// Flush the command buffer by default
Error error = mFence->test(true, &mStatus);
Error error = mFence->test(&mStatus);
if (error.isError())
{
return error;
......@@ -67,11 +60,19 @@ Error FenceNV::testFence(GLboolean *outResult)
return Error(GL_NO_ERROR);
}
Error FenceNV::finishFence()
Error FenceNV::finish()
{
ASSERT(mIsSet);
return mFence->finishFence(&mStatus);
gl::Error error = mFence->finish();
if (error.isError())
{
return error;
}
mStatus = GL_TRUE;
return Error(GL_NO_ERROR);
}
FenceSync::FenceSync(rx::FenceSyncImpl *impl, GLuint id)
......
......@@ -30,11 +30,11 @@ class FenceNV final : angle::NonCopyable
explicit FenceNV(rx::FenceNVImpl *impl);
virtual ~FenceNV();
GLboolean isFence() const;
Error setFence(GLenum condition);
Error testFence(GLboolean *outResult);
Error finishFence();
Error set(GLenum condition);
Error test(GLboolean *outResult);
Error finish();
bool isSet() const { return mIsSet; }
GLboolean getStatus() const { return mStatus; }
GLenum getCondition() const { return mCondition; }
......
......@@ -25,9 +25,9 @@ class MockFenceNVImpl : public rx::FenceNVImpl
public:
virtual ~MockFenceNVImpl() { destroy(); }
MOCK_METHOD0(set, gl::Error());
MOCK_METHOD2(test, gl::Error(bool, GLboolean *));
MOCK_METHOD1(finishFence, gl::Error(GLboolean *));
MOCK_METHOD1(set, gl::Error(GLenum));
MOCK_METHOD1(test, gl::Error(GLboolean *));
MOCK_METHOD0(finish, gl::Error());
MOCK_METHOD0(destroy, void());
};
......@@ -67,23 +67,23 @@ TEST_F(FenceNVTest, DestructionDeletesImpl)
TEST_F(FenceNVTest, SetAndTestBehavior)
{
EXPECT_CALL(*mImpl, set())
EXPECT_CALL(*mImpl, set(_))
.WillOnce(Return(gl::Error(GL_NO_ERROR)))
.RetiresOnSaturation();
EXPECT_EQ(GL_FALSE, mFence->isFence());
mFence->setFence(GL_ALL_COMPLETED_NV);
EXPECT_EQ(GL_TRUE, mFence->isFence());
EXPECT_FALSE(mFence->isSet());
mFence->set(GL_ALL_COMPLETED_NV);
EXPECT_TRUE(mFence->isSet());
// Fake the behavior of testing the fence before and after it's passed.
EXPECT_CALL(*mImpl, test(_, _))
.WillOnce(DoAll(SetArgumentPointee<1>(GL_FALSE),
EXPECT_CALL(*mImpl, test(_))
.WillOnce(DoAll(SetArgumentPointee<0>(GL_FALSE),
Return(gl::Error(GL_NO_ERROR))))
.WillOnce(DoAll(SetArgumentPointee<1>(GL_TRUE),
.WillOnce(DoAll(SetArgumentPointee<0>(GL_TRUE),
Return(gl::Error(GL_NO_ERROR))))
.RetiresOnSaturation();
GLboolean out;
mFence->testFence(&out);
mFence->test(&out);
EXPECT_EQ(GL_FALSE, out);
mFence->testFence(&out);
mFence->test(&out);
EXPECT_EQ(GL_TRUE, out);
}
......
......@@ -24,9 +24,9 @@ class FenceNVImpl : angle::NonCopyable
FenceNVImpl() { };
virtual ~FenceNVImpl() { };
virtual gl::Error set() = 0;
virtual gl::Error test(bool flushCommandBuffer, GLboolean *outFinished) = 0;
virtual gl::Error finishFence(GLboolean *outFinished) = 0;
virtual gl::Error set(GLenum condition) = 0;
virtual gl::Error test(GLboolean *outFinished) = 0;
virtual gl::Error finish() = 0;
};
}
......
......@@ -76,23 +76,22 @@ FenceNV11::~FenceNV11()
SafeRelease(mQuery);
}
gl::Error FenceNV11::set()
gl::Error FenceNV11::set(GLenum condition)
{
return FenceSetHelper(this);
}
gl::Error FenceNV11::test(bool flushCommandBuffer, GLboolean *outFinished)
gl::Error FenceNV11::test(GLboolean *outFinished)
{
return FenceTestHelper(this, flushCommandBuffer, outFinished);
return FenceTestHelper(this, true, outFinished);
}
gl::Error FenceNV11::finishFence(GLboolean *outFinished)
gl::Error FenceNV11::finish()
{
ASSERT(outFinished);
while (*outFinished != GL_TRUE)
GLboolean finished = GL_FALSE;
while (finished != GL_TRUE)
{
gl::Error error = test(true, outFinished);
gl::Error error = FenceTestHelper(this, true, &finished);
if (error.isError())
{
return error;
......
......@@ -20,11 +20,11 @@ class FenceNV11 : public FenceNVImpl
{
public:
explicit FenceNV11(Renderer11 *renderer);
virtual ~FenceNV11();
~FenceNV11() override;
gl::Error set();
gl::Error test(bool flushCommandBuffer, GLboolean *outFinished);
gl::Error finishFence(GLboolean *outFinished);
gl::Error set(GLenum condition) override;
gl::Error test(GLboolean *outFinished) override;
gl::Error finish() override;
private:
template<class T> friend gl::Error FenceSetHelper(T *fence);
......
......@@ -25,7 +25,7 @@ FenceNV9::~FenceNV9()
SafeRelease(mQuery);
}
gl::Error FenceNV9::set()
gl::Error FenceNV9::set(GLenum condition)
{
if (!mQuery)
{
......@@ -47,7 +47,29 @@ gl::Error FenceNV9::set()
return gl::Error(GL_NO_ERROR);
}
gl::Error FenceNV9::test(bool flushCommandBuffer, GLboolean *outFinished)
gl::Error FenceNV9::test(GLboolean *outFinished)
{
return testHelper(true, outFinished);
}
gl::Error FenceNV9::finish()
{
GLboolean finished = GL_FALSE;
while (finished != GL_TRUE)
{
gl::Error error = testHelper(true, &finished);
if (error.isError())
{
return error;
}
Sleep(0);
}
return gl::Error(GL_NO_ERROR);
}
gl::Error FenceNV9::testHelper(bool flushCommandBuffer, GLboolean *outFinished)
{
ASSERT(mQuery);
......@@ -69,22 +91,4 @@ gl::Error FenceNV9::test(bool flushCommandBuffer, GLboolean *outFinished)
return gl::Error(GL_NO_ERROR);
}
gl::Error FenceNV9::finishFence(GLboolean *outFinished)
{
ASSERT(outFinished);
while (*outFinished != GL_TRUE)
{
gl::Error error = test(true, outFinished);
if (error.isError())
{
return error;
}
Sleep(0);
}
return gl::Error(GL_NO_ERROR);
}
}
......@@ -20,13 +20,15 @@ class FenceNV9 : public FenceNVImpl
{
public:
explicit FenceNV9(Renderer9 *renderer);
virtual ~FenceNV9();
~FenceNV9() override;
gl::Error set();
gl::Error test(bool flushCommandBuffer, GLboolean *outFinished);
gl::Error finishFence(GLboolean *outFinished);
gl::Error set(GLenum condition) override;
gl::Error test(GLboolean *outFinished) override;
gl::Error finish() override;
private:
gl::Error testHelper(bool flushCommandBuffer, GLboolean *outFinished);
Renderer9 *mRenderer;
IDirect3DQuery9 *mQuery;
};
......
......@@ -9,33 +9,43 @@
#include "libANGLE/renderer/gl/FenceNVGL.h"
#include "common/debug.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
namespace rx
{
FenceNVGL::FenceNVGL()
: FenceNVImpl()
{}
FenceNVGL::FenceNVGL(const FunctionsGL *functions)
: FenceNVImpl(),
mFunctions(functions)
{
mFunctions->genFencesNV(1, &mFence);
}
FenceNVGL::~FenceNVGL()
{}
{
mFunctions->deleteFencesNV(1, &mFence);
mFence = 0;
}
gl::Error FenceNVGL::set()
gl::Error FenceNVGL::set(GLenum condition)
{
UNIMPLEMENTED();
return gl::Error(GL_INVALID_OPERATION);
ASSERT(condition == GL_ALL_COMPLETED_NV);
mFunctions->setFenceNV(mFence, condition);
return gl::Error(GL_NO_ERROR);
}
gl::Error FenceNVGL::test(bool flushCommandBuffer, GLboolean *outFinished)
gl::Error FenceNVGL::test(GLboolean *outFinished)
{
UNIMPLEMENTED();
return gl::Error(GL_INVALID_OPERATION);
ASSERT(outFinished);
*outFinished = mFunctions->testFenceNV(mFence);
return gl::Error(GL_NO_ERROR);
}
gl::Error FenceNVGL::finishFence(GLboolean *outFinished)
gl::Error FenceNVGL::finish()
{
UNIMPLEMENTED();
return gl::Error(GL_INVALID_OPERATION);
mFunctions->finishFenceNV(mFence);
return gl::Error(GL_NO_ERROR);
}
}
......@@ -13,16 +13,22 @@
namespace rx
{
class FunctionsGL;
class FenceNVGL : public FenceNVImpl
{
public:
FenceNVGL();
explicit FenceNVGL(const FunctionsGL *functions);
~FenceNVGL() override;
gl::Error set() override;
gl::Error test(bool flushCommandBuffer, GLboolean *outFinished) override;
gl::Error finishFence(GLboolean *outFinished) override;
gl::Error set(GLenum condition) override;
gl::Error test(GLboolean *outFinished) override;
gl::Error finish() override;
private:
GLuint mFence;
const FunctionsGL *mFunctions;
};
}
......
......@@ -159,6 +159,14 @@ FunctionsGL::FunctionsGL()
texImage3D(nullptr),
texSubImage3D(nullptr),
deleteFencesNV(nullptr),
genFencesNV(nullptr),
isFenceNV(nullptr),
testFenceNV(nullptr),
getFenceivNV(nullptr),
finishFenceNV(nullptr),
setFenceNV(nullptr),
activeTexture(nullptr),
compressedTexImage1D(nullptr),
compressedTexImage2D(nullptr),
......@@ -863,6 +871,15 @@ void FunctionsGL::initialize()
AssignGLEntryPoint(loadProcAddress("glDrawRangeElements"), &drawRangeElements);
AssignGLEntryPoint(loadProcAddress("glTexImage3D"), &texImage3D);
AssignGLEntryPoint(loadProcAddress("glTexSubImage3D"), &texSubImage3D);
// Extensions
AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glDeleteFencesNV"), &deleteFencesNV);
AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGenFencesNV"), &genFencesNV);
AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glIsFenceNV"), &isFenceNV);
AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glTestFenceNV"), &testFenceNV);
AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGetFenceivNV"), &getFenceivNV);
AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glFinishFenceNV"), &finishFenceNV);
AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glSetFenceNV"), &setFenceNV);
}
// 1.3
......
......@@ -106,6 +106,15 @@ class FunctionsGL
PFNGLTEXIMAGE3DPROC texImage3D;
PFNGLTEXSUBIMAGE3DPROC texSubImage3D;
// 1.2 Extensions
PFNGLDELETEFENCESNVPROC deleteFencesNV;
PFNGLGENFENCESNVPROC genFencesNV;
PFNGLISFENCENVPROC isFenceNV;
PFNGLTESTFENCENVPROC testFenceNV;
PFNGLGETFENCEIVNVPROC getFenceivNV;
PFNGLFINISHFENCENVPROC finishFenceNV;
PFNGLSETFENCENVPROC setFenceNV;
// 1.3
PFNGLACTIVETEXTUREPROC activeTexture;
PFNGLCOMPRESSEDTEXIMAGE1DPROC compressedTexImage1D;
......
......@@ -144,7 +144,7 @@ QueryImpl *RendererGL::createQuery(GLenum type)
FenceNVImpl *RendererGL::createFenceNV()
{
return new FenceNVGL();
return new FenceNVGL(mFunctions);
}
FenceSyncImpl *RendererGL::createFenceSync()
......
......@@ -250,6 +250,11 @@
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
// 1.2 Extensions
#define GL_ALL_COMPLETED_NV 0x84F2
#define GL_FENCE_STATUS_NV 0x84F3
#define GL_FENCE_CONDITION_NV 0x84F4
// 1.3
#define GL_ACTIVE_TEXTURE 0x84E0
#define GL_CLAMP_TO_BORDER 0x812D
......
......@@ -125,6 +125,15 @@ typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWRANGEELEMENTSPROC)(GLenum, GLuint,
typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE3DPROC)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
// 1.2 Extensions
typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETEFENCESNVPROC)(GLsizei, const GLuint *);
typedef void (INTERNAL_GL_APIENTRY *PFNGLGENFENCESNVPROC)(GLsizei, GLuint *);
typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISFENCENVPROC)(GLuint);
typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLTESTFENCENVPROC)(GLuint);
typedef void (INTERNAL_GL_APIENTRY *PFNGLGETFENCEIVNVPROC)(GLuint, GLenum, GLint *);
typedef void (INTERNAL_GL_APIENTRY *PFNGLFINISHFENCENVPROC)(GLuint);
typedef void (INTERNAL_GL_APIENTRY *PFNGLSETFENCENVPROC)(GLuint, GLenum);
// 1.3
typedef void (INTERNAL_GL_APIENTRY *PFNGLACTIVETEXTUREPROC)(GLenum);
typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *);
......
......@@ -155,6 +155,7 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM
extensions->textureStorage = true;
extensions->fboRenderMipmap = true;
extensions->framebufferMultisample = caps->maxSamples > 0;
extensions->fence = std::find(functions->extensions.begin(), functions->extensions.end(), "GL_NV_fence") != functions->extensions.end();
}
}
......
......@@ -168,13 +168,13 @@ void GL_APIENTRY FinishFenceNV(GLuint fence)
return;
}
if (fenceObject->isFence() != GL_TRUE)
if (fenceObject->isSet() != GL_TRUE)
{
context->recordError(Error(GL_INVALID_OPERATION));
return;
}
fenceObject->finishFence();
fenceObject->finish();
}
}
......@@ -233,7 +233,7 @@ void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
return;
}
if (fenceObject->isFence() != GL_TRUE)
if (fenceObject->isSet() != GL_TRUE)
{
context->recordError(Error(GL_INVALID_OPERATION));
return;
......@@ -249,7 +249,7 @@ void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
GLboolean status = GL_TRUE;
if (fenceObject->getStatus() != GL_TRUE)
{
Error error = fenceObject->testFence(&status);
Error error = fenceObject->test(&status);
if (error.isError())
{
context->recordError(error);
......@@ -448,7 +448,9 @@ GLboolean GL_APIENTRY IsFenceNV(GLuint fence)
return GL_FALSE;
}
return fenceObject->isFence();
// GL_NV_fence spec:
// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
return fenceObject->isSet();
}
return GL_FALSE;
......@@ -548,7 +550,7 @@ void GL_APIENTRY SetFenceNV(GLuint fence, GLenum condition)
return;
}
Error error = fenceObject->setFence(condition);
Error error = fenceObject->set(condition);
if (error.isError())
{
context->recordError(error);
......@@ -572,14 +574,14 @@ GLboolean GL_APIENTRY TestFenceNV(GLuint fence)
return GL_TRUE;
}
if (fenceObject->isFence() != GL_TRUE)
if (fenceObject->isSet() != GL_TRUE)
{
context->recordError(Error(GL_INVALID_OPERATION));
return GL_TRUE;
}
GLboolean result;
Error error = fenceObject->testFence(&result);
Error error = fenceObject->test(&result);
if (error.isError())
{
context->recordError(error);
......
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