OSDN Git Service

Adapt D3D9 to Renderer changes.
[android-x86/external-swiftshader.git] / src / D3D9 / Direct3DVolumeTexture9.cpp
1 // 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
21 namespace 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
193                         int sWidth = source->getWidth();
194                         int sHeight = source->getHeight();
195                         int sDepth = source->getDepth();
196
197                         int dWidth = dest->getWidth();
198                         int dHeight = dest->getHeight();
199                         int dDepth = dest->getDepth();
200
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                                         {
219                                                 sw::Color<float> color;
220
221                                                 if(filter <= D3DTEXF_POINT)
222                                                 {
223                                                         color = source->readInternal((int)x, (int)y, (int)z);
224                                                 }
225                                                 else   // filter >= D3DTEXF_LINEAR
226                                                 {
227                                                         color = source->sampleInternal(x, y, z);
228                                                 }
229
230                                                 dest->writeInternal(i, j, k, color);
231
232                                                 x += w;
233                                         }
234
235                                         y += h;
236                                 }
237
238                                 z += d;
239                         }
240
241                         source->unlockInternal();
242                         dest->unlockInternal();
243                 }
244
245                 volumeLevel[0]->cleanMipmaps();
246
247                 resource->unlock();
248         }
249
250         D3DTEXTUREFILTERTYPE Direct3DVolumeTexture9::GetAutoGenFilterType()
251         {
252                 CriticalSection cs(device);
253
254                 TRACE("");
255
256                 return Direct3DBaseTexture9::GetAutoGenFilterType();
257         }
258
259         unsigned long Direct3DVolumeTexture9::GetLevelCount()
260         {
261                 CriticalSection cs(device);
262
263                 TRACE("");
264
265                 return Direct3DBaseTexture9::GetLevelCount();
266         }
267
268         unsigned long Direct3DVolumeTexture9::GetLOD()
269         {
270                 CriticalSection cs(device);
271
272                 TRACE("");
273
274                 return Direct3DBaseTexture9::GetLOD();
275         }
276
277         long Direct3DVolumeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType)
278         {
279                 CriticalSection cs(device);
280
281                 TRACE("");
282
283                 return Direct3DBaseTexture9::SetAutoGenFilterType(filterType);
284         }
285
286         unsigned long Direct3DVolumeTexture9::SetLOD(unsigned long newLOD)
287         {
288                 CriticalSection cs(device);
289
290                 TRACE("");
291
292                 return Direct3DBaseTexture9::SetLOD(newLOD);
293         }
294
295         long Direct3DVolumeTexture9::GetVolumeLevel(unsigned int level, IDirect3DVolume9 **volume)
296         {
297                 CriticalSection cs(device);
298
299                 TRACE("");
300
301                 *volume = 0;
302
303                 if(level >= GetLevelCount() || !volumeLevel[level])
304                 {
305                         return INVALIDCALL();
306                 }
307
308                 volumeLevel[level]->AddRef();
309                 *volume = volumeLevel[level];
310
311                 return D3D_OK;
312         }
313
314         long Direct3DVolumeTexture9::LockBox(unsigned int level, D3DLOCKED_BOX *lockedVolume, const D3DBOX *box, unsigned long flags)
315         {
316                 CriticalSection cs(device);
317
318                 TRACE("");
319
320                 if(!lockedVolume || level >= GetLevelCount() || !volumeLevel[level])
321                 {
322                         return INVALIDCALL();
323                 }
324
325                 return volumeLevel[level]->LockBox(lockedVolume, box, flags);
326         }
327
328         long Direct3DVolumeTexture9::UnlockBox(unsigned int level)
329         {
330                 CriticalSection cs(device);
331
332                 TRACE("");
333
334                 if(level >= GetLevelCount() || !volumeLevel[level])
335                 {
336                         return INVALIDCALL();
337                 }
338
339                 return volumeLevel[level]->UnlockBox();
340         }
341
342         long Direct3DVolumeTexture9::AddDirtyBox(const D3DBOX *dirtyBox)
343         {
344                 CriticalSection cs(device);
345
346                 TRACE("");
347
348         //      UNIMPLEMENTED();
349
350                 return D3D_OK;
351         }
352
353         long Direct3DVolumeTexture9::GetLevelDesc(unsigned int level, D3DVOLUME_DESC *description)
354         {
355                 CriticalSection cs(device);
356
357                 TRACE("");
358
359                 if(!description || level >= GetLevelCount() || !volumeLevel[level])
360                 {
361                         return INVALIDCALL();
362                 }
363
364                 return volumeLevel[level]->GetDesc(description);
365         }
366
367         Direct3DVolume9 *Direct3DVolumeTexture9::getInternalVolumeLevel(unsigned int level)
368         {
369                 return volumeLevel[level];
370         }
371 }