Implement FenceNVGL.
BUG=angleproject:888
Change-Id: Iea6993fe5459cf829f4bd23b0df5e223f22903f5
Reviewed-on: https://chromium-review.googlesource.com/264989
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Fence.cpp b/src/libANGLE/Fence.cpp
index 2337364..aa76791 100644
--- a/src/libANGLE/Fence.cpp
+++ b/src/libANGLE/Fence.cpp
@@ -32,16 +32,9 @@
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 @@
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 @@
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)
diff --git a/src/libANGLE/Fence.h b/src/libANGLE/Fence.h
index 2d8beee..74dad05 100644
--- a/src/libANGLE/Fence.h
+++ b/src/libANGLE/Fence.h
@@ -30,11 +30,11 @@
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; }
diff --git a/src/libANGLE/Fence_unittest.cpp b/src/libANGLE/Fence_unittest.cpp
index 50a56bb..37b3e6f 100644
--- a/src/libANGLE/Fence_unittest.cpp
+++ b/src/libANGLE/Fence_unittest.cpp
@@ -25,9 +25,9 @@
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, 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);
}
diff --git a/src/libANGLE/renderer/FenceNVImpl.h b/src/libANGLE/renderer/FenceNVImpl.h
index 3463921..a534914 100644
--- a/src/libANGLE/renderer/FenceNVImpl.h
+++ b/src/libANGLE/renderer/FenceNVImpl.h
@@ -24,9 +24,9 @@
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;
};
}
diff --git a/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp b/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
index ec006b5..e1bfdef 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
@@ -76,23 +76,22 @@
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;
diff --git a/src/libANGLE/renderer/d3d/d3d11/Fence11.h b/src/libANGLE/renderer/d3d/d3d11/Fence11.h
index 74e9763..5959788 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Fence11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Fence11.h
@@ -20,11 +20,11 @@
{
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);
diff --git a/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp b/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp
index 27c265e..3300681 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp
@@ -25,7 +25,7 @@
SafeRelease(mQuery);
}
-gl::Error FenceNV9::set()
+gl::Error FenceNV9::set(GLenum condition)
{
if (!mQuery)
{
@@ -47,7 +47,29 @@
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 @@
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);
-}
-
}
diff --git a/src/libANGLE/renderer/d3d/d3d9/Fence9.h b/src/libANGLE/renderer/d3d/d3d9/Fence9.h
index 4b86747..200ac68 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Fence9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Fence9.h
@@ -20,13 +20,15 @@
{
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;
};
diff --git a/src/libANGLE/renderer/gl/FenceNVGL.cpp b/src/libANGLE/renderer/gl/FenceNVGL.cpp
index 6e4dd40..b463054 100644
--- a/src/libANGLE/renderer/gl/FenceNVGL.cpp
+++ b/src/libANGLE/renderer/gl/FenceNVGL.cpp
@@ -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()
-{}
-
-gl::Error FenceNVGL::set()
{
- UNIMPLEMENTED();
- return gl::Error(GL_INVALID_OPERATION);
+ mFunctions->deleteFencesNV(1, &mFence);
+ mFence = 0;
}
-gl::Error FenceNVGL::test(bool flushCommandBuffer, GLboolean *outFinished)
+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::finishFence(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::finish()
+{
+ mFunctions->finishFenceNV(mFence);
+ return gl::Error(GL_NO_ERROR);
}
}
diff --git a/src/libANGLE/renderer/gl/FenceNVGL.h b/src/libANGLE/renderer/gl/FenceNVGL.h
index 84d549f..ffeca85 100644
--- a/src/libANGLE/renderer/gl/FenceNVGL.h
+++ b/src/libANGLE/renderer/gl/FenceNVGL.h
@@ -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;
};
}
diff --git a/src/libANGLE/renderer/gl/FunctionsGL.cpp b/src/libANGLE/renderer/gl/FunctionsGL.cpp
index e20249f..926209b 100644
--- a/src/libANGLE/renderer/gl/FunctionsGL.cpp
+++ b/src/libANGLE/renderer/gl/FunctionsGL.cpp
@@ -159,6 +159,14 @@
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 @@
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
diff --git a/src/libANGLE/renderer/gl/FunctionsGL.h b/src/libANGLE/renderer/gl/FunctionsGL.h
index f479086..bf6c2bf 100644
--- a/src/libANGLE/renderer/gl/FunctionsGL.h
+++ b/src/libANGLE/renderer/gl/FunctionsGL.h
@@ -106,6 +106,15 @@
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;
diff --git a/src/libANGLE/renderer/gl/RendererGL.cpp b/src/libANGLE/renderer/gl/RendererGL.cpp
index 53f2e89..7e1b0b0 100644
--- a/src/libANGLE/renderer/gl/RendererGL.cpp
+++ b/src/libANGLE/renderer/gl/RendererGL.cpp
@@ -144,7 +144,7 @@
FenceNVImpl *RendererGL::createFenceNV()
{
- return new FenceNVGL();
+ return new FenceNVGL(mFunctions);
}
FenceSyncImpl *RendererGL::createFenceSync()
diff --git a/src/libANGLE/renderer/gl/functionsgl_enums.h b/src/libANGLE/renderer/gl/functionsgl_enums.h
index 8e27af9..42e5f38 100644
--- a/src/libANGLE/renderer/gl/functionsgl_enums.h
+++ b/src/libANGLE/renderer/gl/functionsgl_enums.h
@@ -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
diff --git a/src/libANGLE/renderer/gl/functionsgl_typedefs.h b/src/libANGLE/renderer/gl/functionsgl_typedefs.h
index 713a35a..82fb5d8 100644
--- a/src/libANGLE/renderer/gl/functionsgl_typedefs.h
+++ b/src/libANGLE/renderer/gl/functionsgl_typedefs.h
@@ -125,6 +125,15 @@
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 *);
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
index 433aee2..f395ff4 100644
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -155,6 +155,7 @@
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();
}
}
diff --git a/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
index 6f85b2f..1756618 100644
--- a/src/libGLESv2/entry_points_gles_2_0_ext.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -168,13 +168,13 @@
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 @@
return;
}
- if (fenceObject->isFence() != GL_TRUE)
+ if (fenceObject->isSet() != GL_TRUE)
{
context->recordError(Error(GL_INVALID_OPERATION));
return;
@@ -249,7 +249,7 @@
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 @@
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 @@
return;
}
- Error error = fenceObject->setFence(condition);
+ Error error = fenceObject->set(condition);
if (error.isError())
{
context->recordError(error);
@@ -572,14 +574,14 @@
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);