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 "Direct3D9.hpp"
     16 
     17 #include "Direct3DDevice9.hpp"
     18 #include "Capabilities.hpp"
     19 #include "Configurator.hpp"
     20 #include "Debug.hpp"
     21 #include "CPUID.hpp"
     22 #include "Version.h"
     23 #include "Config.hpp"
     24 
     25 #define COMPILE_MULTIMON_STUBS
     26 #include <multimon.h>
     27 #include <assert.h>
     28 #include <psapi.h>
     29 
     30 namespace D3D9
     31 {
     32 	Direct3D9::Direct3D9(int version, const HINSTANCE instance) : version(version), instance(instance)
     33 	{
     34 		displayMode = 0;
     35 		numDisplayModes = 0;
     36 
     37 		DEVMODE devmode;
     38 		devmode.dmSize = sizeof(DEVMODE);
     39 
     40 		// Count number of display modes
     41 		while(EnumDisplaySettings(0, numDisplayModes, &devmode))   // FIXME: Only enumarate internal modes!
     42 		{
     43 			numDisplayModes++;
     44 		}
     45 
     46 		displayMode = new DEVMODE[numDisplayModes];
     47 
     48 		// Store display modes information
     49 		for(int i = 0; i < numDisplayModes; i++)
     50 		{
     51 			displayMode[i].dmSize = sizeof(DEVMODE);
     52 			EnumDisplaySettings(0, i, &displayMode[i]);
     53 		}
     54 
     55 		d3d9Lib = 0;
     56 		d3d9 = 0;
     57 
     58 		sw::Configurator ini("SwiftShader.ini");
     59 
     60 		disableAlphaMode = ini.getBoolean("Testing", "DisableAlphaMode", false);
     61 		disable10BitMode = ini.getBoolean("Testing", "Disable10BitMode", false);
     62 
     63 		int ps = ini.getInteger("Capabilities", "PixelShaderVersion", 30);
     64 		int vs = ini.getInteger("Capabilities", "VertexShaderVersion", 30);
     65 
     66 		     if(ps ==  0) pixelShaderVersionX = D3DPS_VERSION(0, 0);
     67 		else if(ps <= 11) pixelShaderVersionX = D3DPS_VERSION(1, 1);
     68 		else if(ps <= 12) pixelShaderVersionX = D3DPS_VERSION(1, 2);
     69 		else if(ps <= 13) pixelShaderVersionX = D3DPS_VERSION(1, 3);
     70 		else if(ps <= 14) pixelShaderVersionX = D3DPS_VERSION(1, 4);
     71 		else if(ps <= 20) pixelShaderVersionX = D3DPS_VERSION(2, 0);
     72 		else if(ps <= 21) pixelShaderVersionX = D3DPS_VERSION(2, 1);
     73 		else              pixelShaderVersionX = D3DPS_VERSION(3, 0);
     74 
     75 		     if(vs ==  0) vertexShaderVersionX = D3DVS_VERSION(0, 0);
     76 		else if(vs <= 11) vertexShaderVersionX = D3DVS_VERSION(1, 1);
     77 		else if(vs <= 20) vertexShaderVersionX = D3DVS_VERSION(2, 0);
     78 		else if(vs <= 21) vertexShaderVersionX = D3DVS_VERSION(2, 1);
     79 		else              vertexShaderVersionX = D3DVS_VERSION(3, 0);
     80 
     81 		pixelShaderArbitrarySwizzle = 0;
     82 		pixelShaderGradientInstructions = 0;
     83 		pixelShaderPredication = 0;
     84 		pixelShaderNoDependentReadLimit = 0;
     85 		pixelShaderNoTexInstructionLimit = 0;
     86 
     87 		pixelShaderDynamicFlowControlDepth = D3DPS20_MIN_DYNAMICFLOWCONTROLDEPTH;
     88 		pixelShaderStaticFlowControlDepth = D3DPS20_MIN_STATICFLOWCONTROLDEPTH;
     89 
     90 		if(ps >= 21)
     91 		{
     92 			pixelShaderArbitrarySwizzle = D3DPS20CAPS_ARBITRARYSWIZZLE;
     93 			pixelShaderGradientInstructions = D3DPS20CAPS_GRADIENTINSTRUCTIONS;
     94 			pixelShaderPredication = D3DPS20CAPS_PREDICATION;
     95 			pixelShaderNoDependentReadLimit = D3DPS20CAPS_NODEPENDENTREADLIMIT;
     96 			pixelShaderNoTexInstructionLimit = D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
     97 
     98 			pixelShaderDynamicFlowControlDepth = D3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH;
     99 			pixelShaderStaticFlowControlDepth = D3DPS20_MAX_STATICFLOWCONTROLDEPTH;
    100 		}
    101 
    102 		vertexShaderPredication = 0;
    103 		vertexShaderDynamicFlowControlDepth = 0;
    104 
    105 		if(vs >= 21)
    106 		{
    107 			vertexShaderPredication = D3DVS20CAPS_PREDICATION;
    108 			vertexShaderDynamicFlowControlDepth = D3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH;
    109 		}
    110 
    111 		textureMemory = 1024 * 1024 * ini.getInteger("Capabilities", "TextureMemory", 256);
    112 
    113 		int shadowMapping = ini.getInteger("Testing", "ShadowMapping", 3);
    114 
    115 		if(shadowMapping != 2 && shadowMapping != 3)   // No DST support
    116 		{
    117 			Capabilities::Texture::DepthStencil::D32 = false;
    118 			Capabilities::Texture::DepthStencil::D24S8 = false;
    119 			Capabilities::Texture::DepthStencil::D24X8 = false;
    120 			Capabilities::Texture::DepthStencil::D16 = false;
    121 			Capabilities::Texture::DepthStencil::D24FS8 = false;
    122 			Capabilities::Texture::DepthStencil::D32F_LOCKABLE = false;
    123 
    124 			Capabilities::Texture::D32 = false;
    125 			Capabilities::Texture::D24S8 = false;
    126 			Capabilities::Texture::D24X8 = false;
    127 			Capabilities::Texture::D16 = false;
    128 			Capabilities::Texture::D24FS8 = false;
    129 			Capabilities::Texture::D32F_LOCKABLE = false;
    130 		}
    131 
    132 		if(shadowMapping != 1 && shadowMapping != 3)   // No Fetch4 support
    133 		{
    134 			Capabilities::Texture::DepthStencil::DF24 = false;
    135 			Capabilities::Texture::DepthStencil::DF16 = false;
    136 
    137 			Capabilities::Texture::DF24 = false;
    138 			Capabilities::Texture::DF16 = false;
    139 		}
    140 	}
    141 
    142 	Direct3D9::~Direct3D9()
    143 	{
    144 		delete[] displayMode;
    145 		displayMode = 0;
    146 
    147 		if(d3d9)
    148 		{
    149 			d3d9->Release();
    150 			d3d9 = 0;
    151 		}
    152 
    153 		if(d3d9Lib)
    154 		{
    155 			FreeLibrary(d3d9Lib);
    156 			d3d9Lib = 0;
    157 		}
    158 	}
    159 
    160 	long Direct3D9::QueryInterface(const IID &iid, void **object)
    161 	{
    162 		TRACE("const IID &iid = 0x%0.8p, void **object = 0x%0.8p", iid, object);
    163 
    164 		if(iid == IID_IDirect3D9 ||
    165 		   iid == IID_IUnknown)
    166 		{
    167 			AddRef();
    168 			*object = this;
    169 
    170 			return S_OK;
    171 		}
    172 
    173 		*object = 0;
    174 
    175 		return NOINTERFACE(iid);
    176 	}
    177 
    178 	unsigned long Direct3D9::AddRef()
    179 	{
    180 		TRACE("void");
    181 
    182 		return Unknown::AddRef();
    183 	}
    184 
    185 	unsigned long Direct3D9::Release()
    186 	{
    187 		TRACE("void");
    188 
    189 		return Unknown::Release();
    190 	}
    191 
    192 	long Direct3D9::CheckDepthStencilMatch(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat)
    193 	{
    194 		TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT adapterFormat = %d, D3DFORMAT renderTargetFormat = %d, D3DFORMAT depthStencilFormat = %d", adapter, deviceType, adapterFormat, renderTargetFormat, depthStencilFormat);
    195 
    196 		if(deviceType != D3DDEVTYPE_HAL)
    197 		{
    198 			loadSystemD3D9();
    199 
    200 			if(d3d9)
    201 			{
    202 				return d3d9->CheckDepthStencilMatch(adapter, deviceType, adapterFormat, renderTargetFormat, depthStencilFormat);
    203 			}
    204 			else
    205 			{
    206 				return CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, adapterFormat, renderTargetFormat, depthStencilFormat);
    207 			}
    208 		}
    209 
    210 		return D3D_OK;   // Any format combination is ok
    211 	}
    212 
    213 	long Direct3D9::CheckDeviceFormat(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, unsigned long usage, D3DRESOURCETYPE resourceType, D3DFORMAT checkFormat)
    214 	{
    215 		TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT adapterFormat = %d, unsigned long usage = %d, D3DRESOURCETYPE resourceType = %d, D3DFORMAT checkFormat = %d", adapter, deviceType, adapterFormat, usage, resourceType, checkFormat);
    216 
    217 		if(deviceType != D3DDEVTYPE_HAL)
    218 		{
    219 			loadSystemD3D9();
    220 
    221 			if(d3d9)
    222 			{
    223 				return d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, usage, resourceType, checkFormat);
    224 			}
    225 			else
    226 			{
    227 				return CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, adapterFormat, usage, resourceType, checkFormat);
    228 			}
    229 		}
    230 
    231 		if(usage & D3DUSAGE_QUERY_SRGBREAD)
    232 		{
    233 			if(!Capabilities::isSRGBreadable(checkFormat))
    234 			{
    235 				return NOTAVAILABLE();
    236 			}
    237 		}
    238 
    239 		if(usage & D3DUSAGE_QUERY_SRGBWRITE)
    240 		{
    241 			if(!Capabilities::isSRGBwritable(checkFormat))
    242 			{
    243 				return NOTAVAILABLE();
    244 			}
    245 		}
    246 
    247 		// ATI hack to indicate instancing support on SM 2.0 hardware
    248 		if(checkFormat == D3DFMT_INST && pixelShaderVersionX >= D3DPS_VERSION(2, 0) && pixelShaderVersionX < D3DPS_VERSION(3, 0))
    249 		{
    250 			return D3D_OK;
    251 		}
    252 
    253 		switch(resourceType)
    254 		{
    255 		case D3DRTYPE_SURFACE:
    256 			if(usage & D3DUSAGE_RENDERTARGET)
    257 			{
    258 				switch(checkFormat)
    259 				{
    260 				case D3DFMT_NULL:			if(!Capabilities::Surface::RenderTarget::NULL_)			return NOTAVAILABLE();	else return D3D_OK;
    261 				case D3DFMT_R8G8B8:			if(!Capabilities::Surface::RenderTarget::R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    262 				case D3DFMT_R5G6B5:			if(!Capabilities::Surface::RenderTarget::R5G6B5)		return NOTAVAILABLE();	else return D3D_OK;
    263 				case D3DFMT_X1R5G5B5:		if(!Capabilities::Surface::RenderTarget::X1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    264 				case D3DFMT_A1R5G5B5:		if(!Capabilities::Surface::RenderTarget::A1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    265 				case D3DFMT_A4R4G4B4:		if(!Capabilities::Surface::RenderTarget::A4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    266 				case D3DFMT_R3G3B2:			if(!Capabilities::Surface::RenderTarget::R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    267 				case D3DFMT_A8R3G3B2:		if(!Capabilities::Surface::RenderTarget::A8R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    268 				case D3DFMT_X4R4G4B4:		if(!Capabilities::Surface::RenderTarget::X4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    269 				case D3DFMT_A8R8G8B8:		if(!Capabilities::Surface::RenderTarget::A8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    270 				case D3DFMT_X8R8G8B8:		if(!Capabilities::Surface::RenderTarget::X8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    271 				case D3DFMT_A8B8G8R8:		if(!Capabilities::Surface::RenderTarget::A8B8G8R8)		return NOTAVAILABLE();	else return D3D_OK;
    272 				case D3DFMT_X8B8G8R8:		if(!Capabilities::Surface::RenderTarget::X8B8G8R8)		return NOTAVAILABLE();	else return D3D_OK;
    273 				// Integer HDR formats
    274 				case D3DFMT_G16R16:			if(!Capabilities::Surface::RenderTarget::G16R16)		return NOTAVAILABLE();	else return D3D_OK;
    275 				case D3DFMT_A2B10G10R10:	if(!Capabilities::Surface::RenderTarget::A2B10G10R10)	return NOTAVAILABLE();	else return D3D_OK;
    276 				case D3DFMT_A2R10G10B10:	if(!Capabilities::Surface::RenderTarget::A2R10G10B10)	return NOTAVAILABLE();	else return D3D_OK;
    277 				case D3DFMT_A16B16G16R16:	if(!Capabilities::Surface::RenderTarget::A16B16G16R16)	return NOTAVAILABLE();	else return D3D_OK;
    278 				// Floating-point formats
    279 				case D3DFMT_R16F:			if(!Capabilities::Surface::RenderTarget::R16F)			return NOTAVAILABLE();	else return D3D_OK;
    280 				case D3DFMT_G16R16F:		if(!Capabilities::Surface::RenderTarget::G16R16F)		return NOTAVAILABLE();	else return D3D_OK;
    281 				case D3DFMT_A16B16G16R16F:	if(!Capabilities::Surface::RenderTarget::A16B16G16R16F)	return NOTAVAILABLE();	else return D3D_OK;
    282 				case D3DFMT_R32F:			if(!Capabilities::Surface::RenderTarget::R32F)			return NOTAVAILABLE();	else return D3D_OK;
    283 				case D3DFMT_G32R32F:		if(!Capabilities::Surface::RenderTarget::G32R32F)		return NOTAVAILABLE();	else return D3D_OK;
    284 				case D3DFMT_A32B32G32R32F:	if(!Capabilities::Surface::RenderTarget::A32B32G32R32F)	return NOTAVAILABLE();	else return D3D_OK;
    285 				default:
    286 					return NOTAVAILABLE();
    287 				}
    288 			}
    289 			else if(usage & D3DUSAGE_DEPTHSTENCIL)
    290 			{
    291 				switch(checkFormat)
    292 				{
    293 				case D3DFMT_D32:			if(!Capabilities::Surface::DepthStencil::D32)			return NOTAVAILABLE();	else return D3D_OK;
    294 				case D3DFMT_D24S8:			if(!Capabilities::Surface::DepthStencil::D24S8)			return NOTAVAILABLE();	else return D3D_OK;
    295 				case D3DFMT_D24X8:			if(!Capabilities::Surface::DepthStencil::D24X8)			return NOTAVAILABLE();	else return D3D_OK;
    296 				case D3DFMT_D16:			if(!Capabilities::Surface::DepthStencil::D16)			return NOTAVAILABLE();	else return D3D_OK;
    297 				case D3DFMT_D24FS8:			if(!Capabilities::Surface::DepthStencil::D24FS8)		return NOTAVAILABLE();	else return D3D_OK;
    298 				case D3DFMT_D32F_LOCKABLE:	if(!Capabilities::Surface::DepthStencil::D32F_LOCKABLE)	return NOTAVAILABLE();	else return D3D_OK;
    299 				case D3DFMT_DF24:			if(!Capabilities::Surface::DepthStencil::DF24)			return NOTAVAILABLE();	else return D3D_OK;
    300 				case D3DFMT_DF16:			if(!Capabilities::Surface::DepthStencil::DF16)			return NOTAVAILABLE();	else return D3D_OK;
    301 				case D3DFMT_INTZ:			if(!Capabilities::Surface::DepthStencil::INTZ)			return NOTAVAILABLE();	else return D3D_OK;
    302 				default:
    303 					return NOTAVAILABLE();
    304 				}
    305 			}
    306 			else
    307 			{
    308 				switch(checkFormat)
    309 				{
    310 				case D3DFMT_A8:				if(!Capabilities::Surface::A8)							return NOTAVAILABLE();	else return D3D_OK;
    311 				case D3DFMT_R5G6B5:			if(!Capabilities::Surface::R5G6B5)						return NOTAVAILABLE();	else return D3D_OK;
    312 				case D3DFMT_X1R5G5B5:		if(!Capabilities::Surface::X1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    313 				case D3DFMT_A1R5G5B5:		if(!Capabilities::Surface::A1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    314 				case D3DFMT_A4R4G4B4:		if(!Capabilities::Surface::A4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    315 				case D3DFMT_R3G3B2:			if(!Capabilities::Surface::R3G3B2)						return NOTAVAILABLE();	else return D3D_OK;
    316 				case D3DFMT_A8R3G3B2:		if(!Capabilities::Surface::A8R3G3B2)					return NOTAVAILABLE();	else return D3D_OK;
    317 				case D3DFMT_X4R4G4B4:		if(!Capabilities::Surface::X4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    318 				case D3DFMT_R8G8B8:			if(!Capabilities::Surface::R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    319 				case D3DFMT_X8R8G8B8:		if(!Capabilities::Surface::X8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    320 				case D3DFMT_A8R8G8B8:		if(!Capabilities::Surface::A8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    321 				case D3DFMT_X8B8G8R8:		if(!Capabilities::Surface::X8B8G8R8)					return NOTAVAILABLE();	else return D3D_OK;
    322 				case D3DFMT_A8B8G8R8:		if(!Capabilities::Surface::A8B8G8R8)					return NOTAVAILABLE();	else return D3D_OK;
    323 				// Paletted formats
    324 				case D3DFMT_P8:				if(!Capabilities::Surface::P8)							return NOTAVAILABLE();	else return D3D_OK;
    325 				case D3DFMT_A8P8:			if(!Capabilities::Surface::A8P8)						return NOTAVAILABLE();	else return D3D_OK;
    326 				// Integer HDR formats
    327 				case D3DFMT_G16R16:			if(!Capabilities::Surface::G16R16)						return NOTAVAILABLE();	else return D3D_OK;
    328 				case D3DFMT_A2R10G10B10:	if(!Capabilities::Surface::A2R10G10B10)					return NOTAVAILABLE();	else return D3D_OK;
    329 				case D3DFMT_A2B10G10R10:	if(!Capabilities::Surface::A2B10G10R10)					return NOTAVAILABLE();	else return D3D_OK;
    330 				case D3DFMT_A16B16G16R16:	if(!Capabilities::Surface::A16B16G16R16)				return NOTAVAILABLE();	else return D3D_OK;
    331 				// Compressed formats
    332 				case D3DFMT_DXT1:			if(!Capabilities::Surface::DXT1)						return NOTAVAILABLE();	else return D3D_OK;
    333 				case D3DFMT_DXT2:			if(!Capabilities::Surface::DXT2)						return NOTAVAILABLE();	else return D3D_OK;
    334 				case D3DFMT_DXT3:			if(!Capabilities::Surface::DXT3)						return NOTAVAILABLE();	else return D3D_OK;
    335 				case D3DFMT_DXT4:			if(!Capabilities::Surface::DXT4)						return NOTAVAILABLE();	else return D3D_OK;
    336 				case D3DFMT_DXT5:			if(!Capabilities::Surface::DXT5)						return NOTAVAILABLE();	else return D3D_OK;
    337 				case D3DFMT_ATI1:			if(!Capabilities::Surface::ATI1)						return NOTAVAILABLE();	else return D3D_OK;
    338 				case D3DFMT_ATI2:			if(!Capabilities::Surface::ATI2)						return NOTAVAILABLE();	else return D3D_OK;
    339 				// Floating-point formats
    340 				case D3DFMT_R16F:			if(!Capabilities::Surface::R16F)						return NOTAVAILABLE();	else return D3D_OK;
    341 				case D3DFMT_G16R16F:		if(!Capabilities::Surface::G16R16F)						return NOTAVAILABLE();	else return D3D_OK;
    342 				case D3DFMT_A16B16G16R16F:	if(!Capabilities::Surface::A16B16G16R16F)				return NOTAVAILABLE();	else return D3D_OK;
    343 				case D3DFMT_R32F:			if(!Capabilities::Surface::R32F)						return NOTAVAILABLE();	else return D3D_OK;
    344 				case D3DFMT_G32R32F:		if(!Capabilities::Surface::G32R32F)						return NOTAVAILABLE();	else return D3D_OK;
    345 				case D3DFMT_A32B32G32R32F:	if(!Capabilities::Surface::A32B32G32R32F)				return NOTAVAILABLE();	else return D3D_OK;
    346 				// Bump map formats
    347 				case D3DFMT_V8U8:			if(!Capabilities::Surface::V8U8)						return NOTAVAILABLE();	else return D3D_OK;
    348 				case D3DFMT_L6V5U5:			if(!Capabilities::Surface::L6V5U5)						return NOTAVAILABLE();	else return D3D_OK;
    349 				case D3DFMT_X8L8V8U8:		if(!Capabilities::Surface::X8L8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    350 				case D3DFMT_Q8W8V8U8:		if(!Capabilities::Surface::Q8W8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    351 				case D3DFMT_V16U16:			if(!Capabilities::Surface::V16U16)						return NOTAVAILABLE();	else return D3D_OK;
    352 				case D3DFMT_A2W10V10U10:	if(!Capabilities::Surface::A2W10V10U10)					return NOTAVAILABLE();	else return D3D_OK;
    353 				case D3DFMT_Q16W16V16U16:	if(!Capabilities::Surface::Q16W16V16U16)				return NOTAVAILABLE();	else return D3D_OK;
    354 				// Luminance formats
    355 				case D3DFMT_L8:				if(!Capabilities::Surface::L8)							return NOTAVAILABLE();	else return D3D_OK;
    356 				case D3DFMT_A4L4:			if(!Capabilities::Surface::A4L4)						return NOTAVAILABLE();	else return D3D_OK;
    357 				case D3DFMT_L16:			if(!Capabilities::Surface::L16)							return NOTAVAILABLE();	else return D3D_OK;
    358 				case D3DFMT_A8L8:			if(!Capabilities::Surface::A8L8)						return NOTAVAILABLE();	else return D3D_OK;
    359 				// Depth Bounds Test
    360 				case D3DFMT_NVDB:			if(!Capabilities::Surface::NVDB)						return NOTAVAILABLE();	else return D3D_OK;
    361 				// Transparency anti-aliasing
    362 				case D3DFMT_ATOC:			if(!Capabilities::Surface::ATOC)						return NOTAVAILABLE();	else return D3D_OK;
    363 				default:
    364 					return NOTAVAILABLE();
    365 				}
    366 			}
    367 		case D3DRTYPE_VOLUME:
    368 			switch(checkFormat)
    369 			{
    370 			case D3DFMT_A8:					if(!Capabilities::Volume::A8)							return NOTAVAILABLE();	else return D3D_OK;
    371 			case D3DFMT_R5G6B5:				if(!Capabilities::Volume::R5G6B5)						return NOTAVAILABLE();	else return D3D_OK;
    372 			case D3DFMT_X1R5G5B5:			if(!Capabilities::Volume::X1R5G5B5)						return NOTAVAILABLE();	else return D3D_OK;
    373 			case D3DFMT_A1R5G5B5:			if(!Capabilities::Volume::A1R5G5B5)						return NOTAVAILABLE();	else return D3D_OK;
    374 			case D3DFMT_A4R4G4B4:			if(!Capabilities::Volume::A4R4G4B4)						return NOTAVAILABLE();	else return D3D_OK;
    375 			case D3DFMT_R3G3B2:				if(!Capabilities::Volume::R3G3B2)						return NOTAVAILABLE();	else return D3D_OK;
    376 			case D3DFMT_A8R3G3B2:			if(!Capabilities::Volume::A8R3G3B2)						return NOTAVAILABLE();	else return D3D_OK;
    377 			case D3DFMT_X4R4G4B4:			if(!Capabilities::Volume::X4R4G4B4)						return NOTAVAILABLE();	else return D3D_OK;
    378 			case D3DFMT_R8G8B8:				if(!Capabilities::Volume::R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    379 			case D3DFMT_X8R8G8B8:			if(!Capabilities::Volume::X8R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    380 			case D3DFMT_A8R8G8B8:			if(!Capabilities::Volume::A8R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    381 			case D3DFMT_X8B8G8R8:			if(!Capabilities::Volume::X8B8G8R8)						return NOTAVAILABLE();	else return D3D_OK;
    382 			case D3DFMT_A8B8G8R8:			if(!Capabilities::Volume::A8B8G8R8)						return NOTAVAILABLE();	else return D3D_OK;
    383 			// Paletted formats
    384 			case D3DFMT_P8:					if(!Capabilities::Volume::P8)							return NOTAVAILABLE();	else return D3D_OK;
    385 			case D3DFMT_A8P8:				if(!Capabilities::Volume::A8P8)							return NOTAVAILABLE();	else return D3D_OK;
    386 			// Integer HDR formats
    387 			case D3DFMT_G16R16:				if(!Capabilities::Volume::G16R16)						return NOTAVAILABLE();	else return D3D_OK;
    388 			case D3DFMT_A2R10G10B10:		if(!Capabilities::Volume::A2R10G10B10)					return NOTAVAILABLE();	else return D3D_OK;
    389 			case D3DFMT_A2B10G10R10:		if(!Capabilities::Volume::A2B10G10R10)					return NOTAVAILABLE();	else return D3D_OK;
    390 			case D3DFMT_A16B16G16R16:		if(!Capabilities::Volume::A16B16G16R16)					return NOTAVAILABLE();	else return D3D_OK;
    391 			// Compressed formats
    392 			case D3DFMT_DXT1:				if(!Capabilities::Volume::DXT1)							return NOTAVAILABLE();	else return D3D_OK;
    393 			case D3DFMT_DXT2:				if(!Capabilities::Volume::DXT2)							return NOTAVAILABLE();	else return D3D_OK;
    394 			case D3DFMT_DXT3:				if(!Capabilities::Volume::DXT3)							return NOTAVAILABLE();	else return D3D_OK;
    395 			case D3DFMT_DXT4:				if(!Capabilities::Volume::DXT4)							return NOTAVAILABLE();	else return D3D_OK;
    396 			case D3DFMT_DXT5:				if(!Capabilities::Volume::DXT5)							return NOTAVAILABLE();	else return D3D_OK;
    397 			case D3DFMT_ATI1:				if(!Capabilities::Volume::ATI1)							return NOTAVAILABLE();	else return D3D_OK;
    398 			case D3DFMT_ATI2:				if(!Capabilities::Volume::ATI2)							return NOTAVAILABLE();	else return D3D_OK;
    399 			// Floating-point formats
    400 			case D3DFMT_R16F:				if(!Capabilities::Volume::R16F)							return NOTAVAILABLE();	else return D3D_OK;
    401 			case D3DFMT_G16R16F:			if(!Capabilities::Volume::G16R16F)						return NOTAVAILABLE();	else return D3D_OK;
    402 			case D3DFMT_A16B16G16R16F:		if(!Capabilities::Volume::A16B16G16R16F)				return NOTAVAILABLE();	else return D3D_OK;
    403 			case D3DFMT_R32F:				if(!Capabilities::Volume::R32F)							return NOTAVAILABLE();	else return D3D_OK;
    404 			case D3DFMT_G32R32F:			if(!Capabilities::Volume::G32R32F)						return NOTAVAILABLE();	else return D3D_OK;
    405 			case D3DFMT_A32B32G32R32F:		if(!Capabilities::Volume::A32B32G32R32F)				return NOTAVAILABLE();	else return D3D_OK;
    406 			// Bump map formats
    407 			case D3DFMT_V8U8:				if(!Capabilities::Volume::V8U8)							return NOTAVAILABLE();	else return D3D_OK;
    408 			case D3DFMT_L6V5U5:				if(!Capabilities::Volume::L6V5U5)						return NOTAVAILABLE();	else return D3D_OK;
    409 			case D3DFMT_X8L8V8U8:			if(!Capabilities::Volume::X8L8V8U8)						return NOTAVAILABLE();	else return D3D_OK;
    410 			case D3DFMT_Q8W8V8U8:			if(!Capabilities::Volume::Q8W8V8U8)						return NOTAVAILABLE();	else return D3D_OK;
    411 			case D3DFMT_V16U16:				if(!Capabilities::Volume::V16U16)						return NOTAVAILABLE();	else return D3D_OK;
    412 			case D3DFMT_A2W10V10U10:		if(!Capabilities::Volume::A2W10V10U10)					return NOTAVAILABLE();	else return D3D_OK;
    413 			case D3DFMT_Q16W16V16U16:		if(!Capabilities::Volume::Q16W16V16U16)					return NOTAVAILABLE();	else return D3D_OK;
    414 			// Luminance formats
    415 			case D3DFMT_L8:					if(!Capabilities::Volume::L8)							return NOTAVAILABLE();	else return D3D_OK;
    416 			case D3DFMT_A4L4:				if(!Capabilities::Volume::A4L4)							return NOTAVAILABLE();	else return D3D_OK;
    417 			case D3DFMT_L16:				if(!Capabilities::Volume::L16)							return NOTAVAILABLE();	else return D3D_OK;
    418 			case D3DFMT_A8L8:				if(!Capabilities::Volume::A8L8)							return NOTAVAILABLE();	else return D3D_OK;
    419 			default:
    420 				return NOTAVAILABLE();
    421 			}
    422 		case D3DRTYPE_CUBETEXTURE:
    423 			if(usage & D3DUSAGE_RENDERTARGET)
    424 			{
    425 				switch(checkFormat)
    426 				{
    427 				case D3DFMT_NULL:			if(!Capabilities::CubeMap::RenderTarget::NULL_)			return NOTAVAILABLE();	else return D3D_OK;
    428 				case D3DFMT_R8G8B8:			if(!Capabilities::CubeMap::RenderTarget::R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    429 				case D3DFMT_R5G6B5:			if(!Capabilities::CubeMap::RenderTarget::R5G6B5)		return NOTAVAILABLE();	else return D3D_OK;
    430 				case D3DFMT_X1R5G5B5:		if(!Capabilities::CubeMap::RenderTarget::X1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    431 				case D3DFMT_A1R5G5B5:		if(!Capabilities::CubeMap::RenderTarget::A1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    432 				case D3DFMT_A4R4G4B4:		if(!Capabilities::CubeMap::RenderTarget::A4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    433 				case D3DFMT_R3G3B2:			if(!Capabilities::CubeMap::RenderTarget::R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    434 				case D3DFMT_A8R3G3B2:		if(!Capabilities::CubeMap::RenderTarget::A8R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    435 				case D3DFMT_X4R4G4B4:		if(!Capabilities::CubeMap::RenderTarget::X4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    436 				case D3DFMT_A8R8G8B8:		if(!Capabilities::CubeMap::RenderTarget::A8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    437 				case D3DFMT_X8R8G8B8:		if(!Capabilities::CubeMap::RenderTarget::X8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    438 				case D3DFMT_A8B8G8R8:		if(!Capabilities::CubeMap::RenderTarget::A8B8G8R8)		return NOTAVAILABLE();	else return D3D_OK;
    439 				case D3DFMT_X8B8G8R8:		if(!Capabilities::CubeMap::RenderTarget::X8B8G8R8)		return NOTAVAILABLE();	else return D3D_OK;
    440 				// Integer HDR formats
    441 				case D3DFMT_G16R16:			if(!Capabilities::CubeMap::RenderTarget::G16R16)		return NOTAVAILABLE();	else return D3D_OK;
    442 				case D3DFMT_A2B10G10R10:	if(!Capabilities::CubeMap::RenderTarget::A2B10G10R10)	return NOTAVAILABLE();	else return D3D_OK;
    443 				case D3DFMT_A2R10G10B10:	if(!Capabilities::CubeMap::RenderTarget::A2R10G10B10)	return NOTAVAILABLE();	else return D3D_OK;
    444 				case D3DFMT_A16B16G16R16:	if(!Capabilities::CubeMap::RenderTarget::A16B16G16R16)	return NOTAVAILABLE();	else return D3D_OK;
    445 				// Floating-point formats
    446 				case D3DFMT_R16F:			if(!Capabilities::CubeMap::RenderTarget::R16F)			return NOTAVAILABLE();	else return D3D_OK;
    447 				case D3DFMT_G16R16F:		if(!Capabilities::CubeMap::RenderTarget::G16R16F)		return NOTAVAILABLE();	else return D3D_OK;
    448 				case D3DFMT_A16B16G16R16F:	if(!Capabilities::CubeMap::RenderTarget::A16B16G16R16F)	return NOTAVAILABLE();	else return D3D_OK;
    449 				case D3DFMT_R32F:			if(!Capabilities::CubeMap::RenderTarget::R32F)			return NOTAVAILABLE();	else return D3D_OK;
    450 				case D3DFMT_G32R32F:		if(!Capabilities::CubeMap::RenderTarget::G32R32F)		return NOTAVAILABLE();	else return D3D_OK;
    451 				case D3DFMT_A32B32G32R32F:	if(!Capabilities::CubeMap::RenderTarget::A32B32G32R32F)	return NOTAVAILABLE();	else return D3D_OK;
    452 				default:
    453 					return NOTAVAILABLE();
    454 				}
    455 			}
    456 			else if(usage & D3DUSAGE_DEPTHSTENCIL)
    457 			{
    458 				switch(checkFormat)
    459 				{
    460 				case D3DFMT_D32:			if(!Capabilities::CubeMap::DepthStencil::D32)			return NOTAVAILABLE();	else return D3D_OK;
    461 				case D3DFMT_D24S8:			if(!Capabilities::CubeMap::DepthStencil::D24S8)			return NOTAVAILABLE();	else return D3D_OK;
    462 				case D3DFMT_D24X8:			if(!Capabilities::CubeMap::DepthStencil::D24X8)			return NOTAVAILABLE();	else return D3D_OK;
    463 				case D3DFMT_D16:			if(!Capabilities::CubeMap::DepthStencil::D16)			return NOTAVAILABLE();	else return D3D_OK;
    464 				case D3DFMT_D24FS8:			if(!Capabilities::CubeMap::DepthStencil::D24FS8)		return NOTAVAILABLE();	else return D3D_OK;
    465 				case D3DFMT_D32F_LOCKABLE:	if(!Capabilities::CubeMap::DepthStencil::D32F_LOCKABLE)	return NOTAVAILABLE();	else return D3D_OK;
    466 				case D3DFMT_DF24:			if(!Capabilities::CubeMap::DepthStencil::DF24)			return NOTAVAILABLE();	else return D3D_OK;
    467 				case D3DFMT_DF16:			if(!Capabilities::CubeMap::DepthStencil::DF16)			return NOTAVAILABLE();	else return D3D_OK;
    468 				case D3DFMT_INTZ:			if(!Capabilities::CubeMap::DepthStencil::INTZ)			return NOTAVAILABLE();	else return D3D_OK;
    469 				default:
    470 					return NOTAVAILABLE();
    471 				}
    472 			}
    473 			else
    474 			{
    475 				switch(checkFormat)
    476 				{
    477 				case D3DFMT_A8:				if(!Capabilities::CubeMap::A8)							return NOTAVAILABLE();	else return D3D_OK;
    478 				case D3DFMT_R5G6B5:			if(!Capabilities::CubeMap::R5G6B5)						return NOTAVAILABLE();	else return D3D_OK;
    479 				case D3DFMT_X1R5G5B5:		if(!Capabilities::CubeMap::X1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    480 				case D3DFMT_A1R5G5B5:		if(!Capabilities::CubeMap::A1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    481 				case D3DFMT_A4R4G4B4:		if(!Capabilities::CubeMap::A4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    482 				case D3DFMT_R3G3B2:			if(!Capabilities::CubeMap::R3G3B2)						return NOTAVAILABLE();	else return D3D_OK;
    483 				case D3DFMT_A8R3G3B2:		if(!Capabilities::CubeMap::A8R3G3B2)					return NOTAVAILABLE();	else return D3D_OK;
    484 				case D3DFMT_X4R4G4B4:		if(!Capabilities::CubeMap::X4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    485 				case D3DFMT_R8G8B8:			if(!Capabilities::CubeMap::R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    486 				case D3DFMT_X8R8G8B8:		if(!Capabilities::CubeMap::X8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    487 				case D3DFMT_A8R8G8B8:		if(!Capabilities::CubeMap::A8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    488 				case D3DFMT_X8B8G8R8:		if(!Capabilities::CubeMap::X8B8G8R8)					return NOTAVAILABLE();	else return D3D_OK;
    489 				case D3DFMT_A8B8G8R8:		if(!Capabilities::CubeMap::A8B8G8R8)					return NOTAVAILABLE();	else return D3D_OK;
    490 				// Paletted formats
    491 				case D3DFMT_P8:				if(!Capabilities::CubeMap::P8)							return NOTAVAILABLE();	else return D3D_OK;
    492 				case D3DFMT_A8P8:			if(!Capabilities::CubeMap::A8P8)						return NOTAVAILABLE();	else return D3D_OK;
    493 				// Integer HDR formats
    494 				case D3DFMT_G16R16:			if(!Capabilities::CubeMap::G16R16)						return NOTAVAILABLE();	else return D3D_OK;
    495 				case D3DFMT_A2R10G10B10:	if(!Capabilities::CubeMap::A2R10G10B10)					return NOTAVAILABLE();	else return D3D_OK;
    496 				case D3DFMT_A2B10G10R10:	if(!Capabilities::CubeMap::A2B10G10R10)					return NOTAVAILABLE();	else return D3D_OK;
    497 				case D3DFMT_A16B16G16R16:	if(!Capabilities::CubeMap::A16B16G16R16)				return NOTAVAILABLE();	else return D3D_OK;
    498 				// Compressed formats
    499 				case D3DFMT_DXT1:			if(!Capabilities::CubeMap::DXT1)						return NOTAVAILABLE();	else return D3D_OK;
    500 				case D3DFMT_DXT2:			if(!Capabilities::CubeMap::DXT2)						return NOTAVAILABLE();	else return D3D_OK;
    501 				case D3DFMT_DXT3:			if(!Capabilities::CubeMap::DXT3)						return NOTAVAILABLE();	else return D3D_OK;
    502 				case D3DFMT_DXT4:			if(!Capabilities::CubeMap::DXT4)						return NOTAVAILABLE();	else return D3D_OK;
    503 				case D3DFMT_DXT5:			if(!Capabilities::CubeMap::DXT5)						return NOTAVAILABLE();	else return D3D_OK;
    504 				case D3DFMT_ATI1:			if(!Capabilities::CubeMap::ATI1)						return NOTAVAILABLE();	else return D3D_OK;
    505 				case D3DFMT_ATI2:			if(!Capabilities::CubeMap::ATI2)						return NOTAVAILABLE();	else return D3D_OK;
    506 				// Floating-point formats
    507 				case D3DFMT_R16F:			if(!Capabilities::CubeMap::R16F)						return NOTAVAILABLE();	else return D3D_OK;
    508 				case D3DFMT_G16R16F:		if(!Capabilities::CubeMap::G16R16F)						return NOTAVAILABLE();	else return D3D_OK;
    509 				case D3DFMT_A16B16G16R16F:	if(!Capabilities::CubeMap::A16B16G16R16F)				return NOTAVAILABLE();	else return D3D_OK;
    510 				case D3DFMT_R32F:			if(!Capabilities::CubeMap::R32F)						return NOTAVAILABLE();	else return D3D_OK;
    511 				case D3DFMT_G32R32F:		if(!Capabilities::CubeMap::G32R32F)						return NOTAVAILABLE();	else return D3D_OK;
    512 				case D3DFMT_A32B32G32R32F:	if(!Capabilities::CubeMap::A32B32G32R32F)				return NOTAVAILABLE();	else return D3D_OK;
    513 				// Bump map formats
    514 				case D3DFMT_V8U8:			if(!Capabilities::CubeMap::V8U8)						return NOTAVAILABLE();	else return D3D_OK;
    515 				case D3DFMT_L6V5U5:			if(!Capabilities::CubeMap::L6V5U5)						return NOTAVAILABLE();	else return D3D_OK;
    516 				case D3DFMT_X8L8V8U8:		if(!Capabilities::CubeMap::X8L8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    517 				case D3DFMT_Q8W8V8U8:		if(!Capabilities::CubeMap::Q8W8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    518 				case D3DFMT_V16U16:			if(!Capabilities::CubeMap::V16U16)						return NOTAVAILABLE();	else return D3D_OK;
    519 				case D3DFMT_A2W10V10U10:	if(!Capabilities::CubeMap::A2W10V10U10)					return NOTAVAILABLE();	else return D3D_OK;
    520 				case D3DFMT_Q16W16V16U16:	if(!Capabilities::CubeMap::Q16W16V16U16)				return NOTAVAILABLE();	else return D3D_OK;
    521 				// Luminance formats
    522 				case D3DFMT_L8:				if(!Capabilities::CubeMap::L8)							return NOTAVAILABLE();	else return D3D_OK;
    523 				case D3DFMT_A4L4:			if(!Capabilities::CubeMap::A4L4)						return NOTAVAILABLE();	else return D3D_OK;
    524 				case D3DFMT_L16:			if(!Capabilities::CubeMap::L16)							return NOTAVAILABLE();	else return D3D_OK;
    525 				case D3DFMT_A8L8:			if(!Capabilities::CubeMap::A8L8)						return NOTAVAILABLE();	else return D3D_OK;
    526 				default:
    527 					return NOTAVAILABLE();
    528 				}
    529 			}
    530 		case D3DRTYPE_VOLUMETEXTURE:
    531 			switch(checkFormat)
    532 			{
    533 			case D3DFMT_A8:					if(!Capabilities::VolumeTexture::A8)					return NOTAVAILABLE();	else return D3D_OK;
    534 			case D3DFMT_R5G6B5:				if(!Capabilities::VolumeTexture::R5G6B5)				return NOTAVAILABLE();	else return D3D_OK;
    535 			case D3DFMT_X1R5G5B5:			if(!Capabilities::VolumeTexture::X1R5G5B5)				return NOTAVAILABLE();	else return D3D_OK;
    536 			case D3DFMT_A1R5G5B5:			if(!Capabilities::VolumeTexture::A1R5G5B5)				return NOTAVAILABLE();	else return D3D_OK;
    537 			case D3DFMT_A4R4G4B4:			if(!Capabilities::VolumeTexture::A4R4G4B4)				return NOTAVAILABLE();	else return D3D_OK;
    538 			case D3DFMT_R3G3B2:				if(!Capabilities::VolumeTexture::R3G3B2)				return NOTAVAILABLE();	else return D3D_OK;
    539 			case D3DFMT_A8R3G3B2:			if(!Capabilities::VolumeTexture::A8R3G3B2)				return NOTAVAILABLE();	else return D3D_OK;
    540 			case D3DFMT_X4R4G4B4:			if(!Capabilities::VolumeTexture::X4R4G4B4)				return NOTAVAILABLE();	else return D3D_OK;
    541 			case D3DFMT_R8G8B8:				if(!Capabilities::VolumeTexture::R8G8B8)				return NOTAVAILABLE();	else return D3D_OK;
    542 			case D3DFMT_X8R8G8B8:			if(!Capabilities::VolumeTexture::X8R8G8B8)				return NOTAVAILABLE();	else return D3D_OK;
    543 			case D3DFMT_A8R8G8B8:			if(!Capabilities::VolumeTexture::A8R8G8B8)				return NOTAVAILABLE();	else return D3D_OK;
    544 			case D3DFMT_X8B8G8R8:			if(!Capabilities::VolumeTexture::X8B8G8R8)				return NOTAVAILABLE();	else return D3D_OK;
    545 			case D3DFMT_A8B8G8R8:			if(!Capabilities::VolumeTexture::A8B8G8R8)				return NOTAVAILABLE();	else return D3D_OK;
    546 			// Paletted formats
    547 			case D3DFMT_P8:					if(!Capabilities::VolumeTexture::P8)					return NOTAVAILABLE();	else return D3D_OK;
    548 			case D3DFMT_A8P8:				if(!Capabilities::VolumeTexture::A8P8)					return NOTAVAILABLE();	else return D3D_OK;
    549 			// Integer HDR formats
    550 			case D3DFMT_G16R16:				if(!Capabilities::VolumeTexture::G16R16)				return NOTAVAILABLE();	else return D3D_OK;
    551 			case D3DFMT_A2R10G10B10:		if(!Capabilities::VolumeTexture::A2R10G10B10)			return NOTAVAILABLE();	else return D3D_OK;
    552 			case D3DFMT_A2B10G10R10:		if(!Capabilities::VolumeTexture::A2B10G10R10)			return NOTAVAILABLE();	else return D3D_OK;
    553 			case D3DFMT_A16B16G16R16:		if(!Capabilities::VolumeTexture::A16B16G16R16)			return NOTAVAILABLE();	else return D3D_OK;
    554 			// Compressed formats
    555 			case D3DFMT_DXT1:				if(!Capabilities::VolumeTexture::DXT1)					return NOTAVAILABLE();	else return D3D_OK;
    556 			case D3DFMT_DXT2:				if(!Capabilities::VolumeTexture::DXT2)					return NOTAVAILABLE();	else return D3D_OK;
    557 			case D3DFMT_DXT3:				if(!Capabilities::VolumeTexture::DXT3)					return NOTAVAILABLE();	else return D3D_OK;
    558 			case D3DFMT_DXT4:				if(!Capabilities::VolumeTexture::DXT4)					return NOTAVAILABLE();	else return D3D_OK;
    559 			case D3DFMT_DXT5:				if(!Capabilities::VolumeTexture::DXT5)					return NOTAVAILABLE();	else return D3D_OK;
    560 			case D3DFMT_ATI1:				if(!Capabilities::VolumeTexture::ATI1)					return NOTAVAILABLE();	else return D3D_OK;
    561 			case D3DFMT_ATI2:				if(!Capabilities::VolumeTexture::ATI2)					return NOTAVAILABLE();	else return D3D_OK;
    562 			// Floating-point formats
    563 			case D3DFMT_R16F:				if(!Capabilities::VolumeTexture::R16F)					return NOTAVAILABLE();	else return D3D_OK;
    564 			case D3DFMT_G16R16F:			if(!Capabilities::VolumeTexture::G16R16F)				return NOTAVAILABLE();	else return D3D_OK;
    565 			case D3DFMT_A16B16G16R16F:		if(!Capabilities::VolumeTexture::A16B16G16R16F)			return NOTAVAILABLE();	else return D3D_OK;
    566 			case D3DFMT_R32F:				if(!Capabilities::VolumeTexture::R32F)					return NOTAVAILABLE();	else return D3D_OK;
    567 			case D3DFMT_G32R32F:			if(!Capabilities::VolumeTexture::G32R32F)				return NOTAVAILABLE();	else return D3D_OK;
    568 			case D3DFMT_A32B32G32R32F:		if(!Capabilities::VolumeTexture::A32B32G32R32F)			return NOTAVAILABLE();	else return D3D_OK;
    569 			// Bump map formats
    570 			case D3DFMT_V8U8:				if(!Capabilities::VolumeTexture::V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    571 			case D3DFMT_L6V5U5:				if(!Capabilities::VolumeTexture::L6V5U5)				return NOTAVAILABLE();	else return D3D_OK;
    572 			case D3DFMT_X8L8V8U8:			if(!Capabilities::VolumeTexture::X8L8V8U8)				return NOTAVAILABLE();	else return D3D_OK;
    573 			case D3DFMT_Q8W8V8U8:			if(!Capabilities::VolumeTexture::Q8W8V8U8)				return NOTAVAILABLE();	else return D3D_OK;
    574 			case D3DFMT_V16U16:				if(!Capabilities::VolumeTexture::V16U16)				return NOTAVAILABLE();	else return D3D_OK;
    575 			case D3DFMT_A2W10V10U10:		if(!Capabilities::VolumeTexture::A2W10V10U10)			return NOTAVAILABLE();	else return D3D_OK;
    576 			case D3DFMT_Q16W16V16U16:		if(!Capabilities::VolumeTexture::Q16W16V16U16)			return NOTAVAILABLE();	else return D3D_OK;
    577 			// Luminance formats
    578 			case D3DFMT_L8:					if(!Capabilities::VolumeTexture::L8)					return NOTAVAILABLE();	else return D3D_OK;
    579 			case D3DFMT_A4L4:				if(!Capabilities::VolumeTexture::A4L4)					return NOTAVAILABLE();	else return D3D_OK;
    580 			case D3DFMT_L16:				if(!Capabilities::VolumeTexture::L16)					return NOTAVAILABLE();	else return D3D_OK;
    581 			case D3DFMT_A8L8:				if(!Capabilities::VolumeTexture::A8L8)					return NOTAVAILABLE();	else return D3D_OK;
    582 			default:
    583 				return NOTAVAILABLE();
    584 			}
    585 		case D3DRTYPE_TEXTURE:
    586 			if(usage & D3DUSAGE_RENDERTARGET)
    587 			{
    588 				switch(checkFormat)
    589 				{
    590 				case D3DFMT_NULL:			if(!Capabilities::Texture::RenderTarget::NULL_)			return NOTAVAILABLE();	else return D3D_OK;
    591 				case D3DFMT_R8G8B8:			if(!Capabilities::Texture::RenderTarget::R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    592 				case D3DFMT_R5G6B5:			if(!Capabilities::Texture::RenderTarget::R5G6B5)		return NOTAVAILABLE();	else return D3D_OK;
    593 				case D3DFMT_X1R5G5B5:		if(!Capabilities::Texture::RenderTarget::X1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    594 				case D3DFMT_A1R5G5B5:		if(!Capabilities::Texture::RenderTarget::A1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    595 				case D3DFMT_A4R4G4B4:		if(!Capabilities::Texture::RenderTarget::A4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    596 				case D3DFMT_R3G3B2:			if(!Capabilities::Texture::RenderTarget::R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    597 				case D3DFMT_A8R3G3B2:		if(!Capabilities::Texture::RenderTarget::A8R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    598 				case D3DFMT_X4R4G4B4:		if(!Capabilities::Texture::RenderTarget::X4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    599 				case D3DFMT_A8R8G8B8:		if(!Capabilities::Texture::RenderTarget::A8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    600 				case D3DFMT_X8R8G8B8:		if(!Capabilities::Texture::RenderTarget::X8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    601 				case D3DFMT_A8B8G8R8:		if(!Capabilities::Texture::RenderTarget::A8B8G8R8)		return NOTAVAILABLE();	else return D3D_OK;
    602 				case D3DFMT_X8B8G8R8:		if(!Capabilities::Texture::RenderTarget::X8B8G8R8)		return NOTAVAILABLE();	else return D3D_OK;
    603 				// Integer HDR formats
    604 				case D3DFMT_G16R16:			if(!Capabilities::Texture::RenderTarget::G16R16)		return NOTAVAILABLE();	else return D3D_OK;
    605 				case D3DFMT_A2B10G10R10:	if(!Capabilities::Texture::RenderTarget::A2B10G10R10)	return NOTAVAILABLE();	else return D3D_OK;
    606 				case D3DFMT_A2R10G10B10:	if(!Capabilities::Texture::RenderTarget::A2R10G10B10)	return NOTAVAILABLE();	else return D3D_OK;
    607 				case D3DFMT_A16B16G16R16:	if(!Capabilities::Texture::RenderTarget::A16B16G16R16)	return NOTAVAILABLE();	else return D3D_OK;
    608 				// Floating-point formats
    609 				case D3DFMT_R16F:			if(!Capabilities::Texture::RenderTarget::R16F)			return NOTAVAILABLE();	else return D3D_OK;
    610 				case D3DFMT_G16R16F:		if(!Capabilities::Texture::RenderTarget::G16R16F)		return NOTAVAILABLE();	else return D3D_OK;
    611 				case D3DFMT_A16B16G16R16F:	if(!Capabilities::Texture::RenderTarget::A16B16G16R16F)	return NOTAVAILABLE();	else return D3D_OK;
    612 				case D3DFMT_R32F:			if(!Capabilities::Texture::RenderTarget::R32F)			return NOTAVAILABLE();	else return D3D_OK;
    613 				case D3DFMT_G32R32F:		if(!Capabilities::Texture::RenderTarget::G32R32F)		return NOTAVAILABLE();	else return D3D_OK;
    614 				case D3DFMT_A32B32G32R32F:	if(!Capabilities::Texture::RenderTarget::A32B32G32R32F)	return NOTAVAILABLE();	else return D3D_OK;
    615 				default:
    616 					return NOTAVAILABLE();
    617 				}
    618 			}
    619 			else if(usage & D3DUSAGE_DEPTHSTENCIL)
    620 			{
    621 				switch(checkFormat)
    622 				{
    623 				case D3DFMT_D32:			if(!Capabilities::Texture::DepthStencil::D32)			return NOTAVAILABLE();	else return D3D_OK;
    624 				case D3DFMT_D24S8:			if(!Capabilities::Texture::DepthStencil::D24S8)			return NOTAVAILABLE();	else return D3D_OK;
    625 				case D3DFMT_D24X8:			if(!Capabilities::Texture::DepthStencil::D24X8)			return NOTAVAILABLE();	else return D3D_OK;
    626 				case D3DFMT_D16:			if(!Capabilities::Texture::DepthStencil::D16)			return NOTAVAILABLE();	else return D3D_OK;
    627 				case D3DFMT_D24FS8:			if(!Capabilities::Texture::DepthStencil::D24FS8)		return NOTAVAILABLE();	else return D3D_OK;
    628 				case D3DFMT_D32F_LOCKABLE:	if(!Capabilities::Texture::DepthStencil::D32F_LOCKABLE)	return NOTAVAILABLE();	else return D3D_OK;
    629 				case D3DFMT_DF24:			if(!Capabilities::Texture::DepthStencil::DF24)			return NOTAVAILABLE();	else return D3D_OK;
    630 				case D3DFMT_DF16:			if(!Capabilities::Texture::DepthStencil::DF16)			return NOTAVAILABLE();	else return D3D_OK;
    631 				case D3DFMT_INTZ:			if(!Capabilities::Texture::DepthStencil::INTZ)			return NOTAVAILABLE();	else return D3D_OK;
    632 				default:
    633 					return NOTAVAILABLE();
    634 				}
    635 			}
    636 			else
    637 			{
    638 				switch(checkFormat)
    639 				{
    640 				case D3DFMT_NULL:			if(!Capabilities::Texture::NULL_)						return NOTAVAILABLE();	else return D3D_OK;
    641 				case D3DFMT_A8:				if(!Capabilities::Texture::A8)							return NOTAVAILABLE();	else return D3D_OK;
    642 				case D3DFMT_R5G6B5:			if(!Capabilities::Texture::R5G6B5)						return NOTAVAILABLE();	else return D3D_OK;
    643 				case D3DFMT_X1R5G5B5:		if(!Capabilities::Texture::X1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    644 				case D3DFMT_A1R5G5B5:		if(!Capabilities::Texture::A1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    645 				case D3DFMT_A4R4G4B4:		if(!Capabilities::Texture::A4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    646 				case D3DFMT_R3G3B2:			if(!Capabilities::Texture::R3G3B2)						return NOTAVAILABLE();	else return D3D_OK;
    647 				case D3DFMT_A8R3G3B2:		if(!Capabilities::Texture::A8R3G3B2)					return NOTAVAILABLE();	else return D3D_OK;
    648 				case D3DFMT_X4R4G4B4:		if(!Capabilities::Texture::X4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    649 				case D3DFMT_R8G8B8:			if(!Capabilities::Texture::R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    650 				case D3DFMT_X8R8G8B8:		if(!Capabilities::Texture::X8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    651 				case D3DFMT_A8R8G8B8:		if(!Capabilities::Texture::A8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    652 				case D3DFMT_X8B8G8R8:		if(!Capabilities::Texture::X8B8G8R8)					return NOTAVAILABLE();	else return D3D_OK;
    653 				case D3DFMT_A8B8G8R8:		if(!Capabilities::Texture::A8B8G8R8)					return NOTAVAILABLE();	else return D3D_OK;
    654 				// Paletted formats
    655 				case D3DFMT_P8:				if(!Capabilities::Texture::P8)							return NOTAVAILABLE();	else return D3D_OK;
    656 				case D3DFMT_A8P8:			if(!Capabilities::Texture::A8P8)						return NOTAVAILABLE();	else return D3D_OK;
    657 				// Integer HDR formats
    658 				case D3DFMT_G16R16:			if(!Capabilities::Texture::G16R16)						return NOTAVAILABLE();	else return D3D_OK;
    659 				case D3DFMT_A2R10G10B10:	if(!Capabilities::Texture::A2R10G10B10)					return NOTAVAILABLE();	else return D3D_OK;
    660 				case D3DFMT_A2B10G10R10:	if(!Capabilities::Texture::A2B10G10R10)					return NOTAVAILABLE();	else return D3D_OK;
    661 				case D3DFMT_A16B16G16R16:	if(!Capabilities::Texture::A16B16G16R16)				return NOTAVAILABLE();	else return D3D_OK;
    662 				// Compressed formats
    663 				case D3DFMT_DXT1:			if(!Capabilities::Texture::DXT1)						return NOTAVAILABLE();	else return D3D_OK;
    664 				case D3DFMT_DXT2:			if(!Capabilities::Texture::DXT2)						return NOTAVAILABLE();	else return D3D_OK;
    665 				case D3DFMT_DXT3:			if(!Capabilities::Texture::DXT3)						return NOTAVAILABLE();	else return D3D_OK;
    666 				case D3DFMT_DXT4:			if(!Capabilities::Texture::DXT4)						return NOTAVAILABLE();	else return D3D_OK;
    667 				case D3DFMT_DXT5:			if(!Capabilities::Texture::DXT5)						return NOTAVAILABLE();	else return D3D_OK;
    668 				case D3DFMT_ATI1:			if(!Capabilities::Texture::ATI1)						return NOTAVAILABLE();	else return D3D_OK;
    669 				case D3DFMT_ATI2:			if(!Capabilities::Texture::ATI2)						return NOTAVAILABLE();	else return D3D_OK;
    670 				// Floating-point formats
    671 				case D3DFMT_R16F:			if(!Capabilities::Texture::R16F)						return NOTAVAILABLE();	else return D3D_OK;
    672 				case D3DFMT_G16R16F:		if(!Capabilities::Texture::G16R16F)						return NOTAVAILABLE();	else return D3D_OK;
    673 				case D3DFMT_A16B16G16R16F:	if(!Capabilities::Texture::A16B16G16R16F)				return NOTAVAILABLE();	else return D3D_OK;
    674 				case D3DFMT_R32F:			if(!Capabilities::Texture::R32F)						return NOTAVAILABLE();	else return D3D_OK;
    675 				case D3DFMT_G32R32F:		if(!Capabilities::Texture::G32R32F)						return NOTAVAILABLE();	else return D3D_OK;
    676 				case D3DFMT_A32B32G32R32F:	if(!Capabilities::Texture::A32B32G32R32F)				return NOTAVAILABLE();	else return D3D_OK;
    677 				// Bump map formats
    678 				case D3DFMT_V8U8:			if(!Capabilities::Texture::V8U8)						return NOTAVAILABLE();	else return D3D_OK;
    679 				case D3DFMT_L6V5U5:			if(!Capabilities::Texture::L6V5U5)						return NOTAVAILABLE();	else return D3D_OK;
    680 				case D3DFMT_X8L8V8U8:		if(!Capabilities::Texture::X8L8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    681 				case D3DFMT_Q8W8V8U8:		if(!Capabilities::Texture::Q8W8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    682 				case D3DFMT_V16U16:			if(!Capabilities::Texture::V16U16)						return NOTAVAILABLE();	else return D3D_OK;
    683 				case D3DFMT_A2W10V10U10:	if(!Capabilities::Texture::A2W10V10U10)					return NOTAVAILABLE();	else return D3D_OK;
    684 				case D3DFMT_Q16W16V16U16:	if(!Capabilities::Texture::Q16W16V16U16)				return NOTAVAILABLE();	else return D3D_OK;
    685 				// Luminance formats
    686 				case D3DFMT_L8:				if(!Capabilities::Texture::L8)							return NOTAVAILABLE();	else return D3D_OK;
    687 				case D3DFMT_A4L4:			if(!Capabilities::Texture::A4L4)						return NOTAVAILABLE();	else return D3D_OK;
    688 				case D3DFMT_L16:			if(!Capabilities::Texture::L16)							return NOTAVAILABLE();	else return D3D_OK;
    689 				case D3DFMT_A8L8:			if(!Capabilities::Texture::A8L8)						return NOTAVAILABLE();	else return D3D_OK;
    690 				// Depth formats
    691 				case D3DFMT_D32:			if(!Capabilities::Texture::D32)							return NOTAVAILABLE();	else return D3D_OK;
    692 				case D3DFMT_D24S8:			if(!Capabilities::Texture::D24S8)						return NOTAVAILABLE();	else return D3D_OK;
    693 				case D3DFMT_D24X8:			if(!Capabilities::Texture::D24X8)						return NOTAVAILABLE();	else return D3D_OK;
    694 				case D3DFMT_D16:			if(!Capabilities::Texture::D16)							return NOTAVAILABLE();	else return D3D_OK;
    695 				case D3DFMT_D24FS8:			if(!Capabilities::Texture::D24FS8)						return NOTAVAILABLE();	else return D3D_OK;
    696 				case D3DFMT_D32F_LOCKABLE:	if(!Capabilities::Texture::D32F_LOCKABLE)				return NOTAVAILABLE();	else return D3D_OK;
    697 				case D3DFMT_DF24:			if(!Capabilities::Texture::DF24)						return NOTAVAILABLE();	else return D3D_OK;
    698 				case D3DFMT_DF16:			if(!Capabilities::Texture::DF16)						return NOTAVAILABLE();	else return D3D_OK;
    699 				case D3DFMT_INTZ:			if(!Capabilities::Texture::INTZ)						return NOTAVAILABLE();	else return D3D_OK;
    700 				default:
    701 					return NOTAVAILABLE();
    702 				}
    703 			}
    704 		case D3DRTYPE_VERTEXBUFFER:
    705 			if(checkFormat == D3DFMT_VERTEXDATA)
    706 			{
    707 				return D3D_OK;
    708 			}
    709 			else
    710 			{
    711 				return NOTAVAILABLE();
    712 			}
    713 		case D3DRTYPE_INDEXBUFFER:
    714 			switch(checkFormat)
    715 			{
    716 			case D3DFMT_INDEX16:
    717 			case D3DFMT_INDEX32:
    718 				return D3D_OK;
    719 			default:
    720 				return NOTAVAILABLE();
    721 			};
    722 		default:
    723 			return NOTAVAILABLE();
    724 		}
    725 	}
    726 
    727 	long Direct3D9::CheckDeviceFormatConversion(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT sourceFormat, D3DFORMAT targetFormat)
    728 	{
    729 		TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT sourceFormat = %d, D3DFORMAT targetFormat = %d", adapter, deviceType, sourceFormat, targetFormat);
    730 
    731 		if(deviceType != D3DDEVTYPE_HAL)
    732 		{
    733 			loadSystemD3D9();
    734 
    735 			if(d3d9)
    736 			{
    737 				return d3d9->CheckDeviceFormatConversion(adapter, deviceType, sourceFormat, targetFormat);
    738 			}
    739 			else
    740 			{
    741 				return CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, sourceFormat, targetFormat);
    742 			}
    743 		}
    744 
    745 		return D3D_OK;
    746 	}
    747 
    748 	long Direct3D9::CheckDeviceMultiSampleType(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT surfaceFormat, int windowed, D3DMULTISAMPLE_TYPE multiSampleType, unsigned long *qualityLevels)
    749 	{
    750 		TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DFORMAT surfaceFormat = %d, int windowed = %d, D3DMULTISAMPLE_TYPE multiSampleType = %d, unsigned long *qualityLevels = 0x%0.8p", adapter, deviceType, surfaceFormat, windowed, multiSampleType, qualityLevels);
    751 
    752 		if(deviceType != D3DDEVTYPE_HAL)
    753 		{
    754 			loadSystemD3D9();
    755 
    756 			if(d3d9)
    757 			{
    758 				return d3d9->CheckDeviceMultiSampleType(adapter, deviceType, surfaceFormat, windowed, multiSampleType, qualityLevels);
    759 			}
    760 			else
    761 			{
    762 				return CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, surfaceFormat, windowed, multiSampleType, qualityLevels);
    763 			}
    764 		}
    765 
    766 		if(adapter >= GetAdapterCount())
    767 		{
    768 			return INVALIDCALL();
    769 		}
    770 
    771 		if(qualityLevels)
    772 		{
    773 			if(multiSampleType == D3DMULTISAMPLE_NONMASKABLE)
    774 			{
    775 				*qualityLevels = 4;   // 2, 4, 8, 16 samples
    776 			}
    777 			else
    778 			{
    779 				*qualityLevels = 1;
    780 			}
    781 		}
    782 
    783 		if(multiSampleType == D3DMULTISAMPLE_NONE ||
    784 		   multiSampleType == D3DMULTISAMPLE_NONMASKABLE ||
    785 		   multiSampleType == D3DMULTISAMPLE_2_SAMPLES ||
    786 		   multiSampleType == D3DMULTISAMPLE_4_SAMPLES ||
    787 		   multiSampleType == D3DMULTISAMPLE_8_SAMPLES ||
    788 		   multiSampleType == D3DMULTISAMPLE_16_SAMPLES)
    789 		{
    790 			if(CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, surfaceFormat) == D3D_OK ||
    791 			   CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, surfaceFormat) == D3D_OK)
    792 			{
    793 				if(surfaceFormat != D3DFMT_D32F_LOCKABLE && surfaceFormat != D3DFMT_D16_LOCKABLE)
    794 				{
    795 					return D3D_OK;
    796 				}
    797 			}
    798 		}
    799 
    800 		return NOTAVAILABLE();
    801 	}
    802 
    803 	long Direct3D9::CheckDeviceType(unsigned int adapter, D3DDEVTYPE checkType, D3DFORMAT displayFormat, D3DFORMAT backBufferFormat, int windowed)
    804 	{
    805 		TRACE("unsigned int adapter = %d, D3DDEVTYPE checkType = %d, D3DFORMAT displayFormat = %d, D3DFORMAT backBufferFormat = %d, int windowed = %d", adapter, checkType, displayFormat, backBufferFormat, windowed);
    806 
    807 		if(checkType != D3DDEVTYPE_HAL)
    808 		{
    809 			loadSystemD3D9();
    810 
    811 			if(d3d9)
    812 			{
    813 				return d3d9->CheckDeviceType(adapter, checkType, displayFormat, backBufferFormat, windowed);
    814 			}
    815 			else
    816 			{
    817 				return CheckDeviceType(adapter, D3DDEVTYPE_HAL, displayFormat, backBufferFormat, windowed);
    818 			}
    819 		}
    820 
    821 		if(adapter >= GetAdapterCount())
    822 		{
    823 			return INVALIDCALL();
    824 		}
    825 
    826 		switch(displayFormat)
    827 		{
    828 		case D3DFMT_UNKNOWN:
    829 			if(windowed == FALSE)
    830 			{
    831 				return INVALIDCALL();
    832 			}
    833 			else
    834 			{
    835 				return NOTAVAILABLE();
    836 			}
    837 		case D3DFMT_A2R10G10B10:
    838 		case D3DFMT_A2B10G10R10:
    839 			if(disable10BitMode)
    840 			{
    841 				return NOTAVAILABLE();
    842 			}
    843 		case D3DFMT_X8R8G8B8:
    844 		case D3DFMT_R5G6B5:
    845 			break;
    846 		default:
    847 			return NOTAVAILABLE();
    848 		}
    849 
    850 		if(windowed != FALSE)
    851 		{
    852 			switch(backBufferFormat)
    853 			{
    854 			case D3DFMT_A2R10G10B10:
    855 			case D3DFMT_A2B10G10R10:
    856 				if(disable10BitMode)
    857 				{
    858 					return NOTAVAILABLE();
    859 				}
    860 			case D3DFMT_A8R8G8B8:
    861 				if(disableAlphaMode)
    862 				{
    863 					return NOTAVAILABLE();
    864 				}
    865 			case D3DFMT_UNKNOWN:
    866 			case D3DFMT_X8R8G8B8:
    867 			case D3DFMT_R5G6B5:
    868 		//	case D3DFMT_X1R5G5B5:      // FIXME: Supported by REF
    869 		//	case D3DFMT_A1R5G5B5:      // FIXME: Supported by REF
    870 				break;
    871 			default:
    872 				return NOTAVAILABLE();
    873 			}
    874 		}
    875 		else
    876 		{
    877 			switch(backBufferFormat)
    878 			{
    879 			case D3DFMT_UNKNOWN:
    880 				return INVALIDCALL();
    881 			case D3DFMT_A2R10G10B10:
    882 			case D3DFMT_A2B10G10R10:
    883 				if(disable10BitMode)
    884 				{
    885 					return NOTAVAILABLE();
    886 				}
    887 			case D3DFMT_A8R8G8B8:
    888 				if(disableAlphaMode)
    889 				{
    890 					return NOTAVAILABLE();
    891 				}
    892 			case D3DFMT_X8R8G8B8:
    893 				break;
    894 			default:
    895 				return NOTAVAILABLE();
    896 			}
    897 		}
    898 
    899 		return D3D_OK;
    900 	}
    901 
    902 	long Direct3D9::CreateDevice(unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviorFlags, D3DPRESENT_PARAMETERS *presentParameters, IDirect3DDevice9 **returnedDeviceInterface)
    903 	{
    904 		TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, HWND focusWindow = %d, unsigned long behaviorFlags = 0x%0.8X, D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, IDirect3DDevice9 **returnedDeviceInterface = 0x%0.8p", adapter, deviceType, focusWindow, behaviorFlags, presentParameters, returnedDeviceInterface);
    905 
    906 		if(deviceType != D3DDEVTYPE_HAL)
    907 		{
    908 			loadSystemD3D9();
    909 
    910 			if(d3d9)
    911 			{
    912 				return d3d9->CreateDevice(adapter, deviceType, focusWindow, behaviorFlags, presentParameters, returnedDeviceInterface);
    913 			}
    914 			else
    915 			{
    916 				return CreateDevice(adapter, D3DDEVTYPE_HAL, focusWindow, behaviorFlags, presentParameters, returnedDeviceInterface);
    917 			}
    918 		}
    919 
    920 		if(!focusWindow || !presentParameters || !returnedDeviceInterface)
    921 		{
    922 			*returnedDeviceInterface = 0;
    923 
    924 			return INVALIDCALL();
    925 		}
    926 
    927 		*returnedDeviceInterface = new Direct3DDevice9(instance, this, adapter, deviceType, focusWindow, behaviorFlags, presentParameters);
    928 
    929 		if(*returnedDeviceInterface)
    930 		{
    931 			(*returnedDeviceInterface)->AddRef();
    932 		}
    933 
    934 		return D3D_OK;
    935 	}
    936 
    937 	long Direct3D9::EnumAdapterModes(unsigned int adapter, D3DFORMAT format, unsigned int index, D3DDISPLAYMODE *mode)
    938 	{
    939 		TRACE("unsigned int adapter = %d, D3DFORMAT format = %d, unsigned int index = %d, D3DDISPLAYMODE *mode = 0x%0.8p", adapter, format, index, mode);
    940 
    941 		if(adapter != D3DADAPTER_DEFAULT || !mode)
    942 		{
    943 			return INVALIDCALL();
    944 		}
    945 
    946 		unsigned int bpp = 32;
    947 
    948 		switch(format)
    949 		{
    950 		case D3DFMT_A1R5G5B5:		bpp = 16; break;
    951 		case D3DFMT_A2R10G10B10:	bpp = 32; break;
    952 		case D3DFMT_A8R8G8B8:		bpp = 32; break;
    953 		case D3DFMT_R5G6B5:			bpp = 16; break;
    954 		case D3DFMT_X1R5G5B5:		bpp = 16; break;
    955 		case D3DFMT_X8R8G8B8:		bpp = 32; break;
    956 		default: return INVALIDCALL();
    957 		}
    958 
    959 		for(int i = 0; i < numDisplayModes; i++)
    960 		{
    961 			if(displayMode[i].dmBitsPerPel == bpp)
    962 			{
    963 				if(index-- == 0)
    964 				{
    965 					mode->Width = displayMode[i].dmPelsWidth;
    966 					mode->Height = displayMode[i].dmPelsHeight;
    967 					mode->RefreshRate = displayMode[i].dmDisplayFrequency;
    968 					mode->Format = format;
    969 
    970 					return D3D_OK;
    971 				}
    972 			}
    973 		}
    974 
    975 		return INVALIDCALL();
    976 	}
    977 
    978 	unsigned int Direct3D9::GetAdapterCount()
    979 	{
    980 		TRACE("void");
    981 
    982 		return 1;   // SwiftShader does not support multiple display adapters
    983 	}
    984 
    985 	long Direct3D9::GetAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode)
    986 	{
    987 		TRACE("unsigned int adapter = %d, D3DDISPLAYMODE *mode = 0x%0.8p", adapter, mode);
    988 
    989 		if(adapter != D3DADAPTER_DEFAULT || !mode)
    990 		{
    991 			return INVALIDCALL();
    992 		}
    993 
    994 		HDC deviceContext = GetDC(0);
    995 
    996 		mode->Width = ::GetDeviceCaps(deviceContext, HORZRES);
    997 		mode->Height = ::GetDeviceCaps(deviceContext, VERTRES);
    998 		mode->RefreshRate = ::GetDeviceCaps(deviceContext, VREFRESH);
    999 		unsigned int bpp = ::GetDeviceCaps(deviceContext, BITSPIXEL);
   1000 
   1001 		ReleaseDC(0, deviceContext);
   1002 
   1003 		bpp = 32;   // FIXME
   1004 
   1005 		switch(bpp)
   1006 		{
   1007 		case 32: mode->Format = D3DFMT_X8R8G8B8; break;
   1008 		case 24: mode->Format = D3DFMT_R8G8B8;   break;
   1009 		case 16: mode->Format = D3DFMT_R5G6B5;   break;
   1010 		default:
   1011 			ASSERT(false);   // Unexpected display mode color depth
   1012 		}
   1013 
   1014 		return D3D_OK;
   1015 	}
   1016 
   1017 	long Direct3D9::GetAdapterIdentifier(unsigned int adapter, unsigned long flags, D3DADAPTER_IDENTIFIER9 *identifier)
   1018 	{
   1019 		TRACE("unsigned int adapter = %d, unsigned long flags = 0x%0.8X, D3DADAPTER_IDENTIFIER9 *identifier = 0x%0.8p", adapter, flags, identifier);
   1020 
   1021 		if(!identifier)
   1022 		{
   1023 			return INVALIDCALL();
   1024 		}
   1025 
   1026 		sw::Configurator ini("SwiftShader.ini");
   1027 		int id = ini.getInteger("Capabilities", "Identifier", 0);
   1028 
   1029 		if(id == 1)
   1030 		{
   1031 			unsigned short product = 6;
   1032 			unsigned short version = 14;
   1033 			unsigned short subVersion = 10;
   1034 			unsigned short revision = 8440;
   1035 			GUID guid = {0xD7B71E3E, 0x41D2, 0x11CF, {0x96, 0x53, 0x7A, 0x23, 0x00, 0xC2, 0xCB, 0x35}};
   1036 
   1037 			identifier->DriverVersion.HighPart = product << 16 | version;
   1038 			identifier->DriverVersion.LowPart = subVersion << 16 | revision;
   1039 			strcpy(identifier->Driver, "nv4_disp.dll");
   1040 			strcpy(identifier->Description, "NVIDIA GeForce 7900 GS");
   1041 			strcpy(identifier->DeviceName, "\\\\.\\DISPLAY1");
   1042 			identifier->VendorId = 0x10DE;
   1043 			identifier->DeviceId = 0x0292;
   1044 			identifier->SubSysId = 0x037010DE;
   1045 			identifier->Revision = 0x00A1;
   1046 			identifier->DeviceIdentifier = guid;
   1047 			identifier->WHQLLevel = 1;
   1048 
   1049 			return D3D_OK;
   1050 		}
   1051 		else if(id == 2)
   1052 		{
   1053 			unsigned short product = 7;
   1054 			unsigned short version = 14;
   1055 			unsigned short subVersion = 10;
   1056 			unsigned short revision = 464;
   1057 			GUID guid = {0xD7B71EE2, 0x3285, 0x11CF, {0x11, 0x72, 0x0D, 0xA2, 0xA1, 0xC2, 0xCA, 0x35}};
   1058 
   1059 			identifier->DriverVersion.HighPart = product << 16 | version;
   1060 			identifier->DriverVersion.LowPart = subVersion << 16 | revision;
   1061 			strcpy(identifier->Driver, "atiumdag.dll");
   1062 			strcpy(identifier->Description, "ATI Mobility Radeon X1600");
   1063 			strcpy(identifier->DeviceName, "\\\\.\\DISPLAY1");
   1064 			identifier->VendorId = 0x1002;
   1065 			identifier->DeviceId = 0x71C5;
   1066 			identifier->SubSysId = 0x82071071;
   1067 			identifier->Revision = 0x0000;
   1068 			identifier->DeviceIdentifier = guid;
   1069 			identifier->WHQLLevel = 1;
   1070 
   1071 			return D3D_OK;
   1072 		}
   1073 		else if(id == 3)
   1074 		{
   1075 			unsigned short product = 7;
   1076 			unsigned short version = 14;
   1077 			unsigned short subVersion = 10;
   1078 			unsigned short revision = 1437;
   1079 			GUID guid = {0xD7B78E66, 0x6942, 0x11CF, {0x05, 0x76, 0x03, 0x22, 0xAD, 0xC2, 0xCA, 0x35}};
   1080 
   1081 			identifier->DriverVersion.HighPart = product << 16 | version;
   1082 			identifier->DriverVersion.LowPart = subVersion << 16 | revision;
   1083 			strcpy(identifier->Driver, "igdumd64.dll");
   1084 			strcpy(identifier->Description, "Intel GMA X3100");
   1085 			strcpy(identifier->DeviceName, "\\\\.\\DISPLAY1");
   1086 			identifier->VendorId = 0x8086;
   1087 			identifier->DeviceId = 0x2A02;
   1088 			identifier->SubSysId = 0x02091028;
   1089 			identifier->Revision = 0x000C;
   1090 			identifier->DeviceIdentifier = guid;
   1091 			identifier->WHQLLevel = 1;
   1092 
   1093 			return D3D_OK;
   1094 		}
   1095 		else if(id == 4)
   1096 		{
   1097 			loadSystemD3D9();
   1098 
   1099 			if(d3d9)
   1100 			{
   1101 				return d3d9->GetAdapterIdentifier(adapter, flags, identifier);
   1102 			}
   1103 		}
   1104 
   1105 		unsigned short product = 'sw';
   1106 		unsigned short version = 3;
   1107 		unsigned short subVersion = 0;
   1108 		unsigned short revision = BUILD_REVISION;
   1109 		GUID guid = {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
   1110 
   1111 		identifier->DriverVersion.HighPart = product << 16 | version;
   1112 		identifier->DriverVersion.LowPart = subVersion << 16 | revision;
   1113 		strcpy(identifier->Driver, "SwiftShader");
   1114 		strcpy(identifier->Description, "Google SwiftShader 3D Renderer");
   1115 		strcpy(identifier->DeviceName, "\\\\.\\DISPLAY1");
   1116 		identifier->VendorId = 0;
   1117 		identifier->DeviceId = 0;
   1118 		identifier->SubSysId = 0;
   1119 		identifier->Revision = 0;
   1120 		identifier->DeviceIdentifier = guid;
   1121 		identifier->WHQLLevel = 0;
   1122 
   1123 		char exeName[MAX_PATH + 1];
   1124 		int n = GetModuleBaseName(GetCurrentProcess(), 0, exeName, MAX_PATH);
   1125 		exeName[n] = '\0';
   1126 
   1127 		if(strncmp(exeName, "Fallout", 7) == 0)
   1128 		{
   1129 			strcpy(identifier->Driver, "nv4_disp.dll");
   1130 		}
   1131 
   1132 		return D3D_OK;
   1133 	}
   1134 
   1135 	unsigned int Direct3D9::GetAdapterModeCount(unsigned int adapter, D3DFORMAT format)
   1136 	{
   1137 		TRACE("unsigned int adapter = %d, D3DFORMAT format = %d", adapter, format);
   1138 
   1139 		if(adapter != D3DADAPTER_DEFAULT)
   1140 		{
   1141 			return 0;
   1142 		}
   1143 
   1144 		int modeCount = 0;
   1145 
   1146 		for(int i = 0; i < numDisplayModes; i++)
   1147 		{
   1148 			switch(format)
   1149 			{
   1150 			case D3DFMT_A8R8G8B8:
   1151 				if(!disableAlphaMode)
   1152 				{
   1153 					if(displayMode[i].dmBitsPerPel == 32) modeCount++;
   1154 				}
   1155 				break;
   1156 			case D3DFMT_X8R8G8B8:    if(displayMode[i].dmBitsPerPel == 32) modeCount++; break;
   1157 			case D3DFMT_A2R10G10B10:
   1158 			case D3DFMT_A2B10G10R10:
   1159 				if(!disable10BitMode)
   1160 				{
   1161 					if(displayMode[i].dmBitsPerPel == 32) modeCount++;
   1162 				}
   1163 				break;
   1164 		//	case D3DFMT_R8G8B8:      if(displayMode[i].dmBitsPerPel == 24) modeCount++; break;   // NOTE: Deprecated by DirectX 9
   1165 			case D3DFMT_R5G6B5:      if(displayMode[i].dmBitsPerPel == 16) modeCount++; break;
   1166 		//	case D3DFMT_X1R5G5B5:    if(displayMode[i].dmBitsPerPel == 16) modeCount++; break;
   1167 		//	case D3DFMT_A1R5G5B5:    if(displayMode[i].dmBitsPerPel == 16) modeCount++; break;
   1168 		//	default:
   1169 		//		ASSERT(false);
   1170 			}
   1171 		}
   1172 
   1173 		return modeCount;
   1174 	}
   1175 
   1176 	HMONITOR Direct3D9::GetAdapterMonitor(unsigned int adapter)
   1177 	{
   1178 		TRACE("unsigned int adapter = %d", adapter);
   1179 
   1180 		POINT point = {0, 0};
   1181 
   1182 		return MonitorFromPoint(point, MONITOR_DEFAULTTOPRIMARY);   // FIXME: Ignores adapter parameter
   1183 	}
   1184 
   1185 	long Direct3D9::GetDeviceCaps(unsigned int adapter, D3DDEVTYPE deviceType, D3DCAPS9 *capabilities)
   1186 	{
   1187 		TRACE("unsigned int adapter = %d, D3DDEVTYPE deviceType = %d, D3DCAPS9 *capabilities = 0x%0.8p", adapter, deviceType, capabilities);
   1188 
   1189 		if(deviceType != D3DDEVTYPE_HAL)
   1190 		{
   1191 			loadSystemD3D9();
   1192 
   1193 			if(d3d9)
   1194 			{
   1195 				return d3d9->GetDeviceCaps(adapter, deviceType, capabilities);
   1196 			}
   1197 			else
   1198 			{
   1199 				return GetDeviceCaps(adapter, D3DDEVTYPE_HAL, capabilities);
   1200 			}
   1201 		}
   1202 
   1203 		if(!capabilities)
   1204 		{
   1205 			return INVALIDCALL();
   1206 		}
   1207 
   1208 		unsigned int pixelShaderVersion = pixelShaderVersionX;
   1209 		unsigned int vertexShaderVersion = vertexShaderVersionX;
   1210 
   1211 		if(pixelShaderVersion == D3DPS_VERSION(2, 1)) pixelShaderVersion = D3DPS_VERSION(2, 0);
   1212 		if(vertexShaderVersion == D3DVS_VERSION(2, 1)) vertexShaderVersion = D3DVS_VERSION(2, 0);
   1213 
   1214 		unsigned int maximumVertexShaderInstructionsExecuted = 0;
   1215 		unsigned int maximumPixelShaderInstructionsExecuted = 0;
   1216 		unsigned int maximumVertexShader30InstructionSlots = 0;
   1217 		unsigned int maximumPixelShader30InstructionSlots = 0;
   1218 
   1219 		if(vertexShaderVersion >= D3DVS_VERSION(1, 0)) maximumVertexShaderInstructionsExecuted = 0xFFFFFFFF;
   1220 		if(pixelShaderVersion >= D3DPS_VERSION(1, 0)) maximumPixelShaderInstructionsExecuted = 0xFFFFFFFF;
   1221 		if(vertexShaderVersion >= D3DVS_VERSION(3, 0)) maximumVertexShader30InstructionSlots = 32768;
   1222 		if(pixelShaderVersion >= D3DPS_VERSION(3, 0)) maximumPixelShader30InstructionSlots = 32768;
   1223 
   1224 		D3DCAPS9 caps;
   1225 		ZeroMemory(&caps, sizeof(D3DCAPS9));
   1226 
   1227 		// Device info
   1228 		caps.DeviceType = D3DDEVTYPE_HAL;
   1229 		caps.AdapterOrdinal = D3DADAPTER_DEFAULT;
   1230 
   1231 		// Caps from DX7
   1232 		caps.Caps =	D3DCAPS_READ_SCANLINE;
   1233 
   1234 		caps.Caps2 =		D3DCAPS2_CANAUTOGENMIPMAP |		// The driver is capable of automatically generating mipmaps. For more information, see Automatic Generation of Mipmaps (Direct3D 9).
   1235 						//	D3DCAPS2_CANCALIBRATEGAMMA |	// The system has a calibrator installed that can automatically adjust the gamma ramp so that the result is identical on all systems that have a calibrator. To invoke the calibrator when setting new gamma levels, use the D3DSGR_CALIBRATE flag when calling SetGammaRamp. Calibrating gamma ramps incurs some processing overhead and should not be used frequently.
   1236 						//	D3DCAPS2_CANSHARERESOURCE |		// The device can create sharable resources. Methods that create resources can set non-NULL values for their pSharedHandle parameters. Differences between Direct3D 9 and Direct3D 9Ex:This flag is available in Direct3D 9Ex only.
   1237 						//	D3DCAPS2_CANMANAGERESOURCE |	// The driver is capable of managing resources. On such drivers, D3DPOOL_MANAGED resources will be managed by the driver. To have Direct3D override the driver so that Direct3D manages resources, use the D3DCREATE_DISABLE_DRIVER_MANAGEMENT flag when calling CreateDevice.
   1238 							D3DCAPS2_DYNAMICTEXTURES | 		// The driver supports dynamic textures.
   1239 							D3DCAPS2_FULLSCREENGAMMA;		// The driver supports dynamic gamma ramp adjustment in full-screen mode.
   1240 
   1241 		caps.Caps3 =		D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |	// Indicates that the device can respect the D3DRS_ALPHABLENDENABLE render state in full-screen mode while using the FLIP or DISCARD swap effect.
   1242 							D3DCAPS3_COPY_TO_VIDMEM |					// Device can accelerate a memory copy from system memory to local video memory.
   1243 							D3DCAPS3_COPY_TO_SYSTEMMEM;					// Device can accelerate a memory copy from local video memory to system memory.
   1244 						//	D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION;		// Indicates that the device can perform gamma correction from a windowed back buffer (containing linear content) to an sRGB desktop.
   1245 
   1246 		caps.PresentationIntervals =		D3DPRESENT_INTERVAL_IMMEDIATE |
   1247 											D3DPRESENT_INTERVAL_ONE;
   1248 										//	D3DPRESENT_INTERVAL_TWO;
   1249 										//	D3DPRESENT_INTERVAL_THREE;
   1250 										//	D3DPRESENT_INTERVAL_FOUR;
   1251 
   1252 		// Cursor caps
   1253 		caps.CursorCaps =	D3DCURSORCAPS_COLOR	|	// A full-color cursor is supported in hardware. Specifically, this flag indicates that the driver supports at least a hardware color cursor in high-resolution modes (with scan lines greater than or equal to 400).
   1254 							D3DCURSORCAPS_LOWRES;	// A full-color cursor is supported in hardware. Specifically, this flag indicates that the driver supports a hardware color cursor in both high-resolution and low-resolution modes (with scan lines less than 400).
   1255 
   1256 		// 3D Device caps
   1257 		caps.DevCaps =		D3DDEVCAPS_CANBLTSYSTONONLOCAL |		// Device supports blits from system-memory textures to nonlocal video-memory textures.
   1258 							D3DDEVCAPS_CANRENDERAFTERFLIP |			// Device can queue rendering commands after a page flip. Applications do not change their behavior if this flag is set; this capability means that the device is relatively fast.
   1259 							D3DDEVCAPS_DRAWPRIMITIVES2 |			// Device can support DrawPrimitives2.
   1260 							D3DDEVCAPS_DRAWPRIMITIVES2EX |			// Device can support extended DrawPrimitives2; that is, this is a DirectX 7.0-compliant driver.
   1261 							D3DDEVCAPS_DRAWPRIMTLVERTEX |			// Device exports an IDirect3DDevice9::DrawPrimitive-aware hardware abstraction layer (HAL).
   1262 							D3DDEVCAPS_EXECUTESYSTEMMEMORY |		// Device can use execute buffers from system memory.
   1263 							D3DDEVCAPS_EXECUTEVIDEOMEMORY |			// Device can use execute buffers from video memory.
   1264 							D3DDEVCAPS_HWRASTERIZATION |			// Device has hardware acceleration for scene rasterization.
   1265 							D3DDEVCAPS_HWTRANSFORMANDLIGHT |		// Device can support transformation and lighting in hardware.
   1266 						//	D3DDEVCAPS_NPATCHES |					// Device supports N patches.
   1267 							D3DDEVCAPS_PUREDEVICE |					// Device can support rasterization, transform, lighting, and shading in hardware.
   1268 						//	D3DDEVCAPS_QUINTICRTPATCHES |			// Device supports quintic Bzier curves and B-splines.
   1269 						//	D3DDEVCAPS_RTPATCHES |					// Device supports rectangular and triangular patches.
   1270 							D3DDEVCAPS_RTPATCHHANDLEZERO |			// When this device capability is set, the hardware architecture does not require caching of any information and uncached patches (handle zero) will be drawn as efficiently as cached ones. Note that setting D3DDEVCAPS_RTPATCHHANDLEZERO does not mean that a patch with handle zero can be drawn. A handle-zero patch can always be drawn whether this cap is set or not.
   1271 						//	D3DDEVCAPS_SEPARATETEXTUREMEMORIES |	// Device is texturing from separate memory pools.
   1272 							D3DDEVCAPS_TEXTURENONLOCALVIDMEM |		// Device can retrieve textures from non-local video memory.
   1273 							D3DDEVCAPS_TEXTURESYSTEMMEMORY |		// Device can retrieve textures from system memory.
   1274 							D3DDEVCAPS_TEXTUREVIDEOMEMORY |			// Device can retrieve textures from device memory.
   1275 							D3DDEVCAPS_TLVERTEXSYSTEMMEMORY |		// Device can use buffers from system memory for transformed and lit vertices.
   1276 							D3DDEVCAPS_TLVERTEXVIDEOMEMORY;			// Device can use buffers from video memory for transformed and lit vertices.
   1277 
   1278 		caps.PrimitiveMiscCaps = 		D3DPMISCCAPS_MASKZ |						// Device can enable and disable modification of the depth buffer on pixel operations.
   1279 										D3DPMISCCAPS_CULLNONE |						// The driver does not perform triangle culling. This corresponds to the D3DCULL_NONE member of the D3DCULL enumerated type.
   1280 										D3DPMISCCAPS_CULLCW |						// The driver supports clockwise triangle culling through the D3DRS_CULLMODE state. (This applies only to triangle primitives.) This flag corresponds to the D3DCULL_CW member of the D3DCULL enumerated type.
   1281 										D3DPMISCCAPS_CULLCCW |						// The driver supports counterclockwise culling through the D3DRS_CULLMODE state. (This applies only to triangle primitives.) This flag corresponds to the D3DCULL_CCW member of the D3DCULL enumerated type.
   1282 										D3DPMISCCAPS_COLORWRITEENABLE |				// Device supports per-channel writes for the render-target color buffer through the D3DRS_COLORWRITEENABLE state.
   1283 										D3DPMISCCAPS_CLIPPLANESCALEDPOINTS |		// Device correctly clips scaled points of size greater than 1.0 to user-defined clipping planes.
   1284 										D3DPMISCCAPS_CLIPTLVERTS |					// Device clips post-transformed vertex primitives. Specify D3DUSAGE_DONOTCLIP when the pipeline should not do any clipping. For this case, additional software clipping may need to be performed at draw time, requiring the vertex buffer to be in system memory.
   1285 										D3DPMISCCAPS_TSSARGTEMP |					// Device supports D3DTA for temporary register.
   1286 										D3DPMISCCAPS_BLENDOP |						// Device supports alpha-blending operations other than D3DBLENDOP_ADD.
   1287 									//	D3DPMISCCAPS_NULLREFERENCE |				// A reference device that does not render.
   1288 										D3DPMISCCAPS_INDEPENDENTWRITEMASKS |		// Device supports independent write masks for multiple element textures or multiple render targets.
   1289 										D3DPMISCCAPS_PERSTAGECONSTANT |				// Device supports per-stage constants. See D3DTSS_CONSTANT in D3DTEXTURESTAGESTATETYPE.
   1290 										D3DPMISCCAPS_FOGANDSPECULARALPHA |			// Device supports separate fog and specular alpha. Many devices use the specular alpha channel to store the fog factor.
   1291 										D3DPMISCCAPS_SEPARATEALPHABLEND |			// Device supports separate blend settings for the alpha channel.
   1292 										D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS |		// Device supports different bit depths for multiple render targets.
   1293 										D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING |	// Device supports post-pixel shader operations for multiple render targets.
   1294 										D3DPMISCCAPS_FOGVERTEXCLAMPED;				// Device clamps fog blend factor per vertex.
   1295 
   1296 		caps.RasterCaps =		D3DPRASTERCAPS_ANISOTROPY |				// Device supports anisotropic filtering.
   1297 								D3DPRASTERCAPS_COLORPERSPECTIVE |		// Device iterates colors perspective correctly.
   1298 							//	D3DPRASTERCAPS_DITHER |					// Device can dither to improve color resolution.
   1299 								D3DPRASTERCAPS_DEPTHBIAS |				// Device supports legacy depth bias. For true depth bias, see D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS.
   1300 								D3DPRASTERCAPS_FOGRANGE |				// Device supports range-based fog. In range-based fog, the distance of an object from the viewer is used to compute fog effects, not the depth of the object (that is, the z-coordinate) in the scene.
   1301 								D3DPRASTERCAPS_FOGTABLE |				// Device calculates the fog value by referring to a lookup table containing fog values that are indexed to the depth of a given pixel.
   1302 								D3DPRASTERCAPS_FOGVERTEX |				// Device calculates the fog value during the lighting operation and interpolates the fog value during rasterization.
   1303 								D3DPRASTERCAPS_MIPMAPLODBIAS |			// Device supports level of detail (LOD) bias adjustments. These bias adjustments enable an application to make a mipmap appear crisper or less sharp than it normally would. For more information about LOD bias in mipmaps, see D3DSAMP_MIPMAPLODBIAS.
   1304 							//	D3DPRASTERCAPS_MULTISAMPLE_TOGGLE |		// Device supports toggling multisampling on and off between IDirect3DDevice9::BeginScene and IDirect3DDevice9::EndScene (using D3DRS_MULTISAMPLEANTIALIAS).
   1305 								D3DPRASTERCAPS_SCISSORTEST |			// Device supports scissor test. See Scissor Test.
   1306 								D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |	// Device performs true slope-scale based depth bias. This is in contrast to the legacy style D3DPRASTERCAPS_DEPTHBIAS.
   1307 							//	D3DPRASTERCAPS_WBUFFER |				// Device supports depth buffering using w.
   1308 								D3DPRASTERCAPS_WFOG |					// Device supports w-based fog. W-based fog is used when a perspective projection matrix is specified, but affine projections still use z-based fog. The system considers a projection matrix that contains a nonzero value in the [3][4] element to be a perspective projection matrix.
   1309 							//	D3DPRASTERCAPS_ZBUFFERLESSHSR |			// Device can perform hidden-surface removal (HSR) without requiring the application to sort polygons and without requiring the allocation of a depth-buffer. This leaves more video memory for textures. The method used to perform HSR is hardware-dependent and is transparent to the application. Z-bufferless HSR is performed if no depth-buffer surface is associated with the rendering-target surface and the depth-buffer comparison test is enabled (that is, when the state value associated with the D3DRS_ZENABLE enumeration constant is set to TRUE).
   1310 								D3DPRASTERCAPS_ZFOG |					// Device supports z-based fog.
   1311 								D3DPRASTERCAPS_ZTEST;					// Device can perform z-test operations. This effectively renders a primitive and indicates whether any z pixels have been rendered.
   1312 
   1313 		caps.ZCmpCaps =		D3DPCMPCAPS_ALWAYS |		// Always pass the z-test.
   1314 							D3DPCMPCAPS_EQUAL |			// Pass the z-test if the new z equals the current z.
   1315 							D3DPCMPCAPS_GREATER |		// Pass the z-test if the new z is greater than the current z.
   1316 							D3DPCMPCAPS_GREATEREQUAL |	// Pass the z-test if the new z is greater than or equal to the current z.
   1317 							D3DPCMPCAPS_LESS |			// Pass the z-test if the new z is less than the current z.
   1318 							D3DPCMPCAPS_LESSEQUAL |		// Pass the z-test if the new z is less than or equal to the current z.
   1319 							D3DPCMPCAPS_NEVER |			// Always fail the z-test.
   1320 							D3DPCMPCAPS_NOTEQUAL;		// Pass the z-test if the new z does not equal the current z.
   1321 
   1322 		caps.SrcBlendCaps =		D3DPBLENDCAPS_BLENDFACTOR |		// The driver supports both D3DBLEND_BLENDFACTOR and D3DBLEND_INVBLENDFACTOR. See D3DBLEND.
   1323 								D3DPBLENDCAPS_BOTHINVSRCALPHA |	// Source blend factor is (1-As,1-As,1-As,1-As) and destination blend factor is (As,As,As,As); the destination blend selection is overridden.
   1324 								D3DPBLENDCAPS_BOTHSRCALPHA |	// The driver supports the D3DBLEND_BOTHSRCALPHA blend mode. (This blend mode is obsolete. For more information, see D3DBLEND.)
   1325 								D3DPBLENDCAPS_DESTALPHA |		// Blend factor is (Ad, Ad, Ad, Ad).
   1326 								D3DPBLENDCAPS_DESTCOLOR |		// Blend factor is (Rd, Gd, Bd, Ad).
   1327 								D3DPBLENDCAPS_INVDESTALPHA |	// Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad).
   1328 								D3DPBLENDCAPS_INVDESTCOLOR |	// Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad).
   1329 								D3DPBLENDCAPS_INVSRCALPHA |		// Blend factor is (1-As, 1-As, 1-As, 1-As).
   1330 								D3DPBLENDCAPS_INVSRCCOLOR |		// Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As).
   1331 								D3DPBLENDCAPS_ONE |				// Blend factor is (1, 1, 1, 1).
   1332 								D3DPBLENDCAPS_SRCALPHA |		// Blend factor is (As, As, As, As).
   1333 								D3DPBLENDCAPS_SRCALPHASAT |		// Blend factor is (f, f, f, 1); f = min(As, 1-Ad).
   1334 								D3DPBLENDCAPS_SRCCOLOR |		// Blend factor is (Rs, Gs, Bs, As).
   1335 								D3DPBLENDCAPS_ZERO;				// Blend factor is (0, 0, 0, 0).
   1336 
   1337 		caps.DestBlendCaps = 	D3DPBLENDCAPS_BLENDFACTOR |		// The driver supports both D3DBLEND_BLENDFACTOR and D3DBLEND_INVBLENDFACTOR. See D3DBLEND.
   1338 								D3DPBLENDCAPS_BOTHINVSRCALPHA |	// Source blend factor is (1-As,1-As,1-As,1-As) and destination blend factor is (As,As,As,As); the destination blend selection is overridden.
   1339 								D3DPBLENDCAPS_BOTHSRCALPHA |	// The driver supports the D3DBLEND_BOTHSRCALPHA blend mode. (This blend mode is obsolete. For more information, see D3DBLEND.)
   1340 								D3DPBLENDCAPS_DESTALPHA |		// Blend factor is (Ad, Ad, Ad, Ad).
   1341 								D3DPBLENDCAPS_DESTCOLOR |		// Blend factor is (Rd, Gd, Bd, Ad).
   1342 								D3DPBLENDCAPS_INVDESTALPHA |	// Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad).
   1343 								D3DPBLENDCAPS_INVDESTCOLOR |	// Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad).
   1344 								D3DPBLENDCAPS_INVSRCALPHA |		// Blend factor is (1-As, 1-As, 1-As, 1-As).
   1345 								D3DPBLENDCAPS_INVSRCCOLOR |		// Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As).
   1346 								D3DPBLENDCAPS_ONE |				// Blend factor is (1, 1, 1, 1).
   1347 								D3DPBLENDCAPS_SRCALPHA |		// Blend factor is (As, As, As, As).
   1348 								D3DPBLENDCAPS_SRCALPHASAT |		// Blend factor is (f, f, f, 1); f = min(As, 1-Ad).
   1349 								D3DPBLENDCAPS_SRCCOLOR |		// Blend factor is (Rs, Gs, Bs, As).
   1350 								D3DPBLENDCAPS_ZERO;				// Blend factor is (0, 0, 0, 0).
   1351 
   1352 		caps.AlphaCmpCaps = D3DPCMPCAPS_ALWAYS |		// Always pass the apha-test.
   1353 							D3DPCMPCAPS_EQUAL |			// Pass the apha-test if the new apha equals the current apha.
   1354 							D3DPCMPCAPS_GREATER |		// Pass the apha-test if the new apha is greater than the current apha.
   1355 							D3DPCMPCAPS_GREATEREQUAL |	// Pass the apha-test if the new apha is greater than or equal to the current apha.
   1356 							D3DPCMPCAPS_LESS |			// Pass the apha-test if the new apha is less than the current apha.
   1357 							D3DPCMPCAPS_LESSEQUAL |		// Pass the apha-test if the new apha is less than or equal to the current apha.
   1358 							D3DPCMPCAPS_NEVER |			// Always fail the apha-test.
   1359 							D3DPCMPCAPS_NOTEQUAL;		// Pass the apha-test if the new apha does not equal the current apha.
   1360 
   1361 		caps.ShadeCaps =	D3DPSHADECAPS_ALPHAGOURAUDBLEND |	// Device can support an alpha component for Gouraud-blended transparency (the D3DSHADE_GOURAUD state for the D3DSHADEMODE enumerated type). In this mode, the alpha color component of a primitive is provided at vertices and interpolated across a face along with the other color components.
   1362 							D3DPSHADECAPS_COLORGOURAUDRGB |		// Device can support colored Gouraud shading in the RGB color model. In this mode, the color component for a primitive is provided at vertices and interpolated across a face along with the other color components. In the RGB lighting model, the red, green, and blue components are interpolated.
   1363 							D3DPSHADECAPS_FOGGOURAUD |			// Device can support fog in the Gouraud shading mode.
   1364 							D3DPSHADECAPS_SPECULARGOURAUDRGB;	// Device supports Gouraud shading of specular highlights.
   1365 
   1366 		caps.TextureCaps =		D3DPTEXTURECAPS_ALPHA |						// Alpha in texture pixels is supported.
   1367 								D3DPTEXTURECAPS_ALPHAPALETTE |				// Device can draw alpha from texture palettes.
   1368 								D3DPTEXTURECAPS_CUBEMAP |					// Supports cube textures.
   1369 							//	D3DPTEXTURECAPS_CUBEMAP_POW2 |				// Device requires that cube texture maps have dimensions specified as powers of two.
   1370 								D3DPTEXTURECAPS_MIPCUBEMAP |				// Device supports mipmapped cube textures.
   1371 								D3DPTEXTURECAPS_MIPMAP |					// Device supports mipmapped textures.
   1372 								D3DPTEXTURECAPS_MIPVOLUMEMAP |				// Device supports mipmapped volume textures.
   1373 							//	D3DPTEXTURECAPS_NONPOW2CONDITIONAL |		// Conditionally supports the use of 2-D textures with dimensions that are not powers of two. A device that exposes this capability can use such a texture if all of the following requirements are met...
   1374 							//	D3DPTEXTURECAPS_NOPROJECTEDBUMPENV |		// Device does not support a projected bump-environment loopkup operation in programmable and fixed function shaders.
   1375 								D3DPTEXTURECAPS_PERSPECTIVE |				// Perspective correction texturing is supported.
   1376 							//	D3DPTEXTURECAPS_POW2 |						// All textures must have widths and heights specified as powers of two. This requirement does not apply to either cube textures or volume textures.
   1377 								D3DPTEXTURECAPS_PROJECTED |					// Supports the D3DTTFF_PROJECTED texture transformation flag. When applied, the device divides transformed texture coordinates by the last texture coordinate. If this capability is present, then the projective divide occurs per pixel. If this capability is not present, but the projective divide needs to occur anyway, then it is performed on a per-vertex basis by the Direct3D runtime.
   1378 							//	D3DPTEXTURECAPS_SQUAREONLY |				// All textures must be square.
   1379 								D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE |	// Texture indices are not scaled by the texture size prior to interpolation.
   1380 								D3DPTEXTURECAPS_VOLUMEMAP;					// Device supports volume textures.
   1381 							//	D3DPTEXTURECAPS_VOLUMEMAP_POW2;				// Device requires that volume texture maps have dimensions specified as powers of two.
   1382 
   1383 		caps.TextureFilterCaps =		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1384 										D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1385 									//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
   1386 									//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
   1387 									//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures.
   1388 										D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1389 										D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1390 										D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
   1391 									//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures.
   1392 									//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures.
   1393 										D3DPTFILTERCAPS_MIPFPOINT |			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1394 										D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1395 
   1396 		caps.CubeTextureFilterCaps =		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1397 											D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1398 										//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
   1399 										//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
   1400 										//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures.
   1401 											D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1402 											D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1403 										//	D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
   1404 										//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures.
   1405 										//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures.
   1406 											D3DPTFILTERCAPS_MIPFPOINT |			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1407 											D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1408 
   1409 		caps.VolumeTextureFilterCaps = 		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1410 											D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1411 										//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
   1412 										//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
   1413 										//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures.
   1414 											D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1415 											D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1416 										//	D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
   1417 										//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures.
   1418 										//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures.
   1419 											D3DPTFILTERCAPS_MIPFPOINT |			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1420 											D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1421 
   1422 		caps.TextureAddressCaps =	D3DPTADDRESSCAPS_BORDER |			// Device supports setting coordinates outside the range [0.0, 1.0] to the border color, as specified by the D3DSAMP_BORDERCOLOR texture-stage state.
   1423 									D3DPTADDRESSCAPS_CLAMP |			// Device can clamp textures to addresses.
   1424 									D3DPTADDRESSCAPS_INDEPENDENTUV |	// Device can separate the texture-addressing modes of the u and v coordinates of the texture. This ability corresponds to the D3DSAMP_ADDRESSU and D3DSAMP_ADDRESSV render-state values.
   1425 									D3DPTADDRESSCAPS_MIRROR |			// Device can mirror textures to addresses.
   1426 									D3DPTADDRESSCAPS_MIRRORONCE |		// Device can take the absolute value of the texture coordinate (thus, mirroring around 0) and then clamp to the maximum value.
   1427 									D3DPTADDRESSCAPS_WRAP;				// Device can wrap textures to addresses.
   1428 
   1429 		caps.VolumeTextureAddressCaps =	D3DPTADDRESSCAPS_BORDER |			// Device supports setting coordinates outside the range [0.0, 1.0] to the border color, as specified by the D3DSAMP_BORDERCOLOR texture-stage state.
   1430 										D3DPTADDRESSCAPS_CLAMP |			// Device can clamp textures to addresses.
   1431 										D3DPTADDRESSCAPS_INDEPENDENTUV |	// Device can separate the texture-addressing modes of the u and v coordinates of the texture. This ability corresponds to the D3DSAMP_ADDRESSU and D3DSAMP_ADDRESSV render-state values.
   1432 										D3DPTADDRESSCAPS_MIRROR |			// Device can mirror textures to addresses.
   1433 										D3DPTADDRESSCAPS_MIRRORONCE |		// Device can take the absolute value of the texture coordinate (thus, mirroring around 0) and then clamp to the maximum value.
   1434 										D3DPTADDRESSCAPS_WRAP;				// Device can wrap textures to addresses.
   1435 
   1436 		caps.LineCaps =		D3DLINECAPS_ALPHACMP |	// Supports alpha-test comparisons.
   1437 						//	D3DLINECAPS_ANTIALIAS | // Antialiased lines are supported.
   1438 							D3DLINECAPS_BLEND |		// Supports source-blending.
   1439 							D3DLINECAPS_FOG |		// Supports fog.
   1440 							D3DLINECAPS_TEXTURE |	// Supports texture-mapping.
   1441 							D3DLINECAPS_ZTEST;		// Supports z-buffer comparisons.
   1442 
   1443 		caps.MaxTextureWidth = 1 << (sw::MIPMAP_LEVELS - 1);
   1444 		caps.MaxTextureHeight = 1 << (sw::MIPMAP_LEVELS - 1);
   1445 		caps.MaxVolumeExtent = 1 << (sw::MIPMAP_LEVELS - 1);
   1446 		caps.MaxTextureRepeat = 8192;
   1447 		caps.MaxTextureAspectRatio = 1 << (sw::MIPMAP_LEVELS - 1);
   1448 		caps.MaxAnisotropy = maxAnisotropy;
   1449 		caps.MaxVertexW = 1e+010;
   1450 
   1451 		caps.GuardBandLeft = -1e+008;
   1452 		caps.GuardBandTop = -1e+008;
   1453 		caps.GuardBandRight = 1e+008;
   1454 		caps.GuardBandBottom = 1e+008;
   1455 
   1456 		caps.ExtentsAdjust = 0;
   1457 
   1458 		caps.StencilCaps =		D3DSTENCILCAPS_KEEP |		// Do not update the entry in the stencil buffer. This is the default value.
   1459 								D3DSTENCILCAPS_ZERO |		// Set the stencil-buffer entry to 0.
   1460 								D3DSTENCILCAPS_REPLACE |	// Replace the stencil-buffer entry with reference value.
   1461 								D3DSTENCILCAPS_INCRSAT |	// Increment the stencil-buffer entry, clamping to the maximum value.
   1462 								D3DSTENCILCAPS_DECRSAT |	// Decrement the stencil-buffer entry, clamping to zero.
   1463 								D3DSTENCILCAPS_INVERT |		// Invert the bits in the stencil-buffer entry.
   1464 								D3DSTENCILCAPS_INCR |		// Increment the stencil-buffer entry, wrapping to zero if the new value exceeds the maximum value.
   1465 								D3DSTENCILCAPS_DECR |		// Decrement the stencil-buffer entry, wrapping to the maximum value if the new value is less than zero.
   1466 								D3DSTENCILCAPS_TWOSIDED;	// The device supports two-sided stencil.
   1467 
   1468 		caps.FVFCaps =		D3DFVFCAPS_DONOTSTRIPELEMENTS |		// It is preferable that vertex elements not be stripped. That is, if the vertex format contains elements that are not used with the current render states, there is no need to regenerate the vertices. If this capability flag is not present, stripping extraneous elements from the vertex format provides better performance.
   1469 							D3DFVFCAPS_PSIZE |					// Point size is determined by either the render state or the vertex data.
   1470 						//	D3DFVFCAPS_TEXCOORDCOUNTMASK |		// Masks the low WORD of FVFCaps. These bits, cast to the WORD data type, describe the total number of texture coordinate sets that the device can simultaneously use for multiple texture blending. (You can use up to eight texture coordinate sets for any vertex, but the device can blend using only the specified number of texture coordinate sets.)
   1471 							8;
   1472 
   1473 		caps.TextureOpCaps =	D3DTEXOPCAPS_ADD |							// The D3DTOP_ADD texture-blending operation is supported.
   1474 								D3DTEXOPCAPS_ADDSIGNED |					// The D3DTOP_ADDSIGNED texture-blending operation is supported.
   1475 								D3DTEXOPCAPS_ADDSIGNED2X |					// The D3DTOP_ADDSIGNED2X texture-blending operation is supported.
   1476 								D3DTEXOPCAPS_ADDSMOOTH |					// The D3DTOP_ADDSMOOTH texture-blending operation is supported.
   1477 								D3DTEXOPCAPS_BLENDCURRENTALPHA |			// The D3DTOP_BLENDCURRENTALPHA texture-blending operation is supported.
   1478 								D3DTEXOPCAPS_BLENDDIFFUSEALPHA |			// The D3DTOP_BLENDDIFFUSEALPHA texture-blending operation is supported.
   1479 								D3DTEXOPCAPS_BLENDFACTORALPHA |				// The D3DTOP_BLENDFACTORALPHA texture-blending operation is supported.
   1480 								D3DTEXOPCAPS_BLENDTEXTUREALPHA |			// The D3DTOP_BLENDTEXTUREALPHA texture-blending operation is supported.
   1481 								D3DTEXOPCAPS_BLENDTEXTUREALPHAPM |			// The D3DTOP_BLENDTEXTUREALPHAPM texture-blending operation is supported.
   1482 								D3DTEXOPCAPS_BUMPENVMAP |					// The D3DTOP_BUMPENVMAP texture-blending operation is supported.
   1483 								D3DTEXOPCAPS_BUMPENVMAPLUMINANCE |			// The D3DTOP_BUMPENVMAPLUMINANCE texture-blending operation is supported.
   1484 								D3DTEXOPCAPS_DISABLE |						// The D3DTOP_DISABLE texture-blending operation is supported.
   1485 								D3DTEXOPCAPS_DOTPRODUCT3 |					// The D3DTOP_DOTPRODUCT3 texture-blending operation is supported.
   1486 								D3DTEXOPCAPS_LERP |							// The D3DTOP_LERP texture-blending operation is supported.
   1487 								D3DTEXOPCAPS_MODULATE |						// The D3DTOP_MODULATE texture-blending operation is supported.
   1488 								D3DTEXOPCAPS_MODULATE2X |					// The D3DTOP_MODULATE2X texture-blending operation is supported.
   1489 								D3DTEXOPCAPS_MODULATE4X |					// The D3DTOP_MODULATE4X texture-blending operation is supported.
   1490 								D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |		// The D3DTOP_MODULATEALPHA_ADDCOLOR texture-blending operation is supported.
   1491 								D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |		// The D3DTOP_MODULATECOLOR_ADDALPHA texture-blending operation is supported.
   1492 								D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |	// The D3DTOP_MODULATEINVALPHA_ADDCOLOR texture-blending operation is supported.
   1493 								D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA |	// The D3DTOP_MODULATEINVCOLOR_ADDALPHA texture-blending operation is supported.
   1494 								D3DTEXOPCAPS_MULTIPLYADD |					// The D3DTOP_MULTIPLYADD texture-blending operation is supported.
   1495 								D3DTEXOPCAPS_PREMODULATE |					// The D3DTOP_PREMODULATE texture-blending operation is supported.
   1496 								D3DTEXOPCAPS_SELECTARG1 |					// The D3DTOP_SELECTARG1 texture-blending operation is supported.
   1497 								D3DTEXOPCAPS_SELECTARG2 |					// The D3DTOP_SELECTARG2 texture-blending operation is supported.
   1498 								D3DTEXOPCAPS_SUBTRACT;						// The D3DTOP_SUBTRACT texture-blending operation is supported.
   1499 
   1500 		caps.MaxTextureBlendStages = 8;
   1501 		caps.MaxSimultaneousTextures = 8;
   1502 
   1503 		caps.VertexProcessingCaps =		D3DVTXPCAPS_DIRECTIONALLIGHTS |			// Device can do directional lights.
   1504 										D3DVTXPCAPS_LOCALVIEWER |				// Device can do local viewer.
   1505 										D3DVTXPCAPS_MATERIALSOURCE7	|			// Device can do Microsoft DirectX 7.0 colormaterialsource operations.
   1506 									//	D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER |	// Device does not support texture generation in non-local viewer mode.
   1507 										D3DVTXPCAPS_POSITIONALLIGHTS |			// Device can do positional lights (includes point and spot).
   1508 										D3DVTXPCAPS_TEXGEN |					// Device can do texgen.
   1509 										D3DVTXPCAPS_TEXGEN_SPHEREMAP;			// Device supports D3DTSS_TCI_SPHEREMAP.
   1510 									//	D3DVTXPCAPS_TWEENING;					// Device can do vertex tweening.
   1511 
   1512 		caps.MaxActiveLights = 8;						// Maximum number of lights that can be active simultaneously. For a given physical device, this capability might vary across Direct3DDevice objects depending on the parameters supplied to IDirect3D9::CreateDevice.
   1513 		caps.MaxUserClipPlanes = 6;						// Maximum number of user-defined clipping planes supported. This member can range from 0 through D3DMAXUSERCLIPPLANES. For a given physical device, this capability may vary across Direct3DDevice objects depending on the parameters supplied to IDirect3D9::CreateDevice.
   1514 		caps.MaxVertexBlendMatrices = 4;				// Maximum number of matrices that this device can apply when performing multimatrix vertex blending. For a given physical device, this capability may vary across Direct3DDevice objects depending on the parameters supplied to IDirect3D9::CreateDevice.
   1515 		caps.MaxVertexBlendMatrixIndex = 11;			// DWORD value that specifies the maximum matrix index that can be indexed into using the per-vertex indices. The number of matrices is MaxVertexBlendMatrixIndex + 1, which is the size of the matrix palette. If normals are present in the vertex data that needs to be blended for lighting, then the number of matrices is half the number specified by this capability flag. If MaxVertexBlendMatrixIndex is set to zero, the driver does not support indexed vertex blending. If this value is not zero then the valid range of indices is zero through MaxVertexBlendMatrixIndex.
   1516 		caps.MaxPointSize = 8192.0f;					// Maximum size of a point primitive. If set to 1.0f then device does not support point size control. The range is greater than or equal to 1.0f.
   1517 		caps.MaxPrimitiveCount = 1 << 21;				// Maximum number of primitives for each IDirect3DDevice9::DrawPrimitive call. Note that when Direct3D is working with a DirectX 6.0 or DirectX 7.0 driver, this field is set to 0xFFFF. This means that not only the number of primitives but also the number of vertices is limited by this value.
   1518 		caps.MaxVertexIndex = 1 << 24;					// Maximum size of indices supported for hardware vertex processing. It is possible to create 32-bit index buffers by specifying D3DFMT_INDEX32; however, you will not be able to render with the index buffer unless this value is greater than 0x0000FFFF.
   1519 		caps.MaxStreams = 16;							// Maximum number of concurrent data streams for IDirect3DDevice9::SetStreamSource. The valid range is 1 to 16. Note that if this value is 0, then the driver is not a DirectX 9.0 driver.
   1520 		caps.MaxStreamStride = 65536;					// Maximum stride for IDirect3DDevice9::SetStreamSource.
   1521 		caps.VertexShaderVersion = vertexShaderVersion;	// Two numbers that represent the vertex shader main and sub versions. For more information about the instructions supported for each vertex shader version, see Version 1_x, Version 2_0, Version 2_0 Extended, or Version 3_0.
   1522 		caps.MaxVertexShaderConst = 256;				// The number of vertex shader Registers that are reserved for constants.
   1523 		caps.PixelShaderVersion = pixelShaderVersion;	// Two numbers that represent the pixel shader main and sub versions. For more information about the instructions supported for each pixel shader version, see Version 1_x, Version 2_0, Version 2_0 Extended, or Version 3_0.
   1524 		caps.PixelShader1xMaxValue = 8.0;				// Maximum value of pixel shader arithmetic component. This value indicates the internal range of values supported for pixel color blending operations. Within the range that they report to, implementations must allow data to pass through pixel processing unmodified (unclamped). Normally, the value of this member is an absolute value. For example, a 1.0 indicates that the range is -1.0 to 1, and an 8.0 indicates that the range is -8.0 to 8.0. The value must be >= 1.0 for any hardware that supports pixel shaders.
   1525 
   1526 		caps.DevCaps2 = //	D3DDEVCAPS2_ADAPTIVETESSRTPATCH |				// Device supports adaptive tessellation of RT-patches
   1527 						//	D3DDEVCAPS2_ADAPTIVETESSNPATCH |				// Device supports adaptive tessellation of N-patches.
   1528 							D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES |		// Device supports IDirect3DDevice9::StretchRect using a texture as the source.
   1529 						//	D3DDEVCAPS2_DMAPNPATCH |						// Device supports displacement maps for N-patches.
   1530 						//	D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH |				// Device supports presampled displacement maps for N-patches. For more information about displacement mapping, see Displacement Mapping.
   1531 							D3DDEVCAPS2_STREAMOFFSET |						// Device supports stream offsets.
   1532 							D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;	// Multiple vertex elements can share the same offset in a stream if D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET is set by the device and the vertex declaration does not have an element with D3DDECLUSAGE_POSITIONT0.
   1533 
   1534 		caps.MaxNpatchTessellationLevel = 0;	// Maximum number of N-patch subdivision levels. The driver will clamp applications to this value, if they are using presampled displacement mapping. See Tessellation and Displacement Mapping.
   1535 		caps.MasterAdapterOrdinal = 0;			// This number indicates which device is the master for this subordinate. This number is taken from the same space as the adapter values passed to the IDirect3D9 methods.
   1536 		caps.AdapterOrdinalInGroup = 0;			// This number indicates the order in which heads are referenced by the application programming interface (API). The master adapter always has AdapterOrdinalInGroup = 0. These values do not correspond to the adapter ordinals passed to the IDirect3D9 methods. They apply only to heads within a group.
   1537 		caps.NumberOfAdaptersInGroup = 1;		// Number of adapters in this adapter group (only if master). This will be 1 for conventional adapters. The value will be greater than 1 for the master adapter of a multihead card. The value will be 0 for a subordinate adapter of a multihead card. Each card can have at most one master, but may have many subordinates.
   1538 
   1539 		caps.DeclTypes =	D3DDTCAPS_UBYTE4 |		// 4-D unsigned byte.
   1540 							D3DDTCAPS_UBYTE4N |		// Normalized, 4-D unsigned byte. Each of the four bytes is normalized by dividing to 255.0.
   1541 							D3DDTCAPS_SHORT2N |		// Normalized, 2-D signed short, expanded to (first byte/32767.0, second byte/32767.0, 0, 1).
   1542 							D3DDTCAPS_SHORT4N |		// Normalized, 4-D signed short, expanded to (first byte/32767.0, second byte/32767.0, third byte/32767.0, fourth byte/32767.0).
   1543 							D3DDTCAPS_USHORT2N |	// Normalized, 2-D unsigned short, expanded to (first byte/65535.0, second byte/65535.0, 0, 1).
   1544 							D3DDTCAPS_USHORT4N |	// Normalized 4-D unsigned short, expanded to (first byte/65535.0, second byte/65535.0, third byte/65535.0, fourth byte/65535.0).
   1545 							D3DDTCAPS_UDEC3 |		// 3-D unsigned 10 10 10 format expanded to (value, value, value, 1).
   1546 							D3DDTCAPS_DEC3N |		// 3-D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1).
   1547 							D3DDTCAPS_FLOAT16_2 |	// 2-D 16-bit floating point numbers.
   1548 							D3DDTCAPS_FLOAT16_4;	// 4-D 16-bit floating point numbers.
   1549 
   1550 		caps.NumSimultaneousRTs = 4;	// Number of simultaneous render targets. This number must be at least one.
   1551 
   1552 		caps.StretchRectFilterCaps = 	D3DPTFILTERCAPS_MINFPOINT |		// Device supports point-sample filtering for minifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_POINT.
   1553 										D3DPTFILTERCAPS_MAGFPOINT |		// Device supports point-sample filtering for magnifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_POINT.
   1554 										D3DPTFILTERCAPS_MINFLINEAR |	// Device supports bilinear interpolation filtering for minifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_LINEAR.
   1555 										D3DPTFILTERCAPS_MAGFLINEAR;		// Device supports bilinear interpolation filtering for magnifying rectangles. This filter type is requested by calling IDirect3DDevice9::StretchRect using D3DTEXF_LINEAR.
   1556 
   1557 		caps.VS20Caps.Caps = vertexShaderPredication;									// Instruction predication is supported. See setp_comp.
   1558 		caps.VS20Caps.DynamicFlowControlDepth = vertexShaderDynamicFlowControlDepth;	// The maximum level of nesting of dynamic flow control instructions (break, breakc, ifc).
   1559 		caps.VS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;									// The maximum number of temporary registers supported.
   1560 		caps.VS20Caps.StaticFlowControlDepth = D3DVS20_MAX_STATICFLOWCONTROLDEPTH;		// The maximum depth of nesting of the loop/rep and call/callnz bool instructions.
   1561 
   1562 		caps.PS20Caps.Caps =	pixelShaderArbitrarySwizzle |						// Arbitrary swizzling is supported.
   1563 								pixelShaderGradientInstructions |					// Gradient instructions are supported.
   1564 								pixelShaderPredication |							// Instruction predication is supported. See setp_comp - ps.
   1565 								pixelShaderNoDependentReadLimit |					// There is no limit on the number of dependent reads per instruction.
   1566 								pixelShaderNoTexInstructionLimit;					// There is no limit on the number of tex instructions.
   1567 
   1568 		caps.PS20Caps.DynamicFlowControlDepth = pixelShaderDynamicFlowControlDepth;		// The maximum level of nesting of dynamic flow control instructions (break, breakc, ifc).
   1569 		caps.PS20Caps.NumInstructionSlots = D3DPS20_MAX_NUMINSTRUCTIONSLOTS;			// The driver will support at most this many instructions.
   1570 		caps.PS20Caps.NumTemps = D3DPS20_MAX_NUMTEMPS;									// The driver will support at most this many temporary register.
   1571 		caps.PS20Caps.StaticFlowControlDepth = pixelShaderStaticFlowControlDepth;		// The maximum depth of nesting of the loop/rep and call/callnz bool instructions.
   1572 
   1573 		caps.VertexTextureFilterCaps =		D3DPTFILTERCAPS_MAGFPOINT |			// Device supports per-stage point-sample filtering for magnifying textures. The point-sample magnification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1574 										//	D3DPTFILTERCAPS_MAGFLINEAR |		// Device supports per-stage bilinear interpolation filtering for magnifying mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1575 										//	D3DPTFILTERCAPS_MAGFANISOTROPIC |	// Device supports per-stage anisotropic filtering for magnifying textures. The anisotropic magnification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
   1576 										//	D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for magnifying textures. The pyramidal magnifying filter is represented by the D3DTEXF_PYRAMIDALQUAD member of the D3DTEXTUREFILTERTYPE enumerated type.
   1577 										//	D3DPTFILTERCAPS_MAGFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for magnifying textures.
   1578 											D3DPTFILTERCAPS_MINFPOINT |			// Device supports per-stage point-sample filtering for minifying textures. The point-sample minification filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1579 										//	D3DPTFILTERCAPS_MINFLINEAR |		// Device supports per-stage linear filtering for minifying textures. The linear minification filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1580 										//	D3DPTFILTERCAPS_MINFANISOTROPIC |	// Device supports per-stage anisotropic filtering for minifying textures. The anisotropic minification filter is represented by the D3DTEXF_ANISOTROPIC member of the D3DTEXTUREFILTERTYPE enumerated type.
   1581 										//	D3DPTFILTERCAPS_MINFPYRAMIDALQUAD |	// Device supports per-stage pyramidal sample filtering for minifying textures.
   1582 										//	D3DPTFILTERCAPS_MINFGAUSSIANQUAD |	// Device supports per-stage Gaussian quad filtering for minifying textures.
   1583 											D3DPTFILTERCAPS_MIPFPOINT;			// Device supports per-stage point-sample filtering for mipmaps. The point-sample mipmapping filter is represented by the D3DTEXF_POINT member of the D3DTEXTUREFILTERTYPE enumerated type.
   1584 										//	D3DPTFILTERCAPS_MIPFLINEAR;			// Device supports per-stage bilinear interpolation filtering for mipmaps. The bilinear interpolation mipmapping filter is represented by the D3DTEXF_LINEAR member of the D3DTEXTUREFILTERTYPE enumerated type.
   1585 
   1586 		caps.MaxVShaderInstructionsExecuted = maximumVertexShaderInstructionsExecuted;	// Maximum number of vertex shader instructions that can be run.
   1587 		caps.MaxPShaderInstructionsExecuted = maximumPixelShaderInstructionsExecuted;	// Maximum number of pixel shader instructions that can be run.
   1588 		caps.MaxVertexShader30InstructionSlots = maximumVertexShader30InstructionSlots;	// Maximum number of vertex shader instruction slots supported. The maximum value that can be set on this cap is 32768. Devices that support vs_3_0 are required to support at least 512 instruction slots.
   1589 		caps.MaxPixelShader30InstructionSlots = maximumPixelShader30InstructionSlots;	// Maximum number of pixel shader instruction slots supported. The maximum value that can be set on this cap is 32768. Devices that support ps_3_0 are required to support at least 512 instruction slots.
   1590 
   1591 		*capabilities = caps;
   1592 
   1593 		return D3D_OK;
   1594 	}
   1595 
   1596 	long Direct3D9::RegisterSoftwareDevice(void *initializeFunction)
   1597 	{
   1598 		TRACE("void *initializeFunction = 0x%0.8p", initializeFunction);
   1599 
   1600 		loadSystemD3D9();
   1601 
   1602 		if(d3d9)
   1603 		{
   1604 			return d3d9->RegisterSoftwareDevice(initializeFunction);
   1605 		}
   1606 		else
   1607 		{
   1608 			return INVALIDCALL();
   1609 		}
   1610 	}
   1611 
   1612 	void Direct3D9::loadSystemD3D9()
   1613 	{
   1614 		if(d3d9)
   1615 		{
   1616 			return;
   1617 		}
   1618 
   1619 		char d3d9Path[MAX_PATH + 16];
   1620 		GetSystemDirectory(d3d9Path, MAX_PATH);
   1621 		strcat(d3d9Path, "\\d3d9.dll");
   1622 		d3d9Lib = LoadLibrary(d3d9Path);
   1623 
   1624 		if(d3d9Lib)
   1625 		{
   1626 			typedef IDirect3D9* (__stdcall *DIRECT3DCREATE9)(unsigned int);
   1627 			DIRECT3DCREATE9 direct3DCreate9 = (DIRECT3DCREATE9)GetProcAddress(d3d9Lib, "Direct3DCreate9");
   1628 			d3d9 = direct3DCreate9(D3D_SDK_VERSION);
   1629 		}
   1630 	}
   1631 }
   1632