blob: dd6280d7d4091731a15e9bc5e3d2be9bc844e374 [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
11#include "libGLESv2/main.h"
12
13namespace gl
14{
15
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000016Query::Query(renderer::Renderer *renderer, GLuint id, GLenum type) : RefCountObject(id)
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000017{
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000018 mRenderer = renderer;
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000019 mQuery = NULL;
20 mStatus = GL_FALSE;
21 mResult = GL_FALSE;
22 mType = type;
23}
24
25Query::~Query()
26{
27 if (mQuery != NULL)
28 {
29 mQuery->Release();
30 mQuery = NULL;
31 }
32}
33
34void Query::begin()
35{
36 if (mQuery == NULL)
37 {
daniel@transgaming.com621ce052012-10-31 17:52:29 +000038 // D3D9_REPLACE
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000039 if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery)))
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000040 {
41 return error(GL_OUT_OF_MEMORY);
42 }
43 }
44
45 HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
46 ASSERT(SUCCEEDED(result));
47}
48
49void Query::end()
50{
51 if (mQuery == NULL)
52 {
53 return error(GL_INVALID_OPERATION);
54 }
55
56 HRESULT result = mQuery->Issue(D3DISSUE_END);
57 ASSERT(SUCCEEDED(result));
58
59 mStatus = GL_FALSE;
60 mResult = GL_FALSE;
61}
62
63GLuint Query::getResult()
64{
65 if (mQuery != NULL)
66 {
67 while (!testQuery())
68 {
69 Sleep(0);
70 // explicitly check for device loss
71 // some drivers seem to return S_FALSE even if the device is lost
72 // instead of D3DERR_DEVICELOST like they should
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000073 if (mRenderer->testDeviceLost())
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000074 {
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000075 gl::getDisplay()->notifyDeviceLost(); // D3D9_REPLACE
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}