• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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