1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // 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 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // 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. 14 15 #include "Direct3DVolume9.hpp" 16 17 #include "Direct3DDevice9.hpp" 18 #include "Direct3DResource9.hpp" 19 #include "Direct3DVolumeTexture9.hpp" 20 #include "Direct3DSurface9.hpp" 21 #include "Resource.hpp" 22 #include "Debug.hpp" 23 24 #include <assert.h> 25 26 namespace D3D9 27 { 28 bool isLockable(D3DPOOL pool, unsigned long usage) 29 { 30 return (pool != D3DPOOL_DEFAULT) || (usage & D3DUSAGE_DYNAMIC); 31 } 32 33 Direct3DVolume9::Direct3DVolume9(Direct3DDevice9 *device, Direct3DVolumeTexture9 *container, int width, int height, int depth, D3DFORMAT format, D3DPOOL pool, unsigned long usage) : device(device), Surface(container->getResource(), width, height, depth, translateFormat(format), isLockable(pool, usage), false), container(container), width(width), height(height), depth(depth), format(format), pool(pool), lockable(isLockable(pool, usage)), usage(usage) 34 { 35 resource = new Direct3DResource9(device, D3DRTYPE_VOLUME, pool, memoryUsage(width, height, depth, format)); 36 resource->bind(); 37 } 38 39 Direct3DVolume9::~Direct3DVolume9() 40 { 41 resource->unbind(); 42 } 43 44 void *Direct3DVolume9::lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) 45 { 46 return Surface::lockInternal(x, y, z, lock, client); 47 } 48 49 void Direct3DVolume9::unlockInternal() 50 { 51 Surface::unlockInternal(); 52 } 53 54 long __stdcall Direct3DVolume9::QueryInterface(const IID &iid, void **object) 55 { 56 CriticalSection cs(device); 57 58 TRACE(""); 59 60 if(iid == IID_IDirect3DVolume9 || 61 iid == IID_IUnknown) 62 { 63 AddRef(); 64 *object = this; 65 66 return S_OK; 67 } 68 69 *object = 0; 70 71 return NOINTERFACE(iid); 72 } 73 74 unsigned long __stdcall Direct3DVolume9::AddRef() 75 { 76 TRACE(""); 77 78 return container->AddRef(); 79 } 80 81 unsigned long __stdcall Direct3DVolume9::Release() 82 { 83 TRACE(""); 84 85 return container->Release(); 86 } 87 88 long Direct3DVolume9::FreePrivateData(const GUID &guid) 89 { 90 CriticalSection cs(device); 91 92 TRACE(""); 93 94 return resource->FreePrivateData(guid); 95 } 96 97 long Direct3DVolume9::GetContainer(const IID &iid, void **container) 98 { 99 CriticalSection cs(device); 100 101 TRACE(""); 102 103 if(!container) 104 { 105 return INVALIDCALL(); 106 } 107 108 long result = this->container->QueryInterface(iid, container); 109 110 if(result == S_OK) 111 { 112 return D3D_OK; 113 } 114 115 return INVALIDCALL(); 116 } 117 118 long Direct3DVolume9::GetDesc(D3DVOLUME_DESC *description) 119 { 120 CriticalSection cs(device); 121 122 TRACE(""); 123 124 if(!description) 125 { 126 return INVALIDCALL(); 127 } 128 129 description->Format = format; 130 description->Type = D3DRTYPE_VOLUME; 131 description->Usage = usage; 132 description->Pool = pool; 133 description->Width = width; 134 description->Height = height; 135 description->Depth = depth; 136 137 return D3D_OK; 138 } 139 140 long Direct3DVolume9::GetDevice(IDirect3DDevice9 **device) 141 { 142 CriticalSection cs(this->device); 143 144 TRACE(""); 145 146 return resource->GetDevice(device); 147 } 148 149 long Direct3DVolume9::GetPrivateData(const GUID &guid, void *data, unsigned long *size) 150 { 151 CriticalSection cs(device); 152 153 TRACE(""); 154 155 return resource->GetPrivateData(guid, data, size); 156 } 157 158 long Direct3DVolume9::LockBox(D3DLOCKED_BOX *lockedVolume, const D3DBOX *box, unsigned long flags) 159 { 160 CriticalSection cs(device); 161 162 TRACE(""); 163 164 if(!lockedVolume) 165 { 166 return INVALIDCALL(); 167 } 168 169 lockedVolume->RowPitch = 0; 170 lockedVolume->SlicePitch = 0; 171 lockedVolume->pBits = 0; 172 173 if(!lockable) 174 { 175 return INVALIDCALL(); 176 } 177 178 lockedVolume->RowPitch = getExternalPitchB(); 179 lockedVolume->SlicePitch = getExternalSliceB(); 180 181 sw::Lock lock = sw::LOCK_READWRITE; 182 183 if(flags & D3DLOCK_DISCARD) 184 { 185 lock = sw::LOCK_DISCARD; 186 } 187 188 if(flags & D3DLOCK_READONLY) 189 { 190 lock = sw::LOCK_READONLY; 191 } 192 193 if(box) 194 { 195 lockedVolume->pBits = lockExternal(box->Left, box->Top, box->Front, lock, sw::PUBLIC); 196 } 197 else 198 { 199 lockedVolume->pBits = lockExternal(0, 0, 0, lock, sw::PUBLIC); 200 } 201 202 return D3D_OK; 203 } 204 205 long Direct3DVolume9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags) 206 { 207 CriticalSection cs(device); 208 209 TRACE(""); 210 211 return resource->SetPrivateData(guid, data, size, flags); 212 } 213 214 long Direct3DVolume9::UnlockBox() 215 { 216 CriticalSection cs(device); 217 218 TRACE(""); 219 220 unlockExternal(); 221 222 return D3D_OK; 223 } 224 225 sw::Format Direct3DVolume9::translateFormat(D3DFORMAT format) 226 { 227 return Direct3DSurface9::translateFormat(format); 228 } 229 230 unsigned int Direct3DVolume9::memoryUsage(int width, int height, int depth, D3DFORMAT format) 231 { 232 return Surface::size(width, height, depth, translateFormat(format)); 233 } 234 } 235