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 "Direct3DDevice9.hpp"
     16 
     17 #include "Direct3D9.hpp"
     18 #include "Direct3DSurface9.hpp"
     19 #include "Direct3DIndexBuffer9.hpp"
     20 #include "Direct3DVertexBuffer9.hpp"
     21 #include "Direct3DTexture9.hpp"
     22 #include "Direct3DVolumeTexture9.hpp"
     23 #include "Direct3DCubeTexture9.hpp"
     24 #include "Direct3DVertexDeclaration9.hpp"
     25 #include "Direct3DSwapChain9.hpp"
     26 #include "Direct3DPixelShader9.hpp"
     27 #include "Direct3DVertexShader9.hpp"
     28 #include "Direct3DStateBlock9.hpp"
     29 #include "Direct3DQuery9.hpp"
     30 #include "Direct3DVolume9.hpp"
     31 
     32 #include "Debug.hpp"
     33 #include "Capabilities.hpp"
     34 #include "Math.hpp"
     35 #include "Renderer.hpp"
     36 #include "Config.hpp"
     37 #include "FrameBuffer.hpp"
     38 #include "Clipper.hpp"
     39 #include "Configurator.hpp"
     40 #include "Timer.hpp"
     41 #include "Resource.hpp"
     42 
     43 #include <assert.h>
     44 
     45 bool localShaderConstants = true;
     46 
     47 namespace D3D9
     48 {
     49 	inline unsigned long FtoDW(float f)
     50 	{
     51 		return (unsigned long&)f;
     52 	}
     53 
     54 	Direct3DDevice9::Direct3DDevice9(const HINSTANCE instance, Direct3D9 *d3d9, unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviourFlags, D3DPRESENT_PARAMETERS *presentParameters) : instance(instance), adapter(adapter), d3d9(d3d9), deviceType(deviceType), focusWindow(focusWindow), behaviourFlags(behaviourFlags)
     55 	{
     56 		InitializeCriticalSection(&criticalSection);
     57 
     58 		init = true;
     59 		stateRecorder = 0;
     60 
     61 		d3d9->AddRef();
     62 
     63 		context = new sw::Context();
     64 		renderer = new sw::Renderer(context, sw::Direct3D, false);
     65 
     66 		swapChain = 0;
     67 		depthStencil = 0;
     68 		autoDepthStencil = 0;
     69 		renderTarget[0] = 0;
     70 		renderTarget[1] = 0;
     71 		renderTarget[2] = 0;
     72 		renderTarget[3] = 0;
     73 
     74 		for(int i = 0; i < 16 + 4; i++)
     75 		{
     76 			texture[i] = 0;
     77 		}
     78 
     79 		cursor = 0;
     80 
     81 		Reset(presentParameters);
     82 
     83 		pixelShader = 0;
     84 		vertexShader = 0;
     85 
     86 		lightsDirty = true;
     87 		pixelShaderDirty = true;
     88 		pixelShaderConstantsBDirty = 0;
     89 		pixelShaderConstantsFDirty = 0;
     90 		pixelShaderConstantsIDirty = 0;
     91 		vertexShaderDirty = true;
     92 		vertexShaderConstantsBDirty = 0;
     93 		vertexShaderConstantsFDirty = 0;
     94 		vertexShaderConstantsIDirty = 0;
     95 
     96 		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
     97 		{
     98 			dataStream[i] = 0;
     99 			streamStride[i] = 0;
    100 			streamOffset[i] = 0;
    101 
    102 			streamSourceFreq[i] = 1;
    103 		}
    104 
    105 		indexData = 0;
    106 		vertexDeclaration = 0;
    107 
    108 		D3DMATERIAL9 material;
    109 
    110 		material.Diffuse.r = 1.0f;
    111 		material.Diffuse.g = 1.0f;
    112 		material.Diffuse.b = 1.0f;
    113 		material.Diffuse.a = 0.0f;
    114 		material.Ambient.r = 0.0f;
    115 		material.Ambient.g = 0.0f;
    116 		material.Ambient.b = 0.0f;
    117 		material.Ambient.a = 0.0f;
    118 		material.Emissive.r = 0.0f;
    119 		material.Emissive.g = 0.0f;
    120 		material.Emissive.b = 0.0f;
    121 		material.Emissive.a = 0.0f;
    122 		material.Specular.r = 0.0f;
    123 		material.Specular.g = 0.0f;
    124 		material.Specular.b = 0.0f;
    125 		material.Specular.a = 0.0f;
    126 		material.Power = 0.0f;
    127 
    128 		SetMaterial(&material);
    129 
    130 		D3DMATRIX identity = {1, 0, 0, 0,
    131 		                      0, 1, 0, 0,
    132 		                      0, 0, 1, 0,
    133 		                      0, 0, 0, 1};
    134 
    135 		SetTransform(D3DTS_VIEW, &identity);
    136 		SetTransform(D3DTS_PROJECTION, &identity);
    137 		SetTransform(D3DTS_TEXTURE0, &identity);
    138 		SetTransform(D3DTS_TEXTURE1, &identity);
    139 		SetTransform(D3DTS_TEXTURE2, &identity);
    140 		SetTransform(D3DTS_TEXTURE3, &identity);
    141 		SetTransform(D3DTS_TEXTURE4, &identity);
    142 		SetTransform(D3DTS_TEXTURE5, &identity);
    143 		SetTransform(D3DTS_TEXTURE6, &identity);
    144 		SetTransform(D3DTS_TEXTURE7, &identity);
    145 
    146 		for(int i = 0; i < 12; i++)
    147 		{
    148 			SetTransform(D3DTS_WORLDMATRIX(i), &identity);
    149 		}
    150 
    151 		for(int i = 0; i < MAX_PIXEL_SHADER_CONST; i++)
    152 		{
    153 			float zero[4] = {0, 0, 0, 0};
    154 
    155 			SetPixelShaderConstantF(i, zero, 1);
    156 		}
    157 
    158 		for(int i = 0; i < MAX_VERTEX_SHADER_CONST; i++)
    159 		{
    160 			float zero[4] = {0, 0, 0, 0};
    161 
    162 			SetVertexShaderConstantF(i, zero, 1);
    163 		}
    164 
    165 		for(int i = 0; i < 16; i++)
    166 		{
    167 			int zero[4] = {0, 0, 0, 0};
    168 
    169 			SetPixelShaderConstantI(i, zero, 1);
    170 			SetVertexShaderConstantI(i, zero, 1);
    171 			SetPixelShaderConstantB(i, &zero[0], 1);
    172 			SetVertexShaderConstantB(i, &zero[0], 1);
    173 		}
    174 
    175 		init = false;
    176 
    177 		if(!(behaviourFlags & D3DCREATE_FPU_PRESERVE))
    178 		{
    179 			configureFPU();
    180 		}
    181 
    182 		instancingEnabled = pixelShaderVersionX >= D3DPS_VERSION(3, 0);
    183 	}
    184 
    185 	Direct3DDevice9::~Direct3DDevice9()
    186 	{
    187 		delete renderer;
    188 		renderer = 0;
    189 		delete context;
    190 		context = 0;
    191 
    192 		d3d9->Release();
    193 		d3d9 = 0;
    194 
    195 		swapChain->unbind();
    196 		swapChain = 0;
    197 
    198 		if(depthStencil)
    199 		{
    200 			depthStencil->unbind();
    201 			depthStencil = 0;
    202 		}
    203 
    204 		if(autoDepthStencil)
    205 		{
    206 			autoDepthStencil->unbind();
    207 			autoDepthStencil = 0;
    208 		}
    209 
    210 		for(int index = 0; index < 4; index++)
    211 		{
    212 			if(renderTarget[index])
    213 			{
    214 				renderTarget[index]->unbind();
    215 				renderTarget[index] = 0;
    216 			}
    217 		}
    218 
    219 		if(vertexDeclaration)
    220 		{
    221 			vertexDeclaration->unbind();
    222 			vertexDeclaration = 0;
    223 		}
    224 
    225 		for(int i = 0; i < 16 + 4; i++)
    226 		{
    227 			if(texture[i])
    228 			{
    229 				texture[i]->unbind();
    230 				texture[i] = 0;
    231 			}
    232 		}
    233 
    234 		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
    235 		{
    236 			if(dataStream[i])
    237 			{
    238 				dataStream[i]->unbind();
    239 				dataStream[i] = 0;
    240 			}
    241 		}
    242 
    243 		if(indexData)
    244 		{
    245 			indexData->unbind();
    246 			indexData = 0;
    247 		}
    248 
    249 		if(pixelShader)
    250 		{
    251 			pixelShader->unbind();
    252 			pixelShader = 0;
    253 		}
    254 
    255 		if(vertexShader)
    256 		{
    257 			vertexShader->unbind();
    258 			vertexShader = 0;
    259 		}
    260 
    261 		if(stateRecorder)
    262 		{
    263 			stateRecorder->unbind();
    264 			stateRecorder = 0;
    265 		}
    266 
    267 		palette.clear();
    268 
    269 		delete cursor;
    270 
    271 		DeleteCriticalSection(&criticalSection);
    272 	}
    273 
    274 	long Direct3DDevice9::QueryInterface(const IID &iid, void **object)
    275 	{
    276 		CriticalSection cs(this);
    277 
    278 		TRACE("const IID &iid = 0x%0.8p, void **object = 0x%0.8p", iid, object);
    279 
    280 		if(iid == IID_IDirect3DDevice9 ||
    281 		   iid == IID_IUnknown)
    282 		{
    283 			AddRef();
    284 			*object = this;
    285 
    286 			return S_OK;
    287 		}
    288 
    289 		*object = 0;
    290 
    291 		return NOINTERFACE(iid);
    292 	}
    293 
    294 	unsigned long Direct3DDevice9::AddRef()
    295 	{
    296 		TRACE("void");
    297 
    298 		return Unknown::AddRef();
    299 	}
    300 
    301 	unsigned long Direct3DDevice9::Release()
    302 	{
    303 		TRACE("void");
    304 
    305 		return Unknown::Release();
    306 	}
    307 
    308 	long Direct3DDevice9::BeginScene()
    309 	{
    310 		CriticalSection cs(this);
    311 
    312 		TRACE("void");
    313 
    314 		return D3D_OK;
    315 	}
    316 
    317 	long Direct3DDevice9::BeginStateBlock()
    318 	{
    319 		CriticalSection cs(this);
    320 
    321 		TRACE("void");
    322 
    323 		if(stateRecorder)
    324 		{
    325 			return INVALIDCALL();
    326 		}
    327 
    328 		stateRecorder = new Direct3DStateBlock9(this, (D3DSTATEBLOCKTYPE)0);
    329 
    330 		if(!stateRecorder)
    331 		{
    332 			return OUTOFMEMORY();
    333 		}
    334 
    335 		stateRecorder->bind();
    336 
    337 		return D3D_OK;
    338 	}
    339 
    340 	long Direct3DDevice9::Clear(unsigned long count, const D3DRECT *rects, unsigned long flags, unsigned long color, float z, unsigned long stencil)
    341 	{
    342 		CriticalSection cs(this);
    343 
    344 		TRACE("unsigned long count = %d, const D3DRECT *rects = 0x%0.8p, unsigned long flags = 0x%0.8X, unsigned long color = 0x%0.8X, float z = %f, unsigned long stencil = %d", count, rects, flags, color, z, stencil);
    345 
    346 		if(!rects && count != 0)
    347 		{
    348 			return INVALIDCALL();
    349 		}
    350 
    351 		if(flags & (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL) && !depthStencil)
    352 		{
    353 			return INVALIDCALL();
    354 		}
    355 
    356 		if(flags & D3DCLEAR_STENCIL)   // Check for stencil component
    357 		{
    358 			D3DSURFACE_DESC description;
    359 			depthStencil->GetDesc(&description);
    360 
    361 			switch(description.Format)
    362 			{
    363 			case D3DFMT_D15S1:
    364 			case D3DFMT_D24S8:
    365 			case D3DFMT_D24X8:
    366 			case D3DFMT_D24X4S4:
    367 			case D3DFMT_D24FS8:
    368 			case D3DFMT_S8_LOCKABLE:   // FIXME: INVALIDCALL when trying to clear depth?
    369 			case D3DFMT_DF24:
    370 			case D3DFMT_DF16:
    371 			case D3DFMT_INTZ:
    372 				break;
    373 			case D3DFMT_D16_LOCKABLE:
    374 			case D3DFMT_D32:
    375 			case D3DFMT_D16:
    376 			case D3DFMT_D32F_LOCKABLE:
    377 			case D3DFMT_D32_LOCKABLE:
    378 				return INVALIDCALL();
    379 			default:
    380 				ASSERT(false);
    381 			}
    382 		}
    383 
    384 		if(!rects)
    385 		{
    386 			count = 1;
    387 
    388 			D3DRECT rect;
    389 			rect.x1 = viewport.X;
    390 			rect.x2 = viewport.X + viewport.Width;
    391 			rect.y1 = viewport.Y;
    392 			rect.y2 = viewport.Y + viewport.Height;
    393 
    394 			rects = &rect;
    395 		}
    396 
    397 		for(unsigned int i = 0; i < count; i++)
    398 		{
    399 			sw::Rect clearRect(rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
    400 
    401 			clearRect.clip(viewport.X, viewport.Y, viewport.X + viewport.Width, viewport.Y + viewport.Height);
    402 
    403 			if(scissorEnable)
    404 			{
    405 				clearRect.clip(scissorRect.left, scissorRect.top, scissorRect.right, scissorRect.bottom);
    406 			}
    407 
    408 			if(flags & D3DCLEAR_TARGET)
    409 			{
    410 				for(int index = 0; index < 4; index++)
    411 				{
    412 					if(renderTarget[index])
    413 					{
    414 						D3DSURFACE_DESC description;
    415 						renderTarget[index]->GetDesc(&description);
    416 
    417 						float rgba[4];
    418 						rgba[0] = (float)(color & 0x00FF0000) / 0x00FF0000;
    419 						rgba[1] = (float)(color & 0x0000FF00) / 0x0000FF00;
    420 						rgba[2] = (float)(color & 0x000000FF) / 0x000000FF;
    421 						rgba[3] = (float)(color & 0xFF000000) / 0xFF000000;
    422 
    423 						if(renderState[D3DRS_SRGBWRITEENABLE] != FALSE && index == 0 && Capabilities::isSRGBwritable(description.Format))
    424 						{
    425 							rgba[0] = sw::linearToSRGB(rgba[0]);
    426 							rgba[1] = sw::linearToSRGB(rgba[1]);
    427 							rgba[2] = sw::linearToSRGB(rgba[2]);
    428 						}
    429 
    430 						renderer->clear(rgba, sw::FORMAT_A32B32G32R32F, renderTarget[index], clearRect, 0xF);
    431 					}
    432 				}
    433 			}
    434 
    435 			if(flags & D3DCLEAR_ZBUFFER)
    436 			{
    437 				z = sw::clamp01(z);
    438 				depthStencil->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
    439 			}
    440 
    441 			if(flags & D3DCLEAR_STENCIL)
    442 			{
    443 				depthStencil->clearStencil(stencil, 0xFF, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
    444 			}
    445 		}
    446 
    447 		return D3D_OK;
    448 	}
    449 
    450 	long Direct3DDevice9::ColorFill(IDirect3DSurface9 *surface, const RECT *rect, D3DCOLOR color)
    451 	{
    452 		CriticalSection cs(this);
    453 
    454 		TRACE("IDirect3DSurface9 *surface = 0x%0.8p, const RECT *rect = 0x%0.8p, D3DCOLOR color = 0x%0.8X", surface, rect, color);
    455 
    456 		if(!surface)
    457 		{
    458 			return INVALIDCALL();
    459 		}
    460 
    461 		D3DSURFACE_DESC description;
    462 
    463 		surface->GetDesc(&description);
    464 
    465 		if(description.Pool != D3DPOOL_DEFAULT)
    466 		{
    467 			return INVALIDCALL();
    468 		}
    469 
    470 		if(!rect)
    471 		{
    472 			RECT lock;
    473 
    474 			lock.left = 0;
    475 			lock.top = 0;
    476 			lock.right = description.Width;
    477 			lock.bottom = description.Height;
    478 
    479 			rect = &lock;
    480 		}
    481 
    482 		static_cast<Direct3DSurface9*>(surface)->fill(color, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top);
    483 
    484 		return D3D_OK;
    485 	}
    486 
    487 	long Direct3DDevice9::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *presentParameters, IDirect3DSwapChain9 **swapChain)
    488 	{
    489 		CriticalSection cs(this);
    490 
    491 		TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, IDirect3DSwapChain9 **swapChain = 0x%0.8p", presentParameters, swapChain);
    492 
    493 		if(!swapChain)
    494 		{
    495 			return INVALIDCALL();
    496 		}
    497 
    498 		*swapChain = 0;
    499 
    500 		if(!presentParameters)
    501 		{
    502 			return INVALIDCALL();
    503 		}
    504 
    505 		if(presentParameters->BackBufferCount > 3)
    506 		{
    507 			return INVALIDCALL();   // Maximum of three back buffers
    508 		}
    509 
    510 		*swapChain = new Direct3DSwapChain9(this, presentParameters);
    511 
    512 		if(!*swapChain)
    513 		{
    514 			return OUTOFMEMORY();
    515 		}
    516 
    517 		if(GetAvailableTextureMem() == 0)
    518 		{
    519 			delete *swapChain;
    520 			*swapChain = 0;
    521 
    522 			return OUTOFVIDEOMEMORY();
    523 		}
    524 
    525 		(*swapChain)->AddRef();
    526 
    527 		return D3D_OK;
    528 	}
    529 
    530 	long Direct3DDevice9::CreateCubeTexture(unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture9 **cubeTexture, void **sharedHandle)
    531 	{
    532 		CriticalSection cs(this);
    533 
    534 		TRACE("unsigned int edgeLength = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DCubeTexture9 **cubeTexture = 0x%0.8p, void **sharedHandle = 0x%0.8p", edgeLength, levels, usage, format, pool, cubeTexture, sharedHandle);
    535 
    536 		*cubeTexture = 0;
    537 
    538 		if(edgeLength == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_CUBETEXTURE, format) != D3D_OK)
    539 		{
    540 			return INVALIDCALL();
    541 		}
    542 
    543 		*cubeTexture = new Direct3DCubeTexture9(this, edgeLength, levels, usage, format, pool);
    544 
    545 		if(!*cubeTexture)
    546 		{
    547 			return OUTOFMEMORY();
    548 		}
    549 
    550 		if(GetAvailableTextureMem() == 0)
    551 		{
    552 			delete *cubeTexture;
    553 			*cubeTexture = 0;
    554 
    555 			return OUTOFVIDEOMEMORY();
    556 		}
    557 
    558 		(*cubeTexture)->AddRef();
    559 
    560 		return D3D_OK;
    561 	}
    562 
    563 	long Direct3DDevice9::CreateDepthStencilSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int discard, IDirect3DSurface9 **surface, void **sharedHandle)
    564 	{
    565 		CriticalSection cs(this);
    566 
    567 		TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DMULTISAMPLE_TYPE multiSample = %d, unsigned long multiSampleQuality = %d, int discard = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, multiSample, multiSampleQuality, discard, surface, sharedHandle);
    568 
    569 		*surface = 0;
    570 
    571 		if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION)
    572 		{
    573 			return INVALIDCALL();
    574 		}
    575 
    576 		bool lockable = false;
    577 
    578 		switch(format)
    579 		{
    580 		case D3DFMT_D15S1:
    581 		case D3DFMT_D24S8:
    582 		case D3DFMT_D24X8:
    583 		case D3DFMT_D24X4S4:
    584 		case D3DFMT_D24FS8:
    585 		case D3DFMT_D32:
    586 		case D3DFMT_D16:
    587 		case D3DFMT_DF24:
    588 		case D3DFMT_DF16:
    589 		case D3DFMT_INTZ:
    590 			lockable = false;
    591 			break;
    592 		case D3DFMT_S8_LOCKABLE:
    593 		case D3DFMT_D16_LOCKABLE:
    594 		case D3DFMT_D32F_LOCKABLE:
    595 		case D3DFMT_D32_LOCKABLE:
    596 			lockable = true;
    597 			break;
    598 		default:
    599 			ASSERT(false);
    600 		}
    601 
    602 		*surface = new Direct3DSurface9(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, multiSampleQuality, lockable, D3DUSAGE_DEPTHSTENCIL);
    603 
    604 		if(!*surface)
    605 		{
    606 			return OUTOFMEMORY();
    607 		}
    608 
    609 		if(GetAvailableTextureMem() == 0)
    610 		{
    611 			delete *surface;
    612 			*surface = 0;
    613 
    614 			return OUTOFVIDEOMEMORY();
    615 		}
    616 
    617 		(*surface)->AddRef();
    618 
    619 		return D3D_OK;
    620 	}
    621 
    622 	long Direct3DDevice9::CreateIndexBuffer(unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **indexBuffer, void **sharedHandle)
    623 	{
    624 		CriticalSection cs(this);
    625 
    626 		TRACE("unsigned int length = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DIndexBuffer9 **indexBuffer = 0x%0.8p, void **sharedHandle = 0x%0.8p", length, usage, format, pool, indexBuffer, sharedHandle);
    627 
    628 		*indexBuffer = new Direct3DIndexBuffer9(this, length, usage, format, pool);
    629 
    630 		if(!*indexBuffer)
    631 		{
    632 			return OUTOFMEMORY();
    633 		}
    634 
    635 		if(GetAvailableTextureMem() == 0)
    636 		{
    637 			delete *indexBuffer;
    638 			*indexBuffer = 0;
    639 
    640 			return OUTOFVIDEOMEMORY();
    641 		}
    642 
    643 		(*indexBuffer)->AddRef();
    644 
    645 		return D3D_OK;
    646 	}
    647 
    648 	long Direct3DDevice9::CreateOffscreenPlainSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, void **sharedHandle)
    649 	{
    650 		CriticalSection cs(this);
    651 
    652 		TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, pool, surface, sharedHandle);
    653 
    654 		*surface = 0;
    655 
    656 		if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, format) != D3D_OK)   // FIXME: Allow all formats supported by runtime/REF
    657 		{
    658 			return INVALIDCALL();
    659 		}
    660 
    661 		if(pool == D3DPOOL_MANAGED)
    662 		{
    663 			return INVALIDCALL();
    664 		}
    665 
    666 		*surface = new Direct3DSurface9(this, this, width, height, format, pool, D3DMULTISAMPLE_NONE, 0, true, 0);
    667 
    668 		if(!*surface)
    669 		{
    670 			return OUTOFMEMORY();
    671 		}
    672 
    673 		if(GetAvailableTextureMem() == 0)
    674 		{
    675 			delete *surface;
    676 			*surface = 0;
    677 
    678 			return OUTOFVIDEOMEMORY();
    679 		}
    680 
    681 		(*surface)->AddRef();
    682 
    683 		return D3D_OK;
    684 	}
    685 
    686 	long Direct3DDevice9::CreatePixelShader(const unsigned long *function, IDirect3DPixelShader9 **shader)
    687 	{
    688 		CriticalSection cs(this);
    689 
    690 		TRACE("const unsigned long *function = 0x%0.8p, IDirect3DPixelShader9 **shader = 0x%0.8p", function, shader);
    691 
    692 		if(!shader)
    693 		{
    694 			return INVALIDCALL();
    695 		}
    696 
    697 		*shader = 0;
    698 
    699 		if(!sw::PixelShader::validate(function) || function[0] > pixelShaderVersionX)
    700 		{
    701 			return INVALIDCALL();   // Shader contains unsupported operations
    702 		}
    703 
    704 		*shader = new Direct3DPixelShader9(this, function);
    705 
    706 		if(!*shader)
    707 		{
    708 			return OUTOFMEMORY();
    709 		}
    710 
    711 		(*shader)->AddRef();
    712 
    713 		return D3D_OK;
    714 	}
    715 
    716 	long Direct3DDevice9::CreateQuery(D3DQUERYTYPE type, IDirect3DQuery9 **query)
    717 	{
    718 		CriticalSection cs(this);
    719 
    720 		TRACE("D3DQUERYTYPE type = %d, IDirect3DQuery9 **query = 0x%0.8p", type, query);
    721 
    722 		if(query == 0)   // Support checked
    723 		{
    724 			switch(type)
    725 			{
    726 			case D3DQUERYTYPE_VCACHE:				return D3D_OK;
    727 			case D3DQUERYTYPE_RESOURCEMANAGER:		return NOTAVAILABLE();
    728 			case D3DQUERYTYPE_VERTEXSTATS:			return NOTAVAILABLE();
    729 			case D3DQUERYTYPE_EVENT:				return D3D_OK;
    730 			case D3DQUERYTYPE_OCCLUSION:			return D3D_OK;
    731 			case D3DQUERYTYPE_TIMESTAMP:			return D3D_OK;
    732 			case D3DQUERYTYPE_TIMESTAMPDISJOINT:	return D3D_OK;
    733 			case D3DQUERYTYPE_TIMESTAMPFREQ:		return D3D_OK;
    734 			case D3DQUERYTYPE_PIPELINETIMINGS:		return NOTAVAILABLE();
    735 			case D3DQUERYTYPE_INTERFACETIMINGS:		return NOTAVAILABLE();
    736 			case D3DQUERYTYPE_VERTEXTIMINGS:		return NOTAVAILABLE();
    737 			case D3DQUERYTYPE_PIXELTIMINGS:			return NOTAVAILABLE();
    738 			case D3DQUERYTYPE_BANDWIDTHTIMINGS:		return NOTAVAILABLE();
    739 			case D3DQUERYTYPE_CACHEUTILIZATION:		return NOTAVAILABLE();
    740 			default:								ASSERT(false);   return NOTAVAILABLE();
    741 			}
    742 		}
    743 		else
    744 		{
    745 			switch(type)
    746 			{
    747 			case D3DQUERYTYPE_VCACHE:				break;
    748 			case D3DQUERYTYPE_RESOURCEMANAGER:		return NOTAVAILABLE();
    749 			case D3DQUERYTYPE_VERTEXSTATS:			return NOTAVAILABLE();
    750 			case D3DQUERYTYPE_EVENT:				break;
    751 			case D3DQUERYTYPE_OCCLUSION:			break;
    752 			case D3DQUERYTYPE_TIMESTAMP:			break;
    753 			case D3DQUERYTYPE_TIMESTAMPDISJOINT:	break;
    754 			case D3DQUERYTYPE_TIMESTAMPFREQ:		break;
    755 			case D3DQUERYTYPE_PIPELINETIMINGS:		return NOTAVAILABLE();
    756 			case D3DQUERYTYPE_INTERFACETIMINGS:		return NOTAVAILABLE();
    757 			case D3DQUERYTYPE_VERTEXTIMINGS:		return NOTAVAILABLE();
    758 			case D3DQUERYTYPE_PIXELTIMINGS:			return NOTAVAILABLE();
    759 			case D3DQUERYTYPE_BANDWIDTHTIMINGS:		return NOTAVAILABLE();
    760 			case D3DQUERYTYPE_CACHEUTILIZATION:		return NOTAVAILABLE();
    761 			default:								ASSERT(false);   return NOTAVAILABLE();
    762 			}
    763 
    764 			*query = new Direct3DQuery9(this, type);
    765 
    766 			if(!*query)
    767 			{
    768 				return OUTOFMEMORY();
    769 			}
    770 
    771 			(*query)->AddRef();
    772 
    773 			return D3D_OK;
    774 		}
    775 	}
    776 
    777 	long Direct3DDevice9::CreateRenderTarget(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int lockable, IDirect3DSurface9 **surface, void **sharedHandle)
    778 	{
    779 		CriticalSection cs(this);
    780 
    781 		TRACE("unsigned int width = %d, unsigned int height = %d, D3DFORMAT format = %d, D3DMULTISAMPLE_TYPE multiSample = %d, unsigned long multiSampleQuality = %d, int lockable = %d, IDirect3DSurface9 **surface = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, format, multiSample, multiSampleQuality, lockable, surface, sharedHandle);
    782 
    783 		*surface = 0;
    784 
    785 		if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION)
    786 		{
    787 			return INVALIDCALL();
    788 		}
    789 
    790 		*surface = new Direct3DSurface9(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, multiSampleQuality, lockable != FALSE, D3DUSAGE_RENDERTARGET);
    791 
    792 		if(!*surface)
    793 		{
    794 			return OUTOFMEMORY();
    795 		}
    796 
    797 		if(GetAvailableTextureMem() == 0)
    798 		{
    799 			delete *surface;
    800 			*surface = 0;
    801 
    802 			return OUTOFVIDEOMEMORY();
    803 		}
    804 
    805 		(*surface)->AddRef();
    806 
    807 		return D3D_OK;
    808 	}
    809 
    810 	long Direct3DDevice9::CreateStateBlock(D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateBlock)
    811 	{
    812 		CriticalSection cs(this);
    813 
    814 		TRACE("D3DSTATEBLOCKTYPE type = %d, IDirect3DStateBlock9 **stateBlock = 0x%0.8p", type, stateBlock);
    815 
    816 		*stateBlock = new Direct3DStateBlock9(this, type);
    817 
    818 		if(!*stateBlock)
    819 		{
    820 			return OUTOFMEMORY();
    821 		}
    822 
    823 		(*stateBlock)->AddRef();
    824 
    825 		return D3D_OK;
    826 	}
    827 
    828 	long Direct3DDevice9::CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture9 **texture, void **sharedHandle)
    829 	{
    830 		CriticalSection cs(this);
    831 
    832 		TRACE("unsigned int width = %d, unsigned int height = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DTexture9 **texture = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, levels, usage, format, pool, texture, sharedHandle);
    833 
    834 		*texture = 0;
    835 
    836 		if(width == 0 || height == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_TEXTURE, format) != D3D_OK)
    837 		{
    838 			return INVALIDCALL();
    839 		}
    840 
    841 		*texture = new Direct3DTexture9(this, width, height, levels, usage, format, pool);
    842 
    843 		if(!*texture)
    844 		{
    845 			return OUTOFMEMORY();
    846 		}
    847 
    848 		if(GetAvailableTextureMem() == 0)
    849 		{
    850 			delete *texture;
    851 			*texture = 0;
    852 
    853 			return OUTOFVIDEOMEMORY();
    854 		}
    855 
    856 		(*texture)->AddRef();
    857 
    858 		return D3D_OK;
    859 	}
    860 
    861 	long Direct3DDevice9::CreateVertexBuffer(unsigned int length, unsigned long usage, unsigned long FVF, D3DPOOL pool, IDirect3DVertexBuffer9 **vertexBuffer, void **sharedHandle)
    862 	{
    863 		CriticalSection cs(this);
    864 
    865 		TRACE("unsigned int length = %d, unsigned long usage = %d, unsigned long FVF = 0x%0.8X, D3DPOOL pool = %d, IDirect3DVertexBuffer9 **vertexBuffer = 0x%0.8p, void **sharedHandle = 0x%0.8p", length, usage, FVF, pool, vertexBuffer, sharedHandle);
    866 
    867 		*vertexBuffer = new Direct3DVertexBuffer9(this, length, usage, FVF, pool);
    868 
    869 		if(!*vertexBuffer)
    870 		{
    871 			return OUTOFMEMORY();
    872 		}
    873 
    874 		if(GetAvailableTextureMem() == 0)
    875 		{
    876 			delete *vertexBuffer;
    877 			*vertexBuffer = 0;
    878 
    879 			return OUTOFVIDEOMEMORY();
    880 		}
    881 
    882 		(*vertexBuffer)->AddRef();
    883 
    884 		return D3D_OK;
    885 	}
    886 
    887 	long Direct3DDevice9::CreateVertexDeclaration(const D3DVERTEXELEMENT9 *vertexElements, IDirect3DVertexDeclaration9 **declaration)
    888 	{
    889 		CriticalSection cs(this);
    890 
    891 		TRACE("const D3DVERTEXELEMENT9 *vertexElements = 0x%0.8p, IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", vertexElements, declaration);
    892 
    893 		if(!declaration)
    894 		{
    895 			return INVALIDCALL();
    896 		}
    897 
    898 		const D3DVERTEXELEMENT9 *element = vertexElements;
    899 
    900 		while(element->Stream != 0xFF)
    901 		{
    902 			if(element->Type > D3DDECLTYPE_UNUSED)   // FIXME: Check other fields too
    903 			{
    904 				return FAIL();
    905 			}
    906 
    907 			element++;
    908 		}
    909 
    910 		*declaration = new Direct3DVertexDeclaration9(this, vertexElements);
    911 
    912 		if(!*declaration)
    913 		{
    914 			return OUTOFMEMORY();
    915 		}
    916 
    917 		(*declaration)->AddRef();
    918 
    919 		return D3D_OK;
    920 	}
    921 
    922 	long Direct3DDevice9::CreateVertexShader(const unsigned long *function, IDirect3DVertexShader9 **shader)
    923 	{
    924 		CriticalSection cs(this);
    925 
    926 		TRACE("const unsigned long *function = 0x%0.8p, IDirect3DVertexShader9 **shader = 0x%0.8p", function, shader);
    927 
    928 		if(!shader)
    929 		{
    930 			return INVALIDCALL();
    931 		}
    932 
    933 		*shader = 0;
    934 
    935 		if(!sw::VertexShader::validate(function) || function[0] > vertexShaderVersionX)
    936 		{
    937 			return INVALIDCALL();   // Shader contains unsupported operations
    938 		}
    939 
    940 		*shader = new Direct3DVertexShader9(this, function);
    941 
    942 		if(!*shader)
    943 		{
    944 			return OUTOFMEMORY();
    945 		}
    946 
    947 		(*shader)->AddRef();
    948 
    949 		return D3D_OK;
    950 	}
    951 
    952 	long Direct3DDevice9::CreateVolumeTexture(unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DVolumeTexture9 **volumeTexture, void **sharedHandle)
    953 	{
    954 		CriticalSection cs(this);
    955 
    956 		TRACE("unsigned int width = %d, unsigned int height = %d, unsigned int depth = %d, unsigned int levels = %d, unsigned long usage = %d, D3DFORMAT format = %d, D3DPOOL pool = %d, IDirect3DVolumeTexture9 **volumeTexture = 0x%0.8p, void **sharedHandle = 0x%0.8p", width, height, depth, levels, usage, format, pool, volumeTexture, sharedHandle);
    957 
    958 		*volumeTexture = 0;
    959 
    960 		if(width == 0 || height == 0 || depth == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_VOLUMETEXTURE, format) != D3D_OK)
    961 		{
    962 			return INVALIDCALL();
    963 		}
    964 
    965 		*volumeTexture = new Direct3DVolumeTexture9(this, width, height, depth, levels, usage, format, pool);
    966 
    967 		if(!*volumeTexture)
    968 		{
    969 			return OUTOFMEMORY();
    970 		}
    971 
    972 		if(GetAvailableTextureMem() == 0)
    973 		{
    974 			delete *volumeTexture;
    975 			*volumeTexture = 0;
    976 
    977 			return OUTOFVIDEOMEMORY();
    978 		}
    979 
    980 		(*volumeTexture)->AddRef();
    981 
    982 		return D3D_OK;
    983 	}
    984 
    985 	long Direct3DDevice9::DeletePatch(unsigned int handle)
    986 	{
    987 		CriticalSection cs(this);
    988 
    989 		TRACE("unsigned int handle = %d", handle);
    990 
    991 		UNIMPLEMENTED();
    992 
    993 		return D3D_OK;
    994 	}
    995 
    996 	long Direct3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE type, int baseVertexIndex, unsigned int minIndex, unsigned int numVertices, unsigned int startIndex, unsigned int primitiveCount)
    997 	{
    998 		CriticalSection cs(this);
    999 
   1000 		TRACE("D3DPRIMITIVETYPE type = %d, int baseVertexIndex = %d, unsigned int minIndex = %d, unsigned int numVertices = %d, unsigned int startIndex = %d, unsigned int primitiveCount = %d", type, baseVertexIndex, minIndex, numVertices, startIndex, primitiveCount);
   1001 
   1002 		if(!indexData)
   1003 		{
   1004 			return INVALIDCALL();
   1005 		}
   1006 
   1007 		if(!bindResources(indexData) || !primitiveCount)
   1008 		{
   1009 			return D3D_OK;
   1010 		}
   1011 
   1012 		unsigned int indexOffset = startIndex * (indexData->is32Bit() ? 4 : 2);   // FIXME: Doesn't take stream frequencies into account
   1013 
   1014 		sw::DrawType drawType;
   1015 
   1016 		if(indexData->is32Bit())
   1017 		{
   1018 			switch(type)
   1019 			{
   1020 			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST32;     break;
   1021 			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST32;      break;
   1022 			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP32;     break;
   1023 			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST32;  break;
   1024 			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break;
   1025 			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN32;   break;
   1026 			default:
   1027 				ASSERT(false);
   1028 			}
   1029 		}
   1030 		else
   1031 		{
   1032 			switch(type)
   1033 			{
   1034 			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST16;     break;
   1035 			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST16;      break;
   1036 			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP16;     break;
   1037 			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST16;  break;
   1038 			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break;
   1039 			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN16;   break;
   1040 			default:
   1041 				ASSERT(false);
   1042 			}
   1043 		}
   1044 
   1045 		if((streamSourceFreq[0] & D3DSTREAMSOURCE_INDEXEDDATA) && instanceData())
   1046 		{
   1047 			int instanceCount = (streamSourceFreq[0] & ~D3DSTREAMSOURCE_INDEXEDDATA);
   1048 
   1049 			for(int instance = 0; instance < instanceCount; instance++)
   1050 			{
   1051 				bindVertexStreams(baseVertexIndex, true, instance);
   1052 				renderer->draw(drawType, indexOffset, primitiveCount, instance == 0);
   1053 			}
   1054 		}
   1055 		else
   1056 		{
   1057 			bindVertexStreams(baseVertexIndex, false, 0);
   1058 			renderer->draw(drawType, indexOffset, primitiveCount);
   1059 		}
   1060 
   1061 		return D3D_OK;
   1062 	}
   1063 
   1064 	long Direct3DDevice9::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE type, unsigned int minIndex, unsigned int numVertices, unsigned int primitiveCount, const void *indexData, D3DFORMAT indexDataFormat, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)
   1065 	{
   1066 		CriticalSection cs(this);
   1067 
   1068 		TRACE("D3DPRIMITIVETYPE type = %d, unsigned int minIndex = %d, unsigned int numVertices = %d, unsigned int primitiveCount = %d, const void *indexData = 0x%0.8p, D3DFORMAT indexDataFormat = %d, const void *vertexStreamZeroData = 0x%0.8p, unsigned int vertexStreamZeroStride = %d", type, minIndex, numVertices, primitiveCount, indexData, indexDataFormat, vertexStreamZeroData, vertexStreamZeroStride);
   1069 
   1070 		if(!vertexStreamZeroData || !indexData)
   1071 		{
   1072 			return INVALIDCALL();
   1073 		}
   1074 
   1075 		int length = (minIndex + numVertices) * vertexStreamZeroStride;
   1076 
   1077 		Direct3DVertexBuffer9 *vertexBuffer = new Direct3DVertexBuffer9(this, length, 0, 0, D3DPOOL_DEFAULT);
   1078 
   1079 		void *data;
   1080 		vertexBuffer->Lock(0, 0, &data, 0);
   1081 		memcpy(data, vertexStreamZeroData, length);
   1082 		vertexBuffer->Unlock();
   1083 
   1084 		SetStreamSource(0, vertexBuffer, 0, vertexStreamZeroStride);
   1085 
   1086 		switch(type)
   1087 		{
   1088 		case D3DPT_POINTLIST:		length = primitiveCount;		break;
   1089 		case D3DPT_LINELIST:		length = primitiveCount * 2;	break;
   1090 		case D3DPT_LINESTRIP:		length = primitiveCount + 1;	break;
   1091 		case D3DPT_TRIANGLELIST:	length = primitiveCount * 3;	break;
   1092 		case D3DPT_TRIANGLESTRIP:	length = primitiveCount + 2;	break;
   1093 		case D3DPT_TRIANGLEFAN:		length = primitiveCount + 2;	break;
   1094 		default:
   1095 			ASSERT(false);
   1096 		}
   1097 
   1098 		length *= indexDataFormat == D3DFMT_INDEX32 ? 4 : 2;
   1099 
   1100 		Direct3DIndexBuffer9 *indexBuffer = new Direct3DIndexBuffer9(this, length, 0, indexDataFormat, D3DPOOL_DEFAULT);
   1101 
   1102 		indexBuffer->Lock(0, 0, &data, 0);
   1103 		memcpy(data, indexData, length);
   1104 		indexBuffer->Unlock();
   1105 
   1106 		SetIndices(indexBuffer);
   1107 
   1108 		if(!bindResources(indexBuffer) || !primitiveCount)
   1109 		{
   1110 			vertexBuffer->Release();
   1111 
   1112 			return D3D_OK;
   1113 		}
   1114 
   1115 		sw::DrawType drawType;
   1116 
   1117 		if(indexDataFormat == D3DFMT_INDEX32)
   1118 		{
   1119 			switch(type)
   1120 			{
   1121 			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST32;     break;
   1122 			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST32;      break;
   1123 			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP32;     break;
   1124 			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST32;  break;
   1125 			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break;
   1126 			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN32;   break;
   1127 			default:
   1128 				ASSERT(false);
   1129 			}
   1130 		}
   1131 		else
   1132 		{
   1133 			switch(type)
   1134 			{
   1135 			case D3DPT_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST16;     break;
   1136 			case D3DPT_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST16;      break;
   1137 			case D3DPT_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP16;     break;
   1138 			case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST16;  break;
   1139 			case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break;
   1140 			case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN16;   break;
   1141 			default:
   1142 				ASSERT(false);
   1143 			}
   1144 		}
   1145 
   1146 		bindVertexStreams(0, false, 0);
   1147 		renderer->draw(drawType, 0, primitiveCount);
   1148 
   1149 		SetStreamSource(0, 0, 0, 0);
   1150 		SetIndices(0);
   1151 
   1152 		return D3D_OK;
   1153 	}
   1154 
   1155 	long Direct3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE primitiveType, unsigned int startVertex, unsigned int primitiveCount)
   1156 	{
   1157 		CriticalSection cs(this);
   1158 
   1159 		TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int startVertex = %d, unsigned int primitiveCount = %d", primitiveType, startVertex, primitiveCount);
   1160 
   1161 		if(!bindResources(0) || !primitiveCount)
   1162 		{
   1163 			return D3D_OK;
   1164 		}
   1165 
   1166 		sw::DrawType drawType;
   1167 
   1168 		switch(primitiveType)
   1169 		{
   1170 		case D3DPT_POINTLIST:     drawType = sw::DRAW_POINTLIST;     break;
   1171 		case D3DPT_LINELIST:      drawType = sw::DRAW_LINELIST;      break;
   1172 		case D3DPT_LINESTRIP:     drawType = sw::DRAW_LINESTRIP;     break;
   1173 		case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_TRIANGLELIST;  break;
   1174 		case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break;
   1175 		case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_TRIANGLEFAN;   break;
   1176 		default:
   1177 			ASSERT(false);
   1178 		}
   1179 
   1180 		bindVertexStreams(startVertex, false, 0);
   1181 		renderer->draw(drawType, 0, primitiveCount);
   1182 
   1183 		return D3D_OK;
   1184 	}
   1185 
   1186 	long Direct3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType, unsigned int primitiveCount, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)
   1187 	{
   1188 		CriticalSection cs(this);
   1189 
   1190 		TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int primitiveCount = %d, const void *vertexStreamZeroData = 0x%0.8p, unsigned int vertexStreamZeroStride = %d", primitiveType, primitiveCount, vertexStreamZeroData, vertexStreamZeroStride);
   1191 
   1192 		if(!vertexStreamZeroData)
   1193 		{
   1194 			return INVALIDCALL();
   1195 		}
   1196 
   1197 		IDirect3DVertexBuffer9 *vertexBuffer = 0;
   1198 		int length = 0;
   1199 
   1200 		switch(primitiveType)
   1201 		{
   1202 		case D3DPT_POINTLIST:		length = primitiveCount;		break;
   1203 		case D3DPT_LINELIST:		length = primitiveCount * 2;	break;
   1204 		case D3DPT_LINESTRIP:		length = primitiveCount + 1;	break;
   1205 		case D3DPT_TRIANGLELIST:	length = primitiveCount * 3;	break;
   1206 		case D3DPT_TRIANGLESTRIP:	length = primitiveCount + 2;	break;
   1207 		case D3DPT_TRIANGLEFAN:		length = primitiveCount + 2;	break;
   1208 		default:
   1209 			ASSERT(false);
   1210 		}
   1211 
   1212 		length *= vertexStreamZeroStride;
   1213 
   1214 		CreateVertexBuffer(length, 0, 0, D3DPOOL_DEFAULT, &vertexBuffer, 0);
   1215 
   1216 		void *data;
   1217 		vertexBuffer->Lock(0, 0, &data, 0);
   1218 		memcpy(data, vertexStreamZeroData, length);
   1219 		vertexBuffer->Unlock();
   1220 
   1221 		SetStreamSource(0, vertexBuffer, 0, vertexStreamZeroStride);
   1222 
   1223 		if(!bindResources(0) || !primitiveCount)
   1224 		{
   1225 			vertexBuffer->Release();
   1226 
   1227 			return D3D_OK;
   1228 		}
   1229 
   1230 		sw::DrawType drawType;
   1231 
   1232 		switch(primitiveType)
   1233 		{
   1234 		case D3DPT_POINTLIST:     drawType = sw::DRAW_POINTLIST;     break;
   1235 		case D3DPT_LINELIST:      drawType = sw::DRAW_LINELIST;      break;
   1236 		case D3DPT_LINESTRIP:     drawType = sw::DRAW_LINESTRIP;     break;
   1237 		case D3DPT_TRIANGLELIST:  drawType = sw::DRAW_TRIANGLELIST;  break;
   1238 		case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break;
   1239 		case D3DPT_TRIANGLEFAN:   drawType = sw::DRAW_TRIANGLEFAN;   break;
   1240 		default:
   1241 			ASSERT(false);
   1242 		}
   1243 
   1244 		bindVertexStreams(0, false, 0);
   1245 		renderer->draw(drawType, 0, primitiveCount);
   1246 
   1247 		SetStreamSource(0, 0, 0, 0);
   1248 		vertexBuffer->Release();
   1249 
   1250 		return D3D_OK;
   1251 	}
   1252 
   1253 	long Direct3DDevice9::DrawRectPatch(unsigned int handle, const float *numSegs, const D3DRECTPATCH_INFO *rectPatchInfo)
   1254 	{
   1255 		CriticalSection cs(this);
   1256 
   1257 		TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DRECTPATCH_INFO *rectPatchInfo = 0x%0.8p", handle, numSegs, rectPatchInfo);
   1258 
   1259 		if(!numSegs || !rectPatchInfo)
   1260 		{
   1261 			return INVALIDCALL();
   1262 		}
   1263 
   1264 		UNIMPLEMENTED();
   1265 
   1266 		return D3D_OK;
   1267 	}
   1268 
   1269 	long Direct3DDevice9::DrawTriPatch(unsigned int handle, const float *numSegs, const D3DTRIPATCH_INFO *triPatchInfo)
   1270 	{
   1271 		CriticalSection cs(this);
   1272 
   1273 		TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DTRIPATCH_INFO *triPatchInfo = 0x%0.8p", handle, numSegs, triPatchInfo);
   1274 
   1275 		if(!numSegs || !triPatchInfo)
   1276 		{
   1277 			return INVALIDCALL();
   1278 		}
   1279 
   1280 		UNIMPLEMENTED();
   1281 
   1282 		return D3D_OK;
   1283 	}
   1284 
   1285 	long Direct3DDevice9::EndScene()
   1286 	{
   1287 		CriticalSection cs(this);
   1288 
   1289 		TRACE("void");
   1290 
   1291 		return D3D_OK;
   1292 	}
   1293 
   1294 	long Direct3DDevice9::EndStateBlock(IDirect3DStateBlock9 **stateBlock)
   1295 	{
   1296 		CriticalSection cs(this);
   1297 
   1298 		TRACE("IDirect3DStateBlock9 **stateBlock = 0x%0.8p", stateBlock);
   1299 
   1300 		if(!stateBlock)
   1301 		{
   1302 			return INVALIDCALL();
   1303 		}
   1304 
   1305 		*stateBlock = 0;
   1306 
   1307 		if(!stateRecorder)
   1308 		{
   1309 			return INVALIDCALL();
   1310 		}
   1311 
   1312 		*stateBlock = stateRecorder;
   1313 		stateRecorder->AddRef();
   1314 		stateRecorder->unbind();
   1315 		stateRecorder = 0;   // Stop recording
   1316 
   1317 		return D3D_OK;
   1318 	}
   1319 
   1320 	long Direct3DDevice9::EvictManagedResources()
   1321 	{
   1322 		CriticalSection cs(this);
   1323 
   1324 		TRACE("void");
   1325 
   1326 		//	UNIMPLEMENTED();   // FIXME
   1327 
   1328 		return D3D_OK;
   1329 	}
   1330 
   1331 	unsigned int Direct3DDevice9::GetAvailableTextureMem()
   1332 	{
   1333 		CriticalSection cs(this);
   1334 
   1335 		TRACE("void");
   1336 
   1337 		int availableMemory = textureMemory - Direct3DResource9::getMemoryUsage();
   1338 		if(availableMemory < 0) availableMemory = 0;
   1339 
   1340 		// Round to nearest MB
   1341 		return (availableMemory + 0x80000) & 0xFFF00000;
   1342 	}
   1343 
   1344 	long Direct3DDevice9::GetBackBuffer(unsigned int swapChainIndex, unsigned int backBufferIndex, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer)
   1345 	{
   1346 		CriticalSection cs(this);
   1347 
   1348 		TRACE("unsigned int swapChainIndex = %d, unsigned int backBufferIndex = %d, D3DBACKBUFFER_TYPE type = %d, IDirect3DSurface9 **backBuffer = 0x%0.8p", swapChainIndex, backBufferIndex, type, backBuffer);
   1349 
   1350 		if(swapChainIndex >= GetNumberOfSwapChains())
   1351 		{
   1352 			return INVALIDCALL();
   1353 		}
   1354 
   1355 		return swapChain->GetBackBuffer(backBufferIndex, type, backBuffer);
   1356 	}
   1357 
   1358 	long Direct3DDevice9::GetClipPlane(unsigned long index, float *plane)
   1359 	{
   1360 		CriticalSection cs(this);
   1361 
   1362 		TRACE("unsigned long index = %d, float *plane = 0x%0.8p", index, plane);
   1363 
   1364 		if(!plane || index >= 6)
   1365 		{
   1366 			return INVALIDCALL();
   1367 		}
   1368 
   1369 		plane[0] = this->plane[index][0];
   1370 		plane[1] = this->plane[index][1];
   1371 		plane[2] = this->plane[index][2];
   1372 		plane[3] = this->plane[index][3];
   1373 
   1374 		return D3D_OK;
   1375 	}
   1376 
   1377 	long Direct3DDevice9::GetClipStatus(D3DCLIPSTATUS9 *clipStatus)
   1378 	{
   1379 		CriticalSection cs(this);
   1380 
   1381 		TRACE("D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);
   1382 
   1383 		if(!clipStatus)
   1384 		{
   1385 			return INVALIDCALL();
   1386 		}
   1387 
   1388 		*clipStatus = this->clipStatus;
   1389 
   1390 		return D3D_OK;
   1391 	}
   1392 
   1393 	long Direct3DDevice9::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *parameters)
   1394 	{
   1395 		CriticalSection cs(this);
   1396 
   1397 		TRACE("D3DDEVICE_CREATION_PARAMETERS *parameters = 0x%0.8p", parameters);
   1398 
   1399 		if(!parameters)
   1400 		{
   1401 			return INVALIDCALL();
   1402 		}
   1403 
   1404 		parameters->AdapterOrdinal = adapter;
   1405 		parameters->BehaviorFlags = behaviourFlags;
   1406 		parameters->DeviceType = deviceType;
   1407 		parameters->hFocusWindow = focusWindow;
   1408 
   1409 		return D3D_OK;
   1410 	}
   1411 
   1412 	long Direct3DDevice9::GetCurrentTexturePalette(unsigned int *paletteNumber)
   1413 	{
   1414 		CriticalSection cs(this);
   1415 
   1416 		TRACE("unsigned int *paletteNumber = 0x%0.8p", paletteNumber);
   1417 
   1418 		if(!paletteNumber)
   1419 		{
   1420 			return INVALIDCALL();
   1421 		}
   1422 
   1423 		*paletteNumber = currentPalette;
   1424 
   1425 		return D3D_OK;
   1426 	}
   1427 
   1428 	long Direct3DDevice9::GetDepthStencilSurface(IDirect3DSurface9 **depthStencilSurface)
   1429 	{
   1430 		CriticalSection cs(this);
   1431 
   1432 		TRACE("IDirect3DSurface9 **depthStencilSurface = 0x%0.8p", depthStencilSurface);
   1433 
   1434 		if(!depthStencilSurface)
   1435 		{
   1436 			return INVALIDCALL();
   1437 		}
   1438 
   1439 		*depthStencilSurface = depthStencil;
   1440 
   1441 		if(depthStencil)
   1442 		{
   1443 			depthStencil->AddRef();
   1444 		}
   1445 		else
   1446 		{
   1447 			return NOTFOUND();
   1448 		}
   1449 
   1450 		return D3D_OK;
   1451 	}
   1452 
   1453 	long Direct3DDevice9::GetDeviceCaps(D3DCAPS9 *caps)
   1454 	{
   1455 		CriticalSection cs(this);
   1456 
   1457 		TRACE("D3DCAPS9 *caps = 0x%0.8p", caps);
   1458 
   1459 		return d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, caps);
   1460 	}
   1461 
   1462 	long Direct3DDevice9::GetDirect3D(IDirect3D9 **d3d9)
   1463 	{
   1464 		CriticalSection cs(this);
   1465 
   1466 		TRACE("IDirect3D9 **d3d9 = 0x%0.8p", d3d9);
   1467 
   1468 		if(!d3d9)
   1469 		{
   1470 			return INVALIDCALL();
   1471 		}
   1472 
   1473 		*d3d9 = this->d3d9;
   1474 		this->d3d9->AddRef();
   1475 
   1476 		return D3D_OK;
   1477 	}
   1478 
   1479 	long Direct3DDevice9::GetDisplayMode(unsigned int index, D3DDISPLAYMODE *mode)
   1480 	{
   1481 		CriticalSection cs(this);
   1482 
   1483 		TRACE("unsigned int index = %d, D3DDISPLAYMODE *mode = 0x%0.8p", index, mode);
   1484 
   1485 		if(index >= GetNumberOfSwapChains())
   1486 		{
   1487 			return INVALIDCALL();
   1488 		}
   1489 
   1490 		return swapChain->GetDisplayMode(mode);
   1491 	}
   1492 
   1493 	long Direct3DDevice9::GetFrontBufferData(unsigned int index, IDirect3DSurface9 *destSurface)
   1494 	{
   1495 		CriticalSection cs(this);
   1496 
   1497 		TRACE("unsigned int index = %d, IDirect3DSurface9 *destSurface = %p", index, destSurface);
   1498 
   1499 		if(index >= GetNumberOfSwapChains())
   1500 		{
   1501 			return INVALIDCALL();
   1502 		}
   1503 
   1504 		return swapChain->GetFrontBufferData(destSurface);
   1505 	}
   1506 
   1507 	long Direct3DDevice9::GetFVF(unsigned long *FVF)
   1508 	{
   1509 		CriticalSection cs(this);
   1510 
   1511 		TRACE("unsigned long *FVF = 0x%0.8p", FVF);
   1512 
   1513 		if(!FVF)
   1514 		{
   1515 			return INVALIDCALL();
   1516 		}
   1517 
   1518 		if(vertexDeclaration)
   1519 		{
   1520 			*FVF = vertexDeclaration->getFVF();
   1521 		}
   1522 		else
   1523 		{
   1524 			*FVF = 0;
   1525 		}
   1526 
   1527 		return D3D_OK;
   1528 	}
   1529 
   1530 	void Direct3DDevice9::GetGammaRamp(unsigned int index, D3DGAMMARAMP *ramp)
   1531 	{
   1532 		CriticalSection cs(this);
   1533 
   1534 		TRACE("unsigned int index = %d, D3DGAMMARAMP *ramp = 0x%0.8p", index, ramp);
   1535 
   1536 		if(!ramp || index >= GetNumberOfSwapChains())
   1537 		{
   1538 			return;
   1539 		}
   1540 
   1541 		swapChain->getGammaRamp((sw::GammaRamp*)ramp);
   1542 	}
   1543 
   1544 	long Direct3DDevice9::GetIndices(IDirect3DIndexBuffer9 **indexData)
   1545 	{
   1546 		CriticalSection cs(this);
   1547 
   1548 		TRACE("IDirect3DIndexBuffer9 **indexData = 0x%0.8p", indexData);
   1549 
   1550 		if(!indexData)
   1551 		{
   1552 			return INVALIDCALL();
   1553 		}
   1554 
   1555 		*indexData = this->indexData;
   1556 
   1557 		if(this->indexData)
   1558 		{
   1559 			this->indexData->AddRef();
   1560 		}
   1561 
   1562 		return D3D_OK;
   1563 	}
   1564 
   1565 	long Direct3DDevice9::GetLight(unsigned long index, D3DLIGHT9 *light)
   1566 	{
   1567 		CriticalSection cs(this);
   1568 
   1569 		TRACE("unsigned long index = %d, D3DLIGHT9 *light = 0x%0.8p", index, light);
   1570 
   1571 		if(!light)
   1572 		{
   1573 			return INVALIDCALL();
   1574 		}
   1575 
   1576 		if(!this->light.exists(index))
   1577 		{
   1578 			return INVALIDCALL();
   1579 		}
   1580 
   1581 		*light = this->light[index];
   1582 
   1583 		return D3D_OK;
   1584 	}
   1585 
   1586 	long Direct3DDevice9::GetLightEnable(unsigned long index, int *enable)
   1587 	{
   1588 		CriticalSection cs(this);
   1589 
   1590 		TRACE("unsigned long index = %d, int *enable = 0x%0.8p", index, enable);
   1591 
   1592 		if(!enable)
   1593 		{
   1594 			return INVALIDCALL();
   1595 		}
   1596 
   1597 		if(!light.exists(index))
   1598 		{
   1599 			return INVALIDCALL();
   1600 		}
   1601 
   1602 		*enable = light[index].enable ? 128 : 0;
   1603 
   1604 		return D3D_OK;
   1605 	}
   1606 
   1607 	long Direct3DDevice9::GetMaterial(D3DMATERIAL9 *material)
   1608 	{
   1609 		CriticalSection cs(this);
   1610 
   1611 		TRACE("D3DMATERIAL9 *material = 0x%0.8p", material);
   1612 
   1613 		if(!material)
   1614 		{
   1615 			return INVALIDCALL();
   1616 		}
   1617 
   1618 		*material = this->material;
   1619 
   1620 		return D3D_OK;
   1621 	}
   1622 
   1623 	float Direct3DDevice9::GetNPatchMode()
   1624 	{
   1625 		CriticalSection cs(this);
   1626 
   1627 		TRACE("void");
   1628 
   1629 		return 0.0f;   // FIXME: Unimplemented
   1630 	}
   1631 
   1632 	unsigned int Direct3DDevice9::GetNumberOfSwapChains()
   1633 	{
   1634 		CriticalSection cs(this);
   1635 
   1636 		TRACE("void");
   1637 
   1638 		return 1;
   1639 	}
   1640 
   1641 	long Direct3DDevice9::GetPaletteEntries(unsigned int paletteNumber, PALETTEENTRY *entries)
   1642 	{
   1643 		CriticalSection cs(this);
   1644 
   1645 		TRACE("unsigned int paletteNumber = %d, PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);
   1646 
   1647 		if(paletteNumber > 0xFFFF || !entries)
   1648 		{
   1649 			return INVALIDCALL();
   1650 		}
   1651 
   1652 		for(int i = 0; i < 256; i++)
   1653 		{
   1654 			entries[i] = palette[paletteNumber].entry[i];
   1655 		}
   1656 
   1657 		return D3D_OK;
   1658 	}
   1659 
   1660 	long Direct3DDevice9::GetPixelShader(IDirect3DPixelShader9 **shader)
   1661 	{
   1662 		CriticalSection cs(this);
   1663 
   1664 		TRACE("IDirect3DPixelShader9 **shader = 0x%0.8p", shader);
   1665 
   1666 		if(!shader)
   1667 		{
   1668 			return INVALIDCALL();
   1669 		}
   1670 
   1671 		if(pixelShader)
   1672 		{
   1673 			pixelShader->AddRef();
   1674 		}
   1675 
   1676 		*shader = pixelShader;
   1677 
   1678 		return D3D_OK;
   1679 	}
   1680 
   1681 	long Direct3DDevice9::GetPixelShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)
   1682 	{
   1683 		CriticalSection cs(this);
   1684 
   1685 		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   1686 
   1687 		if(!constantData)
   1688 		{
   1689 			return INVALIDCALL();
   1690 		}
   1691 
   1692 		for(unsigned int i = 0; i < count; i++)
   1693 		{
   1694 			constantData[i] = pixelShaderConstantB[startRegister + i];
   1695 		}
   1696 
   1697 		return D3D_OK;
   1698 	}
   1699 
   1700 	long Direct3DDevice9::GetPixelShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)
   1701 	{
   1702 		CriticalSection cs(this);
   1703 
   1704 		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   1705 
   1706 		if(!constantData)
   1707 		{
   1708 			return INVALIDCALL();
   1709 		}
   1710 
   1711 		for(unsigned int i = 0; i < count; i++)
   1712 		{
   1713 			constantData[i * 4 + 0] = pixelShaderConstantF[startRegister + i][0];
   1714 			constantData[i * 4 + 1] = pixelShaderConstantF[startRegister + i][1];
   1715 			constantData[i * 4 + 2] = pixelShaderConstantF[startRegister + i][2];
   1716 			constantData[i * 4 + 3] = pixelShaderConstantF[startRegister + i][3];
   1717 		}
   1718 
   1719 		return D3D_OK;
   1720 	}
   1721 
   1722 	long Direct3DDevice9::GetPixelShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)
   1723 	{
   1724 		CriticalSection cs(this);
   1725 
   1726 		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   1727 
   1728 		if(!constantData)
   1729 		{
   1730 			return INVALIDCALL();
   1731 		}
   1732 
   1733 		for(unsigned int i = 0; i < count; i++)
   1734 		{
   1735 			constantData[i * 4 + 0] = pixelShaderConstantI[startRegister + i][0];
   1736 			constantData[i * 4 + 1] = pixelShaderConstantI[startRegister + i][1];
   1737 			constantData[i * 4 + 2] = pixelShaderConstantI[startRegister + i][2];
   1738 			constantData[i * 4 + 3] = pixelShaderConstantI[startRegister + i][3];
   1739 		}
   1740 
   1741 		return D3D_OK;
   1742 	}
   1743 
   1744 	long Direct3DDevice9::GetRasterStatus(unsigned int index, D3DRASTER_STATUS *rasterStatus)
   1745 	{
   1746 		CriticalSection cs(this);
   1747 
   1748 		TRACE("unsigned int swapChain = %d, D3DRASTER_STATUS *rasterStatus = 0x%0.8p", index, rasterStatus);
   1749 
   1750 		if(index >= GetNumberOfSwapChains())
   1751 		{
   1752 			return INVALIDCALL();
   1753 		}
   1754 
   1755 		return swapChain->GetRasterStatus(rasterStatus);
   1756 	}
   1757 
   1758 	long Direct3DDevice9::GetRenderState(D3DRENDERSTATETYPE state, unsigned long *value)
   1759 	{
   1760 		CriticalSection cs(this);
   1761 
   1762 		TRACE("D3DRENDERSTATETYPE state = %d, unsigned long *value = 0x%0.8p", state, value);
   1763 
   1764 		if(!value)
   1765 		{
   1766 			return INVALIDCALL();
   1767 		}
   1768 
   1769 		*value = renderState[state];
   1770 
   1771 		return D3D_OK;
   1772 	}
   1773 
   1774 	long Direct3DDevice9::GetRenderTarget(unsigned long index, IDirect3DSurface9 **renderTarget)
   1775 	{
   1776 		CriticalSection cs(this);
   1777 
   1778 		TRACE("unsigned long index = %d, IDirect3DSurface9 **renderTarget = 0x%0.8p", index, renderTarget);
   1779 
   1780 		if(index >= 4 || !renderTarget)
   1781 		{
   1782 			return INVALIDCALL();
   1783 		}
   1784 
   1785 		*renderTarget = 0;
   1786 
   1787 		if(!this->renderTarget[index])
   1788 		{
   1789 			return NOTFOUND();
   1790 		}
   1791 
   1792 		*renderTarget = this->renderTarget[index];
   1793 		this->renderTarget[index]->AddRef();
   1794 
   1795 		return D3D_OK;
   1796 	}
   1797 
   1798 	long Direct3DDevice9::GetRenderTargetData(IDirect3DSurface9 *renderTarget, IDirect3DSurface9 *destSurface)
   1799 	{
   1800 		CriticalSection cs(this);
   1801 
   1802 		TRACE("IDirect3DSurface9 *renderTarget = 0x%0.8p, IDirect3DSurface9 *destSurface = 0x%0.8p", renderTarget, destSurface);
   1803 
   1804 		if(!renderTarget || !destSurface)
   1805 		{
   1806 			return INVALIDCALL();
   1807 		}
   1808 
   1809 		D3DSURFACE_DESC sourceDescription;
   1810 		D3DSURFACE_DESC destinationDescription;
   1811 
   1812 		renderTarget->GetDesc(&sourceDescription);
   1813 		destSurface->GetDesc(&destinationDescription);
   1814 
   1815 		if(sourceDescription.Width  != destinationDescription.Width ||
   1816 		   sourceDescription.Height != destinationDescription.Height ||
   1817 		   sourceDescription.Format != destinationDescription.Format ||
   1818 		   sourceDescription.MultiSampleType != D3DMULTISAMPLE_NONE)
   1819 		{
   1820 			return INVALIDCALL();
   1821 		}
   1822 
   1823 		if(sourceDescription.Format == D3DFMT_A8R8G8B8 ||
   1824 		   sourceDescription.Format == D3DFMT_X8R8G8B8)
   1825 		{
   1826 			sw::Surface *source = static_cast<Direct3DSurface9*>(renderTarget);
   1827 			sw::Surface *dest = static_cast<Direct3DSurface9*>(destSurface);
   1828 
   1829 			void *sourceBuffer = source->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
   1830 			void *destBuffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
   1831 
   1832 			static void (__cdecl *blitFunction)(void *dst, void *src);
   1833 			static sw::Routine *blitRoutine;
   1834 			static sw::BlitState blitState = {};
   1835 
   1836 			sw::BlitState update;
   1837 			update.width = sourceDescription.Width;
   1838 			update.height = sourceDescription.Height;
   1839 			update.sourceFormat = sw::FORMAT_A8R8G8B8;
   1840 			update.sourceStride = source->getExternalPitchB();
   1841 			update.destFormat = sw::FORMAT_A8R8G8B8;
   1842 			update.destStride = dest->getExternalPitchB();
   1843 			update.cursorHeight = 0;
   1844 			update.cursorWidth = 0;
   1845 
   1846 			if(memcmp(&blitState, &update, sizeof(sw::BlitState)) != 0)
   1847 			{
   1848 				blitState = update;
   1849 				delete blitRoutine;
   1850 
   1851 				blitRoutine = sw::FrameBuffer::copyRoutine(blitState);
   1852 				blitFunction = (void(__cdecl*)(void*, void*))blitRoutine->getEntry();
   1853 			}
   1854 
   1855 			blitFunction(destBuffer, sourceBuffer);
   1856 
   1857 			dest->unlockExternal();
   1858 			source->unlockExternal();
   1859 		}
   1860 		else
   1861 		{
   1862 			return UpdateSurface(renderTarget, 0, destSurface, 0);
   1863 		}
   1864 
   1865 		return D3D_OK;
   1866 	}
   1867 
   1868 	long Direct3DDevice9::GetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long *value)
   1869 	{
   1870 		CriticalSection cs(this);
   1871 
   1872 		TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE type = %d, unsigned long *value = 0x%0.8p", sampler, state, value);
   1873 
   1874 		if(!value || state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET)   // FIXME: Set *value to 0?
   1875 		{
   1876 			return INVALIDCALL();
   1877 		}
   1878 
   1879 		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
   1880 		{
   1881 			return INVALIDCALL();
   1882 		}
   1883 
   1884 		if(sampler >= D3DVERTEXTEXTURESAMPLER0)
   1885 		{
   1886 			sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
   1887 		}
   1888 
   1889 		*value = samplerState[sampler][state];
   1890 
   1891 		return D3D_OK;
   1892 	}
   1893 
   1894 	long Direct3DDevice9::GetScissorRect(RECT *rect)
   1895 	{
   1896 		CriticalSection cs(this);
   1897 
   1898 		TRACE("RECT *rect = 0x%0.8p", rect);
   1899 
   1900 		if(!rect)
   1901 		{
   1902 			return INVALIDCALL();
   1903 		}
   1904 
   1905 		*rect = scissorRect;
   1906 
   1907 		return D3D_OK;
   1908 	}
   1909 
   1910 	int Direct3DDevice9::GetSoftwareVertexProcessing()
   1911 	{
   1912 		CriticalSection cs(this);
   1913 
   1914 		TRACE("void");
   1915 
   1916 		return softwareVertexProcessing ? TRUE : FALSE;
   1917 	}
   1918 
   1919 	long Direct3DDevice9::GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer9 **streamData, unsigned int *offset, unsigned int *stride)
   1920 	{
   1921 		CriticalSection cs(this);
   1922 
   1923 		TRACE("unsigned int streamNumber = %d, IDirect3DVertexBuffer9 **streamData = 0x%0.8p, unsigned int *offset = 0x%0.8p, unsigned int *stride = 0x%0.8p", streamNumber, streamData, offset, stride);
   1924 
   1925 		if(streamNumber >= 16 || !streamData || !offset || !stride)
   1926 		{
   1927 			return INVALIDCALL();
   1928 		}
   1929 
   1930 		*streamData = dataStream[streamNumber];
   1931 
   1932 		if(dataStream[streamNumber])
   1933 		{
   1934 			dataStream[streamNumber]->AddRef();
   1935 		}
   1936 
   1937 		*offset = streamOffset[streamNumber];
   1938 		*stride = streamStride[streamNumber];
   1939 
   1940 		return D3D_OK;
   1941 	}
   1942 
   1943 	long Direct3DDevice9::GetStreamSourceFreq(unsigned int streamNumber, unsigned int *divider)
   1944 	{
   1945 		CriticalSection cs(this);
   1946 
   1947 		TRACE("unsigned int streamNumber = %d, unsigned int *divider = 0x%0.8p", streamNumber, divider);
   1948 
   1949 		if(streamNumber >= 16 || !divider)
   1950 		{
   1951 			return INVALIDCALL();
   1952 		}
   1953 
   1954 		*divider = streamSourceFreq[streamNumber];
   1955 
   1956 		return D3D_OK;
   1957 	}
   1958 
   1959 	long Direct3DDevice9::GetSwapChain(unsigned int index, IDirect3DSwapChain9 **swapChain)
   1960 	{
   1961 		CriticalSection cs(this);
   1962 
   1963 		TRACE("unsigned int index = %d, IDirect3DSwapChain9 **swapChain = 0x%0.8p", index, swapChain);
   1964 
   1965 		if(!swapChain || index >= GetNumberOfSwapChains())
   1966 		{
   1967 			return INVALIDCALL();
   1968 		}
   1969 
   1970 		*swapChain = this->swapChain;
   1971 
   1972 		if(*swapChain)
   1973 		{
   1974 			(*swapChain)->AddRef();
   1975 		}
   1976 
   1977 		return D3D_OK;
   1978 	}
   1979 
   1980 	long Direct3DDevice9::GetTexture(unsigned long sampler, IDirect3DBaseTexture9 **texture)
   1981 	{
   1982 		CriticalSection cs(this);
   1983 
   1984 		TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 **texture = 0x%0.8p", sampler, texture);
   1985 
   1986 		if(!texture)
   1987 		{
   1988 			return INVALIDCALL();
   1989 		}
   1990 
   1991 		*texture = 0;
   1992 
   1993 		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
   1994 		{
   1995 			return INVALIDCALL();
   1996 		}
   1997 
   1998 		*texture = this->texture[sampler];
   1999 
   2000 		if(this->texture[sampler])
   2001 		{
   2002 			this->texture[sampler]->AddRef();
   2003 		}
   2004 
   2005 		return D3D_OK;
   2006 	}
   2007 
   2008 	long Direct3DDevice9::GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long *value)
   2009 	{
   2010 		CriticalSection cs(this);
   2011 
   2012 		TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long *value = 0x%0.8p", stage, type, value);
   2013 
   2014 		if(!value)
   2015 		{
   2016 			return INVALIDCALL();
   2017 		}
   2018 
   2019 		*value = textureStageState[stage][type];
   2020 
   2021 		return D3D_OK;
   2022 	}
   2023 
   2024 	long Direct3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix)
   2025 	{
   2026 		CriticalSection cs(this);
   2027 
   2028 		TRACE("D3DTRANSFORMSTATETYPE state = %d, D3DMATRIX *matrix = 0x%0.8p", state, matrix);
   2029 
   2030 		if(!matrix || state < 0 || state > 511)
   2031 		{
   2032 			return INVALIDCALL();
   2033 		}
   2034 
   2035 		*matrix = this->matrix[state];
   2036 
   2037 		return D3D_OK;
   2038 	}
   2039 
   2040 	long Direct3DDevice9::GetVertexDeclaration(IDirect3DVertexDeclaration9 **declaration)
   2041 	{
   2042 		CriticalSection cs(this);
   2043 
   2044 		TRACE("IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", declaration);
   2045 
   2046 		if(!declaration)
   2047 		{
   2048 			return INVALIDCALL();
   2049 		}
   2050 
   2051 		*declaration = vertexDeclaration;
   2052 
   2053 		if(vertexDeclaration)
   2054 		{
   2055 			vertexDeclaration->AddRef();
   2056 		}
   2057 
   2058 		return D3D_OK;
   2059 	}
   2060 
   2061 	long Direct3DDevice9::GetVertexShader(IDirect3DVertexShader9 **shader)
   2062 	{
   2063 		CriticalSection cs(this);
   2064 
   2065 		TRACE("IDirect3DVertexShader9 **shader = 0x%0.8p", shader);
   2066 
   2067 		if(!shader)
   2068 		{
   2069 			return INVALIDCALL();
   2070 		}
   2071 
   2072 		*shader = vertexShader;
   2073 
   2074 		if(vertexShader)
   2075 		{
   2076 			vertexShader->AddRef();
   2077 		}
   2078 
   2079 		return D3D_OK;
   2080 	}
   2081 
   2082 	long Direct3DDevice9::GetVertexShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)
   2083 	{
   2084 		CriticalSection cs(this);
   2085 
   2086 		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   2087 
   2088 		if(!constantData)
   2089 		{
   2090 			return INVALIDCALL();
   2091 		}
   2092 
   2093 		for(unsigned int i = 0; i < count; i++)
   2094 		{
   2095 			constantData[i] = vertexShaderConstantB[startRegister + i];
   2096 		}
   2097 
   2098 		return D3D_OK;
   2099 	}
   2100 
   2101 	long Direct3DDevice9::GetVertexShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)
   2102 	{
   2103 		CriticalSection cs(this);
   2104 
   2105 		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   2106 
   2107 		if(!constantData)
   2108 		{
   2109 			return INVALIDCALL();
   2110 		}
   2111 
   2112 		for(unsigned int i = 0; i < count; i++)
   2113 		{
   2114 			constantData[i * 4 + 0] = vertexShaderConstantF[startRegister + i][0];
   2115 			constantData[i * 4 + 1] = vertexShaderConstantF[startRegister + i][1];
   2116 			constantData[i * 4 + 2] = vertexShaderConstantF[startRegister + i][2];
   2117 			constantData[i * 4 + 3] = vertexShaderConstantF[startRegister + i][3];
   2118 		}
   2119 
   2120 		return D3D_OK;
   2121 	}
   2122 
   2123 	long Direct3DDevice9::GetVertexShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)
   2124 	{
   2125 		CriticalSection cs(this);
   2126 
   2127 		TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   2128 
   2129 		if(!constantData)
   2130 		{
   2131 			return INVALIDCALL();
   2132 		}
   2133 
   2134 		for(unsigned int i = 0; i < count; i++)
   2135 		{
   2136 			constantData[i * 4 + 0] = vertexShaderConstantI[startRegister + i][0];
   2137 			constantData[i * 4 + 1] = vertexShaderConstantI[startRegister + i][1];
   2138 			constantData[i * 4 + 2] = vertexShaderConstantI[startRegister + i][2];
   2139 			constantData[i * 4 + 3] = vertexShaderConstantI[startRegister + i][3];
   2140 		}
   2141 
   2142 		return D3D_OK;
   2143 	}
   2144 
   2145 	long Direct3DDevice9::GetViewport(D3DVIEWPORT9 *viewport)
   2146 	{
   2147 		CriticalSection cs(this);
   2148 
   2149 		TRACE("D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
   2150 
   2151 		if(!viewport)
   2152 		{
   2153 			return INVALIDCALL();
   2154 		}
   2155 
   2156 		*viewport = this->viewport;
   2157 
   2158 		return D3D_OK;
   2159 	}
   2160 
   2161 	long Direct3DDevice9::LightEnable(unsigned long index, int enable)
   2162 	{
   2163 		CriticalSection cs(this);
   2164 
   2165 		TRACE("unsigned long index = %d, int enable = %d", index, enable);
   2166 
   2167 		if(!light.exists(index))   // Insert default light
   2168 		{
   2169 			D3DLIGHT9 light;
   2170 
   2171 			light.Type = D3DLIGHT_DIRECTIONAL;
   2172 			light.Diffuse.r = 1;
   2173 			light.Diffuse.g = 1;
   2174 			light.Diffuse.b = 1;
   2175 			light.Diffuse.a = 0;
   2176 			light.Specular.r = 0;
   2177 			light.Specular.g = 0;
   2178 			light.Specular.b = 0;
   2179 			light.Specular.a = 0;
   2180 			light.Ambient.r = 0;
   2181 			light.Ambient.g = 0;
   2182 			light.Ambient.b = 0;
   2183 			light.Ambient.a = 0;
   2184 			light.Position.x = 0;
   2185 			light.Position.y = 0;
   2186 			light.Position.z = 0;
   2187 			light.Direction.x = 0;
   2188 			light.Direction.y = 0;
   2189 			light.Direction.z = 1;
   2190 			light.Range = 0;
   2191 			light.Falloff = 0;
   2192 			light.Attenuation0 = 0;
   2193 			light.Attenuation1 = 0;
   2194 			light.Attenuation2 = 0;
   2195 			light.Theta = 0;
   2196 			light.Phi = 0;
   2197 
   2198 			this->light[index] = light;
   2199 			this->light[index].enable = false;
   2200 		}
   2201 
   2202 		if(!stateRecorder)
   2203 		{
   2204 			light[index].enable = (enable != FALSE);
   2205 
   2206 			lightsDirty = true;
   2207 		}
   2208 		else
   2209 		{
   2210 			stateRecorder->lightEnable(index, enable);
   2211 		}
   2212 
   2213 		return D3D_OK;
   2214 	}
   2215 
   2216 	long Direct3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
   2217 	{
   2218 		CriticalSection cs(this);
   2219 
   2220 		TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
   2221 
   2222 		if(!matrix)
   2223 		{
   2224 			return INVALIDCALL();
   2225 		}
   2226 
   2227 		D3DMATRIX *current = &this->matrix[state];
   2228 
   2229 		sw::Matrix C(current->_11, current->_21, current->_31, current->_41,
   2230 		             current->_12, current->_22, current->_32, current->_42,
   2231 		             current->_13, current->_23, current->_33, current->_43,
   2232 		             current->_14, current->_24, current->_34, current->_44);
   2233 
   2234 		sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,
   2235 		             matrix->_12, matrix->_22, matrix->_32, matrix->_42,
   2236 		             matrix->_13, matrix->_23, matrix->_33, matrix->_43,
   2237 		             matrix->_14, matrix->_24, matrix->_34, matrix->_44);
   2238 
   2239 		switch(state)
   2240 		{
   2241 		case D3DTS_WORLD:
   2242 			renderer->setModelMatrix(C * M);
   2243 			break;
   2244 		case D3DTS_VIEW:
   2245 			renderer->setViewMatrix(C * M);
   2246 			break;
   2247 		case D3DTS_PROJECTION:
   2248 			renderer->setProjectionMatrix(C * M);
   2249 			break;
   2250 		case D3DTS_TEXTURE0:
   2251 			renderer->setTextureMatrix(0, C * M);
   2252 			break;
   2253 		case D3DTS_TEXTURE1:
   2254 			renderer->setTextureMatrix(1, C * M);
   2255 			break;
   2256 		case D3DTS_TEXTURE2:
   2257 			renderer->setTextureMatrix(2, C * M);
   2258 			break;
   2259 		case D3DTS_TEXTURE3:
   2260 			renderer->setTextureMatrix(3, C * M);
   2261 			break;
   2262 		case D3DTS_TEXTURE4:
   2263 			renderer->setTextureMatrix(4, C * M);
   2264 			break;
   2265 		case D3DTS_TEXTURE5:
   2266 			renderer->setTextureMatrix(5, C * M);
   2267 			break;
   2268 		case D3DTS_TEXTURE6:
   2269 			renderer->setTextureMatrix(6, C * M);
   2270 			break;
   2271 		case D3DTS_TEXTURE7:
   2272 			renderer->setTextureMatrix(7, C * M);
   2273 			break;
   2274 		default:
   2275 			if(state > 256 && state < 512)
   2276 			{
   2277 				renderer->setModelMatrix(C * M, state - 256);
   2278 			}
   2279 			else ASSERT(false);
   2280 		}
   2281 
   2282 		return D3D_OK;
   2283 	}
   2284 
   2285 	long Direct3DDevice9::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion)
   2286 	{
   2287 		CriticalSection cs(this);
   2288 
   2289 		TRACE("const RECT *sourceRect = 0x%0.8p, const RECT *destRect = 0x%0.8p, HWND destWindowOverride = %d, const RGNDATA *dirtyRegion = 0x%0.8p", sourceRect, destRect, destWindowOverride, dirtyRegion);
   2290 
   2291 		return swapChain->Present(sourceRect, destRect, destWindowOverride, dirtyRegion, 0);
   2292 	}
   2293 
   2294 	long Direct3DDevice9::ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer9 *destBuffer, IDirect3DVertexDeclaration9 *vertexDeclaration, unsigned long flags)
   2295 	{
   2296 		CriticalSection cs(this);
   2297 
   2298 		TRACE("unsigned int srcStartIndex = %d, unsigned int destIndex = %d, unsigned int vertexCount = %d, IDirect3DVertexBuffer9 *destBuffer = 0x%0.8p, IDirect3DVertexDeclaration9 *vertexDeclaration = 0x%0.8p, unsigned long flags = %d", srcStartIndex, destIndex, vertexCount, destBuffer, vertexDeclaration, flags);
   2299 
   2300 		if(!destBuffer)
   2301 		{
   2302 			return INVALIDCALL();
   2303 		}
   2304 
   2305 		UNIMPLEMENTED();
   2306 
   2307 		return D3D_OK;
   2308 	}
   2309 
   2310 	long Direct3DDevice9::Reset(D3DPRESENT_PARAMETERS *presentParameters)
   2311 	{
   2312 		CriticalSection cs(this);
   2313 
   2314 		TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p", presentParameters);
   2315 
   2316 		if(!presentParameters)
   2317 		{
   2318 			return INVALIDCALL();
   2319 		}
   2320 
   2321 		deviceWindow = presentParameters->hDeviceWindow;
   2322 
   2323 		if(depthStencil)
   2324 		{
   2325 			depthStencil->unbind();
   2326 			depthStencil = 0;
   2327 		}
   2328 
   2329 		if(autoDepthStencil)
   2330 		{
   2331 			autoDepthStencil->unbind();
   2332 			autoDepthStencil = 0;
   2333 		}
   2334 
   2335 		for(int index = 0; index < 4; index++)
   2336 		{
   2337 			if(renderTarget[index])
   2338 			{
   2339 				renderTarget[index]->unbind();
   2340 				renderTarget[index] = 0;
   2341 			}
   2342 		}
   2343 
   2344 		if(!swapChain)
   2345 		{
   2346 			swapChain = new Direct3DSwapChain9(this, presentParameters);
   2347 			swapChain->bind();
   2348 		}
   2349 		else
   2350 		{
   2351 			swapChain->reset(presentParameters);
   2352 		}
   2353 
   2354 		if(presentParameters->EnableAutoDepthStencil != FALSE)
   2355 		{
   2356 			bool lockable = false;
   2357 
   2358 			switch(presentParameters->AutoDepthStencilFormat)
   2359 			{
   2360 			case D3DFMT_D15S1:
   2361 			case D3DFMT_D24S8:
   2362 			case D3DFMT_D24X8:
   2363 			case D3DFMT_D24X4S4:
   2364 			case D3DFMT_D24FS8:
   2365 			case D3DFMT_D32:
   2366 			case D3DFMT_D16:
   2367 			case D3DFMT_DF24:
   2368 			case D3DFMT_DF16:
   2369 			case D3DFMT_INTZ:
   2370 				lockable = false;
   2371 				break;
   2372 			case D3DFMT_S8_LOCKABLE:
   2373 			case D3DFMT_D16_LOCKABLE:
   2374 			case D3DFMT_D32F_LOCKABLE:
   2375 			case D3DFMT_D32_LOCKABLE:
   2376 				lockable = true;
   2377 				break;
   2378 			default:
   2379 				ASSERT(false);
   2380 			}
   2381 
   2382 			autoDepthStencil = new Direct3DSurface9(this, this, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->AutoDepthStencilFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, presentParameters->MultiSampleQuality, lockable, D3DUSAGE_DEPTHSTENCIL);
   2383 			autoDepthStencil->bind();
   2384 
   2385 			SetDepthStencilSurface(autoDepthStencil);
   2386 		}
   2387 
   2388 		IDirect3DSurface9 *renderTarget;
   2389 		swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &renderTarget);
   2390 		SetRenderTarget(0, renderTarget);
   2391 		renderTarget->Release();
   2392 
   2393 		SetRenderTarget(1, 0);
   2394 		SetRenderTarget(2, 0);
   2395 		SetRenderTarget(3, 0);
   2396 
   2397 		softwareVertexProcessing = (behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) == D3DCREATE_SOFTWARE_VERTEXPROCESSING;
   2398 
   2399 		SetRenderState(D3DRS_ZENABLE, presentParameters->EnableAutoDepthStencil != FALSE ? D3DZB_TRUE : D3DZB_FALSE);
   2400 		SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
   2401 		SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
   2402 		SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
   2403 		SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
   2404 		SetRenderState(D3DRS_LASTPIXEL, TRUE);
   2405 		SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
   2406 		SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
   2407 		SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
   2408 		SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
   2409 		SetRenderState(D3DRS_ALPHAREF, 0);
   2410 		SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
   2411 		SetRenderState(D3DRS_DITHERENABLE, FALSE);
   2412 		SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
   2413 		SetRenderState(D3DRS_FOGENABLE, FALSE);
   2414 		SetRenderState(D3DRS_SPECULARENABLE, FALSE);
   2415 	//	SetRenderState(D3DRS_ZVISIBLE, 0);
   2416 		SetRenderState(D3DRS_FOGCOLOR, 0);
   2417 		SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
   2418 		SetRenderState(D3DRS_FOGSTART, FtoDW(0.0f));
   2419 		SetRenderState(D3DRS_FOGEND, FtoDW(1.0f));
   2420 		SetRenderState(D3DRS_FOGDENSITY, FtoDW(1.0f));
   2421 		SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
   2422 		SetRenderState(D3DRS_STENCILENABLE, FALSE);
   2423 		SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
   2424 		SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
   2425 		SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
   2426 		SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
   2427 		SetRenderState(D3DRS_STENCILREF, 0);
   2428 		SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF);
   2429 		SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
   2430 		SetRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
   2431 		SetRenderState(D3DRS_WRAP0, 0);
   2432 		SetRenderState(D3DRS_WRAP1, 0);
   2433 		SetRenderState(D3DRS_WRAP2, 0);
   2434 		SetRenderState(D3DRS_WRAP3, 0);
   2435 		SetRenderState(D3DRS_WRAP4, 0);
   2436 		SetRenderState(D3DRS_WRAP5, 0);
   2437 		SetRenderState(D3DRS_WRAP6, 0);
   2438 		SetRenderState(D3DRS_WRAP7, 0);
   2439 		SetRenderState(D3DRS_CLIPPING, TRUE);
   2440 		SetRenderState(D3DRS_LIGHTING, TRUE);
   2441 		SetRenderState(D3DRS_AMBIENT, 0);
   2442 		SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
   2443 		SetRenderState(D3DRS_COLORVERTEX, TRUE);
   2444 		SetRenderState(D3DRS_LOCALVIEWER, TRUE);
   2445 		SetRenderState(D3DRS_NORMALIZENORMALS, FALSE);
   2446 		SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
   2447 		SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
   2448 		SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
   2449 		SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
   2450 		SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
   2451 		SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
   2452 		SetRenderState(D3DRS_POINTSIZE, FtoDW(1.0f));
   2453 		SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(1.0f));
   2454 		SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
   2455 		SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
   2456 		SetRenderState(D3DRS_POINTSCALE_A, FtoDW(1.0f));
   2457 		SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.0f));
   2458 		SetRenderState(D3DRS_POINTSCALE_C, FtoDW(0.0f));
   2459 		SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
   2460 		SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
   2461 		SetRenderState(D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
   2462 		SetRenderState(D3DRS_DEBUGMONITORTOKEN, D3DDMT_ENABLE);
   2463 		SetRenderState(D3DRS_POINTSIZE_MAX, FtoDW(64.0f));
   2464 		SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
   2465 		SetRenderState(D3DRS_COLORWRITEENABLE, 0x0000000F);
   2466 		SetRenderState(D3DRS_TWEENFACTOR, FtoDW(0.0f));
   2467 		SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
   2468 		SetRenderState(D3DRS_POSITIONDEGREE, D3DDEGREE_CUBIC);
   2469 		SetRenderState(D3DRS_NORMALDEGREE, D3DDEGREE_LINEAR);
   2470 		SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
   2471 		SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FtoDW(0.0f));
   2472 		SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE);
   2473 		SetRenderState(D3DRS_MINTESSELLATIONLEVEL, FtoDW(1.0f));
   2474 		SetRenderState(D3DRS_MAXTESSELLATIONLEVEL, FtoDW(1.0f));
   2475 		SetRenderState(D3DRS_ADAPTIVETESS_X, FtoDW(0.0f));
   2476 		SetRenderState(D3DRS_ADAPTIVETESS_Y, FtoDW(0.0f));
   2477 		SetRenderState(D3DRS_ADAPTIVETESS_Z, FtoDW(1.0f));
   2478 		SetRenderState(D3DRS_ADAPTIVETESS_W, FtoDW(0.0f));
   2479 		SetRenderState(D3DRS_ENABLEADAPTIVETESSELLATION, FALSE);
   2480 		SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
   2481 		SetRenderState(D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_KEEP);
   2482 		SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP);
   2483 		SetRenderState(D3DRS_CCW_STENCILPASS, D3DSTENCILOP_KEEP);
   2484 		SetRenderState(D3DRS_CCW_STENCILFUNC, D3DCMP_ALWAYS);
   2485 		SetRenderState(D3DRS_COLORWRITEENABLE1, 0x0000000F);
   2486 		SetRenderState(D3DRS_COLORWRITEENABLE2, 0x0000000F);
   2487 		SetRenderState(D3DRS_COLORWRITEENABLE3, 0x0000000F);
   2488 		SetRenderState(D3DRS_BLENDFACTOR, 0xFFFFFFFF);
   2489 		SetRenderState(D3DRS_SRGBWRITEENABLE, 0);
   2490 		SetRenderState(D3DRS_DEPTHBIAS, FtoDW(0.0f));
   2491 		SetRenderState(D3DRS_WRAP8, 0);
   2492 		SetRenderState(D3DRS_WRAP9, 0);
   2493 		SetRenderState(D3DRS_WRAP10, 0);
   2494 		SetRenderState(D3DRS_WRAP11, 0);
   2495 		SetRenderState(D3DRS_WRAP12, 0);
   2496 		SetRenderState(D3DRS_WRAP13, 0);
   2497 		SetRenderState(D3DRS_WRAP14, 0);
   2498 		SetRenderState(D3DRS_WRAP15, 0);
   2499 		SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
   2500 		SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
   2501 		SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO);
   2502 		SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD);
   2503 
   2504 		for(int i = 0; i < 8; i++)
   2505 		{
   2506 			SetTextureStageState(i, D3DTSS_COLOROP, i == 0 ? D3DTOP_MODULATE : D3DTOP_DISABLE);
   2507 			SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
   2508 			SetTextureStageState(i, D3DTSS_COLORARG2, D3DTA_CURRENT);
   2509 			SetTextureStageState(i, D3DTSS_ALPHAOP, i == 0 ? D3DTOP_SELECTARG1 : D3DTOP_DISABLE);
   2510 			SetTextureStageState(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
   2511 			SetTextureStageState(i, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
   2512 			SetTextureStageState(i, D3DTSS_BUMPENVMAT00, FtoDW(0.0f));
   2513 			SetTextureStageState(i, D3DTSS_BUMPENVMAT01, FtoDW(0.0f));
   2514 			SetTextureStageState(i, D3DTSS_BUMPENVMAT10, FtoDW(0.0f));
   2515 			SetTextureStageState(i, D3DTSS_BUMPENVMAT11, FtoDW(0.0f));
   2516 			SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, i);
   2517 			SetTextureStageState(i, D3DTSS_BUMPENVLSCALE, FtoDW(0.0f));
   2518 			SetTextureStageState(i, D3DTSS_BUMPENVLOFFSET, FtoDW(0.0f));
   2519 			SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
   2520 			SetTextureStageState(i, D3DTSS_COLORARG0, D3DTA_CURRENT);
   2521 			SetTextureStageState(i, D3DTSS_ALPHAARG0, D3DTA_CURRENT);
   2522 			SetTextureStageState(i, D3DTSS_RESULTARG, D3DTA_CURRENT);
   2523 			SetTextureStageState(i, D3DTSS_CONSTANT, 0x00000000);
   2524 		}
   2525 
   2526 		for(int i = 0; i <= D3DVERTEXTEXTURESAMPLER3; i = (i != 15) ? (i + 1) : D3DVERTEXTEXTURESAMPLER0)
   2527 		{
   2528 			SetTexture(i, 0);
   2529 
   2530 			SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
   2531 			SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
   2532 			SetSamplerState(i, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
   2533 			SetSamplerState(i, D3DSAMP_BORDERCOLOR, 0x00000000);
   2534 			SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
   2535 			SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
   2536 			SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
   2537 			SetSamplerState(i, D3DSAMP_MIPMAPLODBIAS, 0);
   2538 			SetSamplerState(i, D3DSAMP_MAXMIPLEVEL, 0);
   2539 			SetSamplerState(i, D3DSAMP_MAXANISOTROPY, 1);
   2540 			SetSamplerState(i, D3DSAMP_SRGBTEXTURE, 0);
   2541 			SetSamplerState(i, D3DSAMP_ELEMENTINDEX, 0);
   2542 			SetSamplerState(i, D3DSAMP_DMAPOFFSET, 0);
   2543 		}
   2544 
   2545 		for(int i = 0; i < 6; i++)
   2546 		{
   2547 			float plane[4] = {0, 0, 0, 0};
   2548 
   2549 			SetClipPlane(i, plane);
   2550 		}
   2551 
   2552 		currentPalette = 0xFFFF;
   2553 
   2554 		ShowCursor(FALSE);
   2555 		delete cursor;
   2556 		cursor = 0;
   2557 
   2558 		return D3D_OK;
   2559 	}
   2560 
   2561 	long Direct3DDevice9::SetClipPlane(unsigned long index, const float *plane)
   2562 	{
   2563 		CriticalSection cs(this);
   2564 
   2565 		TRACE("unsigned long index = %d, const float *plane = 0x%0.8p", index, plane);
   2566 
   2567 		if(!plane || index >= 6)
   2568 		{
   2569 			return INVALIDCALL();
   2570 		}
   2571 
   2572 		if(!stateRecorder)
   2573 		{
   2574 			this->plane[index][0] = plane[0];
   2575 			this->plane[index][1] = plane[1];
   2576 			this->plane[index][2] = plane[2];
   2577 			this->plane[index][3] = plane[3];
   2578 
   2579 			renderer->setClipPlane(index, plane);
   2580 		}
   2581 		else
   2582 		{
   2583 			stateRecorder->setClipPlane(index, plane);
   2584 		}
   2585 
   2586 		return D3D_OK;
   2587 	}
   2588 
   2589 	long Direct3DDevice9::SetClipStatus(const D3DCLIPSTATUS9 *clipStatus)
   2590 	{
   2591 		CriticalSection cs(this);
   2592 
   2593 		TRACE("const D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);
   2594 
   2595 		if(!clipStatus)
   2596 		{
   2597 			return INVALIDCALL();
   2598 		}
   2599 
   2600 		this->clipStatus = *clipStatus;
   2601 
   2602 		UNIMPLEMENTED();
   2603 
   2604 		return D3D_OK;
   2605 	}
   2606 
   2607 	long Direct3DDevice9::SetCurrentTexturePalette(unsigned int paletteNumber)
   2608 	{
   2609 		CriticalSection cs(this);
   2610 
   2611 		TRACE("unsigned int paletteNumber = %d", paletteNumber);
   2612 
   2613 		if(paletteNumber > 0xFFFF || palette.find(paletteNumber) == palette.end())
   2614 		{
   2615 			return INVALIDCALL();
   2616 		}
   2617 
   2618 		if(!stateRecorder)
   2619 		{
   2620 			currentPalette = paletteNumber;
   2621 
   2622 			sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
   2623 		}
   2624 		else
   2625 		{
   2626 			stateRecorder->setCurrentTexturePalette(paletteNumber);
   2627 		}
   2628 
   2629 		return D3D_OK;
   2630 	}
   2631 
   2632 	void Direct3DDevice9::SetCursorPosition(int x, int y, unsigned long flags)
   2633 	{
   2634 		CriticalSection cs(this);
   2635 
   2636 		TRACE("int x = %d, int y = %d, unsigned long flags = 0x%0.8X", x, y, flags);
   2637 
   2638 		POINT point = {x, y};
   2639 		HWND window = deviceWindow ? deviceWindow : focusWindow;
   2640 		ScreenToClient(window, &point);
   2641 
   2642 		sw::FrameBuffer::setCursorPosition(point.x, point.y);
   2643 	}
   2644 
   2645 	long Direct3DDevice9::SetCursorProperties(unsigned int x0, unsigned int y0, IDirect3DSurface9 *cursorBitmap)
   2646 	{
   2647 		CriticalSection cs(this);
   2648 
   2649 		TRACE("unsigned int x0 = %d, unsigned int y0 = %d, IDirect3DSurface9 *cursorBitmap = 0x%0.8p", x0, y0, cursorBitmap);
   2650 
   2651 		if(!cursorBitmap)
   2652 		{
   2653 			return INVALIDCALL();
   2654 		}
   2655 
   2656 		sw::Surface *cursorSurface = static_cast<Direct3DSurface9*>(cursorBitmap);
   2657 
   2658 		int width = cursorSurface->getWidth();
   2659 		int height = cursorSurface->getHeight();
   2660 		void *bitmap = cursorSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
   2661 
   2662 		delete cursor;
   2663 		cursor = sw::Surface::create(nullptr, width, height, 1, 0, 1, sw::FORMAT_A8R8G8B8, false, false);
   2664 
   2665 		void *buffer = cursor->lockExternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
   2666 		memcpy(buffer, bitmap, width * height * sizeof(unsigned int));
   2667 		cursor->unlockExternal();
   2668 
   2669 		cursorSurface->unlockExternal();
   2670 
   2671 		if(showCursor)
   2672 		{
   2673 			sw::FrameBuffer::setCursorImage(cursor);
   2674 		}
   2675 		else
   2676 		{
   2677 			sw::FrameBuffer::setCursorImage(nullptr);
   2678 		}
   2679 
   2680 		sw::FrameBuffer::setCursorOrigin(x0, y0);
   2681 
   2682 		return D3D_OK;
   2683 	}
   2684 
   2685 	long Direct3DDevice9::SetDepthStencilSurface(IDirect3DSurface9 *iDepthStencil)
   2686 	{
   2687 		CriticalSection cs(this);
   2688 
   2689 		TRACE("IDirect3DSurface9 *newDepthStencil = 0x%0.8p", iDepthStencil);
   2690 
   2691 		Direct3DSurface9 *depthStencil = static_cast<Direct3DSurface9*>(iDepthStencil);
   2692 
   2693 		if(this->depthStencil == depthStencil)
   2694 		{
   2695 			return D3D_OK;
   2696 		}
   2697 
   2698 		if(depthStencil)
   2699 		{
   2700 			depthStencil->bind();
   2701 		}
   2702 
   2703 		if(this->depthStencil)
   2704 		{
   2705 			this->depthStencil->unbind();
   2706 		}
   2707 
   2708 		this->depthStencil = depthStencil;
   2709 
   2710 		renderer->setDepthBuffer(depthStencil);
   2711 		renderer->setStencilBuffer(depthStencil);
   2712 
   2713 		return D3D_OK;
   2714 	}
   2715 
   2716 	long Direct3DDevice9::SetDialogBoxMode(int enableDialogs)
   2717 	{
   2718 		CriticalSection cs(this);
   2719 
   2720 		TRACE("int enableDialogs = %d", enableDialogs);
   2721 
   2722 		UNIMPLEMENTED();
   2723 
   2724 		return D3D_OK;
   2725 	}
   2726 
   2727 	long Direct3DDevice9::SetFVF(unsigned long FVF)
   2728 	{
   2729 		CriticalSection cs(this);
   2730 
   2731 		TRACE("unsigned long FVF = 0x%0.8X", FVF);
   2732 
   2733 		if(!stateRecorder)
   2734 		{
   2735 			if(FVF != 0 || !this->vertexDeclaration)
   2736 			{
   2737 				Direct3DVertexDeclaration9 *vertexDeclaration = new Direct3DVertexDeclaration9(this, FVF);
   2738 				vertexDeclaration->bind();
   2739 
   2740 				if(this->vertexDeclaration)
   2741 				{
   2742 					this->vertexDeclaration->unbind();
   2743 				}
   2744 
   2745 				this->vertexDeclaration = vertexDeclaration;
   2746 			}
   2747 		}
   2748 		else
   2749 		{
   2750 			stateRecorder->setFVF(FVF);
   2751 		}
   2752 
   2753 		return D3D_OK;
   2754 	}
   2755 
   2756 	void Direct3DDevice9::SetGammaRamp(unsigned int index, unsigned long flags, const D3DGAMMARAMP *ramp)
   2757 	{
   2758 		CriticalSection cs(this);
   2759 
   2760 		TRACE("unsigned int index = %d, unsigned long flags = 0x%0.8X, const D3DGAMMARAMP *ramp = 0x%0.8p", index, flags, ramp);
   2761 
   2762 		if(!ramp || index >= GetNumberOfSwapChains())
   2763 		{
   2764 			return;
   2765 		}
   2766 
   2767 		swapChain->setGammaRamp((sw::GammaRamp*)ramp, flags & D3DSGR_CALIBRATE);
   2768 	}
   2769 
   2770 	long Direct3DDevice9::SetIndices(IDirect3DIndexBuffer9* iIndexBuffer)
   2771 	{
   2772 		CriticalSection cs(this);
   2773 
   2774 		TRACE("IDirect3DIndexBuffer9* indexData = 0x%0.8p", iIndexBuffer);
   2775 
   2776 		Direct3DIndexBuffer9 *indexBuffer = static_cast<Direct3DIndexBuffer9*>(iIndexBuffer);
   2777 
   2778 		if(!stateRecorder)
   2779 		{
   2780 			if(this->indexData == indexBuffer)
   2781 			{
   2782 				return D3D_OK;
   2783 			}
   2784 
   2785 			if(indexBuffer)
   2786 			{
   2787 				indexBuffer->bind();
   2788 			}
   2789 
   2790 			if(this->indexData)
   2791 			{
   2792 				this->indexData->unbind();
   2793 			}
   2794 
   2795 			this->indexData = indexBuffer;
   2796 		}
   2797 		else
   2798 		{
   2799 			stateRecorder->setIndices(indexBuffer);
   2800 		}
   2801 
   2802 		return D3D_OK;
   2803 	}
   2804 
   2805 	long Direct3DDevice9::SetLight(unsigned long index, const D3DLIGHT9 *light)
   2806 	{
   2807 		CriticalSection cs(this);
   2808 
   2809 		TRACE("unsigned long index = %d, const D3DLIGHT9 *light = 0x%0.8p", index, light);
   2810 
   2811 		if(!light)
   2812 		{
   2813 			return INVALIDCALL();
   2814 		}
   2815 
   2816 		if(!stateRecorder)
   2817 		{
   2818 			this->light[index] = *light;
   2819 
   2820 			lightsDirty = true;
   2821 		}
   2822 		else
   2823 		{
   2824 			stateRecorder->setLight(index, light);
   2825 		}
   2826 
   2827 		return D3D_OK;
   2828 	}
   2829 
   2830 	long Direct3DDevice9::SetMaterial(const D3DMATERIAL9 *material)
   2831 	{
   2832 		CriticalSection cs(this);
   2833 
   2834 		TRACE("const D3DMATERIAL9 *material = 0x%0.8p", material);
   2835 
   2836 		if(!material)
   2837 		{
   2838 			return INVALIDCALL();   // FIXME: Correct behaviour?
   2839 		}
   2840 
   2841 		if(!stateRecorder)
   2842 		{
   2843 			this->material = *material;
   2844 
   2845 			renderer->setMaterialAmbient(sw::Color<float>(material->Ambient.r, material->Ambient.g, material->Ambient.b, material->Ambient.a));
   2846 			renderer->setMaterialDiffuse(sw::Color<float>(material->Diffuse.r, material->Diffuse.g, material->Diffuse.b, material->Diffuse.a));
   2847 			renderer->setMaterialEmission(sw::Color<float>(material->Emissive.r, material->Emissive.g, material->Emissive.b, material->Emissive.a));
   2848 			renderer->setMaterialShininess(material->Power);
   2849 			renderer->setMaterialSpecular(sw::Color<float>(material->Specular.r, material->Specular.g, material->Specular.b, material->Specular.a));
   2850 		}
   2851 		else
   2852 		{
   2853 			stateRecorder->setMaterial(material);
   2854 		}
   2855 
   2856 		return D3D_OK;
   2857 	}
   2858 
   2859 	long Direct3DDevice9::SetNPatchMode(float segments)
   2860 	{
   2861 		CriticalSection cs(this);
   2862 
   2863 		TRACE("float segments = %f", segments);
   2864 
   2865 		if(!stateRecorder)
   2866 		{
   2867 			if(segments < 1)
   2868 			{
   2869 				// NOTE: Disable
   2870 			}
   2871 			else
   2872 			{
   2873 				UNIMPLEMENTED();
   2874 			}
   2875 		}
   2876 		else
   2877 		{
   2878 			stateRecorder->setNPatchMode(segments);
   2879 		}
   2880 
   2881 		return D3D_OK;
   2882 	}
   2883 
   2884 	long Direct3DDevice9::SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries)
   2885 	{
   2886 		CriticalSection cs(this);
   2887 
   2888 		TRACE("unsigned int paletteNumber = %d, const PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);
   2889 
   2890 		if(paletteNumber > 0xFFFF || !entries)
   2891 		{
   2892 			return INVALIDCALL();
   2893 		}
   2894 
   2895 		for(int i = 0; i < 256; i++)
   2896 		{
   2897 			palette[paletteNumber].entry[i] = entries[i];
   2898 		}
   2899 
   2900 		if(paletteNumber == currentPalette)
   2901 		{
   2902 			sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
   2903 		}
   2904 
   2905 		return D3D_OK;
   2906 	}
   2907 
   2908 	long Direct3DDevice9::SetPixelShader(IDirect3DPixelShader9 *iPixelShader)
   2909 	{
   2910 		CriticalSection cs(this);
   2911 
   2912 		TRACE("IDirect3DPixelShader9 *shader = 0x%0.8p", iPixelShader);
   2913 
   2914 		Direct3DPixelShader9 *pixelShader = static_cast<Direct3DPixelShader9*>(iPixelShader);
   2915 
   2916 		if(!stateRecorder)
   2917 		{
   2918 			if(this->pixelShader == pixelShader)
   2919 			{
   2920 				return D3D_OK;
   2921 			}
   2922 
   2923 			if(pixelShader)
   2924 			{
   2925 				pixelShader->bind();
   2926 			}
   2927 
   2928 			if(this->pixelShader)
   2929 			{
   2930 				this->pixelShader->unbind();
   2931 			}
   2932 
   2933 			this->pixelShader = pixelShader;
   2934 			pixelShaderDirty = true;
   2935 		}
   2936 		else
   2937 		{
   2938 			stateRecorder->setPixelShader(pixelShader);
   2939 		}
   2940 
   2941 		return D3D_OK;
   2942 	}
   2943 
   2944 	long Direct3DDevice9::SetPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
   2945 	{
   2946 		CriticalSection cs(this);
   2947 
   2948 		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   2949 
   2950 		if(!stateRecorder)
   2951 		{
   2952 			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
   2953 			{
   2954 				pixelShaderConstantB[startRegister + i] = constantData[i];
   2955 			}
   2956 
   2957 			pixelShaderConstantsBDirty = sw::max(startRegister + count, pixelShaderConstantsBDirty);
   2958 			pixelShaderDirty = true;   // Reload DEF constants
   2959 		}
   2960 		else
   2961 		{
   2962 			stateRecorder->setPixelShaderConstantB(startRegister, constantData, count);
   2963 		}
   2964 
   2965 		return D3D_OK;
   2966 	}
   2967 
   2968 	long Direct3DDevice9::SetPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
   2969 	{
   2970 		CriticalSection cs(this);
   2971 
   2972 		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   2973 
   2974 		if(!stateRecorder)
   2975 		{
   2976 			for(unsigned int i = 0; i < count && startRegister + i < MAX_PIXEL_SHADER_CONST; i++)
   2977 			{
   2978 				pixelShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
   2979 				pixelShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
   2980 				pixelShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
   2981 				pixelShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
   2982 			}
   2983 
   2984 			pixelShaderConstantsFDirty = sw::max(startRegister + count, pixelShaderConstantsFDirty);
   2985 			pixelShaderDirty = true;   // Reload DEF constants
   2986 		}
   2987 		else
   2988 		{
   2989 			stateRecorder->setPixelShaderConstantF(startRegister, constantData, count);
   2990 		}
   2991 
   2992 		return D3D_OK;
   2993 	}
   2994 
   2995 	long Direct3DDevice9::SetPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
   2996 	{
   2997 		CriticalSection cs(this);
   2998 
   2999 		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   3000 
   3001 		if(!stateRecorder)
   3002 		{
   3003 			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
   3004 			{
   3005 				pixelShaderConstantI[startRegister + i][0] = constantData[i * 4 + 0];
   3006 				pixelShaderConstantI[startRegister + i][1] = constantData[i * 4 + 1];
   3007 				pixelShaderConstantI[startRegister + i][2] = constantData[i * 4 + 2];
   3008 				pixelShaderConstantI[startRegister + i][3] = constantData[i * 4 + 3];
   3009 			}
   3010 
   3011 			pixelShaderConstantsIDirty = sw::max(startRegister + count, pixelShaderConstantsIDirty);
   3012 			pixelShaderDirty = true;   // Reload DEF constants
   3013 		}
   3014 		else
   3015 		{
   3016 			stateRecorder->setPixelShaderConstantI(startRegister, constantData, count);
   3017 		}
   3018 
   3019 		return D3D_OK;
   3020 	}
   3021 
   3022 	long Direct3DDevice9::SetRenderState(D3DRENDERSTATETYPE state, unsigned long value)
   3023 	{
   3024 		CriticalSection cs(this);
   3025 
   3026 		TRACE("D3DRENDERSTATETYPE state = %d, unsigned long value = %d", state, value);
   3027 
   3028 		if(state < D3DRS_ZENABLE || state > D3DRS_BLENDOPALPHA)
   3029 		{
   3030 			return D3D_OK;   // FIXME: Warning
   3031 		}
   3032 
   3033 		if(!stateRecorder)
   3034 		{
   3035 			if(!init && renderState[state] == value)
   3036 			{
   3037 				return D3D_OK;
   3038 			}
   3039 
   3040 			renderState[state] = value;
   3041 
   3042 			switch(state)
   3043 			{
   3044 			case D3DRS_ZENABLE:
   3045 				switch(value)
   3046 				{
   3047 				case D3DZB_TRUE:
   3048 				case D3DZB_USEW:
   3049 					renderer->setDepthBufferEnable(true);
   3050 					break;
   3051 				case D3DZB_FALSE:
   3052 					renderer->setDepthBufferEnable(false);
   3053 					break;
   3054 				default:
   3055 					ASSERT(false);
   3056 				}
   3057 				break;
   3058 			case D3DRS_FILLMODE:
   3059 				switch(value)
   3060 				{
   3061 				case D3DFILL_POINT:
   3062 					renderer->setFillMode(sw::FILL_VERTEX);
   3063 					break;
   3064 				case D3DFILL_WIREFRAME:
   3065 					renderer->setFillMode(sw::FILL_WIREFRAME);
   3066 					break;
   3067 				case D3DFILL_SOLID:
   3068 					renderer->setFillMode(sw::FILL_SOLID);
   3069 					break;
   3070 				default:
   3071 					ASSERT(false);
   3072 				}
   3073 				break;
   3074 			case D3DRS_SHADEMODE:
   3075 				switch(value)
   3076 				{
   3077 				case D3DSHADE_FLAT:
   3078 					renderer->setShadingMode(sw::SHADING_FLAT);
   3079 					break;
   3080 				case D3DSHADE_GOURAUD:
   3081 					renderer->setShadingMode(sw::SHADING_GOURAUD);
   3082 					break;
   3083 				case D3DSHADE_PHONG:
   3084 					break;
   3085 				default:
   3086 					ASSERT(false);
   3087 				}
   3088 				break;
   3089 			case D3DRS_ZWRITEENABLE:
   3090 				renderer->setDepthWriteEnable(value != FALSE);
   3091 				break;
   3092 			case D3DRS_ALPHATESTENABLE:
   3093 				renderer->setAlphaTestEnable(value != FALSE);
   3094 				break;
   3095 			case D3DRS_LASTPIXEL:
   3096 			//	if(!init) UNIMPLEMENTED();   // FIXME
   3097 				break;
   3098 			case D3DRS_SRCBLEND:
   3099 				switch(value)
   3100 				{
   3101 				case D3DBLEND_ZERO:
   3102 					renderer->setSourceBlendFactor(sw::BLEND_ZERO);
   3103 					break;
   3104 				case D3DBLEND_ONE:
   3105 					renderer->setSourceBlendFactor(sw::BLEND_ONE);
   3106 					break;
   3107 				case D3DBLEND_SRCCOLOR:
   3108 					renderer->setSourceBlendFactor(sw::BLEND_SOURCE);
   3109 					break;
   3110 				case D3DBLEND_INVSRCCOLOR:
   3111 					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCE);
   3112 					break;
   3113 				case D3DBLEND_SRCALPHA:
   3114 					renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
   3115 					break;
   3116 				case D3DBLEND_INVSRCALPHA:
   3117 					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
   3118 					break;
   3119 				case D3DBLEND_DESTALPHA:
   3120 					renderer->setSourceBlendFactor(sw::BLEND_DESTALPHA);
   3121 					break;
   3122 				case D3DBLEND_INVDESTALPHA:
   3123 					renderer->setSourceBlendFactor(sw::BLEND_INVDESTALPHA);
   3124 					break;
   3125 				case D3DBLEND_DESTCOLOR:
   3126 					renderer->setSourceBlendFactor(sw::BLEND_DEST);
   3127 					break;
   3128 				case D3DBLEND_INVDESTCOLOR:
   3129 					renderer->setSourceBlendFactor(sw::BLEND_INVDEST);
   3130 					break;
   3131 				case D3DBLEND_SRCALPHASAT:
   3132 					renderer->setSourceBlendFactor(sw::BLEND_SRCALPHASAT);
   3133 					break;
   3134 				case D3DBLEND_BOTHSRCALPHA:
   3135 					renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
   3136 					renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
   3137 					break;
   3138 				case D3DBLEND_BOTHINVSRCALPHA:
   3139 					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
   3140 					renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
   3141 					break;
   3142 				case D3DBLEND_BLENDFACTOR:
   3143 					renderer->setSourceBlendFactor(sw::BLEND_CONSTANT);
   3144 					break;
   3145 				case D3DBLEND_INVBLENDFACTOR:
   3146 					renderer->setSourceBlendFactor(sw::BLEND_INVCONSTANT);
   3147 					break;
   3148 				default:
   3149 					ASSERT(false);
   3150 				}
   3151 				break;
   3152 			case D3DRS_DESTBLEND:
   3153 				switch(value)
   3154 				{
   3155 				case D3DBLEND_ZERO:
   3156 					renderer->setDestBlendFactor(sw::BLEND_ZERO);
   3157 					break;
   3158 				case D3DBLEND_ONE:
   3159 					renderer->setDestBlendFactor(sw::BLEND_ONE);
   3160 					break;
   3161 				case D3DBLEND_SRCCOLOR:
   3162 					renderer->setDestBlendFactor(sw::BLEND_SOURCE);
   3163 					break;
   3164 				case D3DBLEND_INVSRCCOLOR:
   3165 					renderer->setDestBlendFactor(sw::BLEND_INVSOURCE);
   3166 					break;
   3167 				case D3DBLEND_SRCALPHA:
   3168 					renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
   3169 					break;
   3170 				case D3DBLEND_INVSRCALPHA:
   3171 					renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
   3172 					break;
   3173 				case D3DBLEND_DESTALPHA:
   3174 					renderer->setDestBlendFactor(sw::BLEND_DESTALPHA);
   3175 					break;
   3176 				case D3DBLEND_INVDESTALPHA:
   3177 					renderer->setDestBlendFactor(sw::BLEND_INVDESTALPHA);
   3178 					break;
   3179 				case D3DBLEND_DESTCOLOR:
   3180 					renderer->setDestBlendFactor(sw::BLEND_DEST);
   3181 					break;
   3182 				case D3DBLEND_INVDESTCOLOR:
   3183 					renderer->setDestBlendFactor(sw::BLEND_INVDEST);
   3184 					break;
   3185 				case D3DBLEND_SRCALPHASAT:
   3186 					renderer->setDestBlendFactor(sw::BLEND_SRCALPHASAT);
   3187 					break;
   3188 				case D3DBLEND_BOTHSRCALPHA:
   3189 					renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
   3190 					renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
   3191 					break;
   3192 				case D3DBLEND_BOTHINVSRCALPHA:
   3193 					renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
   3194 					renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
   3195 					break;
   3196 				case D3DBLEND_BLENDFACTOR:
   3197 					renderer->setDestBlendFactor(sw::BLEND_CONSTANT);
   3198 					break;
   3199 				case D3DBLEND_INVBLENDFACTOR:
   3200 					renderer->setDestBlendFactor(sw::BLEND_INVCONSTANT);
   3201 					break;
   3202 				default:
   3203 					ASSERT(false);
   3204 				}
   3205 				break;
   3206 			case D3DRS_CULLMODE:
   3207 				switch(value)
   3208 				{
   3209 				case D3DCULL_NONE:
   3210 					renderer->setCullMode(sw::CULL_NONE);
   3211 					break;
   3212 				case D3DCULL_CCW:
   3213 					renderer->setCullMode(sw::CULL_COUNTERCLOCKWISE);
   3214 					break;
   3215 				case D3DCULL_CW:
   3216 					renderer->setCullMode(sw::CULL_CLOCKWISE);
   3217 					break;
   3218 				default:
   3219 					ASSERT(false);
   3220 				}
   3221 				break;
   3222 			case D3DRS_ZFUNC:
   3223 				switch(value)
   3224 				{
   3225 				case D3DCMP_NEVER:
   3226 					renderer->setDepthCompare(sw::DEPTH_NEVER);
   3227 					break;
   3228 				case D3DCMP_LESS:
   3229 					renderer->setDepthCompare(sw::DEPTH_LESS);
   3230 					break;
   3231 				case D3DCMP_EQUAL:
   3232 					renderer->setDepthCompare(sw::DEPTH_EQUAL);
   3233 					break;
   3234 				case D3DCMP_LESSEQUAL:
   3235 					renderer->setDepthCompare(sw::DEPTH_LESSEQUAL);
   3236 					break;
   3237 				case D3DCMP_GREATER:
   3238 					renderer->setDepthCompare(sw::DEPTH_GREATER);
   3239 					break;
   3240 				case D3DCMP_NOTEQUAL:
   3241 					renderer->setDepthCompare(sw::DEPTH_NOTEQUAL);
   3242 					break;
   3243 				case D3DCMP_GREATEREQUAL:
   3244 					renderer->setDepthCompare(sw::DEPTH_GREATEREQUAL);
   3245 					break;
   3246 				case D3DCMP_ALWAYS:
   3247 					renderer->setDepthCompare(sw::DEPTH_ALWAYS);
   3248 					break;
   3249 				default:
   3250 					ASSERT(false);
   3251 				}
   3252 				break;
   3253 			case D3DRS_ALPHAREF:
   3254 				renderer->setAlphaReference(value & 0x000000FF);
   3255 				break;
   3256 			case D3DRS_ALPHAFUNC:
   3257 				switch(value)
   3258 				{
   3259 				case D3DCMP_NEVER:
   3260 					renderer->setAlphaCompare(sw::ALPHA_NEVER);
   3261 					break;
   3262 				case D3DCMP_LESS:
   3263 					renderer->setAlphaCompare(sw::ALPHA_LESS);
   3264 					break;
   3265 				case D3DCMP_EQUAL:
   3266 					renderer->setAlphaCompare(sw::ALPHA_EQUAL);
   3267 					break;
   3268 				case D3DCMP_LESSEQUAL:
   3269 					renderer->setAlphaCompare(sw::ALPHA_LESSEQUAL);
   3270 					break;
   3271 				case D3DCMP_GREATER:
   3272 					renderer->setAlphaCompare(sw::ALPHA_GREATER);
   3273 					break;
   3274 				case D3DCMP_NOTEQUAL:
   3275 					renderer->setAlphaCompare(sw::ALPHA_NOTEQUAL);
   3276 					break;
   3277 				case D3DCMP_GREATEREQUAL:
   3278 					renderer->setAlphaCompare(sw::ALPHA_GREATEREQUAL);
   3279 					break;
   3280 				case D3DCMP_ALWAYS:
   3281 					renderer->setAlphaCompare(sw::ALPHA_ALWAYS);
   3282 					break;
   3283 				default:
   3284 					ASSERT(false);
   3285 				}
   3286 				break;
   3287 			case D3DRS_DITHERENABLE:
   3288 			//	if(!init) UNIMPLEMENTED();
   3289 				break;
   3290 			case D3DRS_ALPHABLENDENABLE:
   3291 				renderer->setAlphaBlendEnable(value != FALSE);
   3292 				break;
   3293 			case D3DRS_FOGENABLE:
   3294 				renderer->setFogEnable(value != FALSE);
   3295 				break;
   3296 			case D3DRS_FOGCOLOR:
   3297 				renderer->setFogColor(value);
   3298 				break;
   3299 			case D3DRS_FOGTABLEMODE:
   3300 				switch(value)
   3301 				{
   3302 				case D3DFOG_NONE:
   3303 					renderer->setPixelFogMode(sw::FOG_NONE);
   3304 					break;
   3305 				case D3DFOG_LINEAR:
   3306 					renderer->setPixelFogMode(sw::FOG_LINEAR);
   3307 					break;
   3308 				case D3DFOG_EXP:
   3309 					renderer->setPixelFogMode(sw::FOG_EXP);
   3310 					break;
   3311 				case D3DFOG_EXP2:
   3312 					renderer->setPixelFogMode(sw::FOG_EXP2);
   3313 					break;
   3314 				default:
   3315 					ASSERT(false);
   3316 				}
   3317 				break;
   3318 			case D3DRS_FOGSTART:
   3319 				renderer->setFogStart((float&)value);
   3320 				break;
   3321 			case D3DRS_FOGEND:
   3322 				renderer->setFogEnd((float&)value);
   3323 				break;
   3324 			case D3DRS_FOGDENSITY:
   3325 				renderer->setFogDensity((float&)value);
   3326 				break;
   3327 			case D3DRS_RANGEFOGENABLE:
   3328 				renderer->setRangeFogEnable(value != FALSE);
   3329 				break;
   3330 			case D3DRS_SPECULARENABLE:
   3331 				renderer->setSpecularEnable(value != FALSE);
   3332 				break;
   3333 			case D3DRS_STENCILENABLE:
   3334 				renderer->setStencilEnable(value != FALSE);
   3335 				break;
   3336 			case D3DRS_STENCILFAIL:
   3337 				switch(value)
   3338 				{
   3339 				case D3DSTENCILOP_KEEP:
   3340 					renderer->setStencilFailOperation(sw::OPERATION_KEEP);
   3341 					break;
   3342 				case D3DSTENCILOP_ZERO:
   3343 					renderer->setStencilFailOperation(sw::OPERATION_ZERO);
   3344 					break;
   3345 				case D3DSTENCILOP_REPLACE:
   3346 					renderer->setStencilFailOperation(sw::OPERATION_REPLACE);
   3347 					break;
   3348 				case D3DSTENCILOP_INCRSAT:
   3349 					renderer->setStencilFailOperation(sw::OPERATION_INCRSAT);
   3350 					break;
   3351 				case D3DSTENCILOP_DECRSAT:
   3352 					renderer->setStencilFailOperation(sw::OPERATION_DECRSAT);
   3353 					break;
   3354 				case D3DSTENCILOP_INVERT:
   3355 					renderer->setStencilFailOperation(sw::OPERATION_INVERT);
   3356 					break;
   3357 				case D3DSTENCILOP_INCR:
   3358 					renderer->setStencilFailOperation(sw::OPERATION_INCR);
   3359 					break;
   3360 				case D3DSTENCILOP_DECR:
   3361 					renderer->setStencilFailOperation(sw::OPERATION_DECR);
   3362 					break;
   3363 				default:
   3364 					ASSERT(false);
   3365 				}
   3366 				break;
   3367 			case D3DRS_STENCILZFAIL:
   3368 				switch(value)
   3369 				{
   3370 				case D3DSTENCILOP_KEEP:
   3371 					renderer->setStencilZFailOperation(sw::OPERATION_KEEP);
   3372 					break;
   3373 				case D3DSTENCILOP_ZERO:
   3374 					renderer->setStencilZFailOperation(sw::OPERATION_ZERO);
   3375 					break;
   3376 				case D3DSTENCILOP_REPLACE:
   3377 					renderer->setStencilZFailOperation(sw::OPERATION_REPLACE);
   3378 					break;
   3379 				case D3DSTENCILOP_INCRSAT:
   3380 					renderer->setStencilZFailOperation(sw::OPERATION_INCRSAT);
   3381 					break;
   3382 				case D3DSTENCILOP_DECRSAT:
   3383 					renderer->setStencilZFailOperation(sw::OPERATION_DECRSAT);
   3384 					break;
   3385 				case D3DSTENCILOP_INVERT:
   3386 					renderer->setStencilZFailOperation(sw::OPERATION_INVERT);
   3387 					break;
   3388 				case D3DSTENCILOP_INCR:
   3389 					renderer->setStencilZFailOperation(sw::OPERATION_INCR);
   3390 					break;
   3391 				case D3DSTENCILOP_DECR:
   3392 					renderer->setStencilZFailOperation(sw::OPERATION_DECR);
   3393 					break;
   3394 				default:
   3395 					ASSERT(false);
   3396 				}
   3397 				break;
   3398 			case D3DRS_STENCILPASS:
   3399 				switch(value)
   3400 				{
   3401 				case D3DSTENCILOP_KEEP:
   3402 					renderer->setStencilPassOperation(sw::OPERATION_KEEP);
   3403 					break;
   3404 				case D3DSTENCILOP_ZERO:
   3405 					renderer->setStencilPassOperation(sw::OPERATION_ZERO);
   3406 					break;
   3407 				case D3DSTENCILOP_REPLACE:
   3408 					renderer->setStencilPassOperation(sw::OPERATION_REPLACE);
   3409 					break;
   3410 				case D3DSTENCILOP_INCRSAT:
   3411 					renderer->setStencilPassOperation(sw::OPERATION_INCRSAT);
   3412 					break;
   3413 				case D3DSTENCILOP_DECRSAT:
   3414 					renderer->setStencilPassOperation(sw::OPERATION_DECRSAT);
   3415 					break;
   3416 				case D3DSTENCILOP_INVERT:
   3417 					renderer->setStencilPassOperation(sw::OPERATION_INVERT);
   3418 					break;
   3419 				case D3DSTENCILOP_INCR:
   3420 					renderer->setStencilPassOperation(sw::OPERATION_INCR);
   3421 					break;
   3422 				case D3DSTENCILOP_DECR:
   3423 					renderer->setStencilPassOperation(sw::OPERATION_DECR);
   3424 					break;
   3425 				default:
   3426 					ASSERT(false);
   3427 				}
   3428 				break;
   3429 			case D3DRS_STENCILFUNC:
   3430 				switch(value)
   3431 				{
   3432 				case D3DCMP_NEVER:
   3433 					renderer->setStencilCompare(sw::STENCIL_NEVER);
   3434 					break;
   3435 				case D3DCMP_LESS:
   3436 					renderer->setStencilCompare(sw::STENCIL_LESS);
   3437 					break;
   3438 				case D3DCMP_EQUAL:
   3439 					renderer->setStencilCompare(sw::STENCIL_EQUAL);
   3440 					break;
   3441 				case D3DCMP_LESSEQUAL:
   3442 					renderer->setStencilCompare(sw::STENCIL_LESSEQUAL);
   3443 					break;
   3444 				case D3DCMP_GREATER:
   3445 					renderer->setStencilCompare(sw::STENCIL_GREATER);
   3446 					break;
   3447 				case D3DCMP_NOTEQUAL:
   3448 					renderer->setStencilCompare(sw::STENCIL_NOTEQUAL);
   3449 					break;
   3450 				case D3DCMP_GREATEREQUAL:
   3451 					renderer->setStencilCompare(sw::STENCIL_GREATEREQUAL);
   3452 					break;
   3453 				case D3DCMP_ALWAYS:
   3454 					renderer->setStencilCompare(sw::STENCIL_ALWAYS);
   3455 					break;
   3456 				default:
   3457 					ASSERT(false);
   3458 				}
   3459 				break;
   3460 			case D3DRS_STENCILREF:
   3461 				renderer->setStencilReference(value);
   3462 				renderer->setStencilReferenceCCW(value);
   3463 				break;
   3464 			case D3DRS_STENCILMASK:
   3465 				renderer->setStencilMask(value);
   3466 				renderer->setStencilMaskCCW(value);
   3467 				break;
   3468 			case D3DRS_STENCILWRITEMASK:
   3469 				renderer->setStencilWriteMask(value);
   3470 				renderer->setStencilWriteMaskCCW(value);
   3471 				break;
   3472 			case D3DRS_TEXTUREFACTOR:
   3473 				renderer->setTextureFactor(value);
   3474 				break;
   3475 			case D3DRS_WRAP0:
   3476 				renderer->setTextureWrap(0, value);
   3477 				break;
   3478 			case D3DRS_WRAP1:
   3479 				renderer->setTextureWrap(1, value);
   3480 				break;
   3481 			case D3DRS_WRAP2:
   3482 				renderer->setTextureWrap(2, value);
   3483 				break;
   3484 			case D3DRS_WRAP3:
   3485 				renderer->setTextureWrap(3, value);
   3486 				break;
   3487 			case D3DRS_WRAP4:
   3488 				renderer->setTextureWrap(4, value);
   3489 				break;
   3490 			case D3DRS_WRAP5:
   3491 				renderer->setTextureWrap(5, value);
   3492 				break;
   3493 			case D3DRS_WRAP6:
   3494 				renderer->setTextureWrap(6, value);
   3495 				break;
   3496 			case D3DRS_WRAP7:
   3497 				renderer->setTextureWrap(7, value);
   3498 				break;
   3499 			case D3DRS_CLIPPING:
   3500 				// Ignored, clipping is always performed
   3501 				break;
   3502 			case D3DRS_LIGHTING:
   3503 				renderer->setLightingEnable(value != FALSE);
   3504 				break;
   3505 			case D3DRS_AMBIENT:
   3506 				renderer->setGlobalAmbient(value);
   3507 				break;
   3508 			case D3DRS_FOGVERTEXMODE:
   3509 				switch(value)
   3510 				{
   3511 				case D3DFOG_NONE:
   3512 					renderer->setVertexFogMode(sw::FOG_NONE);
   3513 					break;
   3514 				case D3DFOG_LINEAR:
   3515 					renderer->setVertexFogMode(sw::FOG_LINEAR);
   3516 					break;
   3517 				case D3DFOG_EXP:
   3518 					renderer->setVertexFogMode(sw::FOG_EXP);
   3519 					break;
   3520 				case D3DFOG_EXP2:
   3521 					renderer->setVertexFogMode(sw::FOG_EXP2);
   3522 					break;
   3523 				default:
   3524 					ASSERT(false);
   3525 				}
   3526 				break;
   3527 			case D3DRS_COLORVERTEX:
   3528 				renderer->setColorVertexEnable(value != FALSE);
   3529 				break;
   3530 			case D3DRS_LOCALVIEWER:
   3531 				renderer->setLocalViewer(value != FALSE);
   3532 				break;
   3533 			case D3DRS_NORMALIZENORMALS:
   3534 				renderer->setNormalizeNormals(value != FALSE);
   3535 				break;
   3536 			case D3DRS_DIFFUSEMATERIALSOURCE:
   3537 				switch(value)
   3538 				{
   3539 				case D3DMCS_MATERIAL:
   3540 					renderer->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
   3541 					break;
   3542 				case D3DMCS_COLOR1:
   3543 					renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
   3544 					break;
   3545 				case D3DMCS_COLOR2:
   3546 					renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR2);
   3547 					break;
   3548 				default:
   3549 					ASSERT(false);
   3550 				}
   3551 				break;
   3552 			case D3DRS_SPECULARMATERIALSOURCE:
   3553 				switch(value)
   3554 				{
   3555 				case D3DMCS_MATERIAL:
   3556 					renderer->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
   3557 					break;
   3558 				case D3DMCS_COLOR1:
   3559 					renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR1);
   3560 					break;
   3561 				case D3DMCS_COLOR2:
   3562 					renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR2);
   3563 					break;
   3564 				default:
   3565 					ASSERT(false);
   3566 				}
   3567 				break;
   3568 			case D3DRS_AMBIENTMATERIALSOURCE:
   3569 				switch(value)
   3570 				{
   3571 				case D3DMCS_MATERIAL:
   3572 					renderer->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
   3573 					break;
   3574 				case D3DMCS_COLOR1:
   3575 					renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
   3576 					break;
   3577 				case D3DMCS_COLOR2:
   3578 					renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR2);
   3579 					break;
   3580 				default:
   3581 					ASSERT(false);
   3582 				}
   3583 				break;
   3584 			case D3DRS_EMISSIVEMATERIALSOURCE:
   3585 				switch(value)
   3586 				{
   3587 				case D3DMCS_MATERIAL:
   3588 					renderer->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
   3589 					break;
   3590 				case D3DMCS_COLOR1:
   3591 					renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);
   3592 					break;
   3593 				case D3DMCS_COLOR2:
   3594 					renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR2);
   3595 					break;
   3596 				default:
   3597 					ASSERT(false);
   3598 				}
   3599 				break;
   3600 			case D3DRS_VERTEXBLEND:
   3601 				switch(value)
   3602 				{
   3603 				case D3DVBF_DISABLE:
   3604 					renderer->setVertexBlendMatrixCount(0);
   3605 					break;
   3606 				case D3DVBF_1WEIGHTS:
   3607 					renderer->setVertexBlendMatrixCount(2);
   3608 					break;
   3609 				case D3DVBF_2WEIGHTS:
   3610 					renderer->setVertexBlendMatrixCount(3);
   3611 					break;
   3612 				case D3DVBF_3WEIGHTS:
   3613 					renderer->setVertexBlendMatrixCount(4);
   3614 					break;
   3615 				case D3DVBF_TWEENING:
   3616 					UNIMPLEMENTED();
   3617 					break;
   3618 				case D3DVBF_0WEIGHTS:
   3619 					renderer->setVertexBlendMatrixCount(1);
   3620 					break;
   3621 				default:
   3622 					ASSERT(false);
   3623 				}
   3624 				break;
   3625 			case D3DRS_CLIPPLANEENABLE:
   3626 				renderer->setClipFlags(value);
   3627 				break;
   3628 			case D3DRS_POINTSIZE:
   3629 				if(value == D3DFMT_INST && pixelShaderVersionX >= D3DPS_VERSION(2, 0))   // ATI hack to enable instancing on SM 2.0 hardware
   3630 				{
   3631 					instancingEnabled = true;
   3632 				}
   3633 				else if(value == D3DFMT_A2M1)   // ATI hack to enable transparency anti-aliasing
   3634 				{
   3635 					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
   3636 					renderer->setAlphaTestEnable(true);
   3637 				}
   3638 				else if(value == D3DFMT_A2M0)   // ATI hack to disable transparency anti-aliasing
   3639 				{
   3640 					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
   3641 					renderer->setAlphaTestEnable(false);
   3642 				}
   3643 				else
   3644 				{
   3645 					renderer->setPointSize((float&)value);
   3646 				}
   3647 				break;
   3648 			case D3DRS_POINTSIZE_MIN:
   3649 				renderer->setPointSizeMin((float&)value);
   3650 				break;
   3651 			case D3DRS_POINTSPRITEENABLE:
   3652 				renderer->setPointSpriteEnable(value != FALSE);
   3653 				break;
   3654 			case D3DRS_POINTSCALEENABLE:
   3655 				renderer->setPointScaleEnable(value != FALSE);
   3656 				break;
   3657 			case D3DRS_POINTSCALE_A:
   3658 				renderer->setPointScaleA((float&)value);
   3659 				break;
   3660 			case D3DRS_POINTSCALE_B:
   3661 				renderer->setPointScaleB((float&)value);
   3662 				break;
   3663 			case D3DRS_POINTSCALE_C:
   3664 				renderer->setPointScaleC((float&)value);
   3665 				break;
   3666 			case D3DRS_MULTISAMPLEANTIALIAS:
   3667 			//	if(!init) UNIMPLEMENTED();
   3668 				break;
   3669 			case D3DRS_MULTISAMPLEMASK:
   3670 				SetRenderTarget(0, renderTarget[0]);   // Sets the multi-sample mask, if maskable
   3671 				break;
   3672 			case D3DRS_PATCHEDGESTYLE:
   3673 				if(!init) if(value != D3DPATCHEDGE_DISCRETE) UNIMPLEMENTED();
   3674 				break;
   3675 			case D3DRS_DEBUGMONITORTOKEN:
   3676 				if(!init) UNIMPLEMENTED();
   3677 				break;
   3678 			case D3DRS_POINTSIZE_MAX:
   3679 				renderer->setPointSizeMax((float&)value);
   3680 				break;
   3681 			case D3DRS_INDEXEDVERTEXBLENDENABLE:
   3682 				renderer->setIndexedVertexBlendEnable(value != FALSE);
   3683 				break;
   3684 			case D3DRS_COLORWRITEENABLE:
   3685 				renderer->setColorWriteMask(0, value & 0x0000000F);
   3686 				break;
   3687 			case D3DRS_TWEENFACTOR:
   3688 				if(!init) UNIMPLEMENTED();
   3689 				break;
   3690 			case D3DRS_BLENDOP:
   3691 				switch(value)
   3692 				{
   3693 				case D3DBLENDOP_ADD:
   3694 					renderer->setBlendOperation(sw::BLENDOP_ADD);
   3695 					break;
   3696 				case D3DBLENDOP_SUBTRACT:
   3697 					renderer->setBlendOperation(sw::BLENDOP_SUB);
   3698 					break;
   3699 				case D3DBLENDOP_REVSUBTRACT:
   3700 					renderer->setBlendOperation(sw::BLENDOP_INVSUB);
   3701 					break;
   3702 				case D3DBLENDOP_MIN:
   3703 					renderer->setBlendOperation(sw::BLENDOP_MIN);
   3704 					break;
   3705 				case D3DBLENDOP_MAX:
   3706 					renderer->setBlendOperation(sw::BLENDOP_MAX);
   3707 					break;
   3708 				default:
   3709 					ASSERT(false);
   3710 				}
   3711 				break;
   3712 			case D3DRS_POSITIONDEGREE:
   3713 				if(!init) UNIMPLEMENTED();
   3714 				break;
   3715 			case D3DRS_NORMALDEGREE:
   3716 				if(!init) UNIMPLEMENTED();
   3717 				break;
   3718 			case D3DRS_SCISSORTESTENABLE:
   3719 				scissorEnable = (value != FALSE);
   3720 				break;
   3721 			case D3DRS_SLOPESCALEDEPTHBIAS:
   3722 				renderer->setSlopeDepthBias((float&)value);
   3723 				break;
   3724 			case D3DRS_ANTIALIASEDLINEENABLE:
   3725 				if(!init) if(value != FALSE) UNIMPLEMENTED();
   3726 				break;
   3727 			case D3DRS_MINTESSELLATIONLEVEL:
   3728 				if(!init) UNIMPLEMENTED();
   3729 				break;
   3730 			case D3DRS_MAXTESSELLATIONLEVEL:
   3731 				if(!init) UNIMPLEMENTED();
   3732 				break;
   3733 			case D3DRS_ADAPTIVETESS_X:
   3734 				if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
   3735 				break;
   3736 			case D3DRS_ADAPTIVETESS_Y:
   3737 				if(value == D3DFMT_ATOC)   // NVIDIA hack to enable transparency anti-aliasing
   3738 				{
   3739 					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
   3740 				}
   3741 				else if(value == D3DFMT_UNKNOWN)   // NVIDIA hack to disable transparency anti-aliasing
   3742 				{
   3743 					renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
   3744 				}
   3745 				else
   3746 				{
   3747 					if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
   3748 				}
   3749 				break;
   3750 			case D3DRS_ADAPTIVETESS_Z:
   3751 				if(!init) if((float&)value != 1.0f) UNIMPLEMENTED();
   3752 				break;
   3753 			case D3DRS_ADAPTIVETESS_W:
   3754 				if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
   3755 				break;
   3756 			case D3DRS_ENABLEADAPTIVETESSELLATION:
   3757 				if(!init) UNIMPLEMENTED();
   3758 				break;
   3759 			case D3DRS_TWOSIDEDSTENCILMODE:
   3760 				renderer->setTwoSidedStencil(value != FALSE);
   3761 				break;
   3762 			case D3DRS_CCW_STENCILFAIL:
   3763 				switch(value)
   3764 				{
   3765 				case D3DSTENCILOP_KEEP:
   3766 					renderer->setStencilFailOperationCCW(sw::OPERATION_KEEP);
   3767 					break;
   3768 				case D3DSTENCILOP_ZERO:
   3769 					renderer->setStencilFailOperationCCW(sw::OPERATION_ZERO);
   3770 					break;
   3771 				case D3DSTENCILOP_REPLACE:
   3772 					renderer->setStencilFailOperationCCW(sw::OPERATION_REPLACE);
   3773 					break;
   3774 				case D3DSTENCILOP_INCRSAT:
   3775 					renderer->setStencilFailOperationCCW(sw::OPERATION_INCRSAT);
   3776 					break;
   3777 				case D3DSTENCILOP_DECRSAT:
   3778 					renderer->setStencilFailOperationCCW(sw::OPERATION_DECRSAT);
   3779 					break;
   3780 				case D3DSTENCILOP_INVERT:
   3781 					renderer->setStencilFailOperationCCW(sw::OPERATION_INVERT);
   3782 					break;
   3783 				case D3DSTENCILOP_INCR:
   3784 					renderer->setStencilFailOperationCCW(sw::OPERATION_INCR);
   3785 					break;
   3786 				case D3DSTENCILOP_DECR:
   3787 					renderer->setStencilFailOperationCCW(sw::OPERATION_DECR);
   3788 					break;
   3789 				default:
   3790 					ASSERT(false);
   3791 				}
   3792 				break;
   3793 			case D3DRS_CCW_STENCILZFAIL:
   3794 				switch(value)
   3795 				{
   3796 				case D3DSTENCILOP_KEEP:
   3797 					renderer->setStencilZFailOperationCCW(sw::OPERATION_KEEP);
   3798 					break;
   3799 				case D3DSTENCILOP_ZERO:
   3800 					renderer->setStencilZFailOperationCCW(sw::OPERATION_ZERO);
   3801 					break;
   3802 				case D3DSTENCILOP_REPLACE:
   3803 					renderer->setStencilZFailOperationCCW(sw::OPERATION_REPLACE);
   3804 					break;
   3805 				case D3DSTENCILOP_INCRSAT:
   3806 					renderer->setStencilZFailOperationCCW(sw::OPERATION_INCRSAT);
   3807 					break;
   3808 				case D3DSTENCILOP_DECRSAT:
   3809 					renderer->setStencilZFailOperationCCW(sw::OPERATION_DECRSAT);
   3810 					break;
   3811 				case D3DSTENCILOP_INVERT:
   3812 					renderer->setStencilZFailOperationCCW(sw::OPERATION_INVERT);
   3813 					break;
   3814 				case D3DSTENCILOP_INCR:
   3815 					renderer->setStencilZFailOperationCCW(sw::OPERATION_INCR);
   3816 					break;
   3817 				case D3DSTENCILOP_DECR:
   3818 					renderer->setStencilZFailOperationCCW(sw::OPERATION_DECR);
   3819 					break;
   3820 				default:
   3821 					ASSERT(false);
   3822 				}
   3823 				break;
   3824 			case D3DRS_CCW_STENCILPASS:
   3825 				switch(value)
   3826 				{
   3827 				case D3DSTENCILOP_KEEP:
   3828 					renderer->setStencilPassOperationCCW(sw::OPERATION_KEEP);
   3829 					break;
   3830 				case D3DSTENCILOP_ZERO:
   3831 					renderer->setStencilPassOperationCCW(sw::OPERATION_ZERO);
   3832 					break;
   3833 				case D3DSTENCILOP_REPLACE:
   3834 					renderer->setStencilPassOperationCCW(sw::OPERATION_REPLACE);
   3835 					break;
   3836 				case D3DSTENCILOP_INCRSAT:
   3837 					renderer->setStencilPassOperationCCW(sw::OPERATION_INCRSAT);
   3838 					break;
   3839 				case D3DSTENCILOP_DECRSAT:
   3840 					renderer->setStencilPassOperationCCW(sw::OPERATION_DECRSAT);
   3841 					break;
   3842 				case D3DSTENCILOP_INVERT:
   3843 					renderer->setStencilPassOperationCCW(sw::OPERATION_INVERT);
   3844 					break;
   3845 				case D3DSTENCILOP_INCR:
   3846 					renderer->setStencilPassOperationCCW(sw::OPERATION_INCR);
   3847 					break;
   3848 				case D3DSTENCILOP_DECR:
   3849 					renderer->setStencilPassOperationCCW(sw::OPERATION_DECR);
   3850 					break;
   3851 				default:
   3852 					ASSERT(false);
   3853 				}
   3854 				break;
   3855 			case D3DRS_CCW_STENCILFUNC:
   3856 				switch(value)
   3857 				{
   3858 				case D3DCMP_NEVER:
   3859 					renderer->setStencilCompareCCW(sw::STENCIL_NEVER);
   3860 					break;
   3861 				case D3DCMP_LESS:
   3862 					renderer->setStencilCompareCCW(sw::STENCIL_LESS);
   3863 					break;
   3864 				case D3DCMP_EQUAL:
   3865 					renderer->setStencilCompareCCW(sw::STENCIL_EQUAL);
   3866 					break;
   3867 				case D3DCMP_LESSEQUAL:
   3868 					renderer->setStencilCompareCCW(sw::STENCIL_LESSEQUAL);
   3869 					break;
   3870 				case D3DCMP_GREATER:
   3871 					renderer->setStencilCompareCCW(sw::STENCIL_GREATER);
   3872 					break;
   3873 				case D3DCMP_NOTEQUAL:
   3874 					renderer->setStencilCompareCCW(sw::STENCIL_NOTEQUAL);
   3875 					break;
   3876 				case D3DCMP_GREATEREQUAL:
   3877 					renderer->setStencilCompareCCW(sw::STENCIL_GREATEREQUAL);
   3878 					break;
   3879 				case D3DCMP_ALWAYS:
   3880 					renderer->setStencilCompareCCW(sw::STENCIL_ALWAYS);
   3881 					break;
   3882 				default:
   3883 					ASSERT(false);
   3884 				}
   3885 				break;
   3886 			case D3DRS_COLORWRITEENABLE1:
   3887 				renderer->setColorWriteMask(1, value);
   3888 				break;
   3889 			case D3DRS_COLORWRITEENABLE2:
   3890 				renderer->setColorWriteMask(2, value);
   3891 				break;
   3892 			case D3DRS_COLORWRITEENABLE3:
   3893 				renderer->setColorWriteMask(3, value);
   3894 				break;
   3895 			case D3DRS_BLENDFACTOR:
   3896 				renderer->setBlendConstant(sw::Color<float>(value));
   3897 				break;
   3898 			case D3DRS_SRGBWRITEENABLE:
   3899 				renderer->setWriteSRGB(value != FALSE);
   3900 				break;
   3901 			case D3DRS_DEPTHBIAS:
   3902 				renderer->setDepthBias((float&)value);
   3903 				break;
   3904 			case D3DRS_WRAP8:
   3905 				renderer->setTextureWrap(8, value);
   3906 				break;
   3907 			case D3DRS_WRAP9:
   3908 				renderer->setTextureWrap(9, value);
   3909 				break;
   3910 			case D3DRS_WRAP10:
   3911 				renderer->setTextureWrap(10, value);
   3912 				break;
   3913 			case D3DRS_WRAP11:
   3914 				renderer->setTextureWrap(11, value);
   3915 				break;
   3916 			case D3DRS_WRAP12:
   3917 				renderer->setTextureWrap(12, value);
   3918 				break;
   3919 			case D3DRS_WRAP13:
   3920 				renderer->setTextureWrap(13, value);
   3921 				break;
   3922 			case D3DRS_WRAP14:
   3923 				renderer->setTextureWrap(14, value);
   3924 				break;
   3925 			case D3DRS_WRAP15:
   3926 				renderer->setTextureWrap(15, value);
   3927 				break;
   3928 			case D3DRS_SEPARATEALPHABLENDENABLE:
   3929 				renderer->setSeparateAlphaBlendEnable(value != FALSE);
   3930 				break;
   3931 			case D3DRS_SRCBLENDALPHA:
   3932 				switch(value)
   3933 				{
   3934 				case D3DBLEND_ZERO:
   3935 					renderer->setSourceBlendFactorAlpha(sw::BLEND_ZERO);
   3936 					break;
   3937 				case D3DBLEND_ONE:
   3938 					renderer->setSourceBlendFactorAlpha(sw::BLEND_ONE);
   3939 					break;
   3940 				case D3DBLEND_SRCCOLOR:
   3941 					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCE);
   3942 					break;
   3943 				case D3DBLEND_INVSRCCOLOR:
   3944 					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCE);
   3945 					break;
   3946 				case D3DBLEND_SRCALPHA:
   3947 					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
   3948 					break;
   3949 				case D3DBLEND_INVSRCALPHA:
   3950 					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
   3951 					break;
   3952 				case D3DBLEND_DESTALPHA:
   3953 					renderer->setSourceBlendFactorAlpha(sw::BLEND_DESTALPHA);
   3954 					break;
   3955 				case D3DBLEND_INVDESTALPHA:
   3956 					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVDESTALPHA);
   3957 					break;
   3958 				case D3DBLEND_DESTCOLOR:
   3959 					renderer->setSourceBlendFactorAlpha(sw::BLEND_DEST);
   3960 					break;
   3961 				case D3DBLEND_INVDESTCOLOR:
   3962 					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVDEST);
   3963 					break;
   3964 				case D3DBLEND_SRCALPHASAT:
   3965 					renderer->setSourceBlendFactorAlpha(sw::BLEND_SRCALPHASAT);
   3966 					break;
   3967 				case D3DBLEND_BOTHSRCALPHA:
   3968 					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
   3969 					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
   3970 					break;
   3971 				case D3DBLEND_BOTHINVSRCALPHA:
   3972 					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
   3973 					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
   3974 					break;
   3975 				case D3DBLEND_BLENDFACTOR:
   3976 					renderer->setSourceBlendFactorAlpha(sw::BLEND_CONSTANT);
   3977 					break;
   3978 				case D3DBLEND_INVBLENDFACTOR:
   3979 					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVCONSTANT);
   3980 					break;
   3981 				default:
   3982 					ASSERT(false);
   3983 				}
   3984 				break;
   3985 			case D3DRS_DESTBLENDALPHA:
   3986 				switch(value)
   3987 				{
   3988 				case D3DBLEND_ZERO:
   3989 					renderer->setDestBlendFactorAlpha(sw::BLEND_ZERO);
   3990 					break;
   3991 				case D3DBLEND_ONE:
   3992 					renderer->setDestBlendFactorAlpha(sw::BLEND_ONE);
   3993 					break;
   3994 				case D3DBLEND_SRCCOLOR:
   3995 					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCE);
   3996 					break;
   3997 				case D3DBLEND_INVSRCCOLOR:
   3998 					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCE);
   3999 					break;
   4000 				case D3DBLEND_SRCALPHA:
   4001 					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
   4002 					break;
   4003 				case D3DBLEND_INVSRCALPHA:
   4004 					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
   4005 					break;
   4006 				case D3DBLEND_DESTALPHA:
   4007 					renderer->setDestBlendFactorAlpha(sw::BLEND_DESTALPHA);
   4008 					break;
   4009 				case D3DBLEND_INVDESTALPHA:
   4010 					renderer->setDestBlendFactorAlpha(sw::BLEND_INVDESTALPHA);
   4011 					break;
   4012 				case D3DBLEND_DESTCOLOR:
   4013 					renderer->setDestBlendFactorAlpha(sw::BLEND_DEST);
   4014 					break;
   4015 				case D3DBLEND_INVDESTCOLOR:
   4016 					renderer->setDestBlendFactorAlpha(sw::BLEND_INVDEST);
   4017 					break;
   4018 				case D3DBLEND_SRCALPHASAT:
   4019 					renderer->setDestBlendFactorAlpha(sw::BLEND_SRCALPHASAT);
   4020 					break;
   4021 				case D3DBLEND_BOTHSRCALPHA:
   4022 					renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
   4023 					renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
   4024 					break;
   4025 				case D3DBLEND_BOTHINVSRCALPHA:
   4026 					renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
   4027 					renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
   4028 					break;
   4029 				case D3DBLEND_BLENDFACTOR:
   4030 					renderer->setDestBlendFactorAlpha(sw::BLEND_CONSTANT);
   4031 					break;
   4032 				case D3DBLEND_INVBLENDFACTOR:
   4033 					renderer->setDestBlendFactorAlpha(sw::BLEND_INVCONSTANT);
   4034 					break;
   4035 				default:
   4036 					ASSERT(false);
   4037 				}
   4038 				break;
   4039 			case D3DRS_BLENDOPALPHA:
   4040 				switch(value)
   4041 				{
   4042 				case D3DBLENDOP_ADD:
   4043 					renderer->setBlendOperationAlpha(sw::BLENDOP_ADD);
   4044 					break;
   4045 				case D3DBLENDOP_SUBTRACT:
   4046 					renderer->setBlendOperationAlpha(sw::BLENDOP_SUB);
   4047 					break;
   4048 				case D3DBLENDOP_REVSUBTRACT:
   4049 					renderer->setBlendOperationAlpha(sw::BLENDOP_INVSUB);
   4050 					break;
   4051 				case D3DBLENDOP_MIN:
   4052 					renderer->setBlendOperationAlpha(sw::BLENDOP_MIN);
   4053 					break;
   4054 				case D3DBLENDOP_MAX:
   4055 					renderer->setBlendOperationAlpha(sw::BLENDOP_MAX);
   4056 					break;
   4057 				default:
   4058 					ASSERT(false);
   4059 				}
   4060 				break;
   4061 			default:
   4062 				ASSERT(false);
   4063 			}
   4064 		}
   4065 		else   // stateRecorder
   4066 		{
   4067 			stateRecorder->setRenderState(state, value);
   4068 		}
   4069 
   4070 		return D3D_OK;
   4071 	}
   4072 
   4073 	long Direct3DDevice9::SetRenderTarget(unsigned long index, IDirect3DSurface9 *iRenderTarget)
   4074 	{
   4075 		CriticalSection cs(this);
   4076 
   4077 		TRACE("unsigned long index = %d, IDirect3DSurface9 *newRenderTarget = 0x%0.8p", index, iRenderTarget);
   4078 
   4079 		// FIXME: Check for D3DUSAGE_RENDERTARGET
   4080 
   4081 		if(index >= 4 || (index == 0 && !iRenderTarget))
   4082 		{
   4083 			return INVALIDCALL();
   4084 		}
   4085 
   4086 		Direct3DSurface9 *renderTarget = static_cast<Direct3DSurface9*>(iRenderTarget);
   4087 
   4088 		if(renderTarget)
   4089 		{
   4090 			renderTarget->bind();
   4091 		}
   4092 
   4093 		if(this->renderTarget[index])
   4094 		{
   4095 			this->renderTarget[index]->unbind();
   4096 		}
   4097 
   4098 		this->renderTarget[index] = renderTarget;
   4099 
   4100 		if(renderTarget && index == 0)
   4101 		{
   4102 			D3DSURFACE_DESC renderTargetDesc;
   4103 			renderTarget->GetDesc(&renderTargetDesc);
   4104 
   4105 			// Reset viewport to size of current render target
   4106 			viewport.X = 0;
   4107 			viewport.Y = 0;
   4108 			viewport.Width = renderTargetDesc.Width;
   4109 			viewport.Height = renderTargetDesc.Height;
   4110 			viewport.MinZ = 0;
   4111 			viewport.MaxZ = 1;
   4112 
   4113 			// Reset scissor rectangle to size of current render target
   4114 			scissorRect.left = 0;
   4115 			scissorRect.top = 0;
   4116 			scissorRect.right = renderTargetDesc.Width;
   4117 			scissorRect.bottom = renderTargetDesc.Height;
   4118 
   4119 			// Set the multi-sample mask, if maskable
   4120 			if(renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONE &&
   4121 			   renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONMASKABLE)
   4122 			{
   4123 				renderer->setMultiSampleMask(renderState[D3DRS_MULTISAMPLEMASK]);
   4124 			}
   4125 			else
   4126 			{
   4127 				renderer->setMultiSampleMask(0xFFFFFFFF);
   4128 			}
   4129 		}
   4130 
   4131 		renderer->setRenderTarget(index, renderTarget);
   4132 
   4133 		return D3D_OK;
   4134 	}
   4135 
   4136 	long Direct3DDevice9::SetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long value)
   4137 	{
   4138 		CriticalSection cs(this);
   4139 
   4140 		TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE state = %d, unsigned long value = %d", sampler, state, value);
   4141 
   4142 		if(state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET)
   4143 		{
   4144 			return INVALIDCALL();
   4145 		}
   4146 
   4147 		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
   4148 		{
   4149 			return INVALIDCALL();
   4150 		}
   4151 
   4152 		if(sampler >= D3DVERTEXTEXTURESAMPLER0)
   4153 		{
   4154 			sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
   4155 		}
   4156 
   4157 		if(!stateRecorder)
   4158 		{
   4159 			if(!init && samplerState[sampler][state] == value)
   4160 			{
   4161 				return D3D_OK;
   4162 			}
   4163 
   4164 			samplerState[sampler][state] = value;
   4165 
   4166 			sw::SamplerType type = sampler < 16 ? sw::SAMPLER_PIXEL : sw::SAMPLER_VERTEX;
   4167 			int index = sampler < 16 ? sampler : sampler - 16;   // Sampler index within type group
   4168 
   4169 			switch(state)
   4170 			{
   4171 			case D3DSAMP_ADDRESSU:
   4172 				switch(value)
   4173 				{
   4174 				case D3DTADDRESS_WRAP:
   4175 					renderer->setAddressingModeU(type, index, sw::ADDRESSING_WRAP);
   4176 					break;
   4177 				case D3DTADDRESS_MIRROR:
   4178 					renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRROR);
   4179 					break;
   4180 				case D3DTADDRESS_CLAMP:
   4181 					renderer->setAddressingModeU(type, index, sw::ADDRESSING_CLAMP);
   4182 					break;
   4183 				case D3DTADDRESS_BORDER:
   4184 					renderer->setAddressingModeU(type, index, sw::ADDRESSING_BORDER);
   4185 					break;
   4186 				case D3DTADDRESS_MIRRORONCE:
   4187 					renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRRORONCE);
   4188 					break;
   4189 				default:
   4190 					ASSERT(false);
   4191 				}
   4192 				break;
   4193 			case D3DSAMP_ADDRESSV:
   4194 				switch(value)
   4195 				{
   4196 				case D3DTADDRESS_WRAP:
   4197 					renderer->setAddressingModeV(type, index, sw::ADDRESSING_WRAP);
   4198 					break;
   4199 				case D3DTADDRESS_MIRROR:
   4200 					renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRROR);
   4201 					break;
   4202 				case D3DTADDRESS_CLAMP:
   4203 					renderer->setAddressingModeV(type, index, sw::ADDRESSING_CLAMP);
   4204 					break;
   4205 				case D3DTADDRESS_BORDER:
   4206 					renderer->setAddressingModeV(type, index, sw::ADDRESSING_BORDER);
   4207 					break;
   4208 				case D3DTADDRESS_MIRRORONCE:
   4209 					renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRRORONCE);
   4210 					break;
   4211 				default:
   4212 					ASSERT(false);
   4213 				}
   4214 				break;
   4215 			case D3DSAMP_ADDRESSW:
   4216 				switch(value)
   4217 				{
   4218 				case D3DTADDRESS_WRAP:
   4219 					renderer->setAddressingModeW(type, index, sw::ADDRESSING_WRAP);
   4220 					break;
   4221 				case D3DTADDRESS_MIRROR:
   4222 					renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRROR);
   4223 					break;
   4224 				case D3DTADDRESS_CLAMP:
   4225 					renderer->setAddressingModeW(type, index, sw::ADDRESSING_CLAMP);
   4226 					break;
   4227 				case D3DTADDRESS_BORDER:
   4228 					renderer->setAddressingModeW(type, index, sw::ADDRESSING_BORDER);
   4229 					break;
   4230 				case D3DTADDRESS_MIRRORONCE:
   4231 					renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRRORONCE);
   4232 					break;
   4233 				default:
   4234 					ASSERT(false);
   4235 				}
   4236 				break;
   4237 			case D3DSAMP_BORDERCOLOR:
   4238 				renderer->setBorderColor(type, index, value);
   4239 				break;
   4240 			case D3DSAMP_MAGFILTER:
   4241 				// NOTE: SwiftShader does not differentiate between minification and magnification filter
   4242 				switch(value)
   4243 				{
   4244 				case D3DTEXF_NONE:
   4245 					renderer->setTextureFilter(type, index, sw::FILTER_POINT);   // FIXME: Only for mipmap filter
   4246 					break;
   4247 				case D3DTEXF_POINT:
   4248 					renderer->setTextureFilter(type, index, sw::FILTER_POINT);
   4249 					break;
   4250 				case D3DTEXF_LINEAR:
   4251 					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);
   4252 					break;
   4253 				case D3DTEXF_ANISOTROPIC:
   4254 					renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);
   4255 					break;
   4256 				case D3DTEXF_PYRAMIDALQUAD:
   4257 					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
   4258 					break;
   4259 				case D3DTEXF_GAUSSIANQUAD:
   4260 					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
   4261 					break;
   4262 				default:
   4263 					return INVALIDCALL();
   4264 				};
   4265 				break;
   4266 			case D3DSAMP_MINFILTER:
   4267 				// NOTE: SwiftShader does not differentiate between minification and magnification filter
   4268 				switch(value)
   4269 				{
   4270 				case D3DTEXF_NONE:
   4271 					renderer->setTextureFilter(type, index, sw::FILTER_POINT);   // FIXME: Only for mipmap filter
   4272 					break;
   4273 				case D3DTEXF_POINT:
   4274 					renderer->setTextureFilter(type, index, sw::FILTER_POINT);
   4275 					break;
   4276 				case D3DTEXF_LINEAR:
   4277 					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);
   4278 					break;
   4279 				case D3DTEXF_ANISOTROPIC:
   4280 					renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);
   4281 					break;
   4282 				case D3DTEXF_PYRAMIDALQUAD:
   4283 					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
   4284 					break;
   4285 				case D3DTEXF_GAUSSIANQUAD:
   4286 					renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
   4287 					break;
   4288 				default:
   4289 					return INVALIDCALL();
   4290 				};
   4291 				break;
   4292 			case D3DSAMP_MIPFILTER:
   4293 				switch(value)
   4294 				{
   4295 				case D3DTEXF_NONE:
   4296 					renderer->setMipmapFilter(type, index, sw::MIPMAP_NONE);
   4297 					break;
   4298 				case D3DTEXF_POINT:
   4299 					renderer->setMipmapFilter(type, index, sw::MIPMAP_POINT);
   4300 					break;
   4301 				case D3DTEXF_LINEAR:
   4302 					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);
   4303 					break;
   4304 				case D3DTEXF_ANISOTROPIC:
   4305 					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter
   4306 					break;
   4307 				case D3DTEXF_PYRAMIDALQUAD:
   4308 					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter
   4309 					break;
   4310 				case D3DTEXF_GAUSSIANQUAD:
   4311 					renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter
   4312 					break;
   4313 				default:
   4314 					return INVALIDCALL();
   4315 				};
   4316 				break;
   4317 			case D3DSAMP_MIPMAPLODBIAS:
   4318 				if(value == D3DFMT_GET4)   // ATI hack to enable Fetch4
   4319 				{
   4320 					renderer->setGatherEnable(type, index, true);
   4321 				}
   4322 				else if(value == D3DFMT_GET1)   // ATI hack to disable Fetch4
   4323 				{
   4324 					renderer->setGatherEnable(type, index, false);
   4325 				}
   4326 				else
   4327 				{
   4328 					float LOD = (float&)value - sw::log2((float)context->renderTarget[0]->getSuperSampleCount());   // FIXME: Update when render target changes
   4329 					renderer->setMipmapLOD(type, index, LOD);
   4330 				}
   4331 				break;
   4332 			case D3DSAMP_MAXMIPLEVEL:
   4333 				break;
   4334 			case D3DSAMP_MAXANISOTROPY:
   4335 				renderer->setMaxAnisotropy(type, index, sw::clamp((unsigned int)value, (unsigned int)1, maxAnisotropy));
   4336 				break;
   4337 			case D3DSAMP_SRGBTEXTURE:
   4338 				renderer->setReadSRGB(type, index, value != FALSE);
   4339 				break;
   4340 			case D3DSAMP_ELEMENTINDEX:
   4341 				if(!init) UNIMPLEMENTED();   // Multi-element textures deprecated in favor of multiple render targets
   4342 				break;
   4343 			case D3DSAMP_DMAPOFFSET:
   4344 			//	if(!init) UNIMPLEMENTED();
   4345 				break;
   4346 			default:
   4347 				ASSERT(false);
   4348 			}
   4349 		}
   4350 		else   // stateRecorder
   4351 		{
   4352 			stateRecorder->setSamplerState(sampler, state, value);
   4353 		}
   4354 
   4355 		return D3D_OK;
   4356 	}
   4357 
   4358 	long Direct3DDevice9::SetScissorRect(const RECT *rect)
   4359 	{
   4360 		CriticalSection cs(this);
   4361 
   4362 		TRACE("const RECT *rect = 0x%0.8p", rect);
   4363 
   4364 		if(!rect)
   4365 		{
   4366 			return INVALIDCALL();
   4367 		}
   4368 
   4369 		if(!stateRecorder)
   4370 		{
   4371 			scissorRect = *rect;
   4372 		}
   4373 		else
   4374 		{
   4375 			stateRecorder->setScissorRect(rect);
   4376 		}
   4377 
   4378 		return D3D_OK;
   4379 	}
   4380 
   4381 	long Direct3DDevice9::SetSoftwareVertexProcessing(int software)
   4382 	{
   4383 		CriticalSection cs(this);
   4384 
   4385 		TRACE("int software = %d", software);
   4386 
   4387 		if(behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING && software == FALSE)
   4388 		{
   4389 			return INVALIDCALL();
   4390 		}
   4391 
   4392 		if(behaviourFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING && software == TRUE)
   4393 		{
   4394 			return INVALIDCALL();
   4395 		}
   4396 
   4397 		softwareVertexProcessing = (software != FALSE);
   4398 
   4399 		return D3D_OK;
   4400 	}
   4401 
   4402 	long Direct3DDevice9::SetStreamSource(unsigned int stream, IDirect3DVertexBuffer9 *iVertexBuffer, unsigned int offset, unsigned int stride)
   4403 	{
   4404 		CriticalSection cs(this);
   4405 
   4406 		TRACE("unsigned int stream = %d, IDirect3DVertexBuffer9 *data = 0x%0.8p, unsigned int offset = %d, unsigned int stride = %d", stream, iVertexBuffer, offset, stride);
   4407 
   4408 		Direct3DVertexBuffer9 *vertexBuffer = static_cast<Direct3DVertexBuffer9*>(iVertexBuffer);
   4409 
   4410 		if(!stateRecorder)
   4411 		{
   4412 			if(dataStream[stream] == vertexBuffer && streamOffset[stream] == offset && streamStride[stream] == stride)
   4413 			{
   4414 				return D3D_OK;
   4415 			}
   4416 
   4417 			if(vertexBuffer)
   4418 			{
   4419 				vertexBuffer->bind();
   4420 			}
   4421 
   4422 			if(dataStream[stream])
   4423 			{
   4424 				dataStream[stream]->unbind();
   4425 			}
   4426 
   4427 			dataStream[stream] = vertexBuffer;
   4428 			streamOffset[stream] = offset;
   4429 			streamStride[stream] = stride;
   4430 		}
   4431 		else
   4432 		{
   4433 			stateRecorder->setStreamSource(stream, vertexBuffer, offset, stride);
   4434 		}
   4435 
   4436 		return D3D_OK;
   4437 	}
   4438 
   4439 	long Direct3DDevice9::SetStreamSourceFreq(unsigned int streamNumber, unsigned int divider)
   4440 	{
   4441 		CriticalSection cs(this);
   4442 
   4443 		TRACE("unsigned int streamNumber = %d, unsigned int divider = %d", streamNumber, divider);
   4444 
   4445 		if(!instancingEnabled)
   4446 		{
   4447 			return INVALIDCALL();
   4448 		}
   4449 
   4450 		if(!stateRecorder)
   4451 		{
   4452 			streamSourceFreq[streamNumber] = divider;
   4453 		}
   4454 		else
   4455 		{
   4456 			stateRecorder->setStreamSourceFreq(streamNumber, divider);
   4457 		}
   4458 
   4459 		return D3D_OK;
   4460 	}
   4461 
   4462 	long Direct3DDevice9::SetTexture(unsigned long sampler, IDirect3DBaseTexture9 *iBaseTexture)
   4463 	{
   4464 		CriticalSection cs(this);
   4465 
   4466 		TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 *texture = 0x%0.8p", sampler, iBaseTexture);
   4467 
   4468 		if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
   4469 		{
   4470 			return INVALIDCALL();
   4471 		}
   4472 
   4473 		if(sampler >= D3DVERTEXTEXTURESAMPLER0)
   4474 		{
   4475 			sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
   4476 		}
   4477 
   4478 		Direct3DBaseTexture9 *baseTexture = dynamic_cast<Direct3DBaseTexture9*>(iBaseTexture);
   4479 
   4480 		if(!stateRecorder)
   4481 		{
   4482 			if(texture[sampler] == baseTexture)
   4483 			{
   4484 				return D3D_OK;
   4485 			}
   4486 
   4487 			if(baseTexture)
   4488 			{
   4489 				baseTexture->bind();   // FIXME: Bind individual sub-surfaces?
   4490 			}
   4491 
   4492 			if(texture[sampler])
   4493 			{
   4494 				texture[sampler]->unbind();
   4495 			}
   4496 
   4497 			texture[sampler] = baseTexture;
   4498 		}
   4499 		else
   4500 		{
   4501 			stateRecorder->setTexture(sampler, baseTexture);
   4502 		}
   4503 
   4504 		return D3D_OK;
   4505 	}
   4506 
   4507 	long Direct3DDevice9::SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value)
   4508 	{
   4509 		CriticalSection cs(this);
   4510 
   4511 		TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long value = %d", stage, type, value);
   4512 
   4513 		if(stage < 0 || stage >= 8 || type < D3DTSS_COLOROP || type > D3DTSS_CONSTANT)
   4514 		{
   4515 			return INVALIDCALL();
   4516 		}
   4517 
   4518 		if(!stateRecorder)
   4519 		{
   4520 			if(!init && textureStageState[stage][type] == value)
   4521 			{
   4522 				return D3D_OK;
   4523 			}
   4524 
   4525 			textureStageState[stage][type] = value;
   4526 
   4527 			switch(type)
   4528 			{
   4529 			case D3DTSS_COLOROP:
   4530 				switch(value)
   4531 				{
   4532 				case D3DTOP_DISABLE:
   4533 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_DISABLE);
   4534 					break;
   4535 				case D3DTOP_SELECTARG1:
   4536 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG1);
   4537 					break;
   4538 				case D3DTOP_SELECTARG2:
   4539 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG2);
   4540 					break;
   4541 				case D3DTOP_MODULATE:
   4542 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE);
   4543 					break;
   4544 				case D3DTOP_MODULATE2X:
   4545 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE2X);
   4546 					break;
   4547 				case D3DTOP_MODULATE4X:
   4548 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE4X);
   4549 					break;
   4550 				case D3DTOP_ADD:
   4551 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADD);
   4552 					break;
   4553 				case D3DTOP_ADDSIGNED:
   4554 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED);
   4555 					break;
   4556 				case D3DTOP_ADDSIGNED2X:
   4557 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
   4558 					break;
   4559 				case D3DTOP_SUBTRACT:
   4560 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_SUBTRACT);
   4561 					break;
   4562 				case D3DTOP_ADDSMOOTH:
   4563 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSMOOTH);
   4564 					break;
   4565 				case D3DTOP_BLENDDIFFUSEALPHA:
   4566 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
   4567 					break;
   4568 				case D3DTOP_BLENDTEXTUREALPHA:
   4569 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
   4570 					break;
   4571 				case D3DTOP_BLENDFACTORALPHA:
   4572 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
   4573 					break;
   4574 				case D3DTOP_BLENDTEXTUREALPHAPM:
   4575 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
   4576 					break;
   4577 				case D3DTOP_BLENDCURRENTALPHA:
   4578 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
   4579 					break;
   4580 				case D3DTOP_PREMODULATE:
   4581 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_PREMODULATE);
   4582 					break;
   4583 				case D3DTOP_MODULATEALPHA_ADDCOLOR:
   4584 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
   4585 					break;
   4586 				case D3DTOP_MODULATECOLOR_ADDALPHA:
   4587 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
   4588 					break;
   4589 				case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
   4590 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
   4591 					break;
   4592 				case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
   4593 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
   4594 					break;
   4595 				case D3DTOP_BUMPENVMAP:
   4596 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAP);
   4597 					break;
   4598 				case D3DTOP_BUMPENVMAPLUMINANCE:
   4599 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
   4600 					break;
   4601 				case D3DTOP_DOTPRODUCT3:
   4602 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_DOT3);
   4603 					break;
   4604 				case D3DTOP_MULTIPLYADD:
   4605 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_MULTIPLYADD);
   4606 					break;
   4607 				case D3DTOP_LERP:
   4608 					renderer->setStageOperation(stage, sw::TextureStage::STAGE_LERP);
   4609 					break;
   4610 				default:
   4611 					ASSERT(false);
   4612 				}
   4613 				break;
   4614 			case D3DTSS_COLORARG1:
   4615 				switch(value & D3DTA_SELECTMASK)
   4616 				{
   4617 				case D3DTA_DIFFUSE:
   4618 					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
   4619 					break;
   4620 				case D3DTA_CURRENT:
   4621 					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CURRENT);
   4622 					break;
   4623 				case D3DTA_TEXTURE:
   4624 					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
   4625 					break;
   4626 				case D3DTA_TFACTOR:
   4627 					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
   4628 					break;
   4629 				case D3DTA_SPECULAR:
   4630 					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
   4631 					break;
   4632 				case D3DTA_TEMP:
   4633 					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEMP);
   4634 					break;
   4635 				case D3DTA_CONSTANT:
   4636 					renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CONSTANT);
   4637 					break;
   4638 				default:
   4639 					ASSERT(false);
   4640 				}
   4641 
   4642 				switch(value & ~D3DTA_SELECTMASK)
   4643 				{
   4644 				case 0:
   4645 					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_COLOR);
   4646 					break;
   4647 				case D3DTA_COMPLEMENT:
   4648 					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
   4649 					break;
   4650 				case D3DTA_ALPHAREPLICATE:
   4651 					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
   4652 					break;
   4653 				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
   4654 					renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
   4655 					break;
   4656 				default:
   4657 					ASSERT(false);
   4658 				}
   4659 				break;
   4660 			case D3DTSS_COLORARG2:
   4661 				switch(value & D3DTA_SELECTMASK)
   4662 				{
   4663 				case D3DTA_DIFFUSE:
   4664 					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
   4665 					break;
   4666 				case D3DTA_CURRENT:
   4667 					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CURRENT);
   4668 					break;
   4669 				case D3DTA_TEXTURE:
   4670 					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
   4671 					break;
   4672 				case D3DTA_TFACTOR:
   4673 					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
   4674 					break;
   4675 				case D3DTA_SPECULAR:
   4676 					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
   4677 					break;
   4678 				case D3DTA_TEMP:
   4679 					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEMP);
   4680 					break;
   4681 				case D3DTA_CONSTANT:
   4682 					renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CONSTANT);
   4683 					break;
   4684 				default:
   4685 					ASSERT(false);
   4686 				}
   4687 
   4688 				switch(value & ~D3DTA_SELECTMASK)
   4689 				{
   4690 				case 0:
   4691 					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_COLOR);
   4692 					break;
   4693 				case D3DTA_COMPLEMENT:
   4694 					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
   4695 					break;
   4696 				case D3DTA_ALPHAREPLICATE:
   4697 					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
   4698 					break;
   4699 				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
   4700 					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
   4701 					break;
   4702 				default:
   4703 					ASSERT(false);
   4704 				}
   4705 				break;
   4706 			case D3DTSS_ALPHAOP:
   4707 				switch(value)
   4708 				{
   4709 				case D3DTOP_DISABLE:
   4710 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DISABLE);
   4711 					break;
   4712 				case D3DTOP_SELECTARG1:
   4713 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG1);
   4714 					break;
   4715 				case D3DTOP_SELECTARG2:
   4716 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG2);
   4717 					break;
   4718 				case D3DTOP_MODULATE:
   4719 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE);
   4720 					break;
   4721 				case D3DTOP_MODULATE2X:
   4722 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE2X);
   4723 					break;
   4724 				case D3DTOP_MODULATE4X:
   4725 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE4X);
   4726 					break;
   4727 				case D3DTOP_ADD:
   4728 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADD);
   4729 					break;
   4730 				case D3DTOP_ADDSIGNED:
   4731 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED);
   4732 					break;
   4733 				case D3DTOP_ADDSIGNED2X:
   4734 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
   4735 					break;
   4736 				case D3DTOP_SUBTRACT:
   4737 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SUBTRACT);
   4738 					break;
   4739 				case D3DTOP_ADDSMOOTH:
   4740 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSMOOTH);
   4741 					break;
   4742 				case D3DTOP_BLENDDIFFUSEALPHA:
   4743 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
   4744 					break;
   4745 				case D3DTOP_BLENDTEXTUREALPHA:
   4746 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
   4747 					break;
   4748 				case D3DTOP_BLENDFACTORALPHA:
   4749 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
   4750 					break;
   4751 				case D3DTOP_BLENDTEXTUREALPHAPM:
   4752 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
   4753 					break;
   4754 				case D3DTOP_BLENDCURRENTALPHA:
   4755 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
   4756 					break;
   4757 				case D3DTOP_PREMODULATE:
   4758 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_PREMODULATE);
   4759 					break;
   4760 				case D3DTOP_MODULATEALPHA_ADDCOLOR:
   4761 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
   4762 					break;
   4763 				case D3DTOP_MODULATECOLOR_ADDALPHA:
   4764 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
   4765 					break;
   4766 				case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
   4767 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
   4768 					break;
   4769 				case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
   4770 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
   4771 					break;
   4772 				case D3DTOP_BUMPENVMAP:
   4773 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAP);
   4774 					break;
   4775 				case D3DTOP_BUMPENVMAPLUMINANCE:
   4776 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
   4777 					break;
   4778 				case D3DTOP_DOTPRODUCT3:
   4779 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DOT3);
   4780 					break;
   4781 				case D3DTOP_MULTIPLYADD:
   4782 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MULTIPLYADD);
   4783 					break;
   4784 				case D3DTOP_LERP:
   4785 					renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_LERP);
   4786 					break;
   4787 				default:
   4788 					ASSERT(false);
   4789 				}
   4790 				break;
   4791 			case D3DTSS_ALPHAARG1:
   4792 				switch(value & D3DTA_SELECTMASK)
   4793 				{
   4794 				case D3DTA_DIFFUSE:
   4795 					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
   4796 					break;
   4797 				case D3DTA_CURRENT:
   4798 					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
   4799 					break;
   4800 				case D3DTA_TEXTURE:
   4801 					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
   4802 					break;
   4803 				case D3DTA_TFACTOR:
   4804 					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
   4805 					break;
   4806 				case D3DTA_SPECULAR:
   4807 					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
   4808 					break;
   4809 				case D3DTA_TEMP:
   4810 					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
   4811 					break;
   4812 				case D3DTA_CONSTANT:
   4813 					renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
   4814 					break;
   4815 				default:
   4816 					ASSERT(false);
   4817 				}
   4818 
   4819 				switch(value & ~D3DTA_SELECTMASK)
   4820 				{
   4821 				case 0:
   4822 					renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
   4823 					break;
   4824 				case D3DTA_COMPLEMENT:
   4825 					renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
   4826 					break;
   4827 				case D3DTA_ALPHAREPLICATE:
   4828 					renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
   4829 					break;
   4830 				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
   4831 					renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
   4832 					break;
   4833 				default:
   4834 					ASSERT(false);
   4835 				}
   4836 				break;
   4837 			case D3DTSS_ALPHAARG2:
   4838 				switch(value & D3DTA_SELECTMASK)
   4839 				{
   4840 				case D3DTA_DIFFUSE:
   4841 					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
   4842 					break;
   4843 				case D3DTA_CURRENT:
   4844 					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
   4845 					break;
   4846 				case D3DTA_TEXTURE:
   4847 					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
   4848 					break;
   4849 				case D3DTA_TFACTOR:
   4850 					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
   4851 					break;
   4852 				case D3DTA_SPECULAR:
   4853 					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
   4854 					break;
   4855 				case D3DTA_TEMP:
   4856 					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
   4857 					break;
   4858 				case D3DTA_CONSTANT:
   4859 					renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
   4860 					break;
   4861 				default:
   4862 					ASSERT(false);
   4863 				}
   4864 
   4865 				switch(value & ~D3DTA_SELECTMASK)
   4866 				{
   4867 				case 0:
   4868 					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
   4869 					break;
   4870 				case D3DTA_COMPLEMENT:
   4871 					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
   4872 					break;
   4873 				case D3DTA_ALPHAREPLICATE:
   4874 					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
   4875 					break;
   4876 				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
   4877 					renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
   4878 					break;
   4879 				default:
   4880 					ASSERT(false);
   4881 				}
   4882 				break;
   4883 			case D3DTSS_BUMPENVMAT00:
   4884 				renderer->setBumpmapMatrix(stage, 0, (float&)value);
   4885 				break;
   4886 			case D3DTSS_BUMPENVMAT01:
   4887 				renderer->setBumpmapMatrix(stage, 1, (float&)value);
   4888 				break;
   4889 			case D3DTSS_BUMPENVMAT10:
   4890 				renderer->setBumpmapMatrix(stage, 2, (float&)value);
   4891 				break;
   4892 			case D3DTSS_BUMPENVMAT11:
   4893 				renderer->setBumpmapMatrix(stage, 3, (float&)value);
   4894 				break;
   4895 			case D3DTSS_TEXCOORDINDEX:
   4896 				renderer->setTexCoordIndex(stage, value & 0x0000FFFF);
   4897 
   4898 				switch(value & 0xFFFF0000)
   4899 				{
   4900 				case D3DTSS_TCI_PASSTHRU:
   4901 					renderer->setTexGen(stage, sw::TEXGEN_PASSTHRU);
   4902 					break;
   4903 				case D3DTSS_TCI_CAMERASPACENORMAL:
   4904 					renderer->setTexCoordIndex(stage, stage);
   4905 					renderer->setTexGen(stage, sw::TEXGEN_NORMAL);
   4906 					break;
   4907 				case D3DTSS_TCI_CAMERASPACEPOSITION:
   4908 					renderer->setTexCoordIndex(stage, stage);
   4909 					renderer->setTexGen(stage, sw::TEXGEN_POSITION);
   4910 					break;
   4911 				case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
   4912 					renderer->setTexCoordIndex(stage, stage);
   4913 					renderer->setTexGen(stage, sw::TEXGEN_REFLECTION);
   4914 					break;
   4915 				case D3DTSS_TCI_SPHEREMAP:
   4916 					renderer->setTexCoordIndex(stage, stage);
   4917 					renderer->setTexGen(stage, sw::TEXGEN_SPHEREMAP);
   4918 					break;
   4919 				default:
   4920 					ASSERT(false);
   4921 				}
   4922 				break;
   4923 			case D3DTSS_BUMPENVLSCALE:
   4924 				renderer->setLuminanceScale(stage, (float&)value);
   4925 				break;
   4926 			case D3DTSS_BUMPENVLOFFSET:
   4927 				renderer->setLuminanceOffset(stage, (float&)value);
   4928 				break;
   4929 			case D3DTSS_TEXTURETRANSFORMFLAGS:
   4930 				switch(value & ~D3DTTFF_PROJECTED)
   4931 				{
   4932 				case D3DTTFF_DISABLE:
   4933 					renderer->setTextureTransform(stage, 0, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
   4934 					break;
   4935 				case D3DTTFF_COUNT1:
   4936 					renderer->setTextureTransform(stage, 1, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
   4937 					break;
   4938 				case D3DTTFF_COUNT2:
   4939 					renderer->setTextureTransform(stage, 2, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
   4940 					break;
   4941 				case D3DTTFF_COUNT3:
   4942 					renderer->setTextureTransform(stage, 3, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
   4943 					break;
   4944 				case D3DTTFF_COUNT4:
   4945 					renderer->setTextureTransform(stage, 4, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
   4946 					break;
   4947 				default:
   4948 					ASSERT(false);
   4949 				}
   4950 				break;
   4951 			case D3DTSS_COLORARG0:
   4952 				switch(value & D3DTA_SELECTMASK)
   4953 				{
   4954 				case D3DTA_CURRENT:
   4955 					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_CURRENT);
   4956 					break;
   4957 				case D3DTA_DIFFUSE:
   4958 					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
   4959 					break;
   4960 				case D3DTA_SPECULAR:
   4961 					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
   4962 					break;
   4963 				case D3DTA_TEMP:
   4964 					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEMP);
   4965 					break;
   4966 				case D3DTA_TEXTURE:
   4967 					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
   4968 					break;
   4969 				case D3DTA_TFACTOR:
   4970 					renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
   4971 					break;
   4972 				default:
   4973 					ASSERT(false);
   4974 				}
   4975 
   4976 				switch(value & ~D3DTA_SELECTMASK)
   4977 				{
   4978 				case 0:
   4979 					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_COLOR);
   4980 					break;
   4981 				case D3DTA_COMPLEMENT:
   4982 					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
   4983 					break;
   4984 				case D3DTA_ALPHAREPLICATE:
   4985 					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
   4986 					break;
   4987 				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
   4988 					renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
   4989 					break;
   4990 				default:
   4991 					ASSERT(false);
   4992 				}
   4993 				break;
   4994 			case D3DTSS_ALPHAARG0:
   4995 				switch(value & D3DTA_SELECTMASK)
   4996 				{
   4997 				case D3DTA_DIFFUSE:
   4998 					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
   4999 					break;
   5000 				case D3DTA_CURRENT:
   5001 					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
   5002 					break;
   5003 				case D3DTA_TEXTURE:
   5004 					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
   5005 					break;
   5006 				case D3DTA_TFACTOR:
   5007 					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
   5008 					break;
   5009 				case D3DTA_SPECULAR:
   5010 					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
   5011 					break;
   5012 				case D3DTA_TEMP:
   5013 					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
   5014 					break;
   5015 				case D3DTA_CONSTANT:
   5016 					renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
   5017 					break;
   5018 				default:
   5019 					ASSERT(false);
   5020 				}
   5021 
   5022 				switch(value & ~D3DTA_SELECTMASK)
   5023 				{
   5024 				case 0:
   5025 					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
   5026 					break;
   5027 				case D3DTA_COMPLEMENT:
   5028 					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
   5029 					break;
   5030 				case D3DTA_ALPHAREPLICATE:
   5031 					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
   5032 					break;
   5033 				case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
   5034 					renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
   5035 					break;
   5036 				default:
   5037 					ASSERT(false);
   5038 				}
   5039 				break;
   5040 			case D3DTSS_RESULTARG:
   5041 				switch(value & D3DTA_SELECTMASK)
   5042 				{
   5043 				case D3DTA_CURRENT:
   5044 					renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_CURRENT);
   5045 					break;
   5046 				case D3DTA_TEMP:
   5047 					renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_TEMP);
   5048 					break;
   5049 				default:
   5050 					ASSERT(false);
   5051 				}
   5052 				break;
   5053 			case D3DTSS_CONSTANT:
   5054 				renderer->setConstantColor(stage, value);
   5055 				break;
   5056 			default:
   5057 				ASSERT(false);
   5058 			}
   5059 		}
   5060 		else   // stateRecorder
   5061 		{
   5062 			stateRecorder->setTextureStageState(stage, type, value);
   5063 		}
   5064 
   5065 		return D3D_OK;
   5066 	}
   5067 
   5068 	long Direct3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
   5069 	{
   5070 		CriticalSection cs(this);
   5071 
   5072 		TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
   5073 
   5074 		if(!matrix)
   5075 		{
   5076 			return INVALIDCALL();
   5077 		}
   5078 
   5079 		if(!stateRecorder)
   5080 		{
   5081 			this->matrix[state] = *matrix;
   5082 
   5083 			sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,
   5084 			             matrix->_12, matrix->_22, matrix->_32, matrix->_42,
   5085 			             matrix->_13, matrix->_23, matrix->_33, matrix->_43,
   5086 			             matrix->_14, matrix->_24, matrix->_34, matrix->_44);
   5087 
   5088 			switch(state)
   5089 			{
   5090 			case D3DTS_WORLD:
   5091 				renderer->setModelMatrix(M);
   5092 				break;
   5093 			case D3DTS_VIEW:
   5094 				renderer->setViewMatrix(M);
   5095 				break;
   5096 			case D3DTS_PROJECTION:
   5097 				renderer->setProjectionMatrix(M);
   5098 				break;
   5099 			case D3DTS_TEXTURE0:
   5100 				renderer->setTextureMatrix(0, M);
   5101 				break;
   5102 			case D3DTS_TEXTURE1:
   5103 				renderer->setTextureMatrix(1, M);
   5104 				break;
   5105 			case D3DTS_TEXTURE2:
   5106 				renderer->setTextureMatrix(2, M);
   5107 				break;
   5108 			case D3DTS_TEXTURE3:
   5109 				renderer->setTextureMatrix(3, M);
   5110 				break;
   5111 			case D3DTS_TEXTURE4:
   5112 				renderer->setTextureMatrix(4, M);
   5113 				break;
   5114 			case D3DTS_TEXTURE5:
   5115 				renderer->setTextureMatrix(5, M);
   5116 				break;
   5117 			case D3DTS_TEXTURE6:
   5118 				renderer->setTextureMatrix(6, M);
   5119 				break;
   5120 			case D3DTS_TEXTURE7:
   5121 				renderer->setTextureMatrix(7, M);
   5122 				break;
   5123 			default:
   5124 				if(state > 256 && state < 512)
   5125 				{
   5126 					renderer->setModelMatrix(M, state - 256);
   5127 				}
   5128 				else ASSERT(false);
   5129 			}
   5130 		}
   5131 		else   // stateRecorder
   5132 		{
   5133 			stateRecorder->setTransform(state, matrix);
   5134 		}
   5135 
   5136 		return D3D_OK;
   5137 	}
   5138 
   5139 	long Direct3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9 *iVertexDeclaration)
   5140 	{
   5141 		CriticalSection cs(this);
   5142 
   5143 		TRACE("IDirect3DVertexDeclaration9 *declaration = 0x%0.8p", iVertexDeclaration);
   5144 
   5145 		Direct3DVertexDeclaration9 *vertexDeclaration = static_cast<Direct3DVertexDeclaration9*>(iVertexDeclaration);
   5146 
   5147 		if(!stateRecorder)
   5148 		{
   5149 			if(this->vertexDeclaration == vertexDeclaration)
   5150 			{
   5151 				return D3D_OK;
   5152 			}
   5153 
   5154 			if(vertexDeclaration)
   5155 			{
   5156 				vertexDeclaration->bind();
   5157 			}
   5158 
   5159 			if(this->vertexDeclaration)
   5160 			{
   5161 				this->vertexDeclaration->unbind();
   5162 			}
   5163 
   5164 			this->vertexDeclaration = vertexDeclaration;
   5165 		}
   5166 		else
   5167 		{
   5168 			stateRecorder->setVertexDeclaration(vertexDeclaration);
   5169 		}
   5170 
   5171 		return D3D_OK;
   5172 	}
   5173 
   5174 	long Direct3DDevice9::SetVertexShader(IDirect3DVertexShader9 *iVertexShader)
   5175 	{
   5176 		CriticalSection cs(this);
   5177 
   5178 		TRACE("IDirect3DVertexShader9 *shader = 0x%0.8p", iVertexShader);
   5179 
   5180 		Direct3DVertexShader9 *vertexShader = static_cast<Direct3DVertexShader9*>(iVertexShader);
   5181 
   5182 		if(!stateRecorder)
   5183 		{
   5184 			if(this->vertexShader == vertexShader)
   5185 			{
   5186 				return D3D_OK;
   5187 			}
   5188 
   5189 			if(vertexShader)
   5190 			{
   5191 				vertexShader->bind();
   5192 			}
   5193 
   5194 			if(this->vertexShader)
   5195 			{
   5196 				this->vertexShader->unbind();
   5197 			}
   5198 
   5199 			this->vertexShader = vertexShader;
   5200 			vertexShaderDirty = true;
   5201 		}
   5202 		else
   5203 		{
   5204 			stateRecorder->setVertexShader(vertexShader);
   5205 		}
   5206 
   5207 		return D3D_OK;
   5208 	}
   5209 
   5210 	long Direct3DDevice9::SetVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
   5211 	{
   5212 		CriticalSection cs(this);
   5213 
   5214 		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   5215 
   5216 		if(!constantData)
   5217 		{
   5218 			return INVALIDCALL();
   5219 		}
   5220 
   5221 		if(!stateRecorder)
   5222 		{
   5223 			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
   5224 			{
   5225 				vertexShaderConstantB[startRegister + i] = constantData[i];
   5226 			}
   5227 
   5228 			vertexShaderConstantsBDirty = sw::max(startRegister + count, vertexShaderConstantsBDirty);
   5229 			vertexShaderDirty = true;   // Reload DEF constants
   5230 		}
   5231 		else
   5232 		{
   5233 			stateRecorder->setVertexShaderConstantB(startRegister, constantData, count);
   5234 		}
   5235 
   5236 		return D3D_OK;
   5237 	}
   5238 
   5239 	long Direct3DDevice9::SetVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
   5240 	{
   5241 		CriticalSection cs(this);
   5242 
   5243 		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   5244 
   5245 		if(!constantData)
   5246 		{
   5247 			return INVALIDCALL();
   5248 		}
   5249 
   5250 		if(!stateRecorder)
   5251 		{
   5252 			for(unsigned int i = 0; i < count && startRegister + i < MAX_VERTEX_SHADER_CONST; i++)
   5253 			{
   5254 				vertexShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
   5255 				vertexShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
   5256 				vertexShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
   5257 				vertexShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
   5258 			}
   5259 
   5260 			vertexShaderConstantsFDirty = sw::max(startRegister + count, vertexShaderConstantsFDirty);
   5261 			vertexShaderDirty = true;   // Reload DEF constants
   5262 		}
   5263 		else
   5264 		{
   5265 			stateRecorder->setVertexShaderConstantF(startRegister, constantData, count);
   5266 		}
   5267 
   5268 		return D3D_OK;
   5269 	}
   5270 
   5271 	long Direct3DDevice9::SetVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
   5272 	{
   5273 		CriticalSection cs(this);
   5274 
   5275 		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
   5276 
   5277 		if(!constantData)
   5278 		{
   5279 			return INVALIDCALL();
   5280 		}
   5281 
   5282 		if(!stateRecorder)
   5283 		{
   5284 			for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
   5285 			{
   5286 				vertexShaderConstantI[startRegister + i][0] = constantData[i * 4 + 0];
   5287 				vertexShaderConstantI[startRegister + i][1] = constantData[i * 4 + 1];
   5288 				vertexShaderConstantI[startRegister + i][2] = constantData[i * 4 + 2];
   5289 				vertexShaderConstantI[startRegister + i][3] = constantData[i * 4 + 3];
   5290 			}
   5291 
   5292 			vertexShaderConstantsIDirty = sw::max(startRegister + count, vertexShaderConstantsIDirty);
   5293 			vertexShaderDirty = true;   // Reload DEF constants
   5294 		}
   5295 		else
   5296 		{
   5297 			stateRecorder->setVertexShaderConstantI(startRegister, constantData, count);
   5298 		}
   5299 
   5300 		return D3D_OK;
   5301 	}
   5302 
   5303 	long Direct3DDevice9::SetViewport(const D3DVIEWPORT9 *viewport)
   5304 	{
   5305 		CriticalSection cs(this);
   5306 
   5307 		TRACE("const D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
   5308 
   5309 		if(!viewport)   // FIXME: Check if valid
   5310 		{
   5311 			return INVALIDCALL();
   5312 		}
   5313 
   5314 		if(!stateRecorder)
   5315 		{
   5316 			this->viewport = *viewport;
   5317 		}
   5318 		else
   5319 		{
   5320 			stateRecorder->setViewport(viewport);
   5321 		}
   5322 
   5323 		return D3D_OK;
   5324 	}
   5325 
   5326 	int Direct3DDevice9::ShowCursor(int show)
   5327 	{
   5328 		CriticalSection cs(this);
   5329 
   5330 		TRACE("int show = %d", show);
   5331 
   5332 		int oldValue = showCursor ? TRUE : FALSE;
   5333 		showCursor = show != FALSE;
   5334 
   5335 		if(showCursor)
   5336 		{
   5337 			sw::FrameBuffer::setCursorImage(cursor);
   5338 		}
   5339 		else
   5340 		{
   5341 			sw::FrameBuffer::setCursorImage(0);
   5342 		}
   5343 
   5344 		return oldValue;
   5345 	}
   5346 
   5347 	long Direct3DDevice9::StretchRect(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)
   5348 	{
   5349 		CriticalSection cs(this);
   5350 
   5351 		TRACE("IDirect3DSurface9 *sourceSurface = 0x%0.8p, const RECT *sourceRect = 0x%0.8p, IDirect3DSurface9 *destSurface = 0x%0.8p, const RECT *destRect = 0x%0.8p, D3DTEXTUREFILTERTYPE filter = %d", sourceSurface, sourceRect, destSurface, destRect, filter);
   5352 
   5353 		if(!sourceSurface || !destSurface || !validRectangle(sourceRect, sourceSurface) || !validRectangle(destRect, destSurface))
   5354 		{
   5355 			return INVALIDCALL();
   5356 		}
   5357 
   5358 		D3DSURFACE_DESC sourceDescription;
   5359 		D3DSURFACE_DESC destDescription;
   5360 
   5361 		sourceSurface->GetDesc(&sourceDescription);
   5362 		destSurface->GetDesc(&destDescription);
   5363 
   5364 		if(sourceDescription.Pool != D3DPOOL_DEFAULT || destDescription.Pool != D3DPOOL_DEFAULT)
   5365 		{
   5366 			return INVALIDCALL();
   5367 		}
   5368 
   5369 		Direct3DSurface9 *source = static_cast<Direct3DSurface9*>(sourceSurface);
   5370 		Direct3DSurface9 *dest = static_cast<Direct3DSurface9*>(destSurface);
   5371 
   5372 		stretchRect(source, sourceRect, dest, destRect, filter);
   5373 
   5374 		return D3D_OK;
   5375 	}
   5376 
   5377 	long Direct3DDevice9::TestCooperativeLevel()
   5378 	{
   5379 		CriticalSection cs(this);
   5380 
   5381 		TRACE("void");
   5382 
   5383 		return D3D_OK;
   5384 	}
   5385 
   5386 	long Direct3DDevice9::UpdateSurface(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destinationSurface, const POINT *destPoint)
   5387 	{
   5388 		CriticalSection cs(this);
   5389 
   5390 		TRACE("IDirect3DSurface9 *sourceSurface = 0x%0.8p, const RECT *sourceRect = 0x%0.8p, IDirect3DSurface9 *destinationSurface = 0x%0.8p, const POINT *destPoint = 0x%0.8p", sourceSurface, sourceRect, destinationSurface, destPoint);
   5391 
   5392 		if(!sourceSurface || !destinationSurface)
   5393 		{
   5394 			return INVALIDCALL();
   5395 		}
   5396 
   5397 		D3DSURFACE_DESC sourceDescription;
   5398 		D3DSURFACE_DESC destinationDescription;
   5399 
   5400 		sourceSurface->GetDesc(&sourceDescription);
   5401 		destinationSurface->GetDesc(&destinationDescription);
   5402 
   5403 		RECT sRect;
   5404 		RECT dRect;
   5405 
   5406 		if(sourceRect)
   5407 		{
   5408 			sRect.left = sourceRect->left;
   5409 			sRect.top = sourceRect->top;
   5410 			sRect.right = sourceRect->right;
   5411 			sRect.bottom = sourceRect->bottom;
   5412 		}
   5413 		else
   5414 		{
   5415 			sRect.left = 0;
   5416 			sRect.top = 0;
   5417 			sRect.right = sourceDescription.Width;
   5418 			sRect.bottom = sourceDescription.Height;
   5419 		}
   5420 
   5421 		if(destPoint)
   5422 		{
   5423 			dRect.left = destPoint->x;
   5424 			dRect.top = destPoint->y;
   5425 			dRect.right = destPoint->x + sRect.right - sRect.left;
   5426 			dRect.bottom = destPoint->y + sRect.bottom - sRect.top;
   5427 		}
   5428 		else
   5429 		{
   5430 			dRect.left = 0;
   5431 			dRect.top = 0;
   5432 			dRect.right = sRect.right - sRect.left;
   5433 			dRect.bottom = sRect.bottom - sRect.top;
   5434 		}
   5435 
   5436 		if(!validRectangle(&sRect, sourceSurface) || !validRectangle(&dRect, destinationSurface))
   5437 		{
   5438 			return INVALIDCALL();
   5439 		}
   5440 
   5441 		int sWidth = sRect.right - sRect.left;
   5442 		int sHeight = sRect.bottom - sRect.top;
   5443 
   5444 		int dWidth = dRect.right - dRect.left;
   5445 		int dHeight = dRect.bottom - dRect.top;
   5446 
   5447 		if(sourceDescription.MultiSampleType      != D3DMULTISAMPLE_NONE ||
   5448 		   destinationDescription.MultiSampleType != D3DMULTISAMPLE_NONE ||
   5449 		// sourceDescription.Pool      != D3DPOOL_SYSTEMMEM ||   // FIXME: Check back buffer and depth buffer memory pool flags
   5450 		// destinationDescription.Pool != D3DPOOL_DEFAULT ||
   5451 		   sourceDescription.Format != destinationDescription.Format)
   5452 		{
   5453 			return INVALIDCALL();
   5454 		}
   5455 
   5456 		sw::Surface *source = static_cast<Direct3DSurface9*>(sourceSurface);
   5457 		sw::Surface *dest = static_cast<Direct3DSurface9*>(destinationSurface);
   5458 
   5459 		unsigned char *sBuffer = (unsigned char*)source->lockExternal(sRect.left, sRect.top, 0, sw::LOCK_READONLY, sw::PUBLIC);
   5460 		unsigned char *dBuffer = (unsigned char*)dest->lockExternal(dRect.left, dRect.top, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
   5461 		int sPitch = source->getExternalPitchB();
   5462 		int dPitch = dest->getExternalPitchB();
   5463 
   5464 		unsigned int width;
   5465 		unsigned int height;
   5466 		unsigned int bytes;
   5467 
   5468 		switch(sourceDescription.Format)
   5469 		{
   5470 		case D3DFMT_DXT1:
   5471 		case D3DFMT_ATI1:
   5472 			width = (dWidth + 3) / 4;
   5473 			height = (dHeight + 3) / 4;
   5474 			bytes = width * 8;   // 64 bit per 4x4 block
   5475 			break;
   5476 		case D3DFMT_DXT2:
   5477 		case D3DFMT_DXT3:
   5478 		case D3DFMT_DXT4:
   5479 		case D3DFMT_DXT5:
   5480 		case D3DFMT_ATI2:
   5481 			width = (dWidth + 3) / 4;
   5482 			height = (dHeight + 3) / 4;
   5483 			bytes = width * 16;   // 128 bit per 4x4 block
   5484 			break;
   5485 		default:
   5486 			width = dWidth;
   5487 			height = dHeight;
   5488 			bytes = width * Direct3DSurface9::bytes(sourceDescription.Format);
   5489 		}
   5490 
   5491 		if(sourceDescription.Format == D3DFMT_ATI1 || sourceDescription.Format == D3DFMT_ATI2)
   5492 		{
   5493 			// Make the pitch correspond to 4 rows
   5494 			sPitch *= 4;
   5495 			dPitch *= 4;
   5496 		}
   5497 
   5498 		for(unsigned int y = 0; y < height; y++)
   5499 		{
   5500 			memcpy(dBuffer, sBuffer, bytes);
   5501 
   5502 			sBuffer += sPitch;
   5503 			dBuffer += dPitch;
   5504 		}
   5505 
   5506 		source->unlockExternal();
   5507 		dest->unlockExternal();
   5508 
   5509 		return D3D_OK;
   5510 	}
   5511 
   5512 	long Direct3DDevice9::UpdateTexture(IDirect3DBaseTexture9 *sourceTexture, IDirect3DBaseTexture9 *destinationTexture)
   5513 	{
   5514 		CriticalSection cs(this);
   5515 
   5516 		TRACE("IDirect3DBaseTexture9 *sourceTexture = 0x%0.8p, IDirect3DBaseTexture9 *destinationTexture = 0x%0.8p", sourceTexture, destinationTexture);
   5517 
   5518 		if(!sourceTexture || !destinationTexture)
   5519 		{
   5520 			return INVALIDCALL();
   5521 		}
   5522 
   5523 		// FIXME: Check memory pools
   5524 
   5525 		D3DRESOURCETYPE type = sourceTexture->GetType();
   5526 
   5527 		if(type != destinationTexture->GetType())
   5528 		{
   5529 			return INVALIDCALL();
   5530 		}
   5531 
   5532 		switch(type)
   5533 		{
   5534 		case D3DRTYPE_TEXTURE:
   5535 			{
   5536 				IDirect3DTexture9 *source;
   5537 				IDirect3DTexture9 *dest;
   5538 
   5539 				sourceTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&source);
   5540 				destinationTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&dest);
   5541 
   5542 				ASSERT(source && dest);
   5543 
   5544 				for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination
   5545 				{
   5546 					IDirect3DSurface9 *sourceSurface;
   5547 					IDirect3DSurface9 *destinationSurface;
   5548 
   5549 					source->GetSurfaceLevel(level, &sourceSurface);
   5550 					dest->GetSurfaceLevel(level, &destinationSurface);
   5551 
   5552 					UpdateSurface(sourceSurface, 0, destinationSurface, 0);
   5553 
   5554 					sourceSurface->Release();
   5555 					destinationSurface->Release();
   5556 				}
   5557 
   5558 				source->Release();
   5559 				dest->Release();
   5560 			}
   5561 			break;
   5562 		case D3DRTYPE_VOLUMETEXTURE:
   5563 			{
   5564 				IDirect3DVolumeTexture9 *source;
   5565 				IDirect3DVolumeTexture9 *dest;
   5566 
   5567 				sourceTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&source);
   5568 				destinationTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&dest);
   5569 
   5570 				ASSERT(source && dest);
   5571 
   5572 				for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination
   5573 				{
   5574 					IDirect3DVolume9 *sourceVolume;
   5575 					IDirect3DVolume9 *destinationVolume;
   5576 
   5577 					source->GetVolumeLevel(level, &sourceVolume);
   5578 					dest->GetVolumeLevel(level, &destinationVolume);
   5579 
   5580 					updateVolume(sourceVolume, destinationVolume);
   5581 
   5582 					sourceVolume->Release();
   5583 					destinationVolume->Release();
   5584 				}
   5585 
   5586 				source->Release();
   5587 				dest->Release();
   5588 			}
   5589 			break;
   5590 		case D3DRTYPE_CUBETEXTURE:
   5591 			{
   5592 				IDirect3DCubeTexture9 *source;
   5593 				IDirect3DCubeTexture9 *dest;
   5594 
   5595 				sourceTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&source);
   5596 				destinationTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&dest);
   5597 
   5598 				ASSERT(source && dest);
   5599 
   5600 				for(int face = 0; face < 6; face++)
   5601 				{
   5602 					for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination
   5603 					{
   5604 						IDirect3DSurface9 *sourceSurface;
   5605 						IDirect3DSurface9 *destinationSurface;
   5606 
   5607 						source->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &sourceSurface);
   5608 						dest->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &destinationSurface);
   5609 
   5610 						UpdateSurface(sourceSurface, 0, destinationSurface, 0);
   5611 
   5612 						sourceSurface->Release();
   5613 						destinationSurface->Release();
   5614 					}
   5615 				}
   5616 
   5617 				source->Release();
   5618 				dest->Release();
   5619 			}
   5620 			break;
   5621 		default:
   5622 			UNIMPLEMENTED();
   5623 		}
   5624 
   5625 		return D3D_OK;
   5626 	}
   5627 
   5628 	long Direct3DDevice9::ValidateDevice(unsigned long *numPasses)
   5629 	{
   5630 		CriticalSection cs(this);
   5631 
   5632 		TRACE("unsigned long *numPasses = 0x%0.8p", numPasses);
   5633 
   5634 		if(!numPasses)
   5635 		{
   5636 			return INVALIDCALL();
   5637 		}
   5638 
   5639 		*numPasses = 1;
   5640 
   5641 		return D3D_OK;
   5642 	}
   5643 
   5644 	long Direct3DDevice9::getAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode)
   5645 	{
   5646 		return d3d9->GetAdapterDisplayMode(adapter, mode);
   5647 	}
   5648 
   5649 	int Direct3DDevice9::typeStride(unsigned char streamType)
   5650 	{
   5651 		static int LUT[] =
   5652 		{
   5653 			4,	// D3DDECLTYPE_FLOAT1    =  0,  // 1D float expanded to (value, 0., 0., 1.)
   5654 			8,	// D3DDECLTYPE_FLOAT2    =  1,  // 2D float expanded to (value, value, 0., 1.)
   5655 			12,	// D3DDECLTYPE_FLOAT3    =  2,  // 3D float expanded to (value, value, value, 1.)
   5656 			16,	// D3DDECLTYPE_FLOAT4    =  3,  // 4D float
   5657 			4,	// D3DDECLTYPE_D3DCOLOR  =  4,  // 4D packed unsigned bytes mapped to 0. to 1. range. Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)
   5658 			4,	// D3DDECLTYPE_UBYTE4    =  5,  // 4D unsigned byte
   5659 			4,	// D3DDECLTYPE_SHORT2    =  6,  // 2D signed short expanded to (value, value, 0., 1.)
   5660 			8,	// D3DDECLTYPE_SHORT4    =  7,  // 4D signed short
   5661 			4,	// D3DDECLTYPE_UBYTE4N   =  8,  // Each of 4 bytes is normalized by dividing to 255.0
   5662 			4,	// D3DDECLTYPE_SHORT2N   =  9,  // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1)
   5663 			8,	// D3DDECLTYPE_SHORT4N   = 10,  // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)
   5664 			4,	// D3DDECLTYPE_USHORT2N  = 11,  // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1)
   5665 			8,	// D3DDECLTYPE_USHORT4N  = 12,  // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0)
   5666 			4,	// D3DDECLTYPE_UDEC3     = 13,  // 3D unsigned 10 10 10 format expanded to (value, value, value, 1)
   5667 			4,	// D3DDECLTYPE_DEC3N     = 14,  // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1)
   5668 			4,	// D3DDECLTYPE_FLOAT16_2 = 15,  // Two 16-bit floating point values, expanded to (value, value, 0, 1)
   5669 			8,	// D3DDECLTYPE_FLOAT16_4 = 16,  // Four 16-bit floating point values
   5670 			0,	// D3DDECLTYPE_UNUSED    = 17,  // When the type field in a decl is unused.
   5671 		};
   5672 
   5673 		return LUT[streamType];
   5674 	}
   5675 
   5676 	bool Direct3DDevice9::instanceData()
   5677 	{
   5678 		ASSERT(vertexDeclaration);
   5679 
   5680 		D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];
   5681 		unsigned int numElements;
   5682 		vertexDeclaration->GetDeclaration(vertexElement, &numElements);
   5683 
   5684 		bool instanceData = false;
   5685 
   5686 		for(unsigned int i = 0; i < numElements - 1; i++)
   5687 		{
   5688 			unsigned short stream = vertexElement[i].Stream;
   5689 
   5690 			if(stream != 0)
   5691 			{
   5692 				instanceData = instanceData || (streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA) != 0;
   5693 			}
   5694 		}
   5695 
   5696 		return instanceData;
   5697 	}
   5698 
   5699 	bool Direct3DDevice9::bindResources(Direct3DIndexBuffer9 *indexBuffer)
   5700 	{
   5701 		if(!bindViewport())
   5702 		{
   5703 			return false;   // Zero-area target region
   5704 		}
   5705 
   5706 		bindTextures();
   5707 		bindIndexBuffer(indexBuffer);
   5708 		bindShaderConstants();
   5709 		bindLights();
   5710 
   5711 		return true;
   5712 	}
   5713 
   5714 	void Direct3DDevice9::bindVertexStreams(int base, bool instancing, int instance)
   5715 	{
   5716 		ASSERT(vertexDeclaration);
   5717 
   5718 		renderer->resetInputStreams(vertexDeclaration->isPreTransformed());
   5719 
   5720 		D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];
   5721 		unsigned int numElements;
   5722 		vertexDeclaration->GetDeclaration(vertexElement, &numElements);
   5723 
   5724 		// Bind vertex data streams
   5725 		for(unsigned int i = 0; i < numElements - 1; i++)
   5726 		{
   5727 			unsigned short stream = vertexElement[i].Stream;
   5728 			unsigned short offset = vertexElement[i].Offset;
   5729 			unsigned char type = vertexElement[i].Type;
   5730 			unsigned char method = vertexElement[i].Method;
   5731 			unsigned char usage = vertexElement[i].Usage;
   5732 			unsigned char index = vertexElement[i].UsageIndex;
   5733 
   5734 			ASSERT(method == D3DDECLMETHOD_DEFAULT);	// FIXME: Unimplemented
   5735 
   5736 			if(!dataStream[stream])
   5737 			{
   5738 				continue;
   5739 			}
   5740 
   5741 			Direct3DVertexBuffer9 *streamBuffer = dataStream[stream];
   5742 			sw::Resource *resource = streamBuffer->getResource();
   5743 			const void *buffer = ((char*)resource->data() + streamOffset[stream]) + offset;
   5744 
   5745 			int stride = streamStride[stream];
   5746 
   5747 			if(instancing && streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA)
   5748 			{
   5749 				int instanceFrequency = streamSourceFreq[stream] & ~D3DSTREAMSOURCE_INSTANCEDATA;
   5750 				buffer = (char*)buffer + stride * (instance / instanceFrequency);
   5751 
   5752 				stride = 0;
   5753 			}
   5754 			else
   5755 			{
   5756 				buffer = (char*)buffer + stride * base;
   5757 			}
   5758 
   5759 			sw::Stream attribute(resource, buffer, stride);
   5760 
   5761 			switch(type)
   5762 			{
   5763 			case D3DDECLTYPE_FLOAT1:    attribute.define(sw::STREAMTYPE_FLOAT, 1, false);  break;
   5764 			case D3DDECLTYPE_FLOAT2:    attribute.define(sw::STREAMTYPE_FLOAT, 2, false);  break;
   5765 			case D3DDECLTYPE_FLOAT3:    attribute.define(sw::STREAMTYPE_FLOAT, 3, false);  break;
   5766 			case D3DDECLTYPE_FLOAT4:    attribute.define(sw::STREAMTYPE_FLOAT, 4, false);  break;
   5767 			case D3DDECLTYPE_D3DCOLOR:  attribute.define(sw::STREAMTYPE_COLOR, 4, false);  break;
   5768 			case D3DDECLTYPE_UBYTE4:    attribute.define(sw::STREAMTYPE_BYTE, 4, false);   break;
   5769 			case D3DDECLTYPE_SHORT2:    attribute.define(sw::STREAMTYPE_SHORT, 2, false);  break;
   5770 			case D3DDECLTYPE_SHORT4:    attribute.define(sw::STREAMTYPE_SHORT, 4, false);  break;
   5771 			case D3DDECLTYPE_UBYTE4N:   attribute.define(sw::STREAMTYPE_BYTE, 4, true);    break;
   5772 			case D3DDECLTYPE_SHORT2N:   attribute.define(sw::STREAMTYPE_SHORT, 2, true);   break;
   5773 			case D3DDECLTYPE_SHORT4N:   attribute.define(sw::STREAMTYPE_SHORT, 4, true);   break;
   5774 			case D3DDECLTYPE_USHORT2N:  attribute.define(sw::STREAMTYPE_USHORT, 2, true);  break;
   5775 			case D3DDECLTYPE_USHORT4N:  attribute.define(sw::STREAMTYPE_USHORT, 4, true);  break;
   5776 			case D3DDECLTYPE_UDEC3:     attribute.define(sw::STREAMTYPE_UDEC3, 3, false);  break;
   5777 			case D3DDECLTYPE_DEC3N:     attribute.define(sw::STREAMTYPE_DEC3N, 3, true);   break;
   5778 			case D3DDECLTYPE_FLOAT16_2: attribute.define(sw::STREAMTYPE_HALF, 2, false);   break;
   5779 			case D3DDECLTYPE_FLOAT16_4: attribute.define(sw::STREAMTYPE_HALF, 4, false);   break;
   5780 			case D3DDECLTYPE_UNUSED:    attribute.defaults();                              break;
   5781 			default:
   5782 				ASSERT(false);
   5783 			}
   5784 
   5785 			if(vertexShader)
   5786 			{
   5787 				const sw::VertexShader *shader = vertexShader->getVertexShader();
   5788 
   5789 				if(!vertexDeclaration->isPreTransformed())
   5790 				{
   5791 					for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
   5792 					{
   5793 						const sw::Shader::Semantic& input = shader->getInput(i);
   5794 						if((usage == input.usage) && (index == input.index))
   5795 						{
   5796 							renderer->setInputStream(i, attribute);
   5797 
   5798 							break;
   5799 						}
   5800 					}
   5801 				}
   5802 				else   // Bind directly to the output
   5803 				{
   5804 					for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
   5805 					{
   5806 						const sw::Shader::Semantic& output = shader->getOutput(i, 0);
   5807 						if(((usage == output.usage) || (usage == D3DDECLUSAGE_POSITIONT && output.usage == D3DDECLUSAGE_POSITION)) &&
   5808 						   (index == output.index))
   5809 						{
   5810 							renderer->setInputStream(i, attribute);
   5811 
   5812 							break;
   5813 						}
   5814 					}
   5815 				}
   5816 			}
   5817 			else
   5818 			{
   5819 				switch(usage)
   5820 				{
   5821 				case D3DDECLUSAGE_POSITION:     renderer->setInputStream(sw::Position, attribute);                                       break;
   5822 				case D3DDECLUSAGE_BLENDWEIGHT:  renderer->setInputStream(sw::BlendWeight, attribute);                                    break;
   5823 				case D3DDECLUSAGE_BLENDINDICES: renderer->setInputStream(sw::BlendIndices, attribute.define(sw::STREAMTYPE_INDICES, 1)); break;
   5824 				case D3DDECLUSAGE_NORMAL:       renderer->setInputStream(sw::Normal, attribute.define(sw::STREAMTYPE_FLOAT, 3));         break;
   5825 				case D3DDECLUSAGE_PSIZE:        renderer->setInputStream(sw::PointSize, attribute.define(sw::STREAMTYPE_FLOAT, 1));      break;
   5826 				case D3DDECLUSAGE_TEXCOORD:     renderer->setInputStream(sw::TexCoord0 + index, attribute);                              break;
   5827 				case D3DDECLUSAGE_TANGENT:      /* Ignored */                                                                            break;
   5828 				case D3DDECLUSAGE_BINORMAL:     /* Ignored */                                                                            break;
   5829 				case D3DDECLUSAGE_TESSFACTOR:   UNIMPLEMENTED();                                                                         break;
   5830 				case D3DDECLUSAGE_POSITIONT:    renderer->setInputStream(sw::PositionT, attribute.define(sw::STREAMTYPE_FLOAT, 4));      break;
   5831 				case D3DDECLUSAGE_COLOR:        renderer->setInputStream(sw::Color0 + index, attribute.define(sw::STREAMTYPE_COLOR, 4)); break;
   5832 				case D3DDECLUSAGE_FOG:          /* Ignored */                                                                            break;
   5833 				case D3DDECLUSAGE_DEPTH:        /* Ignored */                                                                            break;
   5834 				case D3DDECLUSAGE_SAMPLE:       UNIMPLEMENTED();                                                                         break;
   5835 				default:
   5836 					ASSERT(false);
   5837 				}
   5838 			}
   5839 		}
   5840 	}
   5841 
   5842 	void Direct3DDevice9::bindIndexBuffer(Direct3DIndexBuffer9 *indexBuffer)
   5843 	{
   5844 		sw::Resource *resource = 0;
   5845 
   5846 		if(indexBuffer)
   5847 		{
   5848 			resource = indexBuffer->getResource();
   5849 		}
   5850 
   5851 		renderer->setIndexBuffer(resource);
   5852 	}
   5853 
   5854 	void Direct3DDevice9::bindShaderConstants()
   5855 	{
   5856 		if(pixelShaderDirty)
   5857 		{
   5858 			if(pixelShader)
   5859 			{
   5860 				if(pixelShaderConstantsBDirty)
   5861 				{
   5862 					renderer->setPixelShaderConstantB(0, pixelShaderConstantB, pixelShaderConstantsBDirty);
   5863 				}
   5864 
   5865 				if(pixelShaderConstantsFDirty)
   5866 				{
   5867 					renderer->setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty);
   5868 				}
   5869 
   5870 				if(pixelShaderConstantsIDirty)
   5871 				{
   5872 					renderer->setPixelShaderConstantI(0, pixelShaderConstantI[0], pixelShaderConstantsIDirty);
   5873 				}
   5874 
   5875 				renderer->setPixelShader(pixelShader->getPixelShader());   // Loads shader constants set with DEF
   5876 				pixelShaderConstantsBDirty = pixelShader->getPixelShader()->dirtyConstantsB;   // Shader DEF'ed constants are dirty
   5877 				pixelShaderConstantsFDirty = pixelShader->getPixelShader()->dirtyConstantsF;   // Shader DEF'ed constants are dirty
   5878 				pixelShaderConstantsIDirty = pixelShader->getPixelShader()->dirtyConstantsI;   // Shader DEF'ed constants are dirty
   5879 			}
   5880 			else
   5881 			{
   5882 				renderer->setPixelShader(0);
   5883 			}
   5884 
   5885 			pixelShaderDirty = false;
   5886 		}
   5887 
   5888 		if(vertexShaderDirty)
   5889 		{
   5890 			if(vertexShader)
   5891 			{
   5892 				if(vertexShaderConstantsBDirty)
   5893 				{
   5894 					renderer->setVertexShaderConstantB(0, vertexShaderConstantB, vertexShaderConstantsBDirty);
   5895 				}
   5896 
   5897 				if(vertexShaderConstantsFDirty)
   5898 				{
   5899 					renderer->setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty);
   5900 				}
   5901 
   5902 				if(vertexShaderConstantsIDirty)
   5903 				{
   5904 					renderer->setVertexShaderConstantI(0, vertexShaderConstantI[0], vertexShaderConstantsIDirty);
   5905 				}
   5906 
   5907 				renderer->setVertexShader(vertexShader->getVertexShader());   // Loads shader constants set with DEF
   5908 				vertexShaderConstantsBDirty = vertexShader->getVertexShader()->dirtyConstantsB;   // Shader DEF'ed constants are dirty
   5909 				vertexShaderConstantsFDirty = vertexShader->getVertexShader()->dirtyConstantsF;   // Shader DEF'ed constants are dirty
   5910 				vertexShaderConstantsIDirty = vertexShader->getVertexShader()->dirtyConstantsI;   // Shader DEF'ed constants are dirty
   5911 			}
   5912 			else
   5913 			{
   5914 				renderer->setVertexShader(0);
   5915 			}
   5916 
   5917 			vertexShaderDirty = false;
   5918 		}
   5919 	}
   5920 
   5921 	void Direct3DDevice9::bindLights()
   5922 	{
   5923 		if(!lightsDirty) return;
   5924 
   5925 		Lights::iterator i = light.begin();
   5926 		int active = 0;
   5927 
   5928 		// Set and enable renderer lights
   5929 		while(active < 8)
   5930 		{
   5931 			while(i != light.end() && !i->second.enable)
   5932 			{
   5933 				i++;
   5934 			}
   5935 
   5936 			if(i == light.end())
   5937 			{
   5938 				break;
   5939 			}
   5940 
   5941 			const Light &l = i->second;
   5942 
   5943 			sw::Point position(l.Position.x, l.Position.y, l.Position.z);
   5944 			sw::Color<float> diffuse(l.Diffuse.r, l.Diffuse.g, l.Diffuse.b, l.Diffuse.a);
   5945 			sw::Color<float> specular(l.Specular.r, l.Specular.g, l.Specular.b, l.Specular.a);
   5946 			sw::Color<float> ambient(l.Ambient.r, l.Ambient.g, l.Ambient.b, l.Ambient.a);
   5947 			sw::Vector direction(l.Direction.x, l.Direction.y, l.Direction.z);
   5948 
   5949 			renderer->setLightDiffuse(active, diffuse);
   5950 			renderer->setLightSpecular(active, specular);
   5951 			renderer->setLightAmbient(active, ambient);
   5952 
   5953 			if(l.Type == D3DLIGHT_DIRECTIONAL)
   5954 			{
   5955 				// FIXME: Unsupported, make it a positional light far away without falloff
   5956 				renderer->setLightPosition(active, -1e10f * direction);
   5957 				renderer->setLightRange(active, l.Range);
   5958 				renderer->setLightAttenuation(active, 1, 0, 0);
   5959 			}
   5960 			else if(l.Type == D3DLIGHT_SPOT)
   5961 			{
   5962 				// FIXME: Unsupported, make it a positional light
   5963 				renderer->setLightPosition(active, position);
   5964 				renderer->setLightRange(active, l.Range);
   5965 				renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);
   5966 			}
   5967 			else
   5968 			{
   5969 				renderer->setLightPosition(active, position);
   5970 				renderer->setLightRange(active, l.Range);
   5971 				renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);
   5972 			}
   5973 
   5974 			renderer->setLightEnable(active, true);
   5975 
   5976 			active++;
   5977 			i++;
   5978 		}
   5979 
   5980 		// Remaining lights are disabled
   5981 		while(active < 8)
   5982 		{
   5983 			renderer->setLightEnable(active, false);
   5984 
   5985 			active++;
   5986 		}
   5987 
   5988 		lightsDirty = false;
   5989 	}
   5990 
   5991 	bool Direct3DDevice9::bindViewport()
   5992 	{
   5993 		if(viewport.Width <= 0 || viewport.Height <= 0)
   5994 		{
   5995 			return false;
   5996 		}
   5997 
   5998 		if(scissorEnable)
   5999 		{
   6000 			if(scissorRect.left >= scissorRect.right || scissorRect.top >= scissorRect.bottom)
   6001 			{
   6002 				return false;
   6003 			}
   6004 
   6005 			sw::Rect scissor;
   6006 			scissor.x0 = scissorRect.left;
   6007 			scissor.x1 = scissorRect.right;
   6008 			scissor.y0 = scissorRect.top;
   6009 			scissor.y1 = scissorRect.bottom;
   6010 
   6011 			renderer->setScissor(scissor);
   6012 		}
   6013 		else
   6014 		{
   6015 			sw::Rect scissor;
   6016 			scissor.x0 = viewport.X;
   6017 			scissor.x1 = viewport.X + viewport.Width;
   6018 			scissor.y0 = viewport.Y;
   6019 			scissor.y1 = viewport.Y + viewport.Height;
   6020 
   6021 			renderer->setScissor(scissor);
   6022 		}
   6023 
   6024 		sw::Viewport view;
   6025 		view.x0 = (float)viewport.X;
   6026 		view.y0 = (float)viewport.Y + viewport.Height;
   6027 		view.width = (float)viewport.Width;
   6028 		view.height = -(float)viewport.Height;
   6029 		view.minZ = viewport.MinZ;
   6030 		view.maxZ = viewport.MaxZ;
   6031 
   6032 		renderer->setViewport(view);
   6033 
   6034 		return true;
   6035 	}
   6036 
   6037 	void Direct3DDevice9::bindTextures()
   6038 	{
   6039 		for(int sampler = 0; sampler < 16 + 4; sampler++)
   6040 		{
   6041 			Direct3DBaseTexture9 *baseTexture = texture[sampler];
   6042 
   6043 			sw::SamplerType type = sampler < 16 ? sw::SAMPLER_PIXEL : sw::SAMPLER_VERTEX;
   6044 			int index = sampler < 16 ? sampler : sampler - 16;   // Sampler index within type group
   6045 
   6046 			bool textureUsed = false;
   6047 
   6048 			if(type == sw::SAMPLER_PIXEL && pixelShader)
   6049 			{
   6050 				textureUsed = pixelShader->getPixelShader()->usesSampler(index);
   6051 			}
   6052 			else if(type == sw::SAMPLER_VERTEX && vertexShader)
   6053 			{
   6054 				textureUsed = vertexShader->getVertexShader()->usesSampler(index);
   6055 			}
   6056 			else
   6057 			{
   6058 				textureUsed = true;   // FIXME: Check fixed-function use?
   6059 			}
   6060 
   6061 			sw::Resource *resource = 0;
   6062 
   6063 			if(baseTexture && textureUsed)
   6064 			{
   6065 				resource = baseTexture->getResource();
   6066 			}
   6067 
   6068 			renderer->setTextureResource(sampler, resource);
   6069 
   6070 			if(baseTexture && textureUsed)
   6071 			{
   6072 				baseTexture->GenerateMipSubLevels();
   6073 			}
   6074 
   6075 			if(baseTexture && textureUsed)
   6076 			{
   6077 				int levelCount = baseTexture->getInternalLevelCount();
   6078 
   6079 				int textureLOD = baseTexture->GetLOD();
   6080 				int samplerLOD = samplerState[sampler][D3DSAMP_MAXMIPLEVEL];
   6081 				int LOD = textureLOD > samplerLOD ? textureLOD : samplerLOD;
   6082 
   6083 				if(samplerState[sampler][D3DSAMP_MIPFILTER] == D3DTEXF_NONE)
   6084 				{
   6085 					LOD = 0;
   6086 				}
   6087 
   6088 				switch(baseTexture->GetType())
   6089 				{
   6090 				case D3DRTYPE_TEXTURE:
   6091 					{
   6092 						Direct3DTexture9 *texture = dynamic_cast<Direct3DTexture9*>(baseTexture);
   6093 						Direct3DSurface9 *surface;
   6094 
   6095 						for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
   6096 						{
   6097 							int surfaceLevel = mipmapLevel;
   6098 
   6099 							if(surfaceLevel < LOD)
   6100 							{
   6101 								surfaceLevel = LOD;
   6102 							}
   6103 
   6104 							if(surfaceLevel < 0)
   6105 							{
   6106 								surfaceLevel = 0;
   6107 							}
   6108 							else if(surfaceLevel >= levelCount)
   6109 							{
   6110 								surfaceLevel = levelCount - 1;
   6111 							}
   6112 
   6113 							surface = texture->getInternalSurfaceLevel(surfaceLevel);
   6114 							renderer->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
   6115 						}
   6116 					}
   6117 					break;
   6118 				case D3DRTYPE_CUBETEXTURE:
   6119 					for(int face = 0; face < 6; face++)
   6120 					{
   6121 						Direct3DCubeTexture9 *cubeTexture = dynamic_cast<Direct3DCubeTexture9*>(baseTexture);
   6122 						Direct3DSurface9 *surface;
   6123 
   6124 						for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
   6125 						{
   6126 							int surfaceLevel = mipmapLevel;
   6127 
   6128 							if(surfaceLevel < LOD)
   6129 							{
   6130 								surfaceLevel = LOD;
   6131 							}
   6132 
   6133 							if(surfaceLevel < 0)
   6134 							{
   6135 								surfaceLevel = 0;
   6136 							}
   6137 							else if(surfaceLevel >= levelCount)
   6138 							{
   6139 								surfaceLevel = levelCount - 1;
   6140 							}
   6141 
   6142 							surface = cubeTexture->getInternalCubeMapSurface((D3DCUBEMAP_FACES)face, surfaceLevel);
   6143 							renderer->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
   6144 						}
   6145 					}
   6146 					break;
   6147 				case D3DRTYPE_VOLUMETEXTURE:
   6148 					{
   6149 						Direct3DVolumeTexture9 *volumeTexture = dynamic_cast<Direct3DVolumeTexture9*>(baseTexture);
   6150 						Direct3DVolume9 *volume;
   6151 
   6152 						for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
   6153 						{
   6154 							int surfaceLevel = mipmapLevel;
   6155 
   6156 							if(surfaceLevel < LOD)
   6157 							{
   6158 								surfaceLevel = LOD;
   6159 							}
   6160 
   6161 							if(surfaceLevel < 0)
   6162 							{
   6163 								surfaceLevel = 0;
   6164 							}
   6165 							else if(surfaceLevel >= levelCount)
   6166 							{
   6167 								surfaceLevel = levelCount - 1;
   6168 							}
   6169 
   6170 							volume = volumeTexture->getInternalVolumeLevel(surfaceLevel);
   6171 							renderer->setTextureLevel(sampler, 0, mipmapLevel, volume, sw::TEXTURE_3D);
   6172 						}
   6173 					}
   6174 					break;
   6175 				default:
   6176 					UNIMPLEMENTED();
   6177 				}
   6178 			}
   6179 			else
   6180 			{
   6181 				renderer->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
   6182 			}
   6183 		}
   6184 	}
   6185 
   6186 	bool Direct3DDevice9::isRecording() const
   6187 	{
   6188 		return stateRecorder != 0;
   6189 	}
   6190 
   6191 	void Direct3DDevice9::setOcclusionEnabled(bool enable)
   6192 	{
   6193 		renderer->setOcclusionEnabled(enable);
   6194 	}
   6195 
   6196 	void Direct3DDevice9::removeQuery(sw::Query *query)
   6197 	{
   6198 		renderer->removeQuery(query);
   6199 	}
   6200 
   6201 	void Direct3DDevice9::addQuery(sw::Query *query)
   6202 	{
   6203 		renderer->addQuery(query);
   6204 	}
   6205 
   6206 	void Direct3DDevice9::stretchRect(Direct3DSurface9 *source, const RECT *sourceRect, Direct3DSurface9 *dest, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)
   6207 	{
   6208 		D3DSURFACE_DESC sourceDescription;
   6209 		D3DSURFACE_DESC destDescription;
   6210 
   6211 		source->GetDesc(&sourceDescription);
   6212 		dest->GetDesc(&destDescription);
   6213 
   6214 		int sWidth = source->getWidth();
   6215 		int sHeight = source->getHeight();
   6216 		int dWidth = dest->getWidth();
   6217 		int dHeight = dest->getHeight();
   6218 
   6219 		sw::Rect sRect(0, 0, sWidth, sHeight);
   6220 		sw::Rect dRect(0, 0, dWidth, dHeight);
   6221 
   6222 		if(sourceRect)
   6223 		{
   6224 			sRect.x0 = sourceRect->left;
   6225 			sRect.y0 = sourceRect->top;
   6226 			sRect.x1 = sourceRect->right;
   6227 			sRect.y1 = sourceRect->bottom;
   6228 		}
   6229 
   6230 		if(destRect)
   6231 		{
   6232 			dRect.x0 = destRect->left;
   6233 			dRect.y0 = destRect->top;
   6234 			dRect.x1 = destRect->right;
   6235 			dRect.y1 = destRect->bottom;
   6236 		}
   6237 
   6238 		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);
   6239 		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
   6240 		bool depthStencil = (sourceDescription.Usage & D3DUSAGE_DEPTHSTENCIL) == D3DUSAGE_DEPTHSTENCIL;
   6241 		bool alpha0xFF = false;
   6242 
   6243 		if((sourceDescription.Format == D3DFMT_A8R8G8B8 && destDescription.Format == D3DFMT_X8R8G8B8) ||
   6244 		   (sourceDescription.Format == D3DFMT_X8R8G8B8 && destDescription.Format == D3DFMT_A8R8G8B8))
   6245 		{
   6246 			equalFormats = true;
   6247 			alpha0xFF = true;
   6248 		}
   6249 
   6250 		if(depthStencil)   // Copy entirely, internally   // FIXME: Check
   6251 		{
   6252 			if(source->hasDepth())
   6253 			{
   6254 				byte *sourceBuffer = (byte*)source->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
   6255 				byte *destBuffer = (byte*)dest->lockInternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
   6256 
   6257 				unsigned int width = source->getWidth();
   6258 				unsigned int height = source->getHeight();
   6259 				unsigned int pitch = source->getInternalPitchB();
   6260 
   6261 				for(unsigned int y = 0; y < height; y++)
   6262 				{
   6263 					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
   6264 
   6265 					sourceBuffer += pitch;
   6266 					destBuffer += pitch;
   6267 				}
   6268 
   6269 				source->unlockInternal();
   6270 				dest->unlockInternal();
   6271 			}
   6272 
   6273 			if(source->hasStencil())
   6274 			{
   6275 				byte *sourceBuffer = (byte*)source->lockStencil(0, 0, 0, sw::PUBLIC);
   6276 				byte *destBuffer = (byte*)dest->lockStencil(0, 0, 0, sw::PUBLIC);
   6277 
   6278 				unsigned int width = source->getWidth();
   6279 				unsigned int height = source->getHeight();
   6280 				unsigned int pitch = source->getStencilPitchB();
   6281 
   6282 				for(unsigned int y = 0; y < height; y++)
   6283 				{
   6284 					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
   6285 
   6286 					sourceBuffer += pitch;
   6287 					destBuffer += pitch;
   6288 				}
   6289 
   6290 				source->unlockStencil();
   6291 				dest->unlockStencil();
   6292 			}
   6293 		}
   6294 		else if(!scaling && equalFormats)
   6295 		{
   6296 			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, 0, sw::LOCK_READONLY, sw::PUBLIC);
   6297 			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, 0, sw::LOCK_READWRITE, sw::PUBLIC);
   6298 			unsigned int sourcePitch = source->getInternalPitchB();
   6299 			unsigned int destPitch = dest->getInternalPitchB();
   6300 
   6301 			unsigned int width = dRect.x1 - dRect.x0;
   6302 			unsigned int height = dRect.y1 - dRect.y0;
   6303 			unsigned int bytes = width * sw::Surface::bytes(source->getInternalFormat());
   6304 
   6305 			for(unsigned int y = 0; y < height; y++)
   6306 			{
   6307 				memcpy(destBytes, sourceBytes, bytes);
   6308 
   6309 				if(alpha0xFF)
   6310 				{
   6311 					for(unsigned int x = 0; x < width; x++)
   6312 					{
   6313 						destBytes[4 * x + 3] = 0xFF;
   6314 					}
   6315 				}
   6316 
   6317 				sourceBytes += sourcePitch;
   6318 				destBytes += destPitch;
   6319 			}
   6320 
   6321 			source->unlockInternal();
   6322 			dest->unlockInternal();
   6323 		}
   6324 		else
   6325 		{
   6326 			sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, 0);
   6327 			renderer->blit(source, sRectF, dest, dRect, filter >= D3DTEXF_LINEAR);
   6328 		}
   6329 	}
   6330 
   6331 	long Direct3DDevice9::updateVolume(IDirect3DVolume9 *sourceVolume, IDirect3DVolume9 *destinationVolume)
   6332 	{
   6333 		TRACE("IDirect3DVolume9 *sourceVolume = 0x%0.8p, IDirect3DVolume9 *destinationVolume = 0x%0.8p", sourceVolume, destinationVolume);
   6334 
   6335 		if(!sourceVolume || !destinationVolume)
   6336 		{
   6337 			return INVALIDCALL();
   6338 		}
   6339 
   6340 		D3DVOLUME_DESC sourceDescription;
   6341 		D3DVOLUME_DESC destinationDescription;
   6342 
   6343 		sourceVolume->GetDesc(&sourceDescription);
   6344 		destinationVolume->GetDesc(&destinationDescription);
   6345 
   6346 		if(sourceDescription.Pool      != D3DPOOL_SYSTEMMEM ||
   6347 		   destinationDescription.Pool != D3DPOOL_DEFAULT ||
   6348 		   sourceDescription.Format != destinationDescription.Format ||
   6349 		   sourceDescription.Width  != destinationDescription.Width ||
   6350 		   sourceDescription.Height != destinationDescription.Height ||
   6351 		   sourceDescription.Depth  != destinationDescription.Depth)
   6352 		{
   6353 			return INVALIDCALL();
   6354 		}
   6355 
   6356 		sw::Surface *source = static_cast<Direct3DVolume9*>(sourceVolume);
   6357 		sw::Surface *dest = static_cast<Direct3DVolume9*>(destinationVolume);
   6358 
   6359 		if(source->getExternalPitchB() != dest->getExternalPitchB() ||
   6360 		   source->getExternalSliceB() != dest->getExternalSliceB())
   6361 		{
   6362 			UNIMPLEMENTED();
   6363 		}
   6364 
   6365 		void *sBuffer = source->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
   6366 		void *dBuffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
   6367 
   6368 		memcpy(dBuffer, sBuffer, source->getExternalSliceB() * sourceDescription.Depth);
   6369 
   6370 		source->unlockExternal();
   6371 		dest->unlockExternal();
   6372 
   6373 		return D3D_OK;
   6374 	}
   6375 
   6376 	bool Direct3DDevice9::validRectangle(const RECT *rect, IDirect3DSurface9 *surface)
   6377 	{
   6378 		if(!rect)
   6379 		{
   6380 			return true;
   6381 		}
   6382 
   6383 		if(rect->right <= rect->left || rect->bottom <= rect->top)
   6384 		{
   6385 			return false;
   6386 		}
   6387 
   6388 		if(rect->left < 0 || rect->top < 0)
   6389 		{
   6390 			return false;
   6391 		}
   6392 
   6393 		D3DSURFACE_DESC description;
   6394 		surface->GetDesc(&description);
   6395 
   6396 		if(rect->right > (int)description.Width || rect->bottom > (int)description.Height)
   6397 		{
   6398 			return false;
   6399 		}
   6400 
   6401 		return true;
   6402 	}
   6403 
   6404 	void Direct3DDevice9::configureFPU()
   6405 	{
   6406 	//	_controlfp(_PC_24, _MCW_PC);     // Single-precision
   6407 		_controlfp(_MCW_EM, _MCW_EM);    // Mask all exceptions
   6408 		_controlfp(_RC_NEAR, _MCW_RC);   // Round to nearest
   6409 	}
   6410 }
   6411