Home | History | Annotate | Download | only in D3D8
      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 "Direct3D8.hpp"
     16 
     17 #include "Direct3DDevice8.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 
     29 namespace D3D8
     30 {
     31 	Direct3D8::Direct3D8(int version, const HINSTANCE instance) : version(version), instance(instance)
     32 	{
     33 		displayMode = 0;
     34 		numDisplayModes = 0;
     35 
     36 		DEVMODE devmode;
     37 		devmode.dmSize = sizeof(DEVMODE);
     38 
     39 		// Count number of display modes
     40 		while(EnumDisplaySettings(0, numDisplayModes, &devmode))
     41 		{
     42 			numDisplayModes++;
     43 		}
     44 
     45 		displayMode = new DEVMODE[numDisplayModes];
     46 
     47 		// Store display modes information
     48 		for(int i = 0; i < numDisplayModes; i++)
     49 		{
     50 			displayMode[i].dmSize = sizeof(DEVMODE);
     51 			EnumDisplaySettings(0, i, &displayMode[i]);
     52 		}
     53 
     54 		d3d8Lib = 0;
     55 		d3d8 = 0;
     56 
     57 		sw::Configurator ini("SwiftShader.ini");
     58 
     59 		int ps = ini.getInteger("Capabilities", "PixelShaderVersion", 14);
     60 		int vs = ini.getInteger("Capabilities", "VertexShaderVersion", 11);
     61 
     62 		     if(ps ==  0) pixelShaderVersion = D3DPS_VERSION(0, 0);
     63 		else if(ps <= 11) pixelShaderVersion = D3DPS_VERSION(1, 1);
     64 		else if(ps <= 12) pixelShaderVersion = D3DPS_VERSION(1, 2);
     65 		else if(ps <= 13) pixelShaderVersion = D3DPS_VERSION(1, 3);
     66 		else              pixelShaderVersion = D3DPS_VERSION(1, 4);
     67 
     68 		     if(vs ==  0) vertexShaderVersion = D3DVS_VERSION(0, 0);
     69 		else              vertexShaderVersion = D3DVS_VERSION(1, 1);
     70 
     71 		textureMemory = 1024 * 1024 * ini.getInteger("Capabilities", "TextureMemory", 256);
     72 	}
     73 
     74 	Direct3D8::~Direct3D8()
     75 	{
     76 		delete[] displayMode;
     77 		displayMode = 0;
     78 
     79 		if(d3d8)
     80 		{
     81 			d3d8->Release();
     82 			d3d8 = 0;
     83 		}
     84 
     85 		if(d3d8Lib)
     86 		{
     87 			FreeLibrary(d3d8Lib);
     88 			d3d8Lib = 0;
     89 		}
     90 	}
     91 
     92 	long Direct3D8::QueryInterface(const IID &iid, void **object)
     93 	{
     94 		TRACE("");
     95 
     96 		if(iid == IID_IDirect3D8 ||
     97 		   iid == IID_IUnknown)
     98 		{
     99 			AddRef();
    100 			*object = this;
    101 
    102 			return S_OK;
    103 		}
    104 
    105 		*object = 0;
    106 
    107 		return NOINTERFACE(iid);
    108 	}
    109 
    110 	unsigned long Direct3D8::AddRef()
    111 	{
    112 		TRACE("");
    113 
    114 		return Unknown::AddRef();
    115 	}
    116 
    117 	unsigned long Direct3D8::Release()
    118 	{
    119 		TRACE("");
    120 
    121 		return Unknown::Release();
    122 	}
    123 
    124 	long Direct3D8::CheckDepthStencilMatch(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat)
    125 	{
    126 		TRACE("");
    127 
    128 		if(deviceType != D3DDEVTYPE_HAL)
    129 		{
    130 			loadSystemD3D8();
    131 
    132 			if(d3d8)
    133 			{
    134 				return d3d8->CheckDepthStencilMatch(adapter, deviceType, adapterFormat, renderTargetFormat, depthStencilFormat);
    135 			}
    136 			else
    137 			{
    138 				return CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, adapterFormat, renderTargetFormat, depthStencilFormat);
    139 			}
    140 		}
    141 
    142 		return D3D_OK;   // Any format combination is ok
    143 	}
    144 
    145 	long Direct3D8::CheckDeviceFormat(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT adapterFormat, unsigned long usage, D3DRESOURCETYPE resourceType, D3DFORMAT checkFormat)
    146 	{
    147 		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);
    148 
    149 		if(deviceType != D3DDEVTYPE_HAL)
    150 		{
    151 			loadSystemD3D8();
    152 
    153 			if(d3d8)
    154 			{
    155 				return d3d8->CheckDeviceFormat(adapter, deviceType, adapterFormat, usage, resourceType, checkFormat);
    156 			}
    157 			else
    158 			{
    159 				return CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, adapterFormat, usage, resourceType, checkFormat);
    160 			}
    161 		}
    162 
    163 		switch(resourceType)
    164 		{
    165 		case D3DRTYPE_SURFACE:
    166 			if(usage & D3DUSAGE_RENDERTARGET)
    167 			{
    168 				switch(checkFormat)
    169 				{
    170 				case D3DFMT_R8G8B8:			if(!Capabilities::Surface::RenderTarget::R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    171 				case D3DFMT_R5G6B5:			if(!Capabilities::Surface::RenderTarget::R5G6B5)		return NOTAVAILABLE();	else return D3D_OK;
    172 				case D3DFMT_X1R5G5B5:		if(!Capabilities::Surface::RenderTarget::X1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    173 				case D3DFMT_A1R5G5B5:		if(!Capabilities::Surface::RenderTarget::A1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    174 				case D3DFMT_A4R4G4B4:		if(!Capabilities::Surface::RenderTarget::A4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    175 				case D3DFMT_R3G3B2:			if(!Capabilities::Surface::RenderTarget::R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    176 				case D3DFMT_A8R3G3B2:		if(!Capabilities::Surface::RenderTarget::A8R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    177 				case D3DFMT_X4R4G4B4:		if(!Capabilities::Surface::RenderTarget::X4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    178 				case D3DFMT_A8R8G8B8:		if(!Capabilities::Surface::RenderTarget::A8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    179 				case D3DFMT_X8R8G8B8:		if(!Capabilities::Surface::RenderTarget::X8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    180 				// Integer HDR formats
    181 				case D3DFMT_G16R16:			if(!Capabilities::Surface::RenderTarget::G16R16)		return NOTAVAILABLE();	else return D3D_OK;
    182 				case D3DFMT_A2B10G10R10:	if(!Capabilities::Surface::RenderTarget::A2B10G10R10)	return NOTAVAILABLE();	else return D3D_OK;
    183 				default:
    184 					return NOTAVAILABLE();
    185 				}
    186 			}
    187 			else if(usage & D3DUSAGE_DEPTHSTENCIL)
    188 			{
    189 				switch(checkFormat)
    190 				{
    191 				case D3DFMT_D32:			if(!Capabilities::Surface::DepthStencil::D32)			return NOTAVAILABLE();	else return D3D_OK;
    192 				case D3DFMT_D24S8:			if(!Capabilities::Surface::DepthStencil::D24S8)			return NOTAVAILABLE();	else return D3D_OK;
    193 				case D3DFMT_D24X8:			if(!Capabilities::Surface::DepthStencil::D24X8)			return NOTAVAILABLE();	else return D3D_OK;
    194 				case D3DFMT_D16:			if(!Capabilities::Surface::DepthStencil::D16)			return NOTAVAILABLE();	else return D3D_OK;
    195 				default:
    196 					return NOTAVAILABLE();
    197 				}
    198 			}
    199 			else
    200 			{
    201 				switch(checkFormat)
    202 				{
    203 				case D3DFMT_A8:				if(!Capabilities::Surface::A8)							return NOTAVAILABLE();	else return D3D_OK;
    204 				case D3DFMT_R5G6B5:			if(!Capabilities::Surface::R5G6B5)						return NOTAVAILABLE();	else return D3D_OK;
    205 				case D3DFMT_X1R5G5B5:		if(!Capabilities::Surface::X1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    206 				case D3DFMT_A1R5G5B5:		if(!Capabilities::Surface::A1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    207 				case D3DFMT_A4R4G4B4:		if(!Capabilities::Surface::A4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    208 				case D3DFMT_R3G3B2:			if(!Capabilities::Surface::R3G3B2)						return NOTAVAILABLE();	else return D3D_OK;
    209 				case D3DFMT_A8R3G3B2:		if(!Capabilities::Surface::A8R3G3B2)					return NOTAVAILABLE();	else return D3D_OK;
    210 				case D3DFMT_X4R4G4B4:		if(!Capabilities::Surface::X4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    211 				case D3DFMT_R8G8B8:			if(!Capabilities::Surface::R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    212 				case D3DFMT_X8R8G8B8:		if(!Capabilities::Surface::X8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    213 				case D3DFMT_A8R8G8B8:		if(!Capabilities::Surface::A8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    214 				// Paletted formats
    215 				case D3DFMT_P8:				if(!Capabilities::Surface::P8)							return NOTAVAILABLE();	else return D3D_OK;
    216 				case D3DFMT_A8P8:			if(!Capabilities::Surface::A8P8)						return NOTAVAILABLE();	else return D3D_OK;
    217 				// Integer HDR formats
    218 				case D3DFMT_G16R16:			if(!Capabilities::Surface::G16R16)						return NOTAVAILABLE();	else return D3D_OK;
    219 				case D3DFMT_A2B10G10R10:	if(!Capabilities::Surface::A2B10G10R10)					return NOTAVAILABLE();	else return D3D_OK;
    220 				// Compressed formats
    221 				case D3DFMT_DXT1:			if(!Capabilities::Surface::DXT1)						return NOTAVAILABLE();	else return D3D_OK;
    222 				case D3DFMT_DXT2:			if(!Capabilities::Surface::DXT2)						return NOTAVAILABLE();	else return D3D_OK;
    223 				case D3DFMT_DXT3:			if(!Capabilities::Surface::DXT3)						return NOTAVAILABLE();	else return D3D_OK;
    224 				case D3DFMT_DXT4:			if(!Capabilities::Surface::DXT4)						return NOTAVAILABLE();	else return D3D_OK;
    225 				case D3DFMT_DXT5:			if(!Capabilities::Surface::DXT5)						return NOTAVAILABLE();	else return D3D_OK;
    226 				// Bump map formats
    227 				case D3DFMT_V8U8:			if(!Capabilities::Surface::V8U8)						return NOTAVAILABLE();	else return D3D_OK;
    228 				case D3DFMT_L6V5U5:			if(!Capabilities::Surface::L6V5U5)						return NOTAVAILABLE();	else return D3D_OK;
    229 				case D3DFMT_X8L8V8U8:		if(!Capabilities::Surface::X8L8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    230 				case D3DFMT_Q8W8V8U8:		if(!Capabilities::Surface::Q8W8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    231 				case D3DFMT_V16U16:			if(!Capabilities::Surface::V16U16)						return NOTAVAILABLE();	else return D3D_OK;
    232 				case D3DFMT_A2W10V10U10:	if(!Capabilities::Surface::A2W10V10U10)					return NOTAVAILABLE();	else return D3D_OK;
    233 				// Luminance formats
    234 				case D3DFMT_L8:				if(!Capabilities::Surface::L8)							return NOTAVAILABLE();	else return D3D_OK;
    235 				case D3DFMT_A4L4:			if(!Capabilities::Surface::A4L4)						return NOTAVAILABLE();	else return D3D_OK;
    236 				case D3DFMT_A8L8:			if(!Capabilities::Surface::A8L8)						return NOTAVAILABLE();	else return D3D_OK;
    237 				default:
    238 					return NOTAVAILABLE();
    239 				}
    240 			}
    241 		case D3DRTYPE_VOLUME:
    242 			switch(checkFormat)
    243 			{
    244 			case D3DFMT_A8:					if(!Capabilities::Volume::A8)							return NOTAVAILABLE();	else return D3D_OK;
    245 			case D3DFMT_R5G6B5:				if(!Capabilities::Volume::R5G6B5)						return NOTAVAILABLE();	else return D3D_OK;
    246 			case D3DFMT_X1R5G5B5:			if(!Capabilities::Volume::X1R5G5B5)						return NOTAVAILABLE();	else return D3D_OK;
    247 			case D3DFMT_A1R5G5B5:			if(!Capabilities::Volume::A1R5G5B5)						return NOTAVAILABLE();	else return D3D_OK;
    248 			case D3DFMT_A4R4G4B4:			if(!Capabilities::Volume::A4R4G4B4)						return NOTAVAILABLE();	else return D3D_OK;
    249 			case D3DFMT_R3G3B2:				if(!Capabilities::Volume::R3G3B2)						return NOTAVAILABLE();	else return D3D_OK;
    250 			case D3DFMT_A8R3G3B2:			if(!Capabilities::Volume::A8R3G3B2)						return NOTAVAILABLE();	else return D3D_OK;
    251 			case D3DFMT_X4R4G4B4:			if(!Capabilities::Volume::X4R4G4B4)						return NOTAVAILABLE();	else return D3D_OK;
    252 			case D3DFMT_R8G8B8:				if(!Capabilities::Volume::R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    253 			case D3DFMT_X8R8G8B8:			if(!Capabilities::Volume::X8R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    254 			case D3DFMT_A8R8G8B8:			if(!Capabilities::Volume::A8R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    255 			// Paletted formats
    256 			case D3DFMT_P8:					if(!Capabilities::Volume::P8)							return NOTAVAILABLE();	else return D3D_OK;
    257 			case D3DFMT_A8P8:				if(!Capabilities::Volume::A8P8)							return NOTAVAILABLE();	else return D3D_OK;
    258 			// Integer HDR formats
    259 			case D3DFMT_G16R16:				if(!Capabilities::Volume::G16R16)						return NOTAVAILABLE();	else return D3D_OK;
    260 			case D3DFMT_A2B10G10R10:		if(!Capabilities::Volume::A2B10G10R10)					return NOTAVAILABLE();	else return D3D_OK;
    261 			// Compressed formats
    262 			case D3DFMT_DXT1:				if(!Capabilities::Volume::DXT1)							return NOTAVAILABLE();	else return D3D_OK;
    263 			case D3DFMT_DXT2:				if(!Capabilities::Volume::DXT2)							return NOTAVAILABLE();	else return D3D_OK;
    264 			case D3DFMT_DXT3:				if(!Capabilities::Volume::DXT3)							return NOTAVAILABLE();	else return D3D_OK;
    265 			case D3DFMT_DXT4:				if(!Capabilities::Volume::DXT4)							return NOTAVAILABLE();	else return D3D_OK;
    266 			case D3DFMT_DXT5:				if(!Capabilities::Volume::DXT5)							return NOTAVAILABLE();	else return D3D_OK;
    267 			// Bump map formats
    268 			case D3DFMT_V8U8:				if(!Capabilities::Volume::V8U8)							return NOTAVAILABLE();	else return D3D_OK;
    269 			case D3DFMT_L6V5U5:				if(!Capabilities::Volume::L6V5U5)						return NOTAVAILABLE();	else return D3D_OK;
    270 			case D3DFMT_X8L8V8U8:			if(!Capabilities::Volume::X8L8V8U8)						return NOTAVAILABLE();	else return D3D_OK;
    271 			case D3DFMT_Q8W8V8U8:			if(!Capabilities::Volume::Q8W8V8U8)						return NOTAVAILABLE();	else return D3D_OK;
    272 			case D3DFMT_V16U16:				if(!Capabilities::Volume::V16U16)						return NOTAVAILABLE();	else return D3D_OK;
    273 			case D3DFMT_A2W10V10U10:		if(!Capabilities::Volume::A2W10V10U10)					return NOTAVAILABLE();	else return D3D_OK;
    274 			// Luminance formats
    275 			case D3DFMT_L8:					if(!Capabilities::Volume::L8)							return NOTAVAILABLE();	else return D3D_OK;
    276 			case D3DFMT_A4L4:				if(!Capabilities::Volume::A4L4)							return NOTAVAILABLE();	else return D3D_OK;
    277 			case D3DFMT_A8L8:				if(!Capabilities::Volume::A8L8)							return NOTAVAILABLE();	else return D3D_OK;
    278 			default:
    279 				return NOTAVAILABLE();
    280 			}
    281 		case D3DRTYPE_CUBETEXTURE:
    282 			if(usage & D3DUSAGE_RENDERTARGET)
    283 			{
    284 				switch(checkFormat)
    285 				{
    286 				case D3DFMT_R8G8B8:			if(!Capabilities::CubeMap::RenderTarget::R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    287 				case D3DFMT_R5G6B5:			if(!Capabilities::CubeMap::RenderTarget::R5G6B5)		return NOTAVAILABLE();	else return D3D_OK;
    288 				case D3DFMT_X1R5G5B5:		if(!Capabilities::CubeMap::RenderTarget::X1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    289 				case D3DFMT_A1R5G5B5:		if(!Capabilities::CubeMap::RenderTarget::A1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    290 				case D3DFMT_A4R4G4B4:		if(!Capabilities::CubeMap::RenderTarget::A4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    291 				case D3DFMT_R3G3B2:			if(!Capabilities::CubeMap::RenderTarget::R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    292 				case D3DFMT_A8R3G3B2:		if(!Capabilities::CubeMap::RenderTarget::A8R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    293 				case D3DFMT_X4R4G4B4:		if(!Capabilities::CubeMap::RenderTarget::X4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    294 				case D3DFMT_A8R8G8B8:		if(!Capabilities::CubeMap::RenderTarget::A8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    295 				case D3DFMT_X8R8G8B8:		if(!Capabilities::CubeMap::RenderTarget::X8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    296 				// Integer HDR formats
    297 				case D3DFMT_G16R16:			if(!Capabilities::CubeMap::RenderTarget::G16R16)		return NOTAVAILABLE();	else return D3D_OK;
    298 				case D3DFMT_A2B10G10R10:	if(!Capabilities::CubeMap::RenderTarget::A2B10G10R10)	return NOTAVAILABLE();	else return D3D_OK;
    299 				default:
    300 					return NOTAVAILABLE();
    301 				}
    302 			}
    303 			else if(usage & D3DUSAGE_DEPTHSTENCIL)
    304 			{
    305 				switch(checkFormat)
    306 				{
    307 				case D3DFMT_D32:			if(!Capabilities::CubeMap::DepthStencil::D32)			return NOTAVAILABLE();	else return D3D_OK;
    308 				case D3DFMT_D24S8:			if(!Capabilities::CubeMap::DepthStencil::D24S8)			return NOTAVAILABLE();	else return D3D_OK;
    309 				case D3DFMT_D24X8:			if(!Capabilities::CubeMap::DepthStencil::D24X8)			return NOTAVAILABLE();	else return D3D_OK;
    310 				case D3DFMT_D16:			if(!Capabilities::CubeMap::DepthStencil::D16)			return NOTAVAILABLE();	else return D3D_OK;
    311 				default:
    312 					return NOTAVAILABLE();
    313 				}
    314 			}
    315 			else
    316 			{
    317 				switch(checkFormat)
    318 				{
    319 				case D3DFMT_A8:				if(!Capabilities::CubeMap::A8)							return NOTAVAILABLE();	else return D3D_OK;
    320 				case D3DFMT_R5G6B5:			if(!Capabilities::CubeMap::R5G6B5)						return NOTAVAILABLE();	else return D3D_OK;
    321 				case D3DFMT_X1R5G5B5:		if(!Capabilities::CubeMap::X1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    322 				case D3DFMT_A1R5G5B5:		if(!Capabilities::CubeMap::A1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    323 				case D3DFMT_A4R4G4B4:		if(!Capabilities::CubeMap::A4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    324 				case D3DFMT_R3G3B2:			if(!Capabilities::CubeMap::R3G3B2)						return NOTAVAILABLE();	else return D3D_OK;
    325 				case D3DFMT_A8R3G3B2:		if(!Capabilities::CubeMap::A8R3G3B2)					return NOTAVAILABLE();	else return D3D_OK;
    326 				case D3DFMT_X4R4G4B4:		if(!Capabilities::CubeMap::X4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    327 				case D3DFMT_R8G8B8:			if(!Capabilities::CubeMap::R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    328 				case D3DFMT_X8R8G8B8:		if(!Capabilities::CubeMap::X8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    329 				case D3DFMT_A8R8G8B8:		if(!Capabilities::CubeMap::A8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    330 				// Paletted formats
    331 				case D3DFMT_P8:				if(!Capabilities::CubeMap::P8)							return NOTAVAILABLE();	else return D3D_OK;
    332 				case D3DFMT_A8P8:			if(!Capabilities::CubeMap::A8P8)						return NOTAVAILABLE();	else return D3D_OK;
    333 				// Integer HDR formats
    334 				case D3DFMT_G16R16:			if(!Capabilities::CubeMap::G16R16)						return NOTAVAILABLE();	else return D3D_OK;
    335 				case D3DFMT_A2B10G10R10:	if(!Capabilities::CubeMap::A2B10G10R10)					return NOTAVAILABLE();	else return D3D_OK;
    336 				// Compressed formats
    337 				case D3DFMT_DXT1:			if(!Capabilities::CubeMap::DXT1)						return NOTAVAILABLE();	else return D3D_OK;
    338 				case D3DFMT_DXT2:			if(!Capabilities::CubeMap::DXT2)						return NOTAVAILABLE();	else return D3D_OK;
    339 				case D3DFMT_DXT3:			if(!Capabilities::CubeMap::DXT3)						return NOTAVAILABLE();	else return D3D_OK;
    340 				case D3DFMT_DXT4:			if(!Capabilities::CubeMap::DXT4)						return NOTAVAILABLE();	else return D3D_OK;
    341 				case D3DFMT_DXT5:			if(!Capabilities::CubeMap::DXT5)						return NOTAVAILABLE();	else return D3D_OK;
    342 				// Bump map formats
    343 				case D3DFMT_V8U8:			if(!Capabilities::CubeMap::V8U8)						return NOTAVAILABLE();	else return D3D_OK;
    344 				case D3DFMT_L6V5U5:			if(!Capabilities::CubeMap::L6V5U5)						return NOTAVAILABLE();	else return D3D_OK;
    345 				case D3DFMT_X8L8V8U8:		if(!Capabilities::CubeMap::X8L8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    346 				case D3DFMT_Q8W8V8U8:		if(!Capabilities::CubeMap::Q8W8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    347 				case D3DFMT_V16U16:			if(!Capabilities::CubeMap::V16U16)						return NOTAVAILABLE();	else return D3D_OK;
    348 				case D3DFMT_A2W10V10U10:	if(!Capabilities::CubeMap::A2W10V10U10)					return NOTAVAILABLE();	else return D3D_OK;
    349 				// Luminance formats
    350 				case D3DFMT_L8:				if(!Capabilities::CubeMap::L8)							return NOTAVAILABLE();	else return D3D_OK;
    351 				case D3DFMT_A4L4:			if(!Capabilities::CubeMap::A4L4)						return NOTAVAILABLE();	else return D3D_OK;
    352 				case D3DFMT_A8L8:			if(!Capabilities::CubeMap::A8L8)						return NOTAVAILABLE();	else return D3D_OK;
    353 				default:
    354 					return NOTAVAILABLE();
    355 				}
    356 			}
    357 		case D3DRTYPE_VOLUMETEXTURE:
    358 			switch(checkFormat)
    359 			{
    360 			case D3DFMT_A8:					if(!Capabilities::VolumeTexture::A8)					return NOTAVAILABLE();	else return D3D_OK;
    361 			case D3DFMT_R5G6B5:				if(!Capabilities::VolumeTexture::R5G6B5)				return NOTAVAILABLE();	else return D3D_OK;
    362 			case D3DFMT_X1R5G5B5:			if(!Capabilities::VolumeTexture::X1R5G5B5)				return NOTAVAILABLE();	else return D3D_OK;
    363 			case D3DFMT_A1R5G5B5:			if(!Capabilities::VolumeTexture::A1R5G5B5)				return NOTAVAILABLE();	else return D3D_OK;
    364 			case D3DFMT_A4R4G4B4:			if(!Capabilities::VolumeTexture::A4R4G4B4)				return NOTAVAILABLE();	else return D3D_OK;
    365 			case D3DFMT_R3G3B2:				if(!Capabilities::VolumeTexture::R3G3B2)				return NOTAVAILABLE();	else return D3D_OK;
    366 			case D3DFMT_A8R3G3B2:			if(!Capabilities::VolumeTexture::A8R3G3B2)				return NOTAVAILABLE();	else return D3D_OK;
    367 			case D3DFMT_X4R4G4B4:			if(!Capabilities::VolumeTexture::X4R4G4B4)				return NOTAVAILABLE();	else return D3D_OK;
    368 			case D3DFMT_R8G8B8:				if(!Capabilities::VolumeTexture::R8G8B8)				return NOTAVAILABLE();	else return D3D_OK;
    369 			case D3DFMT_X8R8G8B8:			if(!Capabilities::VolumeTexture::X8R8G8B8)				return NOTAVAILABLE();	else return D3D_OK;
    370 			case D3DFMT_A8R8G8B8:			if(!Capabilities::VolumeTexture::A8R8G8B8)				return NOTAVAILABLE();	else return D3D_OK;
    371 			// Paletted formats
    372 			case D3DFMT_P8:					if(!Capabilities::VolumeTexture::P8)					return NOTAVAILABLE();	else return D3D_OK;
    373 			case D3DFMT_A8P8:				if(!Capabilities::VolumeTexture::A8P8)					return NOTAVAILABLE();	else return D3D_OK;
    374 			// Integer HDR formats
    375 			case D3DFMT_G16R16:				if(!Capabilities::VolumeTexture::G16R16)				return NOTAVAILABLE();	else return D3D_OK;
    376 			case D3DFMT_A2B10G10R10:		if(!Capabilities::VolumeTexture::A2B10G10R10)			return NOTAVAILABLE();	else return D3D_OK;
    377 			// Compressed formats
    378 			case D3DFMT_DXT1:				if(!Capabilities::VolumeTexture::DXT1)					return NOTAVAILABLE();	else return D3D_OK;
    379 			case D3DFMT_DXT2:				if(!Capabilities::VolumeTexture::DXT2)					return NOTAVAILABLE();	else return D3D_OK;
    380 			case D3DFMT_DXT3:				if(!Capabilities::VolumeTexture::DXT3)					return NOTAVAILABLE();	else return D3D_OK;
    381 			case D3DFMT_DXT4:				if(!Capabilities::VolumeTexture::DXT4)					return NOTAVAILABLE();	else return D3D_OK;
    382 			case D3DFMT_DXT5:				if(!Capabilities::VolumeTexture::DXT5)					return NOTAVAILABLE();	else return D3D_OK;
    383 			// Bump map formats
    384 			case D3DFMT_V8U8:				if(!Capabilities::VolumeTexture::V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    385 			case D3DFMT_L6V5U5:				if(!Capabilities::VolumeTexture::L6V5U5)				return NOTAVAILABLE();	else return D3D_OK;
    386 			case D3DFMT_X8L8V8U8:			if(!Capabilities::VolumeTexture::X8L8V8U8)				return NOTAVAILABLE();	else return D3D_OK;
    387 			case D3DFMT_Q8W8V8U8:			if(!Capabilities::VolumeTexture::Q8W8V8U8)				return NOTAVAILABLE();	else return D3D_OK;
    388 			case D3DFMT_V16U16:				if(!Capabilities::VolumeTexture::V16U16)				return NOTAVAILABLE();	else return D3D_OK;
    389 			case D3DFMT_A2W10V10U10:		if(!Capabilities::VolumeTexture::A2W10V10U10)			return NOTAVAILABLE();	else return D3D_OK;
    390 			// Luminance formats
    391 			case D3DFMT_L8:					if(!Capabilities::VolumeTexture::L8)					return NOTAVAILABLE();	else return D3D_OK;
    392 			case D3DFMT_A4L4:				if(!Capabilities::VolumeTexture::A4L4)					return NOTAVAILABLE();	else return D3D_OK;
    393 			case D3DFMT_A8L8:				if(!Capabilities::VolumeTexture::A8L8)					return NOTAVAILABLE();	else return D3D_OK;
    394 			default:
    395 				return NOTAVAILABLE();
    396 			}
    397 		case D3DRTYPE_TEXTURE:
    398 			if(usage & D3DUSAGE_RENDERTARGET)
    399 			{
    400 				switch(checkFormat)
    401 				{
    402 				case D3DFMT_R8G8B8:			if(!Capabilities::Texture::RenderTarget::R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    403 				case D3DFMT_R5G6B5:			if(!Capabilities::Texture::RenderTarget::R5G6B5)		return NOTAVAILABLE();	else return D3D_OK;
    404 				case D3DFMT_X1R5G5B5:		if(!Capabilities::Texture::RenderTarget::X1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    405 				case D3DFMT_A1R5G5B5:		if(!Capabilities::Texture::RenderTarget::A1R5G5B5)		return NOTAVAILABLE();	else return D3D_OK;
    406 				case D3DFMT_A4R4G4B4:		if(!Capabilities::Texture::RenderTarget::A4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    407 				case D3DFMT_R3G3B2:			if(!Capabilities::Texture::RenderTarget::R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    408 				case D3DFMT_A8R3G3B2:		if(!Capabilities::Texture::RenderTarget::A8R3G3B2)		return NOTAVAILABLE();	else return D3D_OK;
    409 				case D3DFMT_X4R4G4B4:		if(!Capabilities::Texture::RenderTarget::X4R4G4B4)		return NOTAVAILABLE();	else return D3D_OK;
    410 				case D3DFMT_A8R8G8B8:		if(!Capabilities::Texture::RenderTarget::A8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    411 				case D3DFMT_X8R8G8B8:		if(!Capabilities::Texture::RenderTarget::X8R8G8B8)		return NOTAVAILABLE();	else return D3D_OK;
    412 				// Integer HDR formats
    413 				case D3DFMT_G16R16:			if(!Capabilities::Texture::RenderTarget::G16R16)		return NOTAVAILABLE();	else return D3D_OK;
    414 				case D3DFMT_A2B10G10R10:	if(!Capabilities::Texture::RenderTarget::A2B10G10R10)	return NOTAVAILABLE();	else return D3D_OK;
    415 				default:
    416 					return NOTAVAILABLE();
    417 				}
    418 			}
    419 			else if(usage & D3DUSAGE_DEPTHSTENCIL)
    420 			{
    421 				switch(checkFormat)
    422 				{
    423 				case D3DFMT_D32:			if(!Capabilities::Texture::DepthStencil::D32)			return NOTAVAILABLE();	else return D3D_OK;
    424 				case D3DFMT_D24S8:			if(!Capabilities::Texture::DepthStencil::D24S8)			return NOTAVAILABLE();	else return D3D_OK;
    425 				case D3DFMT_D24X8:			if(!Capabilities::Texture::DepthStencil::D24X8)			return NOTAVAILABLE();	else return D3D_OK;
    426 				case D3DFMT_D16:			if(!Capabilities::Texture::DepthStencil::D16)			return NOTAVAILABLE();	else return D3D_OK;
    427 				default:
    428 					return NOTAVAILABLE();
    429 				}
    430 			}
    431 			else
    432 			{
    433 				switch(checkFormat)
    434 				{
    435 				case D3DFMT_A8:				if(!Capabilities::Texture::A8)							return NOTAVAILABLE();	else return D3D_OK;
    436 				case D3DFMT_R5G6B5:			if(!Capabilities::Texture::R5G6B5)						return NOTAVAILABLE();	else return D3D_OK;
    437 				case D3DFMT_X1R5G5B5:		if(!Capabilities::Texture::X1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    438 				case D3DFMT_A1R5G5B5:		if(!Capabilities::Texture::A1R5G5B5)					return NOTAVAILABLE();	else return D3D_OK;
    439 				case D3DFMT_A4R4G4B4:		if(!Capabilities::Texture::A4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    440 				case D3DFMT_R3G3B2:			if(!Capabilities::Texture::R3G3B2)						return NOTAVAILABLE();	else return D3D_OK;
    441 				case D3DFMT_A8R3G3B2:		if(!Capabilities::Texture::A8R3G3B2)					return NOTAVAILABLE();	else return D3D_OK;
    442 				case D3DFMT_X4R4G4B4:		if(!Capabilities::Texture::X4R4G4B4)					return NOTAVAILABLE();	else return D3D_OK;
    443 				case D3DFMT_R8G8B8:			if(!Capabilities::Texture::R8G8B8)						return NOTAVAILABLE();	else return D3D_OK;
    444 				case D3DFMT_X8R8G8B8:		if(!Capabilities::Texture::X8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    445 				case D3DFMT_A8R8G8B8:		if(!Capabilities::Texture::A8R8G8B8)					return NOTAVAILABLE();	else return D3D_OK;
    446 				// Paletted formats
    447 				case D3DFMT_P8:				if(!Capabilities::Texture::P8)							return NOTAVAILABLE();	else return D3D_OK;
    448 				case D3DFMT_A8P8:			if(!Capabilities::Texture::A8P8)						return NOTAVAILABLE();	else return D3D_OK;
    449 				// Integer HDR formats
    450 				case D3DFMT_G16R16:			if(!Capabilities::Texture::G16R16)						return NOTAVAILABLE();	else return D3D_OK;
    451 				case D3DFMT_A2B10G10R10:	if(!Capabilities::Texture::A2B10G10R10)					return NOTAVAILABLE();	else return D3D_OK;
    452 				// Compressed formats
    453 				case D3DFMT_DXT1:			if(!Capabilities::Texture::DXT1)						return NOTAVAILABLE();	else return D3D_OK;
    454 				case D3DFMT_DXT2:			if(!Capabilities::Texture::DXT2)						return NOTAVAILABLE();	else return D3D_OK;
    455 				case D3DFMT_DXT3:			if(!Capabilities::Texture::DXT3)						return NOTAVAILABLE();	else return D3D_OK;
    456 				case D3DFMT_DXT4:			if(!Capabilities::Texture::DXT4)						return NOTAVAILABLE();	else return D3D_OK;
    457 				case D3DFMT_DXT5:			if(!Capabilities::Texture::DXT5)						return NOTAVAILABLE();	else return D3D_OK;
    458 				// Bump map formats
    459 				case D3DFMT_V8U8:			if(!Capabilities::Texture::V8U8)						return NOTAVAILABLE();	else return D3D_OK;
    460 				case D3DFMT_L6V5U5:			if(!Capabilities::Texture::L6V5U5)						return NOTAVAILABLE();	else return D3D_OK;
    461 				case D3DFMT_X8L8V8U8:		if(!Capabilities::Texture::X8L8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    462 				case D3DFMT_Q8W8V8U8:		if(!Capabilities::Texture::Q8W8V8U8)					return NOTAVAILABLE();	else return D3D_OK;
    463 				case D3DFMT_V16U16:			if(!Capabilities::Texture::V16U16)						return NOTAVAILABLE();	else return D3D_OK;
    464 				case D3DFMT_A2W10V10U10:	if(!Capabilities::Texture::A2W10V10U10)					return NOTAVAILABLE();	else return D3D_OK;
    465 				// Luminance formats
    466 				case D3DFMT_L8:				if(!Capabilities::Texture::L8)							return NOTAVAILABLE();	else return D3D_OK;
    467 				case D3DFMT_A4L4:			if(!Capabilities::Texture::A4L4)						return NOTAVAILABLE();	else return D3D_OK;
    468 				case D3DFMT_A8L8:			if(!Capabilities::Texture::A8L8)						return NOTAVAILABLE();	else return D3D_OK;
    469 				default:
    470 					return NOTAVAILABLE();
    471 				}
    472 			}
    473 		case D3DRTYPE_VERTEXBUFFER:
    474 			if(checkFormat == D3DFMT_VERTEXDATA)
    475 			{
    476 				return D3D_OK;
    477 			}
    478 			else
    479 			{
    480 				return NOTAVAILABLE();
    481 			}
    482 		case D3DRTYPE_INDEXBUFFER:
    483 			switch(checkFormat)
    484 			{
    485 			case D3DFMT_INDEX16:
    486 			case D3DFMT_INDEX32:
    487 				return D3D_OK;
    488 			default:
    489 				return NOTAVAILABLE();
    490 			};
    491 		default:
    492 			return NOTAVAILABLE();
    493 		}
    494 	}
    495 
    496 	long Direct3D8::CheckDeviceMultiSampleType(unsigned int adapter, D3DDEVTYPE deviceType, D3DFORMAT surfaceFormat, int windowed, D3DMULTISAMPLE_TYPE multiSampleType)
    497 	{
    498 		TRACE("");
    499 
    500 		if(deviceType != D3DDEVTYPE_HAL)
    501 		{
    502 			loadSystemD3D8();
    503 
    504 			if(d3d8)
    505 			{
    506 				return d3d8->CheckDeviceMultiSampleType(adapter, deviceType, surfaceFormat, windowed, multiSampleType);
    507 			}
    508 			else
    509 			{
    510 				return CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, surfaceFormat, windowed, multiSampleType);
    511 			}
    512 		}
    513 
    514 		if(adapter >= GetAdapterCount())
    515 		{
    516 			return INVALIDCALL();
    517 		}
    518 
    519 		if(multiSampleType == D3DMULTISAMPLE_NONE ||
    520 		   multiSampleType == D3DMULTISAMPLE_2_SAMPLES ||
    521 		   multiSampleType == D3DMULTISAMPLE_4_SAMPLES ||
    522 		   multiSampleType == D3DMULTISAMPLE_8_SAMPLES ||
    523 		   multiSampleType == D3DMULTISAMPLE_16_SAMPLES)
    524 		{
    525 			if(surfaceFormat != D3DFMT_UNKNOWN)
    526 			{
    527 				return D3D_OK;
    528 			}
    529 		}
    530 
    531 		return NOTAVAILABLE();
    532 	}
    533 
    534 	long Direct3D8::CheckDeviceType(unsigned int adapter, D3DDEVTYPE checkType, D3DFORMAT displayFormat, D3DFORMAT backBufferFormat, int windowed)
    535 	{
    536 		TRACE("");
    537 
    538 		if(checkType != D3DDEVTYPE_HAL)
    539 		{
    540 			loadSystemD3D8();
    541 
    542 			if(d3d8)
    543 			{
    544 				return d3d8->CheckDeviceType(adapter, checkType, displayFormat, backBufferFormat, windowed);
    545 			}
    546 			else
    547 			{
    548 				return CheckDeviceType(adapter, D3DDEVTYPE_HAL, displayFormat, backBufferFormat, windowed);
    549 			}
    550 		}
    551 
    552 		return D3D_OK;   // TODO
    553 	}
    554 
    555 	long Direct3D8::CreateDevice(unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviorFlags, D3DPRESENT_PARAMETERS *presentParameters, IDirect3DDevice8 **returnedDeviceInterface)
    556 	{
    557 		TRACE("");
    558 
    559 		if(deviceType != D3DDEVTYPE_HAL)
    560 		{
    561 			loadSystemD3D8();
    562 
    563 			if(d3d8)
    564 			{
    565 				return d3d8->CreateDevice(adapter, deviceType, focusWindow, behaviorFlags, presentParameters, returnedDeviceInterface);
    566 			}
    567 			else
    568 			{
    569 				return CreateDevice(adapter, D3DDEVTYPE_HAL, focusWindow, behaviorFlags, presentParameters, returnedDeviceInterface);
    570 			}
    571 		}
    572 
    573 		if(!focusWindow || !presentParameters || !returnedDeviceInterface)
    574 		{
    575 			*returnedDeviceInterface = NULL;
    576 			return INVALIDCALL();
    577 		}
    578 
    579 		if(!sw::CPUID::supportsSSE())
    580 		{
    581 			return NOTAVAILABLE();
    582 		}
    583 
    584 		*returnedDeviceInterface = new Direct3DDevice8(instance, this, adapter, deviceType, focusWindow, behaviorFlags, presentParameters);
    585 
    586 		if(*returnedDeviceInterface)
    587 		{
    588 			(*returnedDeviceInterface)->AddRef();
    589 		}
    590 
    591 		return D3D_OK;
    592 	}
    593 
    594 	long Direct3D8::EnumAdapterModes(unsigned int adapter, unsigned int index, D3DDISPLAYMODE *mode)
    595 	{
    596 		TRACE("");
    597 
    598 		if(adapter != D3DADAPTER_DEFAULT || !mode)
    599 		{
    600 			return INVALIDCALL();
    601 		}
    602 
    603 		for(int i = 0; i < numDisplayModes; i++)
    604 		{
    605 			if(index-- == 0)
    606 			{
    607 				mode->Width = displayMode[i].dmPelsWidth;
    608 				mode->Height = displayMode[i].dmPelsHeight;
    609 				mode->RefreshRate = displayMode[i].dmDisplayFrequency;
    610 
    611 				displayMode[i].dmBitsPerPel = 32;   // FIXME
    612 
    613 				switch(displayMode[i].dmBitsPerPel)
    614 				{
    615 				case 4:
    616 					mode->Format = D3DFMT_A4L4;
    617 					break;
    618 				case 8:
    619 					mode->Format = D3DFMT_P8;
    620 					break;
    621 				case 16:
    622 					mode->Format = D3DFMT_R5G6B5;
    623 					break;
    624 				case 24:
    625 					mode->Format = D3DFMT_R8G8B8;
    626 					break;
    627 				case 32:
    628 					mode->Format = D3DFMT_X8R8G8B8;
    629 					break;
    630 				default:
    631 					ASSERT(false);
    632 				}
    633 
    634 				return D3D_OK;
    635 			}
    636 		}
    637 
    638 		return INVALIDCALL();
    639 	}
    640 
    641 	unsigned int Direct3D8::GetAdapterCount()
    642 	{
    643 		TRACE("");
    644 
    645 		return 1;   // SwiftShader does not support multiple display adapters
    646 	}
    647 
    648 	long Direct3D8::GetAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode)
    649 	{
    650 		TRACE("");
    651 
    652 		if(adapter != D3DADAPTER_DEFAULT || !mode)
    653 		{
    654 			return INVALIDCALL();
    655 		}
    656 
    657 		HDC deviceContext = GetDC(0);
    658 
    659 		mode->Width = ::GetDeviceCaps(deviceContext, HORZRES);
    660 		mode->Height = ::GetDeviceCaps(deviceContext, VERTRES);
    661 		mode->RefreshRate = ::GetDeviceCaps(deviceContext, VREFRESH);
    662 		unsigned int bpp = ::GetDeviceCaps(deviceContext, BITSPIXEL);
    663 
    664 		ReleaseDC(0, deviceContext);
    665 
    666 		bpp = 32;   // FIXME
    667 
    668 		switch(bpp)
    669 		{
    670 		case 32: mode->Format = D3DFMT_X8R8G8B8; break;
    671 		case 24: mode->Format = D3DFMT_R8G8B8; break;
    672 		case 16: mode->Format = D3DFMT_R5G6B5; break;
    673 		default:
    674 			ASSERT(false);   // Unexpected display mode color depth
    675 		}
    676 
    677 		return D3D_OK;
    678 	}
    679 
    680 	long Direct3D8::GetAdapterIdentifier(unsigned int adapter, unsigned long flags, D3DADAPTER_IDENTIFIER8 *identifier)
    681 	{
    682 		TRACE("");
    683 
    684 		if(!identifier)
    685 		{
    686 			return INVALIDCALL();
    687 		}
    688 
    689 		unsigned short product = 'sw';
    690 		unsigned short version = 3;
    691 		unsigned short subVersion = 0;
    692 		unsigned short revision = BUILD_REVISION;
    693 		GUID guid = {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
    694 
    695 		identifier->DriverVersion.HighPart = product << 16 | version;
    696 		identifier->DriverVersion.LowPart = subVersion << 16 | revision;
    697 		strcpy(identifier->Driver, "SwiftShader");
    698 		strcpy(identifier->Description, "Google SwiftShader 3D Renderer");
    699 		identifier->VendorId = 0;
    700 		identifier->DeviceId = 0;
    701 		identifier->SubSysId = 0;
    702 		identifier->Revision = 0;
    703 		identifier->DeviceIdentifier = guid;
    704 		identifier->WHQLLevel = 0;
    705 
    706 		return D3D_OK;
    707 	}
    708 
    709 	unsigned int Direct3D8::GetAdapterModeCount(unsigned int adapter)
    710 	{
    711 		TRACE("");
    712 
    713 		if(adapter != D3DADAPTER_DEFAULT)
    714 		{
    715 			return 0;
    716 		}
    717 
    718 		return numDisplayModes;
    719 	}
    720 
    721 	HMONITOR Direct3D8::GetAdapterMonitor(unsigned int adapter)
    722 	{
    723 		TRACE("");
    724 
    725 		POINT point = {0, 0};
    726 
    727 		return MonitorFromPoint(point, MONITOR_DEFAULTTOPRIMARY);   // FIXME: Ignores adapter parameter
    728 	}
    729 
    730 	long Direct3D8::GetDeviceCaps(unsigned int adapter, D3DDEVTYPE deviceType, D3DCAPS8 *capabilities)
    731 	{
    732 		TRACE("");
    733 
    734 		if(deviceType != D3DDEVTYPE_HAL)
    735 		{
    736 			loadSystemD3D8();
    737 
    738 			if(d3d8)
    739 			{
    740 				return d3d8->GetDeviceCaps(adapter, deviceType, capabilities);
    741 			}
    742 			else
    743 			{
    744 				return GetDeviceCaps(adapter, D3DDEVTYPE_HAL, capabilities);
    745 			}
    746 		}
    747 
    748 		if(!capabilities)
    749 		{
    750 			return INVALIDCALL();
    751 		}
    752 
    753 		D3DCAPS8 caps;
    754 		ZeroMemory(&caps, sizeof(D3DCAPS8));
    755 
    756 		// Device info
    757 		caps.DeviceType = D3DDEVTYPE_HAL;
    758 		caps.AdapterOrdinal = D3DADAPTER_DEFAULT;
    759 
    760 		// Caps from DX7
    761 		caps.Caps =	0;	//	D3DCAPS_READ_SCANLINE
    762 
    763 		caps.Caps2 =	//	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 IDirect3DDevice8::SetGammaRamp. Calibrating gamma ramps incurs some processing overhead and should not be used frequently.
    764 							D3DCAPS2_CANRENDERWINDOWED |	// The driver is capable of rendering in windowed mode.
    765 							D3DCAPS2_CANMANAGERESOURCE |	// The driver is capable of managing resources. On such drivers, D3DPOOL_MANAGED resources will be managed by the driver. To have Microsoft Direct3D override the driver so that Direct3D manages resources, use the D3DCREATE_DISABLE_DRIVER_MANAGEMENT flag when calling IDirect3D8::CreateDevice.
    766 							D3DCAPS2_DYNAMICTEXTURES |		// The driver supports dynamic textures.
    767 							D3DCAPS2_FULLSCREENGAMMA;		// The driver supports dynamic gamma ramp adjustment in full-screen mode.
    768 						//	D3DCAPS2_NO2DDURING3DSCENE;		// When the D3DCAPS2_NO2DDURING3DSCENE capability is set by the driver, it means that 2-D operations cannot be performed between calls to IDirect3DDevice8::BeginScene and IDirect3DDevice8::EndScene.
    769 
    770 		caps.Caps3 = D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD;   //The device will work as expected with the D3DRS_ALPHABLENDENABLE render state when a full-screen application uses D3DSWAPEFFECT_FLIP or D3DRS_SWAPEFFECT_DISCARD. D3DRS_ALPHABLENDENABLE works as expected when using D3DSWAPEFFECT_COPY and D3DSWAPEFFECT_COPYSYNC
    771 
    772 		caps.PresentationIntervals =		D3DPRESENT_INTERVAL_IMMEDIATE |
    773 											D3DPRESENT_INTERVAL_ONE;
    774 										//	D3DPRESENT_INTERVAL_TWO;
    775 										//	D3DPRESENT_INTERVAL_THREE;
    776 										//	D3DPRESENT_INTERVAL_FOUR;
    777 
    778 		// Cursor caps
    779 		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).
    780 							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).
    781 
    782 		// 3D Device caps
    783 		caps.DevCaps =		D3DDEVCAPS_CANBLTSYSTONONLOCAL |		// Device supports blits from system-memory textures to nonlocal video-memory textures.
    784 							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.
    785 							D3DDEVCAPS_DRAWPRIMITIVES2 |			// Device can support DrawPrimitives2.
    786 							D3DDEVCAPS_DRAWPRIMITIVES2EX |			// Device can support extended DrawPrimitives2; that is, this is a DirectX 7.0-compliant driver.
    787 							D3DDEVCAPS_DRAWPRIMTLVERTEX |			// Device exports an IDirect3DDevice8::DrawPrimitive-aware hardware abstraction layer (HAL).
    788 						//	D3DDEVCAPS_EXECUTESYSTEMMEMORY |		// Device can use execute buffers from system memory.
    789 						//	D3DDEVCAPS_EXECUTEVIDEOMEMORY |			// Device can use execute buffers from video memory.
    790 							D3DDEVCAPS_HWRASTERIZATION |			// Device has hardware acceleration for scene rasterization.
    791 							D3DDEVCAPS_HWTRANSFORMANDLIGHT |		// Device can support transformation and lighting in hardware.
    792 						//	D3DDEVCAPS_NPATCHES |					// Device supports N patches.
    793 							D3DDEVCAPS_PUREDEVICE |					// Device can support rasterization, transform, lighting, and shading in hardware.
    794 						//	D3DDEVCAPS_QUINTICRTPATCHES |			// Device supports quintic Bzier curves and B-splines.
    795 						//	D3DDEVCAPS_RTPATCHES |					// Device supports rectangular and triangular patches.
    796 							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.
    797 						//	D3DDEVCAPS_SEPARATETEXTUREMEMORIES |	// Device is texturing from separate memory pools.
    798 							D3DDEVCAPS_TEXTURENONLOCALVIDMEM |		// Device can retrieve textures from non-local video memory.
    799 							D3DDEVCAPS_TEXTURESYSTEMMEMORY |		// Device can retrieve textures from system memory.
    800 							D3DDEVCAPS_TEXTUREVIDEOMEMORY |			// Device can retrieve textures from device memory.
    801 							D3DDEVCAPS_TLVERTEXSYSTEMMEMORY |		// Device can use buffers from system memory for transformed and lit vertices.
    802 							D3DDEVCAPS_TLVERTEXVIDEOMEMORY;			// Device can use buffers from video memory for transformed and lit vertices.
    803 
    804 		caps.PrimitiveMiscCaps = 		D3DPMISCCAPS_BLENDOP | 					// Device supports the alpha-blending operations defined in the D3DBLENDOP enumerated type.
    805 										D3DPMISCCAPS_CLIPPLANESCALEDPOINTS |	// Device correctly clips scaled points of size greater than 1.0 to user-defined clipping planes.
    806 										D3DPMISCCAPS_CLIPTLVERTS |				// Device clips post-transformed vertex primitives.
    807 										D3DPMISCCAPS_COLORWRITEENABLE |			// Device supports per-channel writes for the render target color buffer through the D3DRS_COLORWRITEENABLE state.
    808 										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.
    809 										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.
    810 										D3DPMISCCAPS_CULLNONE |					// The driver does not perform triangle culling. This corresponds to the D3DCULL_NONE member of the D3DCULL enumerated type.
    811 									//	D3DPMISCCAPS_LINEPATTERNREP	|			// The driver can handle values other than 1 in the wRepeatFactor member of the D3DLINEPATTERN structure. (This applies only to line-drawing primitives.)
    812 										D3DPMISCCAPS_MASKZ |					// Device can enable and disable modification of the depth buffer on pixel operations.
    813 										D3DPMISCCAPS_TSSARGTEMP;				// Device supports D3DTA_TEMP for temporary register.
    814 
    815 		caps.RasterCaps =		D3DPRASTERCAPS_ANISOTROPY |				// Device supports anisotropic filtering.
    816 							//	D3DPRASTERCAPS_ANTIALIASEDGES |			// Device can antialias lines forming the convex outline of objects. For more information, see D3DRS_EDGEANTIALIAS.
    817 								D3DPRASTERCAPS_COLORPERSPECTIVE |		// Device iterates colors perspective correctly.
    818 							//	D3DPRASTERCAPS_DITHER |					// Device can dither to improve color resolution.
    819 								D3DPRASTERCAPS_ZBIAS |					// Device supports legacy depth bias. For true depth bias, see D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS.
    820 								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.
    821 								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.
    822 								D3DPRASTERCAPS_FOGVERTEX |				// Device calculates the fog value during the lighting operation and interpolates the fog value during rasterization.
    823 								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.
    824 							//	D3DPRASTERCAPS_PAT |					// The driver can perform patterned drawing lines or fills with D3DRS_LINEPATTERN for the primitive being queried.
    825 							//	D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE |	// Device provides limited multisample support through a stretch-blt implementation. When this capability is set, D3DRS_MULTISAMPLEANTIALIAS cannot be turned on and off in the middle of a scene. Multisample masking cannot be performed if this flag is set.
    826 							//	D3DPRASTERCAPS_WBUFFER |				// Device supports depth buffering using w.
    827 								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.
    828 								D3DPRASTERCAPS_ZBIAS |					// Device supports z-bias values. These are integer values assigned to polygons that allow physically coplanar polygons to appear separate. For more information, see D3DRS_ZBIAS.
    829 							//	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).
    830 								D3DPRASTERCAPS_ZFOG;					// Device supports z-based fog.
    831 							//	D3DPRASTERCAPS_ZTEST;					// Device can perform z-test operations. This effectively renders a primitive and indicates whether any z pixels have been rendered.
    832 
    833 		caps.ZCmpCaps =		D3DPCMPCAPS_ALWAYS |		// Always pass the z-test.
    834 							D3DPCMPCAPS_EQUAL |			// Pass the z-test if the new z equals the current z.
    835 							D3DPCMPCAPS_GREATER |		// Pass the z-test if the new z is greater than the current z.
    836 							D3DPCMPCAPS_GREATEREQUAL |	// Pass the z-test if the new z is greater than or equal to the current z.
    837 							D3DPCMPCAPS_LESS |			// Pass the z-test if the new z is less than the current z.
    838 							D3DPCMPCAPS_LESSEQUAL |		// Pass the z-test if the new z is less than or equal to the current z.
    839 							D3DPCMPCAPS_NEVER |			// Always fail the z-test.
    840 							D3DPCMPCAPS_NOTEQUAL;		// Pass the z-test if the new z does not equal the current z.
    841 
    842 		caps.SrcBlendCaps =		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.
    843 								D3DPBLENDCAPS_BOTHSRCALPHA |	// The driver supports the D3DBLEND_BOTHSRCALPHA blend mode. (This blend mode is obsolete. For more information, see D3DBLEND.)
    844 								D3DPBLENDCAPS_DESTALPHA |		// Blend factor is (Ad, Ad, Ad, Ad).
    845 								D3DPBLENDCAPS_DESTCOLOR |		// Blend factor is (Rd, Gd, Bd, Ad).
    846 								D3DPBLENDCAPS_INVDESTALPHA |	// Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad).
    847 								D3DPBLENDCAPS_INVDESTCOLOR |	// Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad).
    848 								D3DPBLENDCAPS_INVSRCALPHA |		// Blend factor is (1-As, 1-As, 1-As, 1-As).
    849 								D3DPBLENDCAPS_INVSRCCOLOR |		// Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As).
    850 								D3DPBLENDCAPS_ONE |				// Blend factor is (1, 1, 1, 1).
    851 								D3DPBLENDCAPS_SRCALPHA |		// Blend factor is (As, As, As, As).
    852 								D3DPBLENDCAPS_SRCALPHASAT |		// Blend factor is (f, f, f, 1); f = min(As, 1-Ad).
    853 								D3DPBLENDCAPS_SRCCOLOR |		// Blend factor is (Rs, Gs, Bs, As).
    854 								D3DPBLENDCAPS_ZERO;				// Blend factor is (0, 0, 0, 0).
    855 
    856 		caps.DestBlendCaps = 	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.
    857 								D3DPBLENDCAPS_BOTHSRCALPHA |	// The driver supports the D3DBLEND_BOTHSRCALPHA blend mode. (This blend mode is obsolete. For more information, see D3DBLEND.)
    858 								D3DPBLENDCAPS_DESTALPHA |		// Blend factor is (Ad, Ad, Ad, Ad).
    859 								D3DPBLENDCAPS_DESTCOLOR |		// Blend factor is (Rd, Gd, Bd, Ad).
    860 								D3DPBLENDCAPS_INVDESTALPHA |	// Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad).
    861 								D3DPBLENDCAPS_INVDESTCOLOR |	// Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad).
    862 								D3DPBLENDCAPS_INVSRCALPHA |		// Blend factor is (1-As, 1-As, 1-As, 1-As).
    863 								D3DPBLENDCAPS_INVSRCCOLOR |		// Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As).
    864 								D3DPBLENDCAPS_ONE |				// Blend factor is (1, 1, 1, 1).
    865 								D3DPBLENDCAPS_SRCALPHA |		// Blend factor is (As, As, As, As).
    866 								D3DPBLENDCAPS_SRCALPHASAT |		// Blend factor is (f, f, f, 1); f = min(As, 1-Ad).
    867 								D3DPBLENDCAPS_SRCCOLOR |		// Blend factor is (Rs, Gs, Bs, As).
    868 								D3DPBLENDCAPS_ZERO;				// Blend factor is (0, 0, 0, 0).
    869 
    870 		caps.AlphaCmpCaps = D3DPCMPCAPS_ALWAYS |		// Always pass the apha-test.
    871 							D3DPCMPCAPS_EQUAL |			// Pass the apha-test if the new apha equals the current apha.
    872 							D3DPCMPCAPS_GREATER |		// Pass the apha-test if the new apha is greater than the current apha.
    873 							D3DPCMPCAPS_GREATEREQUAL |	// Pass the apha-test if the new apha is greater than or equal to the current apha.
    874 							D3DPCMPCAPS_LESS |			// Pass the apha-test if the new apha is less than the current apha.
    875 							D3DPCMPCAPS_LESSEQUAL |		// Pass the apha-test if the new apha is less than or equal to the current apha.
    876 							D3DPCMPCAPS_NEVER |			// Always fail the apha-test.
    877 							D3DPCMPCAPS_NOTEQUAL;		// Pass the apha-test if the new apha does not equal the current apha.
    878 
    879 		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.
    880 							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.
    881 							D3DPSHADECAPS_FOGGOURAUD |			// Device can support fog in the Gouraud shading mode.
    882 							D3DPSHADECAPS_SPECULARGOURAUDRGB;	// Device supports Gouraud shading of specular highlights.
    883 
    884 		caps.TextureCaps =		D3DPTEXTURECAPS_ALPHA |						// Alpha in texture pixels is supported.
    885 								D3DPTEXTURECAPS_ALPHAPALETTE |				// Device can draw alpha from texture palettes.
    886 								D3DPTEXTURECAPS_CUBEMAP |					// Supports cube textures.
    887 							//	D3DPTEXTURECAPS_CUBEMAP_POW2 |				// Device requires that cube texture maps have dimensions specified as powers of two.
    888 								D3DPTEXTURECAPS_MIPCUBEMAP |				// Device supports mipmapped cube textures.
    889 								D3DPTEXTURECAPS_MIPMAP |					// Device supports mipmapped textures.
    890 								D3DPTEXTURECAPS_MIPVOLUMEMAP |				// Device supports mipmapped volume textures.
    891 							//	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...
    892 								D3DPTEXTURECAPS_PERSPECTIVE |				// Perspective correction texturing is supported.
    893 							//	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.
    894 								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.
    895 							//	D3DPTEXTURECAPS_SQUAREONLY |				// All textures must be square.
    896 								D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE |	// Texture indices are not scaled by the texture size prior to interpolation.
    897 								D3DPTEXTURECAPS_VOLUMEMAP;					// Device supports volume textures.
    898 							//	D3DPTEXTURECAPS_VOLUMEMAP_POW2;				// Device requires that volume texture maps have dimensions specified as powers of two.
    899 
    900 		caps.TextureFilterCaps =	//	D3DPTFILTERCAPS_MAGFAFLATCUBIC |	// Device supports per-stage flat cubic filtering for magnifying textures. The flat cubic magnification filter is represented by the D3DTEXF_FLATCUBIC member of the D3DTEXTUREFILTERTYPE enumerated type.
    901 									//	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.
    902 									//	D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC |	// Device supports the per-stage Gaussian cubic filtering for magnifying textures. The Gaussian cubic magnification filter is represented by the D3DTEXF_GAUSSIANCUBIC member of the D3DTEXTUREFILTERTYPE enumerated type.
    903 										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.
    904 										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.
    905 										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.
    906 										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.
    907 										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.
    908 										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.
    909 										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.
    910 
    911 		caps.CubeTextureFilterCaps =	//	D3DPTFILTERCAPS_MAGFAFLATCUBIC |	// Device supports per-stage flat cubic filtering for magnifying textures. The flat cubic magnification filter is represented by the D3DTEXF_FLATCUBIC member of the D3DTEXTUREFILTERTYPE enumerated type.
    912 										//	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.
    913 										//	D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC |	// Device supports the per-stage Gaussian cubic filtering for magnifying textures. The Gaussian cubic magnification filter is represented by the D3DTEXF_GAUSSIANCUBIC member of the D3DTEXTUREFILTERTYPE enumerated type.
    914 											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.
    915 											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.
    916 										//	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.
    917 											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.
    918 											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.
    919 											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.
    920 											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.
    921 
    922 		caps.VolumeTextureFilterCaps = 	//	D3DPTFILTERCAPS_MAGFAFLATCUBIC |	// Device supports per-stage flat cubic filtering for magnifying textures. The flat cubic magnification filter is represented by the D3DTEXF_FLATCUBIC member of the D3DTEXTUREFILTERTYPE enumerated type.
    923 										//	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.
    924 										//	D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC |	// Device supports the per-stage Gaussian cubic filtering for magnifying textures. The Gaussian cubic magnification filter is represented by the D3DTEXF_GAUSSIANCUBIC member of the D3DTEXTUREFILTERTYPE enumerated type.
    925 											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.
    926 											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.
    927 										//	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.
    928 											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.
    929 											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.
    930 											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.
    931 											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.
    932 
    933 		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.
    934 									D3DPTADDRESSCAPS_CLAMP |			// Device can clamp textures to addresses.
    935 									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.
    936 									D3DPTADDRESSCAPS_MIRROR |			// Device can mirror textures to addresses.
    937 									D3DPTADDRESSCAPS_MIRRORONCE |		// Device can take the absolute value of the texture coordinate (thus, mirroring around 0) and then clamp to the maximum value.
    938 									D3DPTADDRESSCAPS_WRAP;				// Device can wrap textures to addresses.
    939 
    940 		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.
    941 										D3DPTADDRESSCAPS_CLAMP |			// Device can clamp textures to addresses.
    942 										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.
    943 										D3DPTADDRESSCAPS_MIRROR |			// Device can mirror textures to addresses.
    944 										D3DPTADDRESSCAPS_MIRRORONCE |		// Device can take the absolute value of the texture coordinate (thus, mirroring around 0) and then clamp to the maximum value.
    945 										D3DPTADDRESSCAPS_WRAP;				// Device can wrap textures to addresses.
    946 
    947 		caps.LineCaps = D3DLINECAPS_ALPHACMP |	// Supports alpha-test comparisons.
    948 						D3DLINECAPS_BLEND |		// Supports source-blending.
    949 						D3DLINECAPS_FOG |		// Supports fog.
    950 						D3DLINECAPS_TEXTURE |	// Supports texture-mapping.
    951 						D3DLINECAPS_ZTEST;		// Supports z-buffer comparisons.
    952 
    953 		caps.MaxTextureWidth = 1 << (sw::MIPMAP_LEVELS - 1);
    954 		caps.MaxTextureHeight = 1 << (sw::MIPMAP_LEVELS - 1);
    955 		caps.MaxVolumeExtent = 1 << (sw::MIPMAP_LEVELS - 1);
    956 		caps.MaxTextureRepeat = 8192;
    957 		caps.MaxTextureAspectRatio = 1 << (sw::MIPMAP_LEVELS - 1);
    958 		caps.MaxAnisotropy = maxAnisotropy;
    959 		caps.MaxVertexW = 1e+010;
    960 
    961 		caps.GuardBandLeft = -1e+008;
    962 		caps.GuardBandTop = -1e+008;
    963 		caps.GuardBandRight = 1e+008;
    964 		caps.GuardBandBottom = 1e+008;
    965 
    966 		caps.ExtentsAdjust = 0;
    967 
    968 		caps.StencilCaps =		D3DSTENCILCAPS_KEEP |		// Do not update the entry in the stencil buffer. This is the default value.
    969 								D3DSTENCILCAPS_ZERO |		// Set the stencil-buffer entry to 0.
    970 								D3DSTENCILCAPS_REPLACE |	// Replace the stencil-buffer entry with reference value.
    971 								D3DSTENCILCAPS_INCRSAT |	// Increment the stencil-buffer entry, clamping to the maximum value.
    972 								D3DSTENCILCAPS_DECRSAT |	// Decrement the stencil-buffer entry, clamping to zero.
    973 								D3DSTENCILCAPS_INVERT |		// Invert the bits in the stencil-buffer entry.
    974 								D3DSTENCILCAPS_INCR |		// Increment the stencil-buffer entry, wrapping to zero if the new value exceeds the maximum value.
    975 								D3DSTENCILCAPS_DECR;		// Decrement the stencil-buffer entry, wrapping to the maximum value if the new value is less than zero.
    976 
    977 		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.
    978 							D3DFVFCAPS_PSIZE |					// Point size is determined by either the render state or the vertex data.
    979 						//	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.)
    980 							8;
    981 
    982 		caps.TextureOpCaps =	D3DTEXOPCAPS_ADD |							// The D3DTOP_ADD texture-blending operation is supported.
    983 								D3DTEXOPCAPS_ADDSIGNED |					// The D3DTOP_ADDSIGNED texture-blending operation is supported.
    984 								D3DTEXOPCAPS_ADDSIGNED2X |					// The D3DTOP_ADDSIGNED2X texture-blending operation is supported.
    985 								D3DTEXOPCAPS_ADDSMOOTH |					// The D3DTOP_ADDSMOOTH texture-blending operation is supported.
    986 								D3DTEXOPCAPS_BLENDCURRENTALPHA |			// The D3DTOP_BLENDCURRENTALPHA texture-blending operation is supported.
    987 								D3DTEXOPCAPS_BLENDDIFFUSEALPHA |			// The D3DTOP_BLENDDIFFUSEALPHA texture-blending operation is supported.
    988 								D3DTEXOPCAPS_BLENDFACTORALPHA |				// The D3DTOP_BLENDFACTORALPHA texture-blending operation is supported.
    989 								D3DTEXOPCAPS_BLENDTEXTUREALPHA |			// The D3DTOP_BLENDTEXTUREALPHA texture-blending operation is supported.
    990 								D3DTEXOPCAPS_BLENDTEXTUREALPHAPM |			// The D3DTOP_BLENDTEXTUREALPHAPM texture-blending operation is supported.
    991 								D3DTEXOPCAPS_BUMPENVMAP |					// The D3DTOP_BUMPENVMAP texture-blending operation is supported.
    992 								D3DTEXOPCAPS_BUMPENVMAPLUMINANCE |			// The D3DTOP_BUMPENVMAPLUMINANCE texture-blending operation is supported.
    993 								D3DTEXOPCAPS_DISABLE |						// The D3DTOP_DISABLE texture-blending operation is supported.
    994 								D3DTEXOPCAPS_DOTPRODUCT3 |					// The D3DTOP_DOTPRODUCT3 texture-blending operation is supported.
    995 								D3DTEXOPCAPS_LERP |							// The D3DTOP_LERP texture-blending operation is supported.
    996 								D3DTEXOPCAPS_MODULATE |						// The D3DTOP_MODULATE texture-blending operation is supported.
    997 								D3DTEXOPCAPS_MODULATE2X |					// The D3DTOP_MODULATE2X texture-blending operation is supported.
    998 								D3DTEXOPCAPS_MODULATE4X |					// The D3DTOP_MODULATE4X texture-blending operation is supported.
    999 								D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |		// The D3DTOP_MODULATEALPHA_ADDCOLOR texture-blending operation is supported.
   1000 								D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |		// The D3DTOP_MODULATECOLOR_ADDALPHA texture-blending operation is supported.
   1001 								D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |	// The D3DTOP_MODULATEINVALPHA_ADDCOLOR texture-blending operation is supported.
   1002 								D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA |	// The D3DTOP_MODULATEINVCOLOR_ADDALPHA texture-blending operation is supported.
   1003 								D3DTEXOPCAPS_MULTIPLYADD |					// The D3DTOP_MULTIPLYADD texture-blending operation is supported.
   1004 								D3DTEXOPCAPS_PREMODULATE |					// The D3DTOP_PREMODULATE texture-blending operation is supported.
   1005 								D3DTEXOPCAPS_SELECTARG1 |					// The D3DTOP_SELECTARG1 texture-blending operation is supported.
   1006 								D3DTEXOPCAPS_SELECTARG2 |					// The D3DTOP_SELECTARG2 texture-blending operation is supported.
   1007 								D3DTEXOPCAPS_SUBTRACT;						// The D3DTOP_SUBTRACT texture-blending operation is supported.
   1008 
   1009 		caps.MaxTextureBlendStages = 8;
   1010 		caps.MaxSimultaneousTextures = 8;
   1011 
   1012 		caps.VertexProcessingCaps =		D3DVTXPCAPS_DIRECTIONALLIGHTS |			// Device can do directional lights.
   1013 										D3DVTXPCAPS_LOCALVIEWER |				// Device can do local viewer.
   1014 										D3DVTXPCAPS_MATERIALSOURCE7	|			// Device can do Microsoft DirectX 7.0 colormaterialsource operations.
   1015 										D3DVTXPCAPS_POSITIONALLIGHTS |			// Device can do positional lights (includes point and spot).
   1016 										D3DVTXPCAPS_TEXGEN |					// Device can do texgen.
   1017 										D3DVTXPCAPS_TWEENING;					// Device can do vertex tweening.
   1018 									//	D3DVTXPCAPS_NO_VSDT_UBYTE4;				// Device does not support the D3DVSDT_UBYTE4 vertex declaration type.
   1019 
   1020 		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 IDirect3D8::CreateDevice.
   1021 		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 IDirect3D8::CreateDevice.
   1022 		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 IDirect3D8::CreateDevice.
   1023 		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.
   1024 		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.
   1025 		caps.MaxPrimitiveCount = 1 << 21;				// Maximum number of primitives for each IDirect3DDevice8::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.
   1026 		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.
   1027 		caps.MaxStreams = 16;							// Maximum number of concurrent data streams for IDirect3DDevice8::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.
   1028 		caps.MaxStreamStride = 65536;					// Maximum stride for IDirect3DDevice8::SetStreamSource.
   1029 		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.
   1030 		caps.MaxVertexShaderConst = 256;				// The number of vertex shader Registers that are reserved for constants.
   1031 		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.
   1032 		caps.MaxPixelShaderValue = 8.0;
   1033 
   1034 		*capabilities = caps;
   1035 
   1036 		return D3D_OK;
   1037 	}
   1038 
   1039 	long Direct3D8::RegisterSoftwareDevice(void *initializeFunction)
   1040 	{
   1041 		TRACE("");
   1042 
   1043 		loadSystemD3D8();
   1044 
   1045 		if(d3d8)
   1046 		{
   1047 			return d3d8->RegisterSoftwareDevice(initializeFunction);
   1048 		}
   1049 		else
   1050 		{
   1051 			return INVALIDCALL();
   1052 		}
   1053 	}
   1054 
   1055 	void Direct3D8::loadSystemD3D8()
   1056 	{
   1057 		if(d3d8)
   1058 		{
   1059 			return;
   1060 		}
   1061 
   1062 		char d3d8Path[MAX_PATH + 16];
   1063 		GetSystemDirectory(d3d8Path, MAX_PATH);
   1064 		strcat(d3d8Path, "\\d3d8.dll");
   1065 		d3d8Lib = LoadLibrary(d3d8Path);
   1066 
   1067 		if(d3d8Lib)
   1068 		{
   1069 			typedef IDirect3D8* (__stdcall *DIRECT3DCREATE8)(unsigned int);
   1070 			DIRECT3DCREATE8 direct3DCreate8 = (DIRECT3DCREATE8)GetProcAddress(d3d8Lib, "Direct3DCreate8");
   1071 			d3d8 = direct3DCreate8(D3D_SDK_VERSION);
   1072 		}
   1073 	}
   1074 }
   1075