blob: cdd1c8da643566d3d4024af4a76f0e5e4177bfff [file] [log] [blame]
// SwiftShader Software Renderer
//
// Copyright(c) 2005-2012 TransGaming Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//
// Fence.cpp: Implements the Fence class, which supports the GL_NV_fence extension.
#include "Fence.h"
#include "main.h"
#include "Common/Thread.hpp"
namespace gl
{
Fence::Fence()
{
mQuery = false;
mCondition = GL_NONE;
mStatus = GL_FALSE;
}
Fence::~Fence()
{
mQuery = false;
}
GLboolean Fence::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 mQuery;
}
void Fence::setFence(GLenum condition)
{
if(condition != GL_ALL_COMPLETED_NV)
{
return error(GL_INVALID_VALUE);
}
mQuery = true;
mCondition = condition;
mStatus = GL_FALSE;
}
GLboolean Fence::testFence()
{
if(!mQuery)
{
return error(GL_INVALID_OPERATION, GL_TRUE);
}
// The current assumtion is that no matter where the fence is placed, it is
// done by the time it is tested, which is similar to Context::flush(), since
// we don't queue anything without processing it as fast as possible.
mStatus = GL_TRUE;
return mStatus;
}
void Fence::finishFence()
{
if(!mQuery)
{
return error(GL_INVALID_OPERATION);
}
while(!testFence())
{
sw::Thread::yield();
}
}
void Fence::getFenceiv(GLenum pname, GLint *params)
{
if(!mQuery)
{
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)
{
params[0] = GL_TRUE;
return;
}
mStatus = testFence();
params[0] = mStatus;
break;
}
case GL_FENCE_CONDITION_NV:
params[0] = mCondition;
break;
default:
return error(GL_INVALID_ENUM);
break;
}
}
}