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 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 } 119