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