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