blob: f5d52a5bc06cdd37ab8dfda29ebf4851e994937f [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
44 delete query;
45 }
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;
172 case D3DQUERYTYPE_TIMESTAMP: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
173 case D3DQUERYTYPE_TIMESTAMPDISJOINT: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
174 case D3DQUERYTYPE_TIMESTAMPFREQ: if(flags != D3DISSUE_END) return INVALIDCALL(); break;
175 case D3DQUERYTYPE_PIPELINETIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
176 case D3DQUERYTYPE_INTERFACETIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
177 case D3DQUERYTYPE_VERTEXTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
178 case D3DQUERYTYPE_PIXELTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
179 case D3DQUERYTYPE_BANDWIDTHTIMINGS: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
180 case D3DQUERYTYPE_CACHEUTILIZATION: if(flags != D3DISSUE_BEGIN && flags != D3DISSUE_END) return INVALIDCALL(); break;
181 default:
182 ASSERT(false);
183 }
184
185 return D3D_OK;
186 }
187
188 long Direct3DQuery9::GetData(void *data, unsigned long size, unsigned long flags)
189 {
190 CriticalSection cs(device);
191
192 TRACE("void *data = %p, unsigned long size = %d, unsigned long flags = %d", data, size, flags);
193
194 if(query && query->building)
195 {
196 return INVALIDCALL();
197 }
198
Nicolas Capens0bac2852016-05-07 06:09:58 -0400199 bool signaled = !query || query->reference == 0;
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400200
201 if(size && signaled)
202 {
203 if(!data)
204 {
205 return INVALIDCALL();
206 }
207
208 // FIXME: Check size
209
210 switch(type)
211 {
212 case D3DQUERYTYPE_VCACHE:
213 {
214 D3DDEVINFO_VCACHE vcache;
215
216 vcache.Pattern = 'CACH';
217 vcache.OptMethod = 1; // Vertex-cache based optimization
218 vcache.CacheSize = 16;
219 vcache.MagicNumber = 8;
220
221 *(D3DDEVINFO_VCACHE*)data = vcache;
222 }
223 break;
224 case D3DQUERYTYPE_RESOURCEMANAGER: UNIMPLEMENTED(); break;
225 case D3DQUERYTYPE_VERTEXSTATS: UNIMPLEMENTED(); break;
226 case D3DQUERYTYPE_EVENT: *(BOOL*)data = TRUE; break; // FIXME
227 case D3DQUERYTYPE_OCCLUSION:
228 *(DWORD*)data = query->data;
229 break;
230 case D3DQUERYTYPE_TIMESTAMP: *(UINT64*)data = sw::Timer::counter(); break; // FIXME: Verify behaviour
231 case D3DQUERYTYPE_TIMESTAMPDISJOINT: *(BOOL*)data = FALSE; break; // FIXME: Verify behaviour
232 case D3DQUERYTYPE_TIMESTAMPFREQ: *(UINT64*)data = sw::Timer::frequency(); break; // FIXME: Verify behaviour
233 case D3DQUERYTYPE_PIPELINETIMINGS: UNIMPLEMENTED(); break;
234 case D3DQUERYTYPE_INTERFACETIMINGS: UNIMPLEMENTED(); break;
235 case D3DQUERYTYPE_VERTEXTIMINGS: UNIMPLEMENTED(); break;
236 case D3DQUERYTYPE_PIXELTIMINGS: UNIMPLEMENTED(); break;
237 case D3DQUERYTYPE_BANDWIDTHTIMINGS: UNIMPLEMENTED(); break;
238 case D3DQUERYTYPE_CACHEUTILIZATION: UNIMPLEMENTED(); break;
239 default:
240 ASSERT(false);
241 }
242 }
243
244 return signaled ? S_OK : S_FALSE;
245 }
246}