blob: b6a3b2d60a8fa14016007d00be753e1642c75cbc [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
Nicolas Capensee16f0d2015-07-16 17:40:10 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
Nicolas Capensee16f0d2015-07-16 17:40:10 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
Nicolas Capensee16f0d2015-07-16 17:40:10 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
Nicolas Capensee16f0d2015-07-16 17:40:10 -040014
15#include "Direct3DQuery9.hpp"
16
17#include "Direct3DDevice9.hpp"
18#include "Timer.hpp"
19#include "Renderer.hpp"
20#include "Debug.hpp"
21
22#include <assert.h>
23
24namespace D3D9
25{
26 Direct3DQuery9::Direct3DQuery9(Direct3DDevice9 *device, D3DQUERYTYPE type) : device(device), type(type)
27 {
28 if(type == D3DQUERYTYPE_OCCLUSION)
29 {
Alexis Hetu16116cb2016-03-02 15:59:51 -050030 query = new sw::Query(sw::Query::FRAGMENTS_PASSED);
Nicolas Capensee16f0d2015-07-16 17:40:10 -040031 }
32 else
33 {
34 query = 0;
35 }
36 }
37
38 Direct3DQuery9::~Direct3DQuery9()
39 {
40 if(query)
41 {
42 device->removeQuery(query);
43
Alexis Hetu3fc68932018-11-14 10:54:53 -050044 query->release();
Nicolas Capensee16f0d2015-07-16 17:40:10 -040045 }
46 }
47
48 long Direct3DQuery9::QueryInterface(const IID &iid, void **object)
49 {
50 CriticalSection cs(device);
51
52 TRACE("");
53
54 if(iid == IID_IDirect3DQuery9 ||
55 iid == IID_IUnknown)
56 {
57 AddRef();
58 *object = this;
59
60 return S_OK;
61 }
62
63 *object = 0;
64
65 return NOINTERFACE(iid);
66 }
67
68 unsigned long Direct3DQuery9::AddRef()
69 {
70 TRACE("");
71
72 return Unknown::AddRef();
73 }
Nicolas Capens0bac2852016-05-07 06:09:58 -040074
Nicolas Capensee16f0d2015-07-16 17:40:10 -040075 unsigned long Direct3DQuery9::Release()
76 {
77 TRACE("");
78
79 return Unknown::Release();
80 }
81
82 long __stdcall Direct3DQuery9::GetDevice(IDirect3DDevice9 **device)
83 {
84 CriticalSection cs(this->device);
85
86 TRACE("");
87
88 if(!device)
89 {
90 return INVALIDCALL();
91 }
92
93 this->device->AddRef();
94 *device = this->device;
95
96 return D3D_OK;
97 }
98
99 D3DQUERYTYPE Direct3DQuery9::GetType()
100 {
101 CriticalSection cs(device);
102
103 return type;
104 }
105
106 unsigned long Direct3DQuery9::GetDataSize()
107 {
108 CriticalSection cs(device);
109
110 TRACE("");
111
112 switch(type)
113 {
114 case D3DQUERYTYPE_VCACHE: return sizeof(D3DDEVINFO_VCACHE);
115 case D3DQUERYTYPE_RESOURCEMANAGER: return sizeof(D3DDEVINFO_RESOURCEMANAGER);
116 case D3DQUERYTYPE_VERTEXSTATS: return sizeof(D3DDEVINFO_D3DVERTEXSTATS);
117 case D3DQUERYTYPE_EVENT: return sizeof(BOOL);
118 case D3DQUERYTYPE_OCCLUSION: return sizeof(DWORD);
119 case D3DQUERYTYPE_TIMESTAMP: return sizeof(UINT64);
120 case D3DQUERYTYPE_TIMESTAMPDISJOINT: return sizeof(BOOL);
121 case D3DQUERYTYPE_TIMESTAMPFREQ: return sizeof(UINT64);
122 case D3DQUERYTYPE_PIPELINETIMINGS: return sizeof(D3DDEVINFO_D3D9PIPELINETIMINGS);
123 case D3DQUERYTYPE_INTERFACETIMINGS: return sizeof(D3DDEVINFO_D3D9INTERFACETIMINGS);
124 case D3DQUERYTYPE_VERTEXTIMINGS: return sizeof(D3DDEVINFO_D3D9STAGETIMINGS);
125 case D3DQUERYTYPE_PIXELTIMINGS: return sizeof(D3DDEVINFO_D3D9PIPELINETIMINGS);
126 case D3DQUERYTYPE_BANDWIDTHTIMINGS: return sizeof(D3DDEVINFO_D3D9BANDWIDTHTIMINGS);
127 case D3DQUERYTYPE_CACHEUTILIZATION: return sizeof(D3DDEVINFO_D3D9CACHEUTILIZATION);
128 default:
129 ASSERT(false);
130 }
131
132 return D3D_OK;
133 }
134
135 long Direct3DQuery9::Issue(unsigned long flags)
136 {
137 CriticalSection cs(device);
138
139 TRACE("");
140
141 if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END)
142 {
143 return INVALIDCALL();
144 }
145
146 switch(type)
147 {
148 case D3DQUERYTYPE_VCACHE: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
149 case D3DQUERYTYPE_RESOURCEMANAGER: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
150 case D3DQUERYTYPE_VERTEXSTATS: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
151 case D3DQUERYTYPE_EVENT:
152 if(flags == D3DISSUE_END)
153 {
154 // device->renderer->synchronize(); // FIXME
155 }
156 else return INVALIDCALL();
157 break;
158 case D3DQUERYTYPE_OCCLUSION:
159 if(flags == D3DISSUE_BEGIN)
160 {
161 query->begin();
162 device->addQuery(query);
163 device->setOcclusionEnabled(true);
164 }
165 else // flags == D3DISSUE_END
166 {
167 query->end();
168 device->removeQuery(query);
169 device->setOcclusionEnabled(false);
170 }
171 break;
Branimir Karadžić56dda252016-07-01 09:34:28 -0700172 case D3DQUERYTYPE_TIMESTAMP:
173 if(flags == D3DISSUE_END)
174 {
175 timestamp = sw::Timer::counter();
176 }
177 else return INVALIDCALL();
178 break;
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400179 case D3DQUERYTYPE_TIMESTAMPDISJOINT: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
180 case D3DQUERYTYPE_TIMESTAMPFREQ: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
181 case D3DQUERYTYPE_PIPELINETIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
182 case D3DQUERYTYPE_INTERFACETIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
183 case D3DQUERYTYPE_VERTEXTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
184 case D3DQUERYTYPE_PIXELTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
185 case D3DQUERYTYPE_BANDWIDTHTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
186 case D3DQUERYTYPE_CACHEUTILIZATION: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
187 default:
188 ASSERT(false);
189 }
190
191 return D3D_OK;
192 }
193
194 long Direct3DQuery9::GetData(void *data, unsigned long size, unsigned long flags)
195 {
196 CriticalSection cs(device);
197
198 TRACE("void *data = %p, unsigned long size = %d, unsigned long flags = %d", data, size, flags);
199
200 if(query && query->building)
201 {
202 return INVALIDCALL();
203 }
204
Alexis Hetu3fc68932018-11-14 10:54:53 -0500205 bool signaled = !query || query->isReady();
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400206
207 if(size && signaled)
208 {
209 if(!data)
210 {
211 return INVALIDCALL();
212 }
213
214 // FIXME: Check size
215
216 switch(type)
217 {
218 case D3DQUERYTYPE_VCACHE:
219 {
220 D3DDEVINFO_VCACHE vcache;
221
222 vcache.Pattern = 'CACH';
223 vcache.OptMethod = 1; // Vertex-cache based optimization
224 vcache.CacheSize = 16;
225 vcache.MagicNumber = 8;
226
227 *(D3DDEVINFO_VCACHE*)data = vcache;
228 }
229 break;
230 case D3DQUERYTYPE_RESOURCEMANAGER: UNIMPLEMENTED(); break;
231 case D3DQUERYTYPE_VERTEXSTATS: UNIMPLEMENTED(); break;
232 case D3DQUERYTYPE_EVENT: *(BOOL*)data = TRUE; break; // FIXME
233 case D3DQUERYTYPE_OCCLUSION:
234 *(DWORD*)data = query->data;
235 break;
Branimir Karadžić56dda252016-07-01 09:34:28 -0700236 case D3DQUERYTYPE_TIMESTAMP: *(UINT64*)data = timestamp; break; // FIXME: Verify behaviour
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400237 case D3DQUERYTYPE_TIMESTAMPDISJOINT: *(BOOL*)data = FALSE; break; // FIXME: Verify behaviour
238 case D3DQUERYTYPE_TIMESTAMPFREQ: *(UINT64*)data = sw::Timer::frequency(); break; // FIXME: Verify behaviour
239 case D3DQUERYTYPE_PIPELINETIMINGS: UNIMPLEMENTED(); break;
240 case D3DQUERYTYPE_INTERFACETIMINGS: UNIMPLEMENTED(); break;
241 case D3DQUERYTYPE_VERTEXTIMINGS: UNIMPLEMENTED(); break;
242 case D3DQUERYTYPE_PIXELTIMINGS: UNIMPLEMENTED(); break;
243 case D3DQUERYTYPE_BANDWIDTHTIMINGS: UNIMPLEMENTED(); break;
244 case D3DQUERYTYPE_CACHEUTILIZATION: UNIMPLEMENTED(); break;
245 default:
246 ASSERT(false);
247 }
248 }
249
250 return signaled ? S_OK : S_FALSE;
251 }
252}