• 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 // Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl.
9 
10 #include "libGLESv2/renderer/Fence11.h"
11 #include "libGLESv2/main.h"
12 #include "libGLESv2/renderer/Renderer11.h"
13 
14 namespace rx
15 {
16 
Fence11(rx::Renderer11 * renderer)17 Fence11::Fence11(rx::Renderer11 *renderer)
18 {
19     mRenderer = renderer;
20     mQuery = NULL;
21 }
22 
~Fence11()23 Fence11::~Fence11()
24 {
25     if (mQuery)
26     {
27         mQuery->Release();
28         mQuery = NULL;
29     }
30 }
31 
isFence()32 GLboolean Fence11::isFence()
33 {
34     // GL_NV_fence spec:
35     // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
36     return mQuery != NULL;
37 }
38 
setFence(GLenum condition)39 void Fence11::setFence(GLenum condition)
40 {
41     if (!mQuery)
42     {
43         D3D11_QUERY_DESC queryDesc;
44         queryDesc.Query = D3D11_QUERY_EVENT;
45         queryDesc.MiscFlags = 0;
46 
47         if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery)))
48         {
49             return gl::error(GL_OUT_OF_MEMORY);
50         }
51     }
52 
53     mRenderer->getDeviceContext()->End(mQuery);
54 
55     setCondition(condition);
56     setStatus(GL_FALSE);
57 }
58 
testFence()59 GLboolean Fence11::testFence()
60 {
61     if (mQuery == NULL)
62     {
63         return gl::error(GL_INVALID_OPERATION, GL_TRUE);
64     }
65 
66     HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, 0);
67 
68     if (mRenderer->isDeviceLost())
69     {
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 Fence11::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 Fence11::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 = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
112 
113             if (mRenderer->isDeviceLost())
114             {
115                 params[0] = GL_TRUE;
116                 return gl::error(GL_OUT_OF_MEMORY);
117             }
118 
119             ASSERT(result == S_OK || result == S_FALSE);
120             setStatus(result == S_OK);
121             params[0] = getStatus();
122 
123             break;
124         }
125       case GL_FENCE_CONDITION_NV:
126         params[0] = getCondition();
127         break;
128       default:
129         return gl::error(GL_INVALID_ENUM);
130         break;
131     }
132 }
133 
134 }
135