1 // SwiftShader Software Renderer
3 // Copyright(c) 2005-2011 TransGaming Inc.
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.
12 #include "Direct3DVolumeTexture9.hpp"
14 #include "Direct3DVolume9.hpp"
15 #include "Direct3DDevice9.hpp"
16 #include "Resource.hpp"
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)
27 this->levels = sw::log2(sw::max((int)width, (int)height, (int)depth, 1)) + 1;
30 for(unsigned int level = 0; level < MIPMAP_LEVELS; level++)
32 if(level < this->levels)
34 volumeLevel[level] = new Direct3DVolume9(device, this, width, height, depth, format, pool, usage);
35 volumeLevel[level]->bind();
39 volumeLevel[level] = 0;
42 width = sw::max(1, (int)width / 2);
43 height = sw::max(1, (int)height / 2);
44 depth = sw::max(1, (int)depth / 2);
48 Direct3DVolumeTexture9::~Direct3DVolumeTexture9()
50 resource->lock(sw::DESTRUCT);
52 for(int level = 0; level < MIPMAP_LEVELS; level++)
54 if(volumeLevel[level])
56 volumeLevel[level]->unbind();
57 volumeLevel[level] = 0;
64 long Direct3DVolumeTexture9::QueryInterface(const IID &iid, void **object)
66 CriticalSection cs(device);
70 if(iid == IID_IDirect3DVolumeTexture9 ||
71 iid == IID_IDirect3DBaseTexture9 ||
72 iid == IID_IDirect3DResource9 ||
83 return NOINTERFACE(iid);
86 unsigned long Direct3DVolumeTexture9::AddRef()
90 return Direct3DBaseTexture9::AddRef();
93 unsigned long Direct3DVolumeTexture9::Release()
97 return Direct3DBaseTexture9::Release();
100 long Direct3DVolumeTexture9::FreePrivateData(const GUID &guid)
102 CriticalSection cs(device);
106 return Direct3DBaseTexture9::FreePrivateData(guid);
109 long Direct3DVolumeTexture9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
111 CriticalSection cs(device);
115 return Direct3DBaseTexture9::GetPrivateData(guid, data, size);
118 void Direct3DVolumeTexture9::PreLoad()
120 CriticalSection cs(device);
124 Direct3DBaseTexture9::PreLoad();
127 long Direct3DVolumeTexture9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
129 CriticalSection cs(device);
133 return Direct3DBaseTexture9::SetPrivateData(guid, data, size, flags);
136 long Direct3DVolumeTexture9::GetDevice(IDirect3DDevice9 **device)
138 CriticalSection(this->device);
142 return Direct3DBaseTexture9::GetDevice(device);
145 unsigned long Direct3DVolumeTexture9::SetPriority(unsigned long newPriority)
147 CriticalSection cs(device);
151 return Direct3DBaseTexture9::SetPriority(newPriority);
154 unsigned long Direct3DVolumeTexture9::GetPriority()
156 CriticalSection cs(device);
160 return Direct3DBaseTexture9::GetPriority();
163 D3DRESOURCETYPE Direct3DVolumeTexture9::GetType()
165 CriticalSection cs(device);
169 return Direct3DBaseTexture9::GetType();
172 void Direct3DVolumeTexture9::GenerateMipSubLevels()
174 CriticalSection cs(device);
178 if(!(usage & D3DUSAGE_AUTOGENMIPMAP) || !volumeLevel[0]->hasDirtyMipmaps())
183 resource->lock(sw::PUBLIC);
185 for(unsigned int i = 0; i < levels - 1; i++)
187 Direct3DVolume9 *source = volumeLevel[i];
188 Direct3DVolume9 *dest = volumeLevel[i + 1];
190 source->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
191 dest->lockInternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
193 int sWidth = source->getWidth();
194 int sHeight = source->getHeight();
195 int sDepth = source->getDepth();
197 int dWidth = dest->getWidth();
198 int dHeight = dest->getHeight();
199 int dDepth = dest->getDepth();
201 D3DTEXTUREFILTERTYPE filter = GetAutoGenFilterType();
203 float w = (float)sWidth / (float)dWidth;
204 float h = (float)sHeight / (float)dHeight;
205 float d = (float)sDepth / (float)dDepth;
209 for(int k = 0; k < dDepth; k++)
213 for(int j = 0; j < dHeight; j++)
217 for(int i = 0; i < dWidth; i++)
219 sw::Color<float> color;
221 if(filter <= D3DTEXF_POINT)
223 color = source->readInternal((int)x, (int)y, (int)z);
225 else // filter >= D3DTEXF_LINEAR
227 color = source->sampleInternal(x, y, z);
230 dest->writeInternal(i, j, k, color);
241 source->unlockInternal();
242 dest->unlockInternal();
245 volumeLevel[0]->cleanMipmaps();
250 D3DTEXTUREFILTERTYPE Direct3DVolumeTexture9::GetAutoGenFilterType()
252 CriticalSection cs(device);
256 return Direct3DBaseTexture9::GetAutoGenFilterType();
259 unsigned long Direct3DVolumeTexture9::GetLevelCount()
261 CriticalSection cs(device);
265 return Direct3DBaseTexture9::GetLevelCount();
268 unsigned long Direct3DVolumeTexture9::GetLOD()
270 CriticalSection cs(device);
274 return Direct3DBaseTexture9::GetLOD();
277 long Direct3DVolumeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType)
279 CriticalSection cs(device);
283 return Direct3DBaseTexture9::SetAutoGenFilterType(filterType);
286 unsigned long Direct3DVolumeTexture9::SetLOD(unsigned long newLOD)
288 CriticalSection cs(device);
292 return Direct3DBaseTexture9::SetLOD(newLOD);
295 long Direct3DVolumeTexture9::GetVolumeLevel(unsigned int level, IDirect3DVolume9 **volume)
297 CriticalSection cs(device);
303 if(level >= GetLevelCount() || !volumeLevel[level])
305 return INVALIDCALL();
308 volumeLevel[level]->AddRef();
309 *volume = volumeLevel[level];
314 long Direct3DVolumeTexture9::LockBox(unsigned int level, D3DLOCKED_BOX *lockedVolume, const D3DBOX *box, unsigned long flags)
316 CriticalSection cs(device);
320 if(!lockedVolume || level >= GetLevelCount() || !volumeLevel[level])
322 return INVALIDCALL();
325 return volumeLevel[level]->LockBox(lockedVolume, box, flags);
328 long Direct3DVolumeTexture9::UnlockBox(unsigned int level)
330 CriticalSection cs(device);
334 if(level >= GetLevelCount() || !volumeLevel[level])
336 return INVALIDCALL();
339 return volumeLevel[level]->UnlockBox();
342 long Direct3DVolumeTexture9::AddDirtyBox(const D3DBOX *dirtyBox)
344 CriticalSection cs(device);
353 long Direct3DVolumeTexture9::GetLevelDesc(unsigned int level, D3DVOLUME_DESC *description)
355 CriticalSection cs(device);
359 if(!description || level >= GetLevelCount() || !volumeLevel[level])
361 return INVALIDCALL();
364 return volumeLevel[level]->GetDesc(description);
367 Direct3DVolume9 *Direct3DVolumeTexture9::getInternalVolumeLevel(unsigned int level)
369 return volumeLevel[level];