blob: f9f1bff3f48b0a1e7a8799bbb7f9dbecf75bd0b2 [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.com27290c12012-11-28 20:57:47 +000018 mRenderer = rx::Renderer9::makeRenderer9(renderer); // D3D9_REPLACE
daniel@transgaming.comdedd1a02012-11-28 20:57:11 +000019
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000020 mQuery = NULL;
21 mStatus = GL_FALSE;
22 mResult = GL_FALSE;
23 mType = type;
24}
25
26Query::~Query()
27{
28 if (mQuery != NULL)
29 {
30 mQuery->Release();
31 mQuery = NULL;
32 }
33}
34
35void Query::begin()
36{
37 if (mQuery == NULL)
38 {
daniel@transgaming.com621ce052012-10-31 17:52:29 +000039 // D3D9_REPLACE
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000040 if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery)))
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000041 {
42 return error(GL_OUT_OF_MEMORY);
43 }
44 }
45
46 HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
47 ASSERT(SUCCEEDED(result));
48}
49
50void Query::end()
51{
52 if (mQuery == NULL)
53 {
54 return error(GL_INVALID_OPERATION);
55 }
56
57 HRESULT result = mQuery->Issue(D3DISSUE_END);
58 ASSERT(SUCCEEDED(result));
59
60 mStatus = GL_FALSE;
61 mResult = GL_FALSE;
62}
63
64GLuint Query::getResult()
65{
66 if (mQuery != NULL)
67 {
68 while (!testQuery())
69 {
70 Sleep(0);
71 // explicitly check for device loss
72 // some drivers seem to return S_FALSE even if the device is lost
73 // instead of D3DERR_DEVICELOST like they should
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +000074 if (mRenderer->testDeviceLost(true))
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000075 {
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000076 return error(GL_OUT_OF_MEMORY, 0);
77 }
78 }
79 }
80
81 return (GLuint)mResult;
82}
83
84GLboolean Query::isResultAvailable()
85{
86 if (mQuery != NULL)
87 {
88 testQuery();
89 }
90
91 return mStatus;
92}
93
94GLenum Query::getType() const
95{
96 return mType;
97}
98
99GLboolean Query::testQuery()
100{
101 if (mQuery != NULL && mStatus != GL_TRUE)
102 {
103 DWORD numPixels = 0;
104
105 HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH);
106 if (hres == S_OK)
107 {
108 mStatus = GL_TRUE;
109
110 switch (mType)
111 {
112 case GL_ANY_SAMPLES_PASSED_EXT:
113 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
114 mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
115 break;
116 default:
117 ASSERT(false);
118 }
119 }
120 else if (checkDeviceLost(hres))
121 {
122 return error(GL_OUT_OF_MEMORY, GL_TRUE);
123 }
124
125 return mStatus;
126 }
127
128 return GL_TRUE; // prevent blocking when query is null
129}
130}