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 "Direct3DCubeTexture9.hpp" 16 17 #include "Direct3DDevice9.hpp" 18 #include "Direct3DSurface9.hpp" 19 #include "Resource.hpp" 20 #include "Debug.hpp" 21 22 #include <assert.h> 23 24 namespace D3D9 25 { Direct3DCubeTexture9(Direct3DDevice9 * device,unsigned int edgeLength,unsigned int levels,unsigned long usage,D3DFORMAT format,D3DPOOL pool)26 Direct3DCubeTexture9::Direct3DCubeTexture9(Direct3DDevice9 *device, unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool) : Direct3DBaseTexture9(device, D3DRTYPE_CUBETEXTURE, format, pool, levels, usage), edgeLength(edgeLength) 27 { 28 if(levels == 0) 29 { 30 this->levels = sw::log2(sw::max((int)edgeLength, 1)) + 1; 31 } 32 33 for(unsigned int face = 0; face < 6; face++) 34 { 35 int width = edgeLength; 36 int height = edgeLength; 37 38 for(unsigned int level = 0; level < sw::MIPMAP_LEVELS; level++) 39 { 40 if(level < this->levels) 41 { 42 surfaceLevel[face][level] = new Direct3DSurface9(device, this, width, height, format, pool, D3DMULTISAMPLE_NONE, 0, false, usage); 43 surfaceLevel[face][level]->bind(); 44 } 45 else 46 { 47 surfaceLevel[face][level] = 0; 48 } 49 50 width = sw::max(1, width / 2); 51 height = sw::max(1, height / 2); 52 } 53 } 54 } 55 ~Direct3DCubeTexture9()56 Direct3DCubeTexture9::~Direct3DCubeTexture9() 57 { 58 resource->lock(sw::DESTRUCT); 59 60 for(unsigned int face = 0; face < 6; face++) 61 { 62 for(int level = 0; level < sw::MIPMAP_LEVELS; level++) 63 { 64 if(surfaceLevel[face][level]) 65 { 66 surfaceLevel[face][level]->unbind(); 67 surfaceLevel[face][level] = 0; 68 } 69 } 70 } 71 72 resource->unlock(); 73 } 74 QueryInterface(const IID & iid,void ** object)75 long Direct3DCubeTexture9::QueryInterface(const IID &iid, void **object) 76 { 77 CriticalSection cs(device); 78 79 TRACE(""); 80 81 if(iid == IID_IDirect3DCubeTexture9 || 82 iid == IID_IDirect3DBaseTexture9 || 83 iid == IID_IDirect3DResource9 || 84 iid == IID_IUnknown) 85 { 86 AddRef(); 87 *object = this; 88 89 return S_OK; 90 } 91 92 *object = 0; 93 94 return NOINTERFACE(iid); 95 } 96 AddRef()97 unsigned long Direct3DCubeTexture9::AddRef() 98 { 99 TRACE(""); 100 101 return Direct3DBaseTexture9::AddRef(); 102 } 103 Release()104 unsigned long Direct3DCubeTexture9::Release() 105 { 106 TRACE(""); 107 108 return Direct3DBaseTexture9::Release(); 109 } 110 FreePrivateData(const GUID & guid)111 long Direct3DCubeTexture9::FreePrivateData(const GUID &guid) 112 { 113 CriticalSection cs(device); 114 115 TRACE(""); 116 117 return Direct3DBaseTexture9::FreePrivateData(guid); 118 } 119 GetPrivateData(const GUID & guid,void * data,unsigned long * size)120 long Direct3DCubeTexture9::GetPrivateData(const GUID &guid, void *data, unsigned long *size) 121 { 122 CriticalSection cs(device); 123 124 TRACE(""); 125 126 return Direct3DBaseTexture9::GetPrivateData(guid, data, size); 127 } 128 PreLoad()129 void Direct3DCubeTexture9::PreLoad() 130 { 131 CriticalSection cs(device); 132 133 TRACE(""); 134 135 Direct3DBaseTexture9::PreLoad(); 136 } 137 SetPrivateData(const GUID & guid,const void * data,unsigned long size,unsigned long flags)138 long Direct3DCubeTexture9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags) 139 { 140 CriticalSection cs(device); 141 142 TRACE(""); 143 144 return Direct3DBaseTexture9::SetPrivateData(guid, data, size, flags); 145 } 146 GetDevice(IDirect3DDevice9 ** device)147 long Direct3DCubeTexture9::GetDevice(IDirect3DDevice9 **device) 148 { 149 CriticalSection cs(this->device); 150 151 TRACE(""); 152 153 return Direct3DBaseTexture9::GetDevice(device); 154 } 155 SetPriority(unsigned long newPriority)156 unsigned long Direct3DCubeTexture9::SetPriority(unsigned long newPriority) 157 { 158 CriticalSection cs(device); 159 160 TRACE(""); 161 162 return Direct3DBaseTexture9::SetPriority(newPriority); 163 } 164 GetPriority()165 unsigned long Direct3DCubeTexture9::GetPriority() 166 { 167 CriticalSection cs(device); 168 169 TRACE(""); 170 171 return Direct3DBaseTexture9::GetPriority(); 172 } 173 GetType()174 D3DRESOURCETYPE Direct3DCubeTexture9::GetType() 175 { 176 CriticalSection cs(device); 177 178 TRACE(""); 179 180 return Direct3DBaseTexture9::GetType(); 181 } 182 GenerateMipSubLevels()183 void Direct3DCubeTexture9::GenerateMipSubLevels() 184 { 185 CriticalSection cs(device); 186 187 TRACE(""); 188 189 if(!(usage & D3DUSAGE_AUTOGENMIPMAP)) 190 { 191 return; 192 } 193 194 resource->lock(sw::PUBLIC); 195 196 for(unsigned int face = 0; face < 6; face++) 197 { 198 if(!surfaceLevel[face][0]->hasDirtyMipmaps()) 199 { 200 continue; 201 } 202 203 for(unsigned int i = 0; i < levels - 1; i++) 204 { 205 device->stretchRect(surfaceLevel[face][i], 0, surfaceLevel[face][i + 1], 0, GetAutoGenFilterType()); 206 } 207 208 surfaceLevel[face][0]->cleanMipmaps(); 209 } 210 211 resource->unlock(); 212 } 213 GetAutoGenFilterType()214 D3DTEXTUREFILTERTYPE Direct3DCubeTexture9::GetAutoGenFilterType() 215 { 216 CriticalSection cs(device); 217 218 TRACE(""); 219 220 return Direct3DBaseTexture9::GetAutoGenFilterType(); 221 } 222 GetLevelCount()223 unsigned long Direct3DCubeTexture9::GetLevelCount() 224 { 225 CriticalSection cs(device); 226 227 TRACE(""); 228 229 return Direct3DBaseTexture9::GetLevelCount(); 230 } 231 GetLOD()232 unsigned long Direct3DCubeTexture9::GetLOD() 233 { 234 CriticalSection cs(device); 235 236 TRACE(""); 237 238 return Direct3DBaseTexture9::GetLOD(); 239 } 240 SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType)241 long Direct3DCubeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE filterType) 242 { 243 CriticalSection cs(device); 244 245 TRACE(""); 246 247 return Direct3DBaseTexture9::SetAutoGenFilterType(filterType); 248 } 249 SetLOD(unsigned long newLOD)250 unsigned long Direct3DCubeTexture9::SetLOD(unsigned long newLOD) 251 { 252 CriticalSection cs(device); 253 254 TRACE(""); 255 256 return Direct3DBaseTexture9::SetLOD(newLOD); 257 } 258 AddDirtyRect(D3DCUBEMAP_FACES face,const RECT * dirtyRect)259 long Direct3DCubeTexture9::AddDirtyRect(D3DCUBEMAP_FACES face, const RECT *dirtyRect) 260 { 261 CriticalSection cs(device); 262 263 TRACE(""); 264 265 // UNIMPLEMENTED(); 266 267 return D3D_OK; 268 } 269 GetCubeMapSurface(D3DCUBEMAP_FACES face,unsigned int level,IDirect3DSurface9 ** cubeMapSurface)270 long Direct3DCubeTexture9::GetCubeMapSurface(D3DCUBEMAP_FACES face, unsigned int level, IDirect3DSurface9 **cubeMapSurface) 271 { 272 CriticalSection cs(device); 273 274 TRACE(""); 275 276 *cubeMapSurface = 0; 277 278 if(face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level]) 279 { 280 return INVALIDCALL(); 281 } 282 283 surfaceLevel[face][level]->AddRef(); 284 *cubeMapSurface = surfaceLevel[face][level]; 285 286 return D3D_OK; 287 } 288 GetLevelDesc(unsigned int level,D3DSURFACE_DESC * description)289 long Direct3DCubeTexture9::GetLevelDesc(unsigned int level, D3DSURFACE_DESC *description) 290 { 291 CriticalSection cs(device); 292 293 TRACE(""); 294 295 if(!description || level >= GetLevelCount() || !surfaceLevel[0][level]) 296 { 297 return INVALIDCALL(); 298 } 299 300 return surfaceLevel[0][level]->GetDesc(description); 301 } 302 LockRect(D3DCUBEMAP_FACES face,unsigned int level,D3DLOCKED_RECT * lockedRect,const RECT * rect,unsigned long flags)303 long Direct3DCubeTexture9::LockRect(D3DCUBEMAP_FACES face, unsigned int level, D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags) 304 { 305 CriticalSection cs(device); 306 307 TRACE(""); 308 309 if(!lockedRect || face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level]) 310 { 311 return INVALIDCALL(); 312 } 313 314 return surfaceLevel[face][level]->LockRect(lockedRect, rect, flags); 315 } 316 UnlockRect(D3DCUBEMAP_FACES face,unsigned int level)317 long Direct3DCubeTexture9::UnlockRect(D3DCUBEMAP_FACES face, unsigned int level) 318 { 319 CriticalSection cs(device); 320 321 TRACE(""); 322 323 if(face >= 6 || level >= GetLevelCount() || !surfaceLevel[face][level]) 324 { 325 return INVALIDCALL(); 326 } 327 328 return surfaceLevel[face][level]->UnlockRect(); 329 } 330 getInternalCubeMapSurface(D3DCUBEMAP_FACES face,unsigned int level)331 Direct3DSurface9 *Direct3DCubeTexture9::getInternalCubeMapSurface(D3DCUBEMAP_FACES face, unsigned int level) 332 { 333 return surfaceLevel[face][level]; 334 } 335 }