blob: c9024d1aa8bc4d928739fa85bea638c11651c4c8 [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 "Direct3DVolumeTexture9.hpp"
16
17#include "Direct3DVolume9.hpp"
18#include "Direct3DDevice9.hpp"
19#include "Resource.hpp"
20#include "Debug.hpp"
21
22#include <assert.h>
23
24namespace D3D9
25{
26 Direct3DVolumeTexture9::Direct3DVolumeTexture9(Direct3DDevice9 *device, unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool) : Direct3DBaseTexture9(device, D3DRTYPE_VOLUMETEXTURE, format, pool, levels, usage), width(width), height(height), depth(depth)
27 {
28 if(levels == 0)
29 {
30 this->levels = sw::log2(sw::max((int)width, (int)height, (int)depth, 1)) + 1;
31 }
32
Nicolas Capensb663f712016-04-18 12:02:39 -040033 for(unsigned int level = 0; level < sw::MIPMAP_LEVELS; level++)
Nicolas Capensee16f0d2015-07-16 17:40:10 -040034 {
35 if(level < this->levels)
36 {
37 volumeLevel[level] = new Direct3DVolume9(device, this, width, height, depth, format, pool, usage);
38 volumeLevel[level]->bind();
39 }
40 else
41 {
42 volumeLevel[level] = 0;
43 }
44
45 width = sw::max(1, (int)width / 2);
46 height = sw::max(1, (int)height / 2);
47 depth = sw::max(1, (int)depth / 2);
48 }
49 }
50
51 Direct3DVolumeTexture9::~Direct3DVolumeTexture9()
52 {
Nicolas Capensb663f712016-04-18 12:02:39 -040053 for(int level = 0; level < sw::MIPMAP_LEVELS; level++)
Nicolas Capensee16f0d2015-07-16 17:40:10 -040054 {
55 if(volumeLevel[level])
56 {
57 volumeLevel[level]->unbind();
58 volumeLevel[level] = 0;
59 }
60 }
Nicolas Capensee16f0d2015-07-16 17:40:10 -040061 }
62
63 long Direct3DVolumeTexture9::QueryInterface(const IID &iid, void **object)
64 {
65 CriticalSection cs(device);
66
67 TRACE("");
68
69 if(iid == IID_IDirect3DVolumeTexture9 ||
70 iid == IID_IDirect3DBaseTexture9 ||
71 iid == IID_IDirect3DResource9 ||
72 iid == IID_IUnknown)
73 {
74 AddRef();
75 *object = this;
76
77 return S_OK;
78 }
79
80 *object = 0;
81
82 return NOINTERFACE(iid);
83 }
84
85 unsigned long Direct3DVolumeTexture9::AddRef()
86 {
87 TRACE("");
88
89 return Direct3DBaseTexture9::AddRef();
90 }
91
92 unsigned long Direct3DVolumeTexture9::Release()
93 {
94 TRACE("");
95
96 return Direct3DBaseTexture9::Release();
97 }
98
99 long Direct3DVolumeTexture9::FreePrivateData(const GUID &guid)
100 {
101 CriticalSection cs(device);
102
103 TRACE("");
104
105 return Direct3DBaseTexture9::FreePrivateData(guid);
106 }
107
108 long Direct3DVolumeTexture9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
109 {
110 CriticalSection cs(device);
111
112 TRACE("");
113
114 return Direct3DBaseTexture9::GetPrivateData(guid, data, size);
115 }
116
117 void Direct3DVolumeTexture9::PreLoad()
118 {
119 CriticalSection cs(device);
120
121 TRACE("");
122
123 Direct3DBaseTexture9::PreLoad();
124 }
125
126 long Direct3DVolumeTexture9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
127 {
128 CriticalSection cs(device);
129
130 TRACE("");
131
132 return Direct3DBaseTexture9::SetPrivateData(guid, data, size, flags);
133 }
134
135 long Direct3DVolumeTexture9::GetDevice(IDirect3DDevice9 **device)
136 {
137 CriticalSection(this->device);
138
139 TRACE("");
140
141 return Direct3DBaseTexture9::GetDevice(device);
142 }
143
144 unsigned long Direct3DVolumeTexture9::SetPriority(unsigned long newPriority)
145 {
146 CriticalSection cs(device);
147
148 TRACE("");
149
150 return Direct3DBaseTexture9::SetPriority(newPriority);
151 }
152
153 unsigned long Direct3DVolumeTexture9::GetPriority()
154 {
155 CriticalSection cs(device);
156
157 TRACE("");
158
159 return Direct3DBaseTexture9::GetPriority();
160 }
161
162 D3DRESOURCETYPE Direct3DVolumeTexture9::GetType()
163 {
164 CriticalSection cs(device);
165
166 TRACE("");
167
168 return Direct3DBaseTexture9::GetType();
169 }
170
171 void Direct3DVolumeTexture9::GenerateMipSubLevels()
172 {
173 CriticalSection cs(device);
174
175 TRACE("");
176
Nicolas Capens73e18c12017-11-28 13:31:35 -0500177 if(!(usage & D3DUSAGE_AUTOGENMIPMAP) || !volumeLevel[0]->hasDirtyContents())
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400178 {
179 return;
180 }
181
182 resource->lock(sw::PUBLIC);
183
184 for(unsigned int i = 0; i < levels - 1; i++)
185 {
186 Direct3DVolume9 *source = volumeLevel[i];
187 Direct3DVolume9 *dest = volumeLevel[i + 1];
188
189 source->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
190 dest->lockInternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
191
Nicolas Capens66839432015-07-17 11:45:49 -0400192 int sWidth = source->getWidth();
193 int sHeight = source->getHeight();
194 int sDepth = source->getDepth();
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400195
Nicolas Capens66839432015-07-17 11:45:49 -0400196 int dWidth = dest->getWidth();
197 int dHeight = dest->getHeight();
198 int dDepth = dest->getDepth();
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400199
200 D3DTEXTUREFILTERTYPE filter = GetAutoGenFilterType();
201
202 float w = (float)sWidth / (float)dWidth;
203 float h = (float)sHeight / (float)dHeight;
204 float d = (float)sDepth / (float)dDepth;
205
206 float z = 0.5f * d;
207
208 for(int k = 0; k < dDepth; k++)
209 {
210 float y = 0.5f * h;
211
212 for(int j = 0; j < dHeight; j++)
213 {
214 float x = 0.5f * w;
215
216 for(int i = 0; i < dWidth; i++)
217 {
Alexis Hetu43577b82015-10-21 15:32:16 -0400218 dest->copyInternal(source, i, j, k, x, y, z, filter > D3DTEXF_POINT);
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400219
220 x += w;
221 }
222
223 y += h;
224 }
225
226 z += d;
227 }
228
229 source->unlockInternal();
230 dest->unlockInternal();
231 }
232
Nicolas Capens73e18c12017-11-28 13:31:35 -0500233 volumeLevel[0]->markContentsClean();
Nicolas Capensee16f0d2015-07-16 17:40:10 -0400234
235 resource->unlock();
236 }
237
238 D3DTEXTUREFILTERTYPE Direct3DVolumeTexture9::GetAutoGenFilterType()
239 {
240 CriticalSection cs(device);
241
242 TRACE("");
243
244 return Direct3DBaseTexture9::GetAutoGenFilterType();
245 }
246
247 unsigned long Direct3DVolumeTexture9::GetLevelCount()
248 {
249 CriticalSection cs(device);
250
251 TRACE("");
252
253 return Direct3DBaseTexture9::GetLevelCount();
254 }
255
256 unsigned long Direct3DVolumeTexture9::GetLOD()
257 {
258 CriticalSection cs(device);
259
260 TRACE("");
261
262 return Direct3DBaseTexture9::GetLOD();
263 }
264
265 long Direct3DVolumeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType)
266 {
267 CriticalSection cs(device);
268
269 TRACE("");
270
271 return Direct3DBaseTexture9::SetAutoGenFilterType(filterType);
272 }
273
274 unsigned long Direct3DVolumeTexture9::SetLOD(unsigned long newLOD)
275 {
276 CriticalSection cs(device);
277
278 TRACE("");
279
280 return Direct3DBaseTexture9::SetLOD(newLOD);
281 }
282
283 long Direct3DVolumeTexture9::GetVolumeLevel(unsigned int level, IDirect3DVolume9 **volume)
284 {
285 CriticalSection cs(device);
286
287 TRACE("");
288
289 *volume = 0;
290
291 if(level >= GetLevelCount() || !volumeLevel[level])
292 {
293 return INVALIDCALL();
294 }
295
296 volumeLevel[level]->AddRef();
297 *volume = volumeLevel[level];
298
299 return D3D_OK;
300 }
301
302 long Direct3DVolumeTexture9::LockBox(unsigned int level, D3DLOCKED_BOX *lockedVolume, const D3DBOX *box, unsigned long flags)
303 {
304 CriticalSection cs(device);
305
306 TRACE("");
307
308 if(!lockedVolume || level >= GetLevelCount() || !volumeLevel[level])
309 {
310 return INVALIDCALL();
311 }
312
313 return volumeLevel[level]->LockBox(lockedVolume, box, flags);
314 }
315
316 long Direct3DVolumeTexture9::UnlockBox(unsigned int level)
317 {
318 CriticalSection cs(device);
319
320 TRACE("");
321
322 if(level >= GetLevelCount() || !volumeLevel[level])
323 {
324 return INVALIDCALL();
325 }
326
327 return volumeLevel[level]->UnlockBox();
328 }
329
330 long Direct3DVolumeTexture9::AddDirtyBox(const D3DBOX *dirtyBox)
331 {
332 CriticalSection cs(device);
333
334 TRACE("");
335
336 // UNIMPLEMENTED();
337
338 return D3D_OK;
339 }
340
341 long Direct3DVolumeTexture9::GetLevelDesc(unsigned int level, D3DVOLUME_DESC *description)
342 {
343 CriticalSection cs(device);
344
345 TRACE("");
346
347 if(!description || level >= GetLevelCount() || !volumeLevel[level])
348 {
349 return INVALIDCALL();
350 }
351
352 return volumeLevel[level]->GetDesc(description);
353 }
354
355 Direct3DVolume9 *Direct3DVolumeTexture9::getInternalVolumeLevel(unsigned int level)
356 {
357 return volumeLevel[level];
358 }
359}