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