Commit 09752369 by Jamie Madill Committed by Jamie Madill

Move the GL_NV_fence-specific stuff stuff out of the Fence implementation class to gl::Fence.

This will allow us to re-use the same Fence implementation for GLES 3 Fence Sync objects. TRAC #23446 Signed-off-by: Geoff Lang Signed-off-by: Shannon Woods Authored-by: Jamie Madill
parent ac4109a3
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "libGLESv2/Fence.h" #include "libGLESv2/Fence.h"
#include "libGLESv2/renderer/FenceImpl.h" #include "libGLESv2/renderer/FenceImpl.h"
#include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/main.h"
namespace gl namespace gl
{ {
...@@ -24,29 +25,75 @@ Fence::~Fence() ...@@ -24,29 +25,75 @@ Fence::~Fence()
delete mFence; delete mFence;
} }
GLboolean Fence::isFence() GLboolean Fence::isFence() const
{ {
return mFence->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 (mFence->isSet() ? GL_TRUE : GL_FALSE);
} }
void Fence::setFence(GLenum condition) void Fence::setFence(GLenum condition)
{ {
mFence->setFence(condition); mFence->set();
mCondition = condition;
mStatus = GL_FALSE;
} }
GLboolean Fence::testFence() GLboolean Fence::testFence()
{ {
return mFence->testFence(); // Flush the command buffer by default
bool result = mFence->test(true);
mStatus = (result ? GL_TRUE : GL_FALSE);
return mStatus;
} }
void Fence::finishFence() void Fence::finishFence()
{ {
mFence->finishFence(); if (!mFence->isSet())
{
return gl::error(GL_INVALID_OPERATION);
}
while (!mFence->test(true))
{
Sleep(0);
}
} }
void Fence::getFenceiv(GLenum pname, GLint *params) void Fence::getFenceiv(GLenum pname, GLint *params)
{ {
mFence->getFenceiv(pname, params); if (!mFence->isSet())
{
return error(GL_INVALID_OPERATION);
}
switch (pname)
{
case GL_FENCE_STATUS_NV:
{
// GL_NV_fence spec:
// Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
// or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
if (mStatus == GL_TRUE)
{
params[0] = GL_TRUE;
return;
}
mStatus = (mFence->test(false) ? GL_TRUE : GL_FALSE);
params[0] = mStatus;
break;
}
case GL_FENCE_CONDITION_NV:
params[0] = mCondition;
break;
default:
return error(GL_INVALID_ENUM);
}
} }
} }
...@@ -26,16 +26,22 @@ class Fence ...@@ -26,16 +26,22 @@ class Fence
explicit Fence(rx::Renderer *renderer); explicit Fence(rx::Renderer *renderer);
virtual ~Fence(); virtual ~Fence();
GLboolean isFence(); GLboolean isFence() const;
void setFence(GLenum condition); void setFence(GLenum condition);
GLboolean testFence(); GLboolean testFence();
void finishFence(); void finishFence();
void getFenceiv(GLenum pname, GLint *params); void getFenceiv(GLenum pname, GLint *params);
GLboolean getStatus() const { return mStatus; }
GLuint getCondition() const { return mCondition; }
private: private:
DISALLOW_COPY_AND_ASSIGN(Fence); DISALLOW_COPY_AND_ASSIGN(Fence);
rx::FenceImpl *mFence; rx::FenceImpl *mFence;
GLboolean mStatus;
GLenum mCondition;
}; };
} }
......
...@@ -29,14 +29,12 @@ Fence11::~Fence11() ...@@ -29,14 +29,12 @@ Fence11::~Fence11()
} }
} }
GLboolean Fence11::isFence() bool Fence11::isSet() const
{ {
// GL_NV_fence spec:
// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
return mQuery != NULL; return mQuery != NULL;
} }
void Fence11::setFence(GLenum condition) void Fence11::set()
{ {
if (!mQuery) if (!mQuery)
{ {
...@@ -51,84 +49,25 @@ void Fence11::setFence(GLenum condition) ...@@ -51,84 +49,25 @@ void Fence11::setFence(GLenum condition)
} }
mRenderer->getDeviceContext()->End(mQuery); mRenderer->getDeviceContext()->End(mQuery);
setCondition(condition);
setStatus(GL_FALSE);
} }
GLboolean Fence11::testFence() bool Fence11::test(bool flushCommandBuffer)
{ {
if (mQuery == NULL) if (mQuery == NULL)
{ {
return gl::error(GL_INVALID_OPERATION, GL_TRUE); return gl::error(GL_INVALID_OPERATION, true);
} }
HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, 0); UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH);
HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, getDataFlags);
if (mRenderer->isDeviceLost()) if (mRenderer->isDeviceLost())
{ {
return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); return gl::error(GL_OUT_OF_MEMORY, true);
} }
ASSERT(result == S_OK || result == S_FALSE); ASSERT(result == S_OK || result == S_FALSE);
setStatus(result == S_OK); return (result == S_OK);
return getStatus();
}
void Fence11::finishFence()
{
if (mQuery == NULL)
{
return gl::error(GL_INVALID_OPERATION);
}
while (!testFence())
{
Sleep(0);
}
}
void Fence11::getFenceiv(GLenum pname, GLint *params)
{
if (mQuery == NULL)
{
return gl::error(GL_INVALID_OPERATION);
}
switch (pname)
{
case GL_FENCE_STATUS_NV:
{
// GL_NV_fence spec:
// Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
// or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
if (getStatus())
{
params[0] = GL_TRUE;
return;
}
HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
if (mRenderer->isDeviceLost())
{
params[0] = GL_TRUE;
return gl::error(GL_OUT_OF_MEMORY);
}
ASSERT(result == S_OK || result == S_FALSE);
setStatus(result == S_OK);
params[0] = getStatus();
break;
}
case GL_FENCE_CONDITION_NV:
params[0] = getCondition();
break;
default:
return gl::error(GL_INVALID_ENUM);
break;
}
} }
} }
...@@ -21,11 +21,9 @@ class Fence11 : public FenceImpl ...@@ -21,11 +21,9 @@ class Fence11 : public FenceImpl
explicit Fence11(rx::Renderer11 *renderer); explicit Fence11(rx::Renderer11 *renderer);
virtual ~Fence11(); virtual ~Fence11();
GLboolean isFence(); bool isSet() const;
void setFence(GLenum condition); void set();
GLboolean testFence(); bool test(bool flushCommandBuffer);
void finishFence();
void getFenceiv(GLenum pname, GLint *params);
private: private:
DISALLOW_COPY_AND_ASSIGN(Fence11); DISALLOW_COPY_AND_ASSIGN(Fence11);
......
...@@ -30,14 +30,12 @@ Fence9::~Fence9() ...@@ -30,14 +30,12 @@ Fence9::~Fence9()
} }
} }
GLboolean Fence9::isFence() bool Fence9::isSet() const
{ {
// GL_NV_fence spec:
// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
return mQuery != NULL; return mQuery != NULL;
} }
void Fence9::setFence(GLenum condition) void Fence9::set()
{ {
if (!mQuery) if (!mQuery)
{ {
...@@ -50,86 +48,27 @@ void Fence9::setFence(GLenum condition) ...@@ -50,86 +48,27 @@ void Fence9::setFence(GLenum condition)
HRESULT result = mQuery->Issue(D3DISSUE_END); HRESULT result = mQuery->Issue(D3DISSUE_END);
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
setCondition(condition);
setStatus(GL_FALSE);
} }
GLboolean Fence9::testFence() bool Fence9::test(bool flushCommandBuffer)
{ {
if (mQuery == NULL) if (mQuery == NULL)
{ {
return gl::error(GL_INVALID_OPERATION, GL_TRUE); return gl::error(GL_INVALID_OPERATION, true);
} }
HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH); DWORD getDataFlags = (flushCommandBuffer ? D3DGETDATA_FLUSH : 0);
HRESULT result = mQuery->GetData(NULL, 0, getDataFlags);
if (d3d9::isDeviceLostError(result)) if (d3d9::isDeviceLostError(result))
{ {
mRenderer->notifyDeviceLost(); mRenderer->notifyDeviceLost();
return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); return gl::error(GL_OUT_OF_MEMORY, true);
} }
ASSERT(result == S_OK || result == S_FALSE); ASSERT(result == S_OK || result == S_FALSE);
setStatus(result == S_OK);
return getStatus();
}
void Fence9::finishFence()
{
if (mQuery == NULL)
{
return gl::error(GL_INVALID_OPERATION);
}
while (!testFence())
{
Sleep(0);
}
}
void Fence9::getFenceiv(GLenum pname, GLint *params) return (result == S_OK);
{
if (mQuery == NULL)
{
return gl::error(GL_INVALID_OPERATION);
}
switch (pname)
{
case GL_FENCE_STATUS_NV:
{
// GL_NV_fence spec:
// Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
// or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
if (getStatus())
{
params[0] = GL_TRUE;
return;
}
HRESULT result = mQuery->GetData(NULL, 0, 0);
if (d3d9::isDeviceLostError(result))
{
params[0] = GL_TRUE;
mRenderer->notifyDeviceLost();
return gl::error(GL_OUT_OF_MEMORY);
}
ASSERT(result == S_OK || result == S_FALSE);
setStatus(result == S_OK);
params[0] = getStatus();
break;
}
case GL_FENCE_CONDITION_NV:
params[0] = getCondition();
break;
default:
return gl::error(GL_INVALID_ENUM);
break;
}
} }
} }
...@@ -21,11 +21,9 @@ class Fence9 : public FenceImpl ...@@ -21,11 +21,9 @@ class Fence9 : public FenceImpl
explicit Fence9(rx::Renderer9 *renderer); explicit Fence9(rx::Renderer9 *renderer);
virtual ~Fence9(); virtual ~Fence9();
GLboolean isFence(); bool isSet() const;
void setFence(GLenum condition); void set();
GLboolean testFence(); bool test(bool flushCommandBuffer);
void finishFence();
void getFenceiv(GLenum pname, GLint *params);
private: private:
DISALLOW_COPY_AND_ASSIGN(Fence9); DISALLOW_COPY_AND_ASSIGN(Fence9);
......
...@@ -17,27 +17,15 @@ namespace rx ...@@ -17,27 +17,15 @@ namespace rx
class FenceImpl class FenceImpl
{ {
public: public:
FenceImpl() : mStatus(GL_FALSE), mCondition(GL_NONE) { }; FenceImpl() { };
virtual ~FenceImpl() { }; virtual ~FenceImpl() { };
virtual GLboolean isFence() = 0; virtual bool isSet() const = 0;
virtual void setFence(GLenum condition) = 0; virtual void set() = 0;
virtual GLboolean testFence() = 0; virtual bool test(bool flushCommandBuffer) = 0;
virtual void finishFence() = 0;
virtual void getFenceiv(GLenum pname, GLint *params) = 0;
protected:
void setStatus(GLboolean status) { mStatus = status; }
GLboolean getStatus() const { return mStatus; }
void setCondition(GLuint condition) { mCondition = condition; }
GLuint getCondition() const { return mCondition; }
private: private:
DISALLOW_COPY_AND_ASSIGN(FenceImpl); DISALLOW_COPY_AND_ASSIGN(FenceImpl);
GLboolean mStatus;
GLenum mCondition;
}; };
} }
......
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