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