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 25 Fence::Fence() 26 { 27 mQuery = false; 28 mCondition = GL_NONE; 29 mStatus = GL_FALSE; 30 } 31 32 Fence::~Fence() 33 { 34 mQuery = false; 35 } 36 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 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 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 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 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 FenceSync::FenceSync(GLuint name, GLenum condition, GLbitfield flags) : NamedObject(name), mCondition(condition), mFlags(flags) 119 { 120 } 121 122 FenceSync::~FenceSync() 123 { 124 } 125 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 134 void FenceSync::serverWait(GLbitfield flags, GLuint64 timeout) 135 { 136 } 137 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