blob: aaf3014422a0b9b542ee5a071e0e0cb8e68dd069 [file] [log] [blame]
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00001//
2// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Query.cpp: Implements the gl::Query class
8
9#include "libGLESv2/Query.h"
10
daniel@transgaming.com414c9162012-11-28 20:54:57 +000011#include "libGLESv2/renderer/renderer9_utils.h"
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000012
13namespace gl
14{
15
daniel@transgaming.comdedd1a02012-11-28 20:57:11 +000016Query::Query(rx::Renderer *renderer, GLuint id, GLenum type) : RefCountObject(id)
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000017{
daniel@transgaming.comdedd1a02012-11-28 20:57:11 +000018 ASSERT(dynamic_cast<rx::Renderer9*>(renderer) != NULL); // D3D9_REPLACE
19 mRenderer = static_cast<rx::Renderer9*>(renderer);
20
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000021 mQuery = NULL;
22 mStatus = GL_FALSE;
23 mResult = GL_FALSE;
24 mType = type;
25}
26
27Query::~Query()
28{
29 if (mQuery != NULL)
30 {
31 mQuery->Release();
32 mQuery = NULL;
33 }
34}
35
36void Query::begin()
37{
38 if (mQuery == NULL)
39 {
daniel@transgaming.com621ce052012-10-31 17:52:29 +000040 // D3D9_REPLACE
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000041 if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery)))
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000042 {
43 return error(GL_OUT_OF_MEMORY);
44 }
45 }
46
47 HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
48 ASSERT(SUCCEEDED(result));
49}
50
51void Query::end()
52{
53 if (mQuery == NULL)
54 {
55 return error(GL_INVALID_OPERATION);
56 }
57
58 HRESULT result = mQuery->Issue(D3DISSUE_END);
59 ASSERT(SUCCEEDED(result));
60
61 mStatus = GL_FALSE;
62 mResult = GL_FALSE;
63}
64
65GLuint Query::getResult()
66{
67 if (mQuery != NULL)
68 {
69 while (!testQuery())
70 {
71 Sleep(0);
72 // explicitly check for device loss
73 // some drivers seem to return S_FALSE even if the device is lost
74 // instead of D3DERR_DEVICELOST like they should
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +000075 if (mRenderer->testDeviceLost(true))
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000076 {
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000077 return error(GL_OUT_OF_MEMORY, 0);
78 }
79 }
80 }
81
82 return (GLuint)mResult;
83}
84
85GLboolean Query::isResultAvailable()
86{
87 if (mQuery != NULL)
88 {
89 testQuery();
90 }
91
92 return mStatus;
93}
94
95GLenum Query::getType() const
96{
97 return mType;
98}
99
100GLboolean Query::testQuery()
101{
102 if (mQuery != NULL && mStatus != GL_TRUE)
103 {
104 DWORD numPixels = 0;
105
106 HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH);
107 if (hres == S_OK)
108 {
109 mStatus = GL_TRUE;
110
111 switch (mType)
112 {
113 case GL_ANY_SAMPLES_PASSED_EXT:
114 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
115 mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
116 break;
117 default:
118 ASSERT(false);
119 }
120 }
121 else if (checkDeviceLost(hres))
122 {
123 return error(GL_OUT_OF_MEMORY, GL_TRUE);
124 }
125
126 return mStatus;
127 }
128
129 return GL_TRUE; // prevent blocking when query is null
130}
131}