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