1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Fence.cpp: Implements the Fence class, which supports the GL_NV_fence extension.
16
17 #include "Fence.h"
18
19 #include "main.h"
20 #include "Common/Thread.hpp"
21
22 namespace gl
23 {
24
Fence()25 Fence::Fence()
26 {
27 mQuery = false;
28 mCondition = GL_NONE;
29 mStatus = GL_FALSE;
30 }
31
~Fence()32 Fence::~Fence()
33 {
34 mQuery = false;
35 }
36
isFence()37 GLboolean Fence::isFence()
38 {
39 // GL_NV_fence spec:
40 // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
41 return mQuery;
42 }
43
setFence(GLenum condition)44 void Fence::setFence(GLenum condition)
45 {
46 if(condition != GL_ALL_COMPLETED_NV)
47 {
48 return error(GL_INVALID_VALUE);
49 }
50
51 mQuery = true;
52 mCondition = condition;
53 mStatus = GL_FALSE;
54 }
55
testFence()56 GLboolean Fence::testFence()
57 {
58 if(!mQuery)
59 {
60 return error(GL_INVALID_OPERATION, GL_TRUE);
61 }
62
63 // The current assumtion is that no matter where the fence is placed, it is
64 // done by the time it is tested, which is similar to Context::flush(), since
65 // we don't queue anything without processing it as fast as possible.
66 mStatus = GL_TRUE;
67
68 return mStatus;
69 }
70
finishFence()71 void Fence::finishFence()
72 {
73 if(!mQuery)
74 {
75 return error(GL_INVALID_OPERATION);
76 }
77
78 while(!testFence())
79 {
80 sw::Thread::yield();
81 }
82 }
83
getFenceiv(GLenum pname,GLint * params)84 void Fence::getFenceiv(GLenum pname, GLint *params)
85 {
86 if(!mQuery)
87 {
88 return error(GL_INVALID_OPERATION);
89 }
90
91 switch(pname)
92 {
93 case GL_FENCE_STATUS_NV:
94 {
95 // GL_NV_fence spec:
96 // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
97 // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
98 if(mStatus)
99 {
100 params[0] = GL_TRUE;
101 return;
102 }
103
104 mStatus = testFence();
105
106 params[0] = mStatus;
107 break;
108 }
109 case GL_FENCE_CONDITION_NV:
110 params[0] = mCondition;
111 break;
112 default:
113 return error(GL_INVALID_ENUM);
114 break;
115 }
116 }
117
118 }
119