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