blob: 86064d7e52bafae97515084a83abb628a4b8b3f4 [file] [log] [blame]
#include "precompiled.h"
//
// Copyright (c) 2013 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.
//
// Fence9.cpp: Defines the rx::Fence9 class.
#include "libGLESv2/renderer/Fence9.h"
#include "libGLESv2/main.h"
#include "libGLESv2/renderer/renderer9_utils.h"
#include "libGLESv2/renderer/Renderer9.h"
namespace rx
{
Fence9::Fence9(rx::Renderer9 *renderer)
{
mRenderer = renderer;
mQuery = NULL;
}
Fence9::~Fence9()
{
if (mQuery)
{
mRenderer->freeEventQuery(mQuery);
mQuery = NULL;
}
}
GLboolean Fence9::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 != NULL;
}
void Fence9::setFence(GLenum condition)
{
if (!mQuery)
{
mQuery = mRenderer->allocateEventQuery();
if (!mQuery)
{
return gl::error(GL_OUT_OF_MEMORY);
}
}
HRESULT result = mQuery->Issue(D3DISSUE_END);
ASSERT(SUCCEEDED(result));
setCondition(condition);
setStatus(GL_FALSE);
}
GLboolean Fence9::testFence()
{
if (mQuery == NULL)
{
return gl::error(GL_INVALID_OPERATION, GL_TRUE);
}
HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
if (d3d9::isDeviceLostError(result))
{
mRenderer->notifyDeviceLost();
return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
}
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)
{
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;
}
}
}