• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 es2
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 
FenceSync(GLuint name,GLenum condition,GLbitfield flags)118 FenceSync::FenceSync(GLuint name, GLenum condition, GLbitfield flags) : NamedObject(name), mCondition(condition), mFlags(flags)
119 {
120 }
121 
~FenceSync()122 FenceSync::~FenceSync()
123 {
124 }
125 
clientWait(GLbitfield flags,GLuint64 timeout)126 GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout)
127 {
128 	// The current assumtion is that no matter where the fence is placed, it is
129 	// done by the time it is tested, which is similar to Context::flush(), since
130 	// we don't queue anything without processing it as fast as possible.
131 	return GL_ALREADY_SIGNALED;
132 }
133 
serverWait(GLbitfield flags,GLuint64 timeout)134 void FenceSync::serverWait(GLbitfield flags, GLuint64 timeout)
135 {
136 }
137 
getSynciv(GLenum pname,GLsizei * length,GLint * values)138 void FenceSync::getSynciv(GLenum pname, GLsizei *length, GLint *values)
139 {
140 	switch(pname)
141 	{
142 	case GL_OBJECT_TYPE:
143 		values[0] = GL_SYNC_FENCE;
144 		if(length) {
145 			*length = 1;
146 		}
147 		break;
148 	case GL_SYNC_STATUS:
149 		// The current assumtion is that no matter where the fence is placed, it is
150 		// done by the time it is tested, which is similar to Context::flush(), since
151 		// we don't queue anything without processing it as fast as possible.
152 		values[0] = GL_SIGNALED;
153 		if(length) {
154 			*length = 1;
155 		}
156 		break;
157 	case GL_SYNC_CONDITION:
158 		values[0] = GL_SYNC_GPU_COMMANDS_COMPLETE;
159 		if(length) {
160 			*length = 1;
161 		}
162 		break;
163 	case GL_SYNC_FLAGS:
164 		if(length) {
165 			*length = 0;
166 		}
167 		break;
168 	default:
169 		return error(GL_INVALID_ENUM);
170 	}
171 }
172 
173 }
174