1ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch// 2ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 3ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch// Use of this source code is governed by a BSD-style license that can be 4ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch// found in the LICENSE file. 5ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch// 6ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 7ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension. 8ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 9ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "libGLESv2/Fence.h" 10ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 11ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "libGLESv2/main.h" 12ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 13ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochnamespace gl 14ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 15ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 16ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen MurdochFence::Fence() 17ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 18ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mQuery = NULL; 19ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mCondition = GL_NONE; 20ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mStatus = GL_FALSE; 21ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 22ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 23ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen MurdochFence::~Fence() 24ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 25ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (mQuery != NULL) 26ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 27ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mQuery->Release(); 28ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mQuery = NULL; 29ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 30ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 31ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 32ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen MurdochGLboolean Fence::isFence() 33ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 34ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // GL_NV_fence spec: 35ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. 36ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return mQuery != NULL; 37ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 38ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 39ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid Fence::setFence(GLenum condition) 40ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 41ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (mQuery != NULL) 42ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 43ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mQuery->Release(); 44ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mQuery = NULL; 45ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 46ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 47ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (FAILED(getDevice()->CreateQuery(D3DQUERYTYPE_EVENT, &mQuery))) 48ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 49ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return error(GL_OUT_OF_MEMORY); 50ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 51ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 52ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch HRESULT result = mQuery->Issue(D3DISSUE_END); 53ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch ASSERT(SUCCEEDED(result)); 54ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 55ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mCondition = condition; 56ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mStatus = GL_FALSE; 57ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 58ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 59ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen MurdochGLboolean Fence::testFence() 60ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 61ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (mQuery == NULL) 62ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 63ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return error(GL_INVALID_OPERATION, GL_TRUE); 64ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 65ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 66ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH); 67ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 68ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (result == D3DERR_DEVICELOST) 69ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 70ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return error(GL_OUT_OF_MEMORY, GL_TRUE); 71ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 72ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 73ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch ASSERT(result == S_OK || result == S_FALSE); 74ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mStatus = result == S_OK; 75ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return mStatus; 76ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 77ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 78ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid Fence::finishFence() 79ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 80ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (mQuery == NULL) 81ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 82ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return error(GL_INVALID_OPERATION); 83ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 84ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 85ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch while (!testFence()) 86ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 87ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch Sleep(0); 88ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 89ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 90ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 91ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid Fence::getFenceiv(GLenum pname, GLint *params) 92ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 93ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (mQuery == NULL) 94ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 95ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return error(GL_INVALID_OPERATION); 96ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 97ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 98ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch switch (pname) 99ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 100ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch case GL_FENCE_STATUS_NV: 101ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 102ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // GL_NV_fence spec: 103ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV 104ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. 105ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (mStatus) 106ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 107ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch params[0] = GL_TRUE; 108ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return; 109ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 110ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 111ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch HRESULT result = mQuery->GetData(NULL, 0, 0); 112ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 113ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (result == D3DERR_DEVICELOST) 114ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 115ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch params[0] = GL_TRUE; 116ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return error(GL_OUT_OF_MEMORY); 117ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 118ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 119ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch ASSERT(result == S_OK || result == S_FALSE); 120ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch mStatus = result == S_OK; 121ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch params[0] = mStatus; 122ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 123ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch break; 124ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 125ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch case GL_FENCE_CONDITION_NV: 126ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch params[0] = mCondition; 127ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch break; 128ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch default: 129ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return error(GL_INVALID_ENUM); 130ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch break; 131ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 132ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 133ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 134ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 135