1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/libGLESv2/renderer/Fence11.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,134 @@ 1.4 +#include "precompiled.h" 1.5 +// 1.6 +// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. 1.7 +// Use of this source code is governed by a BSD-style license that can be 1.8 +// found in the LICENSE file. 1.9 +// 1.10 + 1.11 +// Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl. 1.12 + 1.13 +#include "libGLESv2/renderer/Fence11.h" 1.14 +#include "libGLESv2/main.h" 1.15 +#include "libGLESv2/renderer/Renderer11.h" 1.16 + 1.17 +namespace rx 1.18 +{ 1.19 + 1.20 +Fence11::Fence11(rx::Renderer11 *renderer) 1.21 +{ 1.22 + mRenderer = renderer; 1.23 + mQuery = NULL; 1.24 +} 1.25 + 1.26 +Fence11::~Fence11() 1.27 +{ 1.28 + if (mQuery) 1.29 + { 1.30 + mQuery->Release(); 1.31 + mQuery = NULL; 1.32 + } 1.33 +} 1.34 + 1.35 +GLboolean Fence11::isFence() 1.36 +{ 1.37 + // GL_NV_fence spec: 1.38 + // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. 1.39 + return mQuery != NULL; 1.40 +} 1.41 + 1.42 +void Fence11::setFence(GLenum condition) 1.43 +{ 1.44 + if (!mQuery) 1.45 + { 1.46 + D3D11_QUERY_DESC queryDesc; 1.47 + queryDesc.Query = D3D11_QUERY_EVENT; 1.48 + queryDesc.MiscFlags = 0; 1.49 + 1.50 + if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) 1.51 + { 1.52 + return gl::error(GL_OUT_OF_MEMORY); 1.53 + } 1.54 + } 1.55 + 1.56 + mRenderer->getDeviceContext()->End(mQuery); 1.57 + 1.58 + setCondition(condition); 1.59 + setStatus(GL_FALSE); 1.60 +} 1.61 + 1.62 +GLboolean Fence11::testFence() 1.63 +{ 1.64 + if (mQuery == NULL) 1.65 + { 1.66 + return gl::error(GL_INVALID_OPERATION, GL_TRUE); 1.67 + } 1.68 + 1.69 + HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, 0); 1.70 + 1.71 + if (mRenderer->isDeviceLost()) 1.72 + { 1.73 + return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); 1.74 + } 1.75 + 1.76 + ASSERT(result == S_OK || result == S_FALSE); 1.77 + setStatus(result == S_OK); 1.78 + return getStatus(); 1.79 +} 1.80 + 1.81 +void Fence11::finishFence() 1.82 +{ 1.83 + if (mQuery == NULL) 1.84 + { 1.85 + return gl::error(GL_INVALID_OPERATION); 1.86 + } 1.87 + 1.88 + while (!testFence()) 1.89 + { 1.90 + Sleep(0); 1.91 + } 1.92 +} 1.93 + 1.94 +void Fence11::getFenceiv(GLenum pname, GLint *params) 1.95 +{ 1.96 + if (mQuery == NULL) 1.97 + { 1.98 + return gl::error(GL_INVALID_OPERATION); 1.99 + } 1.100 + 1.101 + switch (pname) 1.102 + { 1.103 + case GL_FENCE_STATUS_NV: 1.104 + { 1.105 + // GL_NV_fence spec: 1.106 + // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV 1.107 + // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. 1.108 + if (getStatus()) 1.109 + { 1.110 + params[0] = GL_TRUE; 1.111 + return; 1.112 + } 1.113 + 1.114 + HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH); 1.115 + 1.116 + if (mRenderer->isDeviceLost()) 1.117 + { 1.118 + params[0] = GL_TRUE; 1.119 + return gl::error(GL_OUT_OF_MEMORY); 1.120 + } 1.121 + 1.122 + ASSERT(result == S_OK || result == S_FALSE); 1.123 + setStatus(result == S_OK); 1.124 + params[0] = getStatus(); 1.125 + 1.126 + break; 1.127 + } 1.128 + case GL_FENCE_CONDITION_NV: 1.129 + params[0] = getCondition(); 1.130 + break; 1.131 + default: 1.132 + return gl::error(GL_INVALID_ENUM); 1.133 + break; 1.134 + } 1.135 +} 1.136 + 1.137 +}