OSDN Git Service

9b68c47aa7befb97a599a868f1a812c11623e9c1
[android-x86/external-swiftshader.git] / src / D3D9 / Direct3DDevice9.cpp
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::SliceRect clearRect(rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2, 0);
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 = {0};
1835
1836                         sw::BlitState update;
1837                         update.width = sourceDescription.Width;
1838                         update.height = sourceDescription.Height;
1839                         update.sourceFormat = sw::FORMAT_A8R8G8B8;
1840                         update.destFormat = sw::FORMAT_A8R8G8B8;
1841                         update.stride = dest->getExternalPitchB();
1842                         update.cursorHeight = 0;
1843                         update.cursorWidth = 0;
1844
1845                         if(memcmp(&blitState, &update, sizeof(sw::BlitState)) != 0)
1846                         {
1847                                 blitState = update;
1848                                 delete blitRoutine;
1849
1850                                 blitRoutine = sw::FrameBuffer::copyRoutine(blitState);
1851                                 blitFunction = (void(__cdecl*)(void*, void*))blitRoutine->getEntry();
1852                         }
1853
1854                         blitFunction(destBuffer, sourceBuffer);
1855
1856                         dest->unlockExternal();
1857                         source->unlockExternal();
1858                 }
1859                 else
1860                 {
1861                         return UpdateSurface(renderTarget, 0, destSurface, 0);
1862                 }
1863
1864                 return D3D_OK;
1865         }
1866
1867         long Direct3DDevice9::GetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long *value)
1868         {
1869                 CriticalSection cs(this);
1870
1871                 TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE type = %d, unsigned long *value = 0x%0.8p", sampler, state, value);
1872
1873                 if(!value || state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET)   // FIXME: Set *value to 0?
1874                 {
1875                         return INVALIDCALL();
1876                 }
1877
1878                 if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
1879                 {
1880                         return INVALIDCALL();
1881                 }
1882
1883                 if(sampler >= D3DVERTEXTEXTURESAMPLER0)
1884                 {
1885                         sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
1886                 }
1887
1888                 *value = samplerState[sampler][state];
1889
1890                 return D3D_OK;
1891         }
1892
1893         long Direct3DDevice9::GetScissorRect(RECT *rect)
1894         {
1895                 CriticalSection cs(this);
1896
1897                 TRACE("RECT *rect = 0x%0.8p", rect);
1898
1899                 if(!rect)
1900                 {
1901                         return INVALIDCALL();
1902                 }
1903
1904                 *rect = scissorRect;
1905
1906                 return D3D_OK;
1907         }
1908
1909         int Direct3DDevice9::GetSoftwareVertexProcessing()
1910         {
1911                 CriticalSection cs(this);
1912
1913                 TRACE("void");
1914
1915                 return softwareVertexProcessing ? TRUE : FALSE;
1916         }
1917
1918         long Direct3DDevice9::GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer9 **streamData, unsigned int *offset, unsigned int *stride)
1919         {
1920                 CriticalSection cs(this);
1921
1922                 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);
1923
1924                 if(streamNumber >= 16 || !streamData || !offset || !stride)
1925                 {
1926                         return INVALIDCALL();
1927                 }
1928
1929                 *streamData = dataStream[streamNumber];
1930
1931                 if(dataStream[streamNumber])
1932                 {
1933                         dataStream[streamNumber]->AddRef();
1934                 }
1935
1936                 *offset = streamOffset[streamNumber];
1937                 *stride = streamStride[streamNumber];
1938
1939                 return D3D_OK;
1940         }
1941
1942         long Direct3DDevice9::GetStreamSourceFreq(unsigned int streamNumber, unsigned int *divider)
1943         {
1944                 CriticalSection cs(this);
1945
1946                 TRACE("unsigned int streamNumber = %d, unsigned int *divider = 0x%0.8p", streamNumber, divider);
1947
1948                 if(streamNumber >= 16 || !divider)
1949                 {
1950                         return INVALIDCALL();
1951                 }
1952
1953                 *divider = streamSourceFreq[streamNumber];
1954
1955                 return D3D_OK;
1956         }
1957
1958         long Direct3DDevice9::GetSwapChain(unsigned int index, IDirect3DSwapChain9 **swapChain)
1959         {
1960                 CriticalSection cs(this);
1961
1962                 TRACE("unsigned int index = %d, IDirect3DSwapChain9 **swapChain = 0x%0.8p", index, swapChain);
1963
1964                 if(!swapChain || index >= GetNumberOfSwapChains())
1965                 {
1966                         return INVALIDCALL();
1967                 }
1968
1969                 *swapChain = this->swapChain;
1970
1971                 if(*swapChain)
1972                 {
1973                         (*swapChain)->AddRef();
1974                 }
1975
1976                 return D3D_OK;
1977         }
1978
1979         long Direct3DDevice9::GetTexture(unsigned long sampler, IDirect3DBaseTexture9 **texture)
1980         {
1981                 CriticalSection cs(this);
1982
1983                 TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 **texture = 0x%0.8p", sampler, texture);
1984
1985                 if(!texture)
1986                 {
1987                         return INVALIDCALL();
1988                 }
1989
1990                 *texture = 0;
1991
1992                 if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
1993                 {
1994                         return INVALIDCALL();
1995                 }
1996
1997                 *texture = this->texture[sampler];
1998
1999                 if(this->texture[sampler])
2000                 {
2001                         this->texture[sampler]->AddRef();
2002                 }
2003
2004                 return D3D_OK;
2005         }
2006
2007         long Direct3DDevice9::GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long *value)
2008         {
2009                 CriticalSection cs(this);
2010
2011                 TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long *value = 0x%0.8p", stage, type, value);
2012
2013                 if(!value)
2014                 {
2015                         return INVALIDCALL();
2016                 }
2017
2018                 *value = textureStageState[stage][type];
2019
2020                 return D3D_OK;
2021         }
2022
2023         long Direct3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix)
2024         {
2025                 CriticalSection cs(this);
2026
2027                 TRACE("D3DTRANSFORMSTATETYPE state = %d, D3DMATRIX *matrix = 0x%0.8p", state, matrix);
2028
2029                 if(!matrix || state < 0 || state > 511)
2030                 {
2031                         return INVALIDCALL();
2032                 }
2033
2034                 *matrix = this->matrix[state];
2035
2036                 return D3D_OK;
2037         }
2038
2039         long Direct3DDevice9::GetVertexDeclaration(IDirect3DVertexDeclaration9 **declaration)
2040         {
2041                 CriticalSection cs(this);
2042
2043                 TRACE("IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", declaration);
2044
2045                 if(!declaration)
2046                 {
2047                         return INVALIDCALL();
2048                 }
2049
2050                 *declaration = vertexDeclaration;
2051
2052                 if(vertexDeclaration)
2053                 {
2054                         vertexDeclaration->AddRef();
2055                 }
2056
2057                 return D3D_OK;
2058         }
2059
2060         long Direct3DDevice9::GetVertexShader(IDirect3DVertexShader9 **shader)
2061         {
2062                 CriticalSection cs(this);
2063
2064                 TRACE("IDirect3DVertexShader9 **shader = 0x%0.8p", shader);
2065
2066                 if(!shader)
2067                 {
2068                         return INVALIDCALL();
2069                 }
2070
2071                 *shader = vertexShader;
2072
2073                 if(vertexShader)
2074                 {
2075                         vertexShader->AddRef();
2076                 }
2077
2078                 return D3D_OK;
2079         }
2080
2081         long Direct3DDevice9::GetVertexShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)
2082         {
2083                 CriticalSection cs(this);
2084
2085                 TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
2086
2087                 if(!constantData)
2088                 {
2089                         return INVALIDCALL();
2090                 }
2091
2092                 for(unsigned int i = 0; i < count; i++)
2093                 {
2094                         constantData[i] = vertexShaderConstantB[startRegister + i];
2095                 }
2096
2097                 return D3D_OK;
2098         }
2099
2100         long Direct3DDevice9::GetVertexShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)
2101         {
2102                 CriticalSection cs(this);
2103
2104                 TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
2105
2106                 if(!constantData)
2107                 {
2108                         return INVALIDCALL();
2109                 }
2110
2111                 for(unsigned int i = 0; i < count; i++)
2112                 {
2113                         constantData[i * 4 + 0] = vertexShaderConstantF[startRegister + i][0];
2114                         constantData[i * 4 + 1] = vertexShaderConstantF[startRegister + i][1];
2115                         constantData[i * 4 + 2] = vertexShaderConstantF[startRegister + i][2];
2116                         constantData[i * 4 + 3] = vertexShaderConstantF[startRegister + i][3];
2117                 }
2118
2119                 return D3D_OK;
2120         }
2121
2122         long Direct3DDevice9::GetVertexShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)
2123         {
2124                 CriticalSection cs(this);
2125
2126                 TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
2127
2128                 if(!constantData)
2129                 {
2130                         return INVALIDCALL();
2131                 }
2132
2133                 for(unsigned int i = 0; i < count; i++)
2134                 {
2135                         constantData[i * 4 + 0] = vertexShaderConstantI[startRegister + i][0];
2136                         constantData[i * 4 + 1] = vertexShaderConstantI[startRegister + i][1];
2137                         constantData[i * 4 + 2] = vertexShaderConstantI[startRegister + i][2];
2138                         constantData[i * 4 + 3] = vertexShaderConstantI[startRegister + i][3];
2139                 }
2140
2141                 return D3D_OK;
2142         }
2143
2144         long Direct3DDevice9::GetViewport(D3DVIEWPORT9 *viewport)
2145         {
2146                 CriticalSection cs(this);
2147
2148                 TRACE("D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
2149
2150                 if(!viewport)
2151                 {
2152                         return INVALIDCALL();
2153                 }
2154
2155                 *viewport = this->viewport;
2156
2157                 return D3D_OK;
2158         }
2159
2160         long Direct3DDevice9::LightEnable(unsigned long index, int enable)
2161         {
2162                 CriticalSection cs(this);
2163
2164                 TRACE("unsigned long index = %d, int enable = %d", index, enable);
2165
2166                 if(!light.exists(index))   // Insert default light
2167                 {
2168                         D3DLIGHT9 light;
2169
2170                         light.Type = D3DLIGHT_DIRECTIONAL;
2171                         light.Diffuse.r = 1;
2172                         light.Diffuse.g = 1;
2173                         light.Diffuse.b = 1;
2174                         light.Diffuse.a = 0;
2175                         light.Specular.r = 0;
2176                         light.Specular.g = 0;
2177                         light.Specular.b = 0;
2178                         light.Specular.a = 0;
2179                         light.Ambient.r = 0;
2180                         light.Ambient.g = 0;
2181                         light.Ambient.b = 0;
2182                         light.Ambient.a = 0;
2183                         light.Position.x = 0;
2184                         light.Position.y = 0;
2185                         light.Position.z = 0;
2186                         light.Direction.x = 0;
2187                         light.Direction.y = 0;
2188                         light.Direction.z = 1;
2189                         light.Range = 0;
2190                         light.Falloff = 0;
2191                         light.Attenuation0 = 0;
2192                         light.Attenuation1 = 0;
2193                         light.Attenuation2 = 0;
2194                         light.Theta = 0;
2195                         light.Phi = 0;
2196
2197                         this->light[index] = light;
2198                         this->light[index].enable = false;
2199                 }
2200
2201                 if(!stateRecorder)
2202                 {
2203                         light[index].enable = (enable != FALSE);
2204
2205                         lightsDirty = true;
2206                 }
2207                 else
2208                 {
2209                         stateRecorder->lightEnable(index, enable);
2210                 }
2211
2212                 return D3D_OK;
2213         }
2214
2215         long Direct3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
2216         {
2217                 CriticalSection cs(this);
2218
2219                 TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
2220
2221                 if(!matrix)
2222                 {
2223                         return INVALIDCALL();
2224                 }
2225
2226                 D3DMATRIX *current = &this->matrix[state];
2227
2228                 sw::Matrix C(current->_11, current->_21, current->_31, current->_41,
2229                              current->_12, current->_22, current->_32, current->_42,
2230                              current->_13, current->_23, current->_33, current->_43,
2231                              current->_14, current->_24, current->_34, current->_44);
2232
2233                 sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,
2234                              matrix->_12, matrix->_22, matrix->_32, matrix->_42,
2235                              matrix->_13, matrix->_23, matrix->_33, matrix->_43,
2236                              matrix->_14, matrix->_24, matrix->_34, matrix->_44);
2237
2238                 switch(state)
2239                 {
2240                 case D3DTS_WORLD:
2241                         renderer->setModelMatrix(C * M);
2242                         break;
2243                 case D3DTS_VIEW:
2244                         renderer->setViewMatrix(C * M);
2245                         break;
2246                 case D3DTS_PROJECTION:
2247                         renderer->setProjectionMatrix(C * M);
2248                         break;
2249                 case D3DTS_TEXTURE0:
2250                         renderer->setTextureMatrix(0, C * M);
2251                         break;
2252                 case D3DTS_TEXTURE1:
2253                         renderer->setTextureMatrix(1, C * M);
2254                         break;
2255                 case D3DTS_TEXTURE2:
2256                         renderer->setTextureMatrix(2, C * M);
2257                         break;
2258                 case D3DTS_TEXTURE3:
2259                         renderer->setTextureMatrix(3, C * M);
2260                         break;
2261                 case D3DTS_TEXTURE4:
2262                         renderer->setTextureMatrix(4, C * M);
2263                         break;
2264                 case D3DTS_TEXTURE5:
2265                         renderer->setTextureMatrix(5, C * M);
2266                         break;
2267                 case D3DTS_TEXTURE6:
2268                         renderer->setTextureMatrix(6, C * M);
2269                         break;
2270                 case D3DTS_TEXTURE7:
2271                         renderer->setTextureMatrix(7, C * M);
2272                         break;
2273                 default:
2274                         if(state > 256 && state < 512)
2275                         {
2276                                 renderer->setModelMatrix(C * M, state - 256);
2277                         }
2278                         else ASSERT(false);
2279                 }
2280
2281                 return D3D_OK;
2282         }
2283
2284         long Direct3DDevice9::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion)
2285         {
2286                 CriticalSection cs(this);
2287
2288                 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);
2289
2290                 return swapChain->Present(sourceRect, destRect, destWindowOverride, dirtyRegion, 0);
2291         }
2292
2293         long Direct3DDevice9::ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer9 *destBuffer, IDirect3DVertexDeclaration9 *vertexDeclaration, unsigned long flags)
2294         {
2295                 CriticalSection cs(this);
2296
2297                 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);
2298
2299                 if(!destBuffer)
2300                 {
2301                         return INVALIDCALL();
2302                 }
2303
2304                 UNIMPLEMENTED();
2305
2306                 return D3D_OK;
2307         }
2308
2309         long Direct3DDevice9::Reset(D3DPRESENT_PARAMETERS *presentParameters)
2310         {
2311                 CriticalSection cs(this);
2312
2313                 TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p", presentParameters);
2314
2315                 if(!presentParameters)
2316                 {
2317                         return INVALIDCALL();
2318                 }
2319
2320                 deviceWindow = presentParameters->hDeviceWindow;
2321
2322                 if(depthStencil)
2323                 {
2324                         depthStencil->unbind();
2325                         depthStencil = 0;
2326                 }
2327
2328                 if(autoDepthStencil)
2329                 {
2330                         autoDepthStencil->unbind();
2331                         autoDepthStencil = 0;
2332                 }
2333
2334                 for(int index = 0; index < 4; index++)
2335                 {
2336                         if(renderTarget[index])
2337                         {
2338                                 renderTarget[index]->unbind();
2339                                 renderTarget[index] = 0;
2340                         }
2341                 }
2342
2343                 if(!swapChain)
2344                 {
2345                         swapChain = new Direct3DSwapChain9(this, presentParameters);
2346                         swapChain->bind();
2347                 }
2348                 else
2349                 {
2350                         swapChain->reset(presentParameters);
2351                 }
2352
2353                 if(presentParameters->EnableAutoDepthStencil != FALSE)
2354                 {
2355                         bool lockable = false;
2356
2357                         switch(presentParameters->AutoDepthStencilFormat)
2358                         {
2359                         case D3DFMT_D15S1:
2360                         case D3DFMT_D24S8:
2361                         case D3DFMT_D24X8:
2362                         case D3DFMT_D24X4S4:
2363                         case D3DFMT_D24FS8:
2364                         case D3DFMT_D32:
2365                         case D3DFMT_D16:
2366                         case D3DFMT_DF24:
2367                         case D3DFMT_DF16:
2368                         case D3DFMT_INTZ:
2369                                 lockable = false;
2370                                 break;
2371                         case D3DFMT_S8_LOCKABLE:
2372                         case D3DFMT_D16_LOCKABLE:
2373                         case D3DFMT_D32F_LOCKABLE:
2374                         case D3DFMT_D32_LOCKABLE:
2375                                 lockable = true;
2376                                 break;
2377                         default:
2378                                 ASSERT(false);
2379                         }
2380
2381                         autoDepthStencil = new Direct3DSurface9(this, this, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->AutoDepthStencilFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, presentParameters->MultiSampleQuality, lockable, D3DUSAGE_DEPTHSTENCIL);
2382                         autoDepthStencil->bind();
2383
2384                         SetDepthStencilSurface(autoDepthStencil);
2385                 }
2386
2387                 IDirect3DSurface9 *renderTarget;
2388                 swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &renderTarget);
2389                 SetRenderTarget(0, renderTarget);
2390                 renderTarget->Release();
2391
2392                 SetRenderTarget(1, 0);
2393                 SetRenderTarget(2, 0);
2394                 SetRenderTarget(3, 0);
2395
2396                 softwareVertexProcessing = (behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) == D3DCREATE_SOFTWARE_VERTEXPROCESSING;
2397
2398                 SetRenderState(D3DRS_ZENABLE, presentParameters->EnableAutoDepthStencil != FALSE ? D3DZB_TRUE : D3DZB_FALSE);
2399                 SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
2400                 SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
2401                 SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
2402                 SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
2403                 SetRenderState(D3DRS_LASTPIXEL, TRUE);
2404                 SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
2405                 SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
2406                 SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
2407                 SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
2408                 SetRenderState(D3DRS_ALPHAREF, 0);
2409                 SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
2410                 SetRenderState(D3DRS_DITHERENABLE, FALSE);
2411                 SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
2412                 SetRenderState(D3DRS_FOGENABLE, FALSE);
2413                 SetRenderState(D3DRS_SPECULARENABLE, FALSE);
2414         //      SetRenderState(D3DRS_ZVISIBLE, 0);
2415                 SetRenderState(D3DRS_FOGCOLOR, 0);
2416                 SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2417                 SetRenderState(D3DRS_FOGSTART, FtoDW(0.0f));
2418                 SetRenderState(D3DRS_FOGEND, FtoDW(1.0f));
2419                 SetRenderState(D3DRS_FOGDENSITY, FtoDW(1.0f));
2420                 SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
2421                 SetRenderState(D3DRS_STENCILENABLE, FALSE);
2422                 SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
2423                 SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
2424                 SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
2425                 SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
2426                 SetRenderState(D3DRS_STENCILREF, 0);
2427                 SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF);
2428                 SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
2429                 SetRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
2430                 SetRenderState(D3DRS_WRAP0, 0);
2431                 SetRenderState(D3DRS_WRAP1, 0);
2432                 SetRenderState(D3DRS_WRAP2, 0);
2433                 SetRenderState(D3DRS_WRAP3, 0);
2434                 SetRenderState(D3DRS_WRAP4, 0);
2435                 SetRenderState(D3DRS_WRAP5, 0);
2436                 SetRenderState(D3DRS_WRAP6, 0);
2437                 SetRenderState(D3DRS_WRAP7, 0);
2438                 SetRenderState(D3DRS_CLIPPING, TRUE);
2439                 SetRenderState(D3DRS_LIGHTING, TRUE);
2440                 SetRenderState(D3DRS_AMBIENT, 0);
2441                 SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2442                 SetRenderState(D3DRS_COLORVERTEX, TRUE);
2443                 SetRenderState(D3DRS_LOCALVIEWER, TRUE);
2444                 SetRenderState(D3DRS_NORMALIZENORMALS, FALSE);
2445                 SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
2446                 SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
2447                 SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
2448                 SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
2449                 SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
2450                 SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
2451                 SetRenderState(D3DRS_POINTSIZE, FtoDW(1.0f));
2452                 SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(1.0f));
2453                 SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
2454                 SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
2455                 SetRenderState(D3DRS_POINTSCALE_A, FtoDW(1.0f));
2456                 SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.0f));
2457                 SetRenderState(D3DRS_POINTSCALE_C, FtoDW(0.0f));
2458                 SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
2459                 SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
2460                 SetRenderState(D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
2461                 SetRenderState(D3DRS_DEBUGMONITORTOKEN, D3DDMT_ENABLE);
2462                 SetRenderState(D3DRS_POINTSIZE_MAX, FtoDW(64.0f));
2463                 SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
2464                 SetRenderState(D3DRS_COLORWRITEENABLE, 0x0000000F);
2465                 SetRenderState(D3DRS_TWEENFACTOR, FtoDW(0.0f));
2466                 SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
2467                 SetRenderState(D3DRS_POSITIONDEGREE, D3DDEGREE_CUBIC);
2468                 SetRenderState(D3DRS_NORMALDEGREE, D3DDEGREE_LINEAR);
2469                 SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
2470                 SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FtoDW(0.0f));
2471                 SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE);
2472                 SetRenderState(D3DRS_MINTESSELLATIONLEVEL, FtoDW(1.0f));
2473                 SetRenderState(D3DRS_MAXTESSELLATIONLEVEL, FtoDW(1.0f));
2474                 SetRenderState(D3DRS_ADAPTIVETESS_X, FtoDW(0.0f));
2475                 SetRenderState(D3DRS_ADAPTIVETESS_Y, FtoDW(0.0f));
2476                 SetRenderState(D3DRS_ADAPTIVETESS_Z, FtoDW(1.0f));
2477                 SetRenderState(D3DRS_ADAPTIVETESS_W, FtoDW(0.0f));
2478                 SetRenderState(D3DRS_ENABLEADAPTIVETESSELLATION, FALSE);
2479                 SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
2480                 SetRenderState(D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_KEEP);
2481                 SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP);
2482                 SetRenderState(D3DRS_CCW_STENCILPASS, D3DSTENCILOP_KEEP);
2483                 SetRenderState(D3DRS_CCW_STENCILFUNC, D3DCMP_ALWAYS);
2484                 SetRenderState(D3DRS_COLORWRITEENABLE1, 0x0000000F);
2485                 SetRenderState(D3DRS_COLORWRITEENABLE2, 0x0000000F);
2486                 SetRenderState(D3DRS_COLORWRITEENABLE3, 0x0000000F);
2487                 SetRenderState(D3DRS_BLENDFACTOR, 0xFFFFFFFF);
2488                 SetRenderState(D3DRS_SRGBWRITEENABLE, 0);
2489                 SetRenderState(D3DRS_DEPTHBIAS, FtoDW(0.0f));
2490                 SetRenderState(D3DRS_WRAP8, 0);
2491                 SetRenderState(D3DRS_WRAP9, 0);
2492                 SetRenderState(D3DRS_WRAP10, 0);
2493                 SetRenderState(D3DRS_WRAP11, 0);
2494                 SetRenderState(D3DRS_WRAP12, 0);
2495                 SetRenderState(D3DRS_WRAP13, 0);
2496                 SetRenderState(D3DRS_WRAP14, 0);
2497                 SetRenderState(D3DRS_WRAP15, 0);
2498                 SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
2499                 SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
2500                 SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO);
2501                 SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD);
2502
2503                 for(int i = 0; i < 8; i++)
2504                 {
2505                         SetTextureStageState(i, D3DTSS_COLOROP, i == 0 ? D3DTOP_MODULATE : D3DTOP_DISABLE);
2506                         SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2507                         SetTextureStageState(i, D3DTSS_COLORARG2, D3DTA_CURRENT);
2508                         SetTextureStageState(i, D3DTSS_ALPHAOP, i == 0 ? D3DTOP_SELECTARG1 : D3DTOP_DISABLE);
2509                         SetTextureStageState(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
2510                         SetTextureStageState(i, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
2511                         SetTextureStageState(i, D3DTSS_BUMPENVMAT00, FtoDW(0.0f));
2512                         SetTextureStageState(i, D3DTSS_BUMPENVMAT01, FtoDW(0.0f));
2513                         SetTextureStageState(i, D3DTSS_BUMPENVMAT10, FtoDW(0.0f));
2514                         SetTextureStageState(i, D3DTSS_BUMPENVMAT11, FtoDW(0.0f));
2515                         SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, i);
2516                         SetTextureStageState(i, D3DTSS_BUMPENVLSCALE, FtoDW(0.0f));
2517                         SetTextureStageState(i, D3DTSS_BUMPENVLOFFSET, FtoDW(0.0f));
2518                         SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
2519                         SetTextureStageState(i, D3DTSS_COLORARG0, D3DTA_CURRENT);
2520                         SetTextureStageState(i, D3DTSS_ALPHAARG0, D3DTA_CURRENT);
2521                         SetTextureStageState(i, D3DTSS_RESULTARG, D3DTA_CURRENT);
2522                         SetTextureStageState(i, D3DTSS_CONSTANT, 0x00000000);
2523                 }
2524
2525                 for(int i = 0; i <= D3DVERTEXTEXTURESAMPLER3; i = (i != 15) ? (i + 1) : D3DVERTEXTEXTURESAMPLER0)
2526                 {
2527                         SetTexture(i, 0);
2528
2529                         SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
2530                         SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
2531                         SetSamplerState(i, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
2532                         SetSamplerState(i, D3DSAMP_BORDERCOLOR, 0x00000000);
2533                         SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2534                         SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2535                         SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2536                         SetSamplerState(i, D3DSAMP_MIPMAPLODBIAS, 0);
2537                         SetSamplerState(i, D3DSAMP_MAXMIPLEVEL, 0);
2538                         SetSamplerState(i, D3DSAMP_MAXANISOTROPY, 1);
2539                         SetSamplerState(i, D3DSAMP_SRGBTEXTURE, 0);
2540                         SetSamplerState(i, D3DSAMP_ELEMENTINDEX, 0);
2541                         SetSamplerState(i, D3DSAMP_DMAPOFFSET, 0);
2542                 }
2543
2544                 for(int i = 0; i < 6; i++)
2545                 {
2546                         float plane[4] = {0, 0, 0, 0};
2547
2548                         SetClipPlane(i, plane);
2549                 }
2550
2551                 currentPalette = 0xFFFF;
2552
2553                 ShowCursor(FALSE);
2554                 delete cursor;
2555                 cursor = 0;
2556
2557                 return D3D_OK;
2558         }
2559
2560         long Direct3DDevice9::SetClipPlane(unsigned long index, const float *plane)
2561         {
2562                 CriticalSection cs(this);
2563
2564                 TRACE("unsigned long index = %d, const float *plane = 0x%0.8p", index, plane);
2565
2566                 if(!plane || index >= 6)
2567                 {
2568                         return INVALIDCALL();
2569                 }
2570
2571                 if(!stateRecorder)
2572                 {
2573                         this->plane[index][0] = plane[0];
2574                         this->plane[index][1] = plane[1];
2575                         this->plane[index][2] = plane[2];
2576                         this->plane[index][3] = plane[3];
2577
2578                         renderer->setClipPlane(index, plane);
2579                 }
2580                 else
2581                 {
2582                         stateRecorder->setClipPlane(index, plane);
2583                 }
2584
2585                 return D3D_OK;
2586         }
2587
2588         long Direct3DDevice9::SetClipStatus(const D3DCLIPSTATUS9 *clipStatus)
2589         {
2590                 CriticalSection cs(this);
2591
2592                 TRACE("const D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);
2593
2594                 if(!clipStatus)
2595                 {
2596                         return INVALIDCALL();
2597                 }
2598
2599                 this->clipStatus = *clipStatus;
2600
2601                 UNIMPLEMENTED();
2602
2603                 return D3D_OK;
2604         }
2605
2606         long Direct3DDevice9::SetCurrentTexturePalette(unsigned int paletteNumber)
2607         {
2608                 CriticalSection cs(this);
2609
2610                 TRACE("unsigned int paletteNumber = %d", paletteNumber);
2611
2612                 if(paletteNumber > 0xFFFF || palette.find(paletteNumber) == palette.end())
2613                 {
2614                         return INVALIDCALL();
2615                 }
2616
2617                 if(!stateRecorder)
2618                 {
2619                         currentPalette = paletteNumber;
2620
2621                         sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
2622                 }
2623                 else
2624                 {
2625                         stateRecorder->setCurrentTexturePalette(paletteNumber);
2626                 }
2627
2628                 return D3D_OK;
2629         }
2630
2631         void Direct3DDevice9::SetCursorPosition(int x, int y, unsigned long flags)
2632         {
2633                 CriticalSection cs(this);
2634
2635                 TRACE("int x = %d, int y = %d, unsigned long flags = 0x%0.8X", x, y, flags);
2636
2637                 POINT point = {x, y};
2638                 HWND window = deviceWindow ? deviceWindow : focusWindow;
2639                 ScreenToClient(window, &point);
2640
2641                 sw::FrameBuffer::setCursorPosition(point.x, point.y);
2642         }
2643
2644         long Direct3DDevice9::SetCursorProperties(unsigned int x0, unsigned int y0, IDirect3DSurface9 *cursorBitmap)
2645         {
2646                 CriticalSection cs(this);
2647
2648                 TRACE("unsigned int x0 = %d, unsigned int y0 = %d, IDirect3DSurface9 *cursorBitmap = 0x%0.8p", x0, y0, cursorBitmap);
2649
2650                 if(!cursorBitmap)
2651                 {
2652                         return INVALIDCALL();
2653                 }
2654
2655                 sw::Surface *cursorSurface = static_cast<Direct3DSurface9*>(cursorBitmap);
2656
2657                 int width = cursorSurface->getWidth();
2658                 int height = cursorSurface->getHeight();
2659                 void *bitmap = cursorSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
2660
2661                 delete cursor;
2662                 cursor = sw::Surface::create(0, width, height, 1, sw::FORMAT_A8R8G8B8, false, false);
2663
2664                 void *buffer = cursor->lockExternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
2665                 memcpy(buffer, bitmap, width * height * sizeof(unsigned int));
2666                 cursor->unlockExternal();
2667
2668                 cursorSurface->unlockExternal();
2669
2670                 if(showCursor)
2671                 {
2672                         sw::FrameBuffer::setCursorImage(cursor);
2673                 }
2674                 else
2675                 {
2676                         sw::FrameBuffer::setCursorImage(0);
2677                 }
2678
2679                 sw::FrameBuffer::setCursorOrigin(x0, y0);
2680
2681                 return D3D_OK;
2682         }
2683
2684         long Direct3DDevice9::SetDepthStencilSurface(IDirect3DSurface9 *iDepthStencil)
2685         {
2686                 CriticalSection cs(this);
2687
2688                 TRACE("IDirect3DSurface9 *newDepthStencil = 0x%0.8p", iDepthStencil);
2689
2690                 Direct3DSurface9 *depthStencil = static_cast<Direct3DSurface9*>(iDepthStencil);
2691
2692                 if(this->depthStencil == depthStencil)
2693                 {
2694                         return D3D_OK;
2695                 }
2696
2697                 if(depthStencil)
2698                 {
2699                         depthStencil->bind();
2700                 }
2701
2702                 if(this->depthStencil)
2703                 {
2704                         this->depthStencil->unbind();
2705                 }
2706
2707                 this->depthStencil = depthStencil;
2708
2709                 renderer->setDepthBuffer(depthStencil);
2710                 renderer->setStencilBuffer(depthStencil);
2711
2712                 return D3D_OK;
2713         }
2714
2715         long Direct3DDevice9::SetDialogBoxMode(int enableDialogs)
2716         {
2717                 CriticalSection cs(this);
2718
2719                 TRACE("int enableDialogs = %d", enableDialogs);
2720
2721                 UNIMPLEMENTED();
2722
2723                 return D3D_OK;
2724         }
2725
2726         long Direct3DDevice9::SetFVF(unsigned long FVF)
2727         {
2728                 CriticalSection cs(this);
2729
2730                 TRACE("unsigned long FVF = 0x%0.8X", FVF);
2731
2732                 if(!stateRecorder)
2733                 {
2734                         if(FVF != 0 || !this->vertexDeclaration)
2735                         {
2736                                 Direct3DVertexDeclaration9 *vertexDeclaration = new Direct3DVertexDeclaration9(this, FVF);
2737                                 vertexDeclaration->bind();
2738
2739                                 if(this->vertexDeclaration)
2740                                 {
2741                                         this->vertexDeclaration->unbind();
2742                                 }
2743
2744                                 this->vertexDeclaration = vertexDeclaration;
2745                         }
2746                 }
2747                 else
2748                 {
2749                         stateRecorder->setFVF(FVF);
2750                 }
2751
2752                 return D3D_OK;
2753         }
2754
2755         void Direct3DDevice9::SetGammaRamp(unsigned int index, unsigned long flags, const D3DGAMMARAMP *ramp)
2756         {
2757                 CriticalSection cs(this);
2758
2759                 TRACE("unsigned int index = %d, unsigned long flags = 0x%0.8X, const D3DGAMMARAMP *ramp = 0x%0.8p", index, flags, ramp);
2760
2761                 if(!ramp || index >= GetNumberOfSwapChains())
2762                 {
2763                         return;
2764                 }
2765
2766                 swapChain->setGammaRamp((sw::GammaRamp*)ramp, flags & D3DSGR_CALIBRATE);
2767         }
2768
2769         long Direct3DDevice9::SetIndices(IDirect3DIndexBuffer9* iIndexBuffer)
2770         {
2771                 CriticalSection cs(this);
2772
2773                 TRACE("IDirect3DIndexBuffer9* indexData = 0x%0.8p", iIndexBuffer);
2774
2775                 Direct3DIndexBuffer9 *indexBuffer = static_cast<Direct3DIndexBuffer9*>(iIndexBuffer);
2776
2777                 if(!stateRecorder)
2778                 {
2779                         if(this->indexData == indexBuffer)
2780                         {
2781                                 return D3D_OK;
2782                         }
2783
2784                         if(indexBuffer)
2785                         {
2786                                 indexBuffer->bind();
2787                         }
2788
2789                         if(this->indexData)
2790                         {
2791                                 this->indexData->unbind();
2792                         }
2793
2794                         this->indexData = indexBuffer;
2795                 }
2796                 else
2797                 {
2798                         stateRecorder->setIndices(indexBuffer);
2799                 }
2800
2801                 return D3D_OK;
2802         }
2803
2804         long Direct3DDevice9::SetLight(unsigned long index, const D3DLIGHT9 *light)
2805         {
2806                 CriticalSection cs(this);
2807
2808                 TRACE("unsigned long index = %d, const D3DLIGHT9 *light = 0x%0.8p", index, light);
2809
2810                 if(!light)
2811                 {
2812                         return INVALIDCALL();
2813                 }
2814
2815                 if(!stateRecorder)
2816                 {
2817                         this->light[index] = *light;
2818
2819                         lightsDirty = true;
2820                 }
2821                 else
2822                 {
2823                         stateRecorder->setLight(index, light);
2824                 }
2825
2826                 return D3D_OK;
2827         }
2828
2829         long Direct3DDevice9::SetMaterial(const D3DMATERIAL9 *material)
2830         {
2831                 CriticalSection cs(this);
2832
2833                 TRACE("const D3DMATERIAL9 *material = 0x%0.8p", material);
2834
2835                 if(!material)
2836                 {
2837                         return INVALIDCALL();   // FIXME: Correct behaviour?
2838                 }
2839
2840                 if(!stateRecorder)
2841                 {
2842                         this->material = *material;
2843
2844                         renderer->setMaterialAmbient(sw::Color<float>(material->Ambient.r, material->Ambient.g, material->Ambient.b, material->Ambient.a));
2845                         renderer->setMaterialDiffuse(sw::Color<float>(material->Diffuse.r, material->Diffuse.g, material->Diffuse.b, material->Diffuse.a));
2846                         renderer->setMaterialEmission(sw::Color<float>(material->Emissive.r, material->Emissive.g, material->Emissive.b, material->Emissive.a));
2847                         renderer->setMaterialShininess(material->Power);
2848                         renderer->setMaterialSpecular(sw::Color<float>(material->Specular.r, material->Specular.g, material->Specular.b, material->Specular.a));
2849                 }
2850                 else
2851                 {
2852                         stateRecorder->setMaterial(material);
2853                 }
2854
2855                 return D3D_OK;
2856         }
2857
2858         long Direct3DDevice9::SetNPatchMode(float segments)
2859         {
2860                 CriticalSection cs(this);
2861
2862                 TRACE("float segments = %f", segments);
2863
2864                 if(!stateRecorder)
2865                 {
2866                         if(segments < 1)
2867                         {
2868                                 // NOTE: Disable
2869                         }
2870                         else
2871                         {
2872                                 UNIMPLEMENTED();
2873                         }
2874                 }
2875                 else
2876                 {
2877                         stateRecorder->setNPatchMode(segments);
2878                 }
2879
2880                 return D3D_OK;
2881         }
2882
2883         long Direct3DDevice9::SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries)
2884         {
2885                 CriticalSection cs(this);
2886
2887                 TRACE("unsigned int paletteNumber = %d, const PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);
2888
2889                 if(paletteNumber > 0xFFFF || !entries)
2890                 {
2891                         return INVALIDCALL();
2892                 }
2893
2894                 for(int i = 0; i < 256; i++)
2895                 {
2896                         palette[paletteNumber].entry[i] = entries[i];
2897                 }
2898
2899                 if(paletteNumber == currentPalette)
2900                 {
2901                         sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
2902                 }
2903
2904                 return D3D_OK;
2905         }
2906
2907         long Direct3DDevice9::SetPixelShader(IDirect3DPixelShader9 *iPixelShader)
2908         {
2909                 CriticalSection cs(this);
2910
2911                 TRACE("IDirect3DPixelShader9 *shader = 0x%0.8p", iPixelShader);
2912
2913                 Direct3DPixelShader9 *pixelShader = static_cast<Direct3DPixelShader9*>(iPixelShader);
2914
2915                 if(!stateRecorder)
2916                 {
2917                         if(this->pixelShader == pixelShader)
2918                         {
2919                                 return D3D_OK;
2920                         }
2921
2922                         if(pixelShader)
2923                         {
2924                                 pixelShader->bind();
2925                         }
2926
2927                         if(this->pixelShader)
2928                         {
2929                                 this->pixelShader->unbind();
2930                         }
2931
2932                         this->pixelShader = pixelShader;
2933                         pixelShaderDirty = true;
2934                 }
2935                 else
2936                 {
2937                         stateRecorder->setPixelShader(pixelShader);
2938                 }
2939
2940                 return D3D_OK;
2941         }
2942
2943         long Direct3DDevice9::SetPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
2944         {
2945                 CriticalSection cs(this);
2946
2947                 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
2948
2949                 if(!stateRecorder)
2950                 {
2951                         for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
2952                         {
2953                                 pixelShaderConstantB[startRegister + i] = constantData[i];
2954                         }
2955
2956                         pixelShaderConstantsBDirty = sw::max(startRegister + count, pixelShaderConstantsBDirty);
2957                         pixelShaderDirty = true;   // Reload DEF constants
2958                 }
2959                 else
2960                 {
2961                         stateRecorder->setPixelShaderConstantB(startRegister, constantData, count);
2962                 }
2963
2964                 return D3D_OK;
2965         }
2966
2967         long Direct3DDevice9::SetPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
2968         {
2969                 CriticalSection cs(this);
2970
2971                 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
2972
2973                 if(!stateRecorder)
2974                 {
2975                         for(unsigned int i = 0; i < count && startRegister + i < MAX_PIXEL_SHADER_CONST; i++)
2976                         {
2977                                 pixelShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
2978                                 pixelShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
2979                                 pixelShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
2980                                 pixelShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
2981                         }
2982
2983                         pixelShaderConstantsFDirty = sw::max(startRegister + count, pixelShaderConstantsFDirty);
2984                         pixelShaderDirty = true;   // Reload DEF constants
2985                 }
2986                 else
2987                 {
2988                         stateRecorder->setPixelShaderConstantF(startRegister, constantData, count);
2989                 }
2990
2991                 return D3D_OK;
2992         }
2993
2994         long Direct3DDevice9::SetPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
2995         {
2996                 CriticalSection cs(this);
2997
2998                 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
2999
3000                 if(!stateRecorder)
3001                 {
3002                         for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
3003                         {
3004                                 pixelShaderConstantI[startRegister + i][0] = constantData[i * 4 + 0];
3005                                 pixelShaderConstantI[startRegister + i][1] = constantData[i * 4 + 1];
3006                                 pixelShaderConstantI[startRegister + i][2] = constantData[i * 4 + 2];
3007                                 pixelShaderConstantI[startRegister + i][3] = constantData[i * 4 + 3];
3008                         }
3009
3010                         pixelShaderConstantsIDirty = sw::max(startRegister + count, pixelShaderConstantsIDirty);
3011                         pixelShaderDirty = true;   // Reload DEF constants
3012                 }
3013                 else
3014                 {
3015                         stateRecorder->setPixelShaderConstantI(startRegister, constantData, count);
3016                 }
3017
3018                 return D3D_OK;
3019         }
3020
3021         long Direct3DDevice9::SetRenderState(D3DRENDERSTATETYPE state, unsigned long value)
3022         {
3023                 CriticalSection cs(this);
3024
3025                 TRACE("D3DRENDERSTATETYPE state = %d, unsigned long value = %d", state, value);
3026
3027                 if(state < D3DRS_ZENABLE || state > D3DRS_BLENDOPALPHA)
3028                 {
3029                         return D3D_OK;   // FIXME: Warning
3030                 }
3031
3032                 if(!stateRecorder)
3033                 {
3034                         if(!init && renderState[state] == value)
3035                         {
3036                                 return D3D_OK;
3037                         }
3038
3039                         renderState[state] = value;
3040
3041                         switch(state)
3042                         {
3043                         case D3DRS_ZENABLE:
3044                                 switch(value)
3045                                 {
3046                                 case D3DZB_TRUE:
3047                                 case D3DZB_USEW:
3048                                         renderer->setDepthBufferEnable(true);
3049                                         break;
3050                                 case D3DZB_FALSE:
3051                                         renderer->setDepthBufferEnable(false);
3052                                         break;
3053                                 default:
3054                                         ASSERT(false);
3055                                 }
3056                                 break;
3057                         case D3DRS_FILLMODE:
3058                                 switch(value)
3059                                 {
3060                                 case D3DFILL_POINT:
3061                                         renderer->setFillMode(sw::FILL_VERTEX);
3062                                         break;
3063                                 case D3DFILL_WIREFRAME:
3064                                         renderer->setFillMode(sw::FILL_WIREFRAME);
3065                                         break;
3066                                 case D3DFILL_SOLID:
3067                                         renderer->setFillMode(sw::FILL_SOLID);
3068                                         break;
3069                                 default:
3070                                         ASSERT(false);
3071                                 }
3072                                 break;
3073                         case D3DRS_SHADEMODE:
3074                                 switch(value)
3075                                 {
3076                                 case D3DSHADE_FLAT:
3077                                         renderer->setShadingMode(sw::SHADING_FLAT);
3078                                         break;
3079                                 case D3DSHADE_GOURAUD:
3080                                         renderer->setShadingMode(sw::SHADING_GOURAUD);
3081                                         break;
3082                                 case D3DSHADE_PHONG:
3083                                         break;
3084                                 default:
3085                                         ASSERT(false);
3086                                 }
3087                                 break;
3088                         case D3DRS_ZWRITEENABLE:
3089                                 renderer->setDepthWriteEnable(value != FALSE);
3090                                 break;
3091                         case D3DRS_ALPHATESTENABLE:
3092                                 renderer->setAlphaTestEnable(value != FALSE);
3093                                 break;
3094                         case D3DRS_LASTPIXEL:
3095                         //      if(!init) UNIMPLEMENTED();   // FIXME
3096                                 break;
3097                         case D3DRS_SRCBLEND:
3098                                 switch(value)
3099                                 {
3100                                 case D3DBLEND_ZERO:
3101                                         renderer->setSourceBlendFactor(sw::BLEND_ZERO);
3102                                         break;
3103                                 case D3DBLEND_ONE:
3104                                         renderer->setSourceBlendFactor(sw::BLEND_ONE);
3105                                         break;
3106                                 case D3DBLEND_SRCCOLOR:
3107                                         renderer->setSourceBlendFactor(sw::BLEND_SOURCE);
3108                                         break;
3109                                 case D3DBLEND_INVSRCCOLOR:
3110                                         renderer->setSourceBlendFactor(sw::BLEND_INVSOURCE);
3111                                         break;
3112                                 case D3DBLEND_SRCALPHA:
3113                                         renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
3114                                         break;
3115                                 case D3DBLEND_INVSRCALPHA:
3116                                         renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
3117                                         break;
3118                                 case D3DBLEND_DESTALPHA:
3119                                         renderer->setSourceBlendFactor(sw::BLEND_DESTALPHA);
3120                                         break;
3121                                 case D3DBLEND_INVDESTALPHA:
3122                                         renderer->setSourceBlendFactor(sw::BLEND_INVDESTALPHA);
3123                                         break;
3124                                 case D3DBLEND_DESTCOLOR:
3125                                         renderer->setSourceBlendFactor(sw::BLEND_DEST);
3126                                         break;
3127                                 case D3DBLEND_INVDESTCOLOR:
3128                                         renderer->setSourceBlendFactor(sw::BLEND_INVDEST);
3129                                         break;
3130                                 case D3DBLEND_SRCALPHASAT:
3131                                         renderer->setSourceBlendFactor(sw::BLEND_SRCALPHASAT);
3132                                         break;
3133                                 case D3DBLEND_BOTHSRCALPHA:
3134                                         renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
3135                                         renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
3136                                         break;
3137                                 case D3DBLEND_BOTHINVSRCALPHA:
3138                                         renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
3139                                         renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
3140                                         break;
3141                                 case D3DBLEND_BLENDFACTOR:
3142                                         renderer->setSourceBlendFactor(sw::BLEND_CONSTANT);
3143                                         break;
3144                                 case D3DBLEND_INVBLENDFACTOR:
3145                                         renderer->setSourceBlendFactor(sw::BLEND_INVCONSTANT);
3146                                         break;
3147                                 default:
3148                                         ASSERT(false);
3149                                 }
3150                                 break;
3151                         case D3DRS_DESTBLEND:
3152                                 switch(value)
3153                                 {
3154                                 case D3DBLEND_ZERO:
3155                                         renderer->setDestBlendFactor(sw::BLEND_ZERO);
3156                                         break;
3157                                 case D3DBLEND_ONE:
3158                                         renderer->setDestBlendFactor(sw::BLEND_ONE);
3159                                         break;
3160                                 case D3DBLEND_SRCCOLOR:
3161                                         renderer->setDestBlendFactor(sw::BLEND_SOURCE);
3162                                         break;
3163                                 case D3DBLEND_INVSRCCOLOR:
3164                                         renderer->setDestBlendFactor(sw::BLEND_INVSOURCE);
3165                                         break;
3166                                 case D3DBLEND_SRCALPHA:
3167                                         renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
3168                                         break;
3169                                 case D3DBLEND_INVSRCALPHA:
3170                                         renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
3171                                         break;
3172                                 case D3DBLEND_DESTALPHA:
3173                                         renderer->setDestBlendFactor(sw::BLEND_DESTALPHA);
3174                                         break;
3175                                 case D3DBLEND_INVDESTALPHA:
3176                                         renderer->setDestBlendFactor(sw::BLEND_INVDESTALPHA);
3177                                         break;
3178                                 case D3DBLEND_DESTCOLOR:
3179                                         renderer->setDestBlendFactor(sw::BLEND_DEST);
3180                                         break;
3181                                 case D3DBLEND_INVDESTCOLOR:
3182                                         renderer->setDestBlendFactor(sw::BLEND_INVDEST);
3183                                         break;
3184                                 case D3DBLEND_SRCALPHASAT:
3185                                         renderer->setDestBlendFactor(sw::BLEND_SRCALPHASAT);
3186                                         break;
3187                                 case D3DBLEND_BOTHSRCALPHA:
3188                                         renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
3189                                         renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
3190                                         break;
3191                                 case D3DBLEND_BOTHINVSRCALPHA:
3192                                         renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
3193                                         renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
3194                                         break;
3195                                 case D3DBLEND_BLENDFACTOR:
3196                                         renderer->setDestBlendFactor(sw::BLEND_CONSTANT);
3197                                         break;
3198                                 case D3DBLEND_INVBLENDFACTOR:
3199                                         renderer->setDestBlendFactor(sw::BLEND_INVCONSTANT);
3200                                         break;
3201                                 default:
3202                                         ASSERT(false);
3203                                 }
3204                                 break;
3205                         case D3DRS_CULLMODE:
3206                                 switch(value)
3207                                 {
3208                                 case D3DCULL_NONE:
3209                                         renderer->setCullMode(sw::CULL_NONE);
3210                                         break;
3211                                 case D3DCULL_CCW:
3212                                         renderer->setCullMode(sw::CULL_COUNTERCLOCKWISE);
3213                                         break;
3214                                 case D3DCULL_CW:
3215                                         renderer->setCullMode(sw::CULL_CLOCKWISE);
3216                                         break;
3217                                 default:
3218                                         ASSERT(false);
3219                                 }
3220                                 break;
3221                         case D3DRS_ZFUNC:
3222                                 switch(value)
3223                                 {
3224                                 case D3DCMP_NEVER:
3225                                         renderer->setDepthCompare(sw::DEPTH_NEVER);
3226                                         break;
3227                                 case D3DCMP_LESS:
3228                                         renderer->setDepthCompare(sw::DEPTH_LESS);
3229                                         break;
3230                                 case D3DCMP_EQUAL:
3231                                         renderer->setDepthCompare(sw::DEPTH_EQUAL);
3232                                         break;
3233                                 case D3DCMP_LESSEQUAL:
3234                                         renderer->setDepthCompare(sw::DEPTH_LESSEQUAL);
3235                                         break;
3236                                 case D3DCMP_GREATER:
3237                                         renderer->setDepthCompare(sw::DEPTH_GREATER);
3238                                         break;
3239                                 case D3DCMP_NOTEQUAL:
3240                                         renderer->setDepthCompare(sw::DEPTH_NOTEQUAL);
3241                                         break;
3242                                 case D3DCMP_GREATEREQUAL:
3243                                         renderer->setDepthCompare(sw::DEPTH_GREATEREQUAL);
3244                                         break;
3245                                 case D3DCMP_ALWAYS:
3246                                         renderer->setDepthCompare(sw::DEPTH_ALWAYS);
3247                                         break;
3248                                 default:
3249                                         ASSERT(false);
3250                                 }
3251                                 break;
3252                         case D3DRS_ALPHAREF:
3253                                 renderer->setAlphaReference(value & 0x000000FF);
3254                                 break;
3255                         case D3DRS_ALPHAFUNC:
3256                                 switch(value)
3257                                 {
3258                                 case D3DCMP_NEVER:
3259                                         renderer->setAlphaCompare(sw::ALPHA_NEVER);
3260                                         break;
3261                                 case D3DCMP_LESS:
3262                                         renderer->setAlphaCompare(sw::ALPHA_LESS);
3263                                         break;
3264                                 case D3DCMP_EQUAL:
3265                                         renderer->setAlphaCompare(sw::ALPHA_EQUAL);
3266                                         break;
3267                                 case D3DCMP_LESSEQUAL:
3268                                         renderer->setAlphaCompare(sw::ALPHA_LESSEQUAL);
3269                                         break;
3270                                 case D3DCMP_GREATER:
3271                                         renderer->setAlphaCompare(sw::ALPHA_GREATER);
3272                                         break;
3273                                 case D3DCMP_NOTEQUAL:
3274                                         renderer->setAlphaCompare(sw::ALPHA_NOTEQUAL);
3275                                         break;
3276                                 case D3DCMP_GREATEREQUAL:
3277                                         renderer->setAlphaCompare(sw::ALPHA_GREATEREQUAL);
3278                                         break;
3279                                 case D3DCMP_ALWAYS:
3280                                         renderer->setAlphaCompare(sw::ALPHA_ALWAYS);
3281                                         break;
3282                                 default:
3283                                         ASSERT(false);
3284                                 }
3285                                 break;
3286                         case D3DRS_DITHERENABLE:
3287                         //      if(!init) UNIMPLEMENTED();
3288                                 break;
3289                         case D3DRS_ALPHABLENDENABLE:
3290                                 renderer->setAlphaBlendEnable(value != FALSE);
3291                                 break;
3292                         case D3DRS_FOGENABLE:
3293                                 renderer->setFogEnable(value != FALSE);
3294                                 break;
3295                         case D3DRS_FOGCOLOR:
3296                                 renderer->setFogColor(value);
3297                                 break;
3298                         case D3DRS_FOGTABLEMODE:
3299                                 switch(value)
3300                                 {
3301                                 case D3DFOG_NONE:
3302                                         renderer->setPixelFogMode(sw::FOG_NONE);
3303                                         break;
3304                                 case D3DFOG_LINEAR:
3305                                         renderer->setPixelFogMode(sw::FOG_LINEAR);
3306                                         break;
3307                                 case D3DFOG_EXP:
3308                                         renderer->setPixelFogMode(sw::FOG_EXP);
3309                                         break;
3310                                 case D3DFOG_EXP2:
3311                                         renderer->setPixelFogMode(sw::FOG_EXP2);
3312                                         break;
3313                                 default:
3314                                         ASSERT(false);
3315                                 }
3316                                 break;
3317                         case D3DRS_FOGSTART:
3318                                 renderer->setFogStart((float&)value);
3319                                 break;
3320                         case D3DRS_FOGEND:
3321                                 renderer->setFogEnd((float&)value);
3322                                 break;
3323                         case D3DRS_FOGDENSITY:
3324                                 renderer->setFogDensity((float&)value);
3325                                 break;
3326                         case D3DRS_RANGEFOGENABLE:
3327                                 renderer->setRangeFogEnable(value != FALSE);
3328                                 break;
3329                         case D3DRS_SPECULARENABLE:
3330                                 renderer->setSpecularEnable(value != FALSE);
3331                                 break;
3332                         case D3DRS_STENCILENABLE:
3333                                 renderer->setStencilEnable(value != FALSE);
3334                                 break;
3335                         case D3DRS_STENCILFAIL:
3336                                 switch(value)
3337                                 {
3338                                 case D3DSTENCILOP_KEEP:
3339                                         renderer->setStencilFailOperation(sw::OPERATION_KEEP);
3340                                         break;
3341                                 case D3DSTENCILOP_ZERO:
3342                                         renderer->setStencilFailOperation(sw::OPERATION_ZERO);
3343                                         break;
3344                                 case D3DSTENCILOP_REPLACE:
3345                                         renderer->setStencilFailOperation(sw::OPERATION_REPLACE);
3346                                         break;
3347                                 case D3DSTENCILOP_INCRSAT:
3348                                         renderer->setStencilFailOperation(sw::OPERATION_INCRSAT);
3349                                         break;
3350                                 case D3DSTENCILOP_DECRSAT:
3351                                         renderer->setStencilFailOperation(sw::OPERATION_DECRSAT);
3352                                         break;
3353                                 case D3DSTENCILOP_INVERT:
3354                                         renderer->setStencilFailOperation(sw::OPERATION_INVERT);
3355                                         break;
3356                                 case D3DSTENCILOP_INCR:
3357                                         renderer->setStencilFailOperation(sw::OPERATION_INCR);
3358                                         break;
3359                                 case D3DSTENCILOP_DECR:
3360                                         renderer->setStencilFailOperation(sw::OPERATION_DECR);
3361                                         break;
3362                                 default:
3363                                         ASSERT(false);
3364                                 }
3365                                 break;
3366                         case D3DRS_STENCILZFAIL:
3367                                 switch(value)
3368                                 {
3369                                 case D3DSTENCILOP_KEEP:
3370                                         renderer->setStencilZFailOperation(sw::OPERATION_KEEP);
3371                                         break;
3372                                 case D3DSTENCILOP_ZERO:
3373                                         renderer->setStencilZFailOperation(sw::OPERATION_ZERO);
3374                                         break;
3375                                 case D3DSTENCILOP_REPLACE:
3376                                         renderer->setStencilZFailOperation(sw::OPERATION_REPLACE);
3377                                         break;
3378                                 case D3DSTENCILOP_INCRSAT:
3379                                         renderer->setStencilZFailOperation(sw::OPERATION_INCRSAT);
3380                                         break;
3381                                 case D3DSTENCILOP_DECRSAT:
3382                                         renderer->setStencilZFailOperation(sw::OPERATION_DECRSAT);
3383                                         break;
3384                                 case D3DSTENCILOP_INVERT:
3385                                         renderer->setStencilZFailOperation(sw::OPERATION_INVERT);
3386                                         break;
3387                                 case D3DSTENCILOP_INCR:
3388                                         renderer->setStencilZFailOperation(sw::OPERATION_INCR);
3389                                         break;
3390                                 case D3DSTENCILOP_DECR:
3391                                         renderer->setStencilZFailOperation(sw::OPERATION_DECR);
3392                                         break;
3393                                 default:
3394                                         ASSERT(false);
3395                                 }
3396                                 break;
3397                         case D3DRS_STENCILPASS:
3398                                 switch(value)
3399                                 {
3400                                 case D3DSTENCILOP_KEEP:
3401                                         renderer->setStencilPassOperation(sw::OPERATION_KEEP);
3402                                         break;
3403                                 case D3DSTENCILOP_ZERO:
3404                                         renderer->setStencilPassOperation(sw::OPERATION_ZERO);
3405                                         break;
3406                                 case D3DSTENCILOP_REPLACE:
3407                                         renderer->setStencilPassOperation(sw::OPERATION_REPLACE);
3408                                         break;
3409                                 case D3DSTENCILOP_INCRSAT:
3410                                         renderer->setStencilPassOperation(sw::OPERATION_INCRSAT);
3411                                         break;
3412                                 case D3DSTENCILOP_DECRSAT:
3413                                         renderer->setStencilPassOperation(sw::OPERATION_DECRSAT);
3414                                         break;
3415                                 case D3DSTENCILOP_INVERT:
3416                                         renderer->setStencilPassOperation(sw::OPERATION_INVERT);
3417                                         break;
3418                                 case D3DSTENCILOP_INCR:
3419                                         renderer->setStencilPassOperation(sw::OPERATION_INCR);
3420                                         break;
3421                                 case D3DSTENCILOP_DECR:
3422                                         renderer->setStencilPassOperation(sw::OPERATION_DECR);
3423                                         break;
3424                                 default:
3425                                         ASSERT(false);
3426                                 }
3427                                 break;
3428                         case D3DRS_STENCILFUNC:
3429                                 switch(value)
3430                                 {
3431                                 case D3DCMP_NEVER:
3432                                         renderer->setStencilCompare(sw::STENCIL_NEVER);
3433                                         break;
3434                                 case D3DCMP_LESS:
3435                                         renderer->setStencilCompare(sw::STENCIL_LESS);
3436                                         break;
3437                                 case D3DCMP_EQUAL:
3438                                         renderer->setStencilCompare(sw::STENCIL_EQUAL);
3439                                         break;
3440                                 case D3DCMP_LESSEQUAL:
3441                                         renderer->setStencilCompare(sw::STENCIL_LESSEQUAL);
3442                                         break;
3443                                 case D3DCMP_GREATER:
3444                                         renderer->setStencilCompare(sw::STENCIL_GREATER);
3445                                         break;
3446                                 case D3DCMP_NOTEQUAL:
3447                                         renderer->setStencilCompare(sw::STENCIL_NOTEQUAL);
3448                                         break;
3449                                 case D3DCMP_GREATEREQUAL:
3450                                         renderer->setStencilCompare(sw::STENCIL_GREATEREQUAL);
3451                                         break;
3452                                 case D3DCMP_ALWAYS:
3453                                         renderer->setStencilCompare(sw::STENCIL_ALWAYS);
3454                                         break;
3455                                 default:
3456                                         ASSERT(false);
3457                                 }
3458                                 break;
3459                         case D3DRS_STENCILREF:
3460                                 renderer->setStencilReference(value);
3461                                 renderer->setStencilReferenceCCW(value);
3462                                 break;
3463                         case D3DRS_STENCILMASK:
3464                                 renderer->setStencilMask(value);
3465                                 renderer->setStencilMaskCCW(value);
3466                                 break;
3467                         case D3DRS_STENCILWRITEMASK:
3468                                 renderer->setStencilWriteMask(value);
3469                                 renderer->setStencilWriteMaskCCW(value);
3470                                 break;
3471                         case D3DRS_TEXTUREFACTOR:
3472                                 renderer->setTextureFactor(value);
3473                                 break;
3474                         case D3DRS_WRAP0:
3475                                 renderer->setTextureWrap(0, value);
3476                                 break;
3477                         case D3DRS_WRAP1:
3478                                 renderer->setTextureWrap(1, value);
3479                                 break;
3480                         case D3DRS_WRAP2:
3481                                 renderer->setTextureWrap(2, value);
3482                                 break;
3483                         case D3DRS_WRAP3:
3484                                 renderer->setTextureWrap(3, value);
3485                                 break;
3486                         case D3DRS_WRAP4:
3487                                 renderer->setTextureWrap(4, value);
3488                                 break;
3489                         case D3DRS_WRAP5:
3490                                 renderer->setTextureWrap(5, value);
3491                                 break;
3492                         case D3DRS_WRAP6:
3493                                 renderer->setTextureWrap(6, value);
3494                                 break;
3495                         case D3DRS_WRAP7:
3496                                 renderer->setTextureWrap(7, value);
3497                                 break;
3498                         case D3DRS_CLIPPING:
3499                                 // Ignored, clipping is always performed
3500                                 break;
3501                         case D3DRS_LIGHTING:
3502                                 renderer->setLightingEnable(value != FALSE);
3503                                 break;
3504                         case D3DRS_AMBIENT:
3505                                 renderer->setGlobalAmbient(value);
3506                                 break;
3507                         case D3DRS_FOGVERTEXMODE:
3508                                 switch(value)
3509                                 {
3510                                 case D3DFOG_NONE:
3511                                         renderer->setVertexFogMode(sw::FOG_NONE);
3512                                         break;
3513                                 case D3DFOG_LINEAR:
3514                                         renderer->setVertexFogMode(sw::FOG_LINEAR);
3515                                         break;
3516                                 case D3DFOG_EXP:
3517                                         renderer->setVertexFogMode(sw::FOG_EXP);
3518                                         break;
3519                                 case D3DFOG_EXP2:
3520                                         renderer->setVertexFogMode(sw::FOG_EXP2);
3521                                         break;
3522                                 default:
3523                                         ASSERT(false);
3524                                 }
3525                                 break;
3526                         case D3DRS_COLORVERTEX:
3527                                 renderer->setColorVertexEnable(value != FALSE);
3528                                 break;
3529                         case D3DRS_LOCALVIEWER:
3530                                 renderer->setLocalViewer(value != FALSE);
3531                                 break;
3532                         case D3DRS_NORMALIZENORMALS:
3533                                 renderer->setNormalizeNormals(value != FALSE);
3534                                 break;
3535                         case D3DRS_DIFFUSEMATERIALSOURCE:
3536                                 switch(value)
3537                                 {
3538                                 case D3DMCS_MATERIAL:
3539                                         renderer->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
3540                                         break;
3541                                 case D3DMCS_COLOR1:
3542                                         renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
3543                                         break;
3544                                 case D3DMCS_COLOR2:
3545                                         renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR2);
3546                                         break;
3547                                 default:
3548                                         ASSERT(false);
3549                                 }
3550                                 break;
3551                         case D3DRS_SPECULARMATERIALSOURCE:
3552                                 switch(value)
3553                                 {
3554                                 case D3DMCS_MATERIAL:
3555                                         renderer->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3556                                         break;
3557                                 case D3DMCS_COLOR1:
3558                                         renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR1);
3559                                         break;
3560                                 case D3DMCS_COLOR2:
3561                                         renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR2);
3562                                         break;
3563                                 default:
3564                                         ASSERT(false);
3565                                 }
3566                                 break;
3567                         case D3DRS_AMBIENTMATERIALSOURCE:
3568                                 switch(value)
3569                                 {
3570                                 case D3DMCS_MATERIAL:
3571                                         renderer->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
3572                                         break;
3573                                 case D3DMCS_COLOR1:
3574                                         renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
3575                                         break;
3576                                 case D3DMCS_COLOR2:
3577                                         renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR2);
3578                                         break;
3579                                 default:
3580                                         ASSERT(false);
3581                                 }
3582                                 break;
3583                         case D3DRS_EMISSIVEMATERIALSOURCE:
3584                                 switch(value)
3585                                 {
3586                                 case D3DMCS_MATERIAL:
3587                                         renderer->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3588                                         break;
3589                                 case D3DMCS_COLOR1:
3590                                         renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);
3591                                         break;
3592                                 case D3DMCS_COLOR2:
3593                                         renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR2);
3594                                         break;
3595                                 default:
3596                                         ASSERT(false);
3597                                 }
3598                                 break;
3599                         case D3DRS_VERTEXBLEND:
3600                                 switch(value)
3601                                 {
3602                                 case D3DVBF_DISABLE:
3603                                         renderer->setVertexBlendMatrixCount(0);
3604                                         break;
3605                                 case D3DVBF_1WEIGHTS:
3606                                         renderer->setVertexBlendMatrixCount(2);
3607                                         break;
3608                                 case D3DVBF_2WEIGHTS:
3609                                         renderer->setVertexBlendMatrixCount(3);
3610                                         break;
3611                                 case D3DVBF_3WEIGHTS:
3612                                         renderer->setVertexBlendMatrixCount(4);
3613                                         break;
3614                                 case D3DVBF_TWEENING:
3615                                         UNIMPLEMENTED();
3616                                         break;
3617                                 case D3DVBF_0WEIGHTS:
3618                                         renderer->setVertexBlendMatrixCount(1);
3619                                         break;
3620                                 default:
3621                                         ASSERT(false);
3622                                 }
3623                                 break;
3624                         case D3DRS_CLIPPLANEENABLE:
3625                                 renderer->setClipFlags(value);
3626                                 break;
3627                         case D3DRS_POINTSIZE:
3628                                 if(value == D3DFMT_INST && pixelShaderVersionX >= D3DPS_VERSION(2, 0))   // ATI hack to enable instancing on SM 2.0 hardware
3629                                 {
3630                                         instancingEnabled = true;
3631                                 }
3632                                 else if(value == D3DFMT_A2M1)   // ATI hack to enable transparency anti-aliasing
3633                                 {
3634                                         renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
3635                                         renderer->setAlphaTestEnable(true);
3636                                 }
3637                                 else if(value == D3DFMT_A2M0)   // ATI hack to disable transparency anti-aliasing
3638                                 {
3639                                         renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
3640                                         renderer->setAlphaTestEnable(false);
3641                                 }
3642                                 else
3643                                 {
3644                                         renderer->setPointSize((float&)value);
3645                                 }
3646                                 break;
3647                         case D3DRS_POINTSIZE_MIN:
3648                                 renderer->setPointSizeMin((float&)value);
3649                                 break;
3650                         case D3DRS_POINTSPRITEENABLE:
3651                                 renderer->setPointSpriteEnable(value != FALSE);
3652                                 break;
3653                         case D3DRS_POINTSCALEENABLE:
3654                                 renderer->setPointScaleEnable(value != FALSE);
3655                                 break;
3656                         case D3DRS_POINTSCALE_A:
3657                                 renderer->setPointScaleA((float&)value);
3658                                 break;
3659                         case D3DRS_POINTSCALE_B:
3660                                 renderer->setPointScaleB((float&)value);
3661                                 break;
3662                         case D3DRS_POINTSCALE_C:
3663                                 renderer->setPointScaleC((float&)value);
3664                                 break;
3665                         case D3DRS_MULTISAMPLEANTIALIAS:
3666                         //      if(!init) UNIMPLEMENTED();
3667                                 break;
3668                         case D3DRS_MULTISAMPLEMASK:
3669                                 SetRenderTarget(0, renderTarget[0]);   // Sets the multi-sample mask, if maskable
3670                                 break;
3671                         case D3DRS_PATCHEDGESTYLE:
3672                                 if(!init) if(value != D3DPATCHEDGE_DISCRETE) UNIMPLEMENTED();
3673                                 break;
3674                         case D3DRS_DEBUGMONITORTOKEN:
3675                                 if(!init) UNIMPLEMENTED();
3676                                 break;
3677                         case D3DRS_POINTSIZE_MAX:
3678                                 renderer->setPointSizeMax((float&)value);
3679                                 break;
3680                         case D3DRS_INDEXEDVERTEXBLENDENABLE:
3681                                 renderer->setIndexedVertexBlendEnable(value != FALSE);
3682                                 break;
3683                         case D3DRS_COLORWRITEENABLE:
3684                                 renderer->setColorWriteMask(0, value & 0x0000000F);
3685                                 break;
3686                         case D3DRS_TWEENFACTOR:
3687                                 if(!init) UNIMPLEMENTED();
3688                                 break;
3689                         case D3DRS_BLENDOP:
3690                                 switch(value)
3691                                 {
3692                                 case D3DBLENDOP_ADD:
3693                                         renderer->setBlendOperation(sw::BLENDOP_ADD);
3694                                         break;
3695                                 case D3DBLENDOP_SUBTRACT:
3696                                         renderer->setBlendOperation(sw::BLENDOP_SUB);
3697                                         break;
3698                                 case D3DBLENDOP_REVSUBTRACT:
3699                                         renderer->setBlendOperation(sw::BLENDOP_INVSUB);
3700                                         break;
3701                                 case D3DBLENDOP_MIN:
3702                                         renderer->setBlendOperation(sw::BLENDOP_MIN);
3703                                         break;
3704                                 case D3DBLENDOP_MAX:
3705                                         renderer->setBlendOperation(sw::BLENDOP_MAX);
3706                                         break;
3707                                 default:
3708                                         ASSERT(false);
3709                                 }
3710                                 break;
3711                         case D3DRS_POSITIONDEGREE:
3712                                 if(!init) UNIMPLEMENTED();
3713                                 break;
3714                         case D3DRS_NORMALDEGREE:
3715                                 if(!init) UNIMPLEMENTED();
3716                                 break;
3717                         case D3DRS_SCISSORTESTENABLE:
3718                                 scissorEnable = (value != FALSE);
3719                                 break;
3720                         case D3DRS_SLOPESCALEDEPTHBIAS:
3721                                 renderer->setSlopeDepthBias((float&)value);
3722                                 break;
3723                         case D3DRS_ANTIALIASEDLINEENABLE:
3724                                 if(!init) if(value != FALSE) UNIMPLEMENTED();
3725                                 break;
3726                         case D3DRS_MINTESSELLATIONLEVEL:
3727                                 if(!init) UNIMPLEMENTED();
3728                                 break;
3729                         case D3DRS_MAXTESSELLATIONLEVEL:
3730                                 if(!init) UNIMPLEMENTED();
3731                                 break;
3732                         case D3DRS_ADAPTIVETESS_X:
3733                                 if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
3734                                 break;
3735                         case D3DRS_ADAPTIVETESS_Y:
3736                                 if(value == D3DFMT_ATOC)   // NVIDIA hack to enable transparency anti-aliasing
3737                                 {
3738                                         renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
3739                                 }
3740                                 else if(value == D3DFMT_UNKNOWN)   // NVIDIA hack to disable transparency anti-aliasing
3741                                 {
3742                                         renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
3743                                 }
3744                                 else
3745                                 {
3746                                         if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
3747                                 }
3748                                 break;
3749                         case D3DRS_ADAPTIVETESS_Z:
3750                                 if(!init) if((float&)value != 1.0f) UNIMPLEMENTED();
3751                                 break;
3752                         case D3DRS_ADAPTIVETESS_W:
3753                                 if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
3754                                 break;
3755                         case D3DRS_ENABLEADAPTIVETESSELLATION:
3756                                 if(!init) UNIMPLEMENTED();
3757                                 break;
3758                         case D3DRS_TWOSIDEDSTENCILMODE:
3759                                 renderer->setTwoSidedStencil(value != FALSE);
3760                                 break;
3761                         case D3DRS_CCW_STENCILFAIL:
3762                                 switch(value)
3763                                 {
3764                                 case D3DSTENCILOP_KEEP:
3765                                         renderer->setStencilFailOperationCCW(sw::OPERATION_KEEP);
3766                                         break;
3767                                 case D3DSTENCILOP_ZERO:
3768                                         renderer->setStencilFailOperationCCW(sw::OPERATION_ZERO);
3769                                         break;
3770                                 case D3DSTENCILOP_REPLACE:
3771                                         renderer->setStencilFailOperationCCW(sw::OPERATION_REPLACE);
3772                                         break;
3773                                 case D3DSTENCILOP_INCRSAT:
3774                                         renderer->setStencilFailOperationCCW(sw::OPERATION_INCRSAT);
3775                                         break;
3776                                 case D3DSTENCILOP_DECRSAT:
3777                                         renderer->setStencilFailOperationCCW(sw::OPERATION_DECRSAT);
3778                                         break;
3779                                 case D3DSTENCILOP_INVERT:
3780                                         renderer->setStencilFailOperationCCW(sw::OPERATION_INVERT);
3781                                         break;
3782                                 case D3DSTENCILOP_INCR:
3783                                         renderer->setStencilFailOperationCCW(sw::OPERATION_INCR);
3784                                         break;
3785                                 case D3DSTENCILOP_DECR:
3786                                         renderer->setStencilFailOperationCCW(sw::OPERATION_DECR);
3787                                         break;
3788                                 default:
3789                                         ASSERT(false);
3790                                 }
3791                                 break;
3792                         case D3DRS_CCW_STENCILZFAIL:
3793                                 switch(value)
3794                                 {
3795                                 case D3DSTENCILOP_KEEP:
3796                                         renderer->setStencilZFailOperationCCW(sw::OPERATION_KEEP);
3797                                         break;
3798                                 case D3DSTENCILOP_ZERO:
3799                                         renderer->setStencilZFailOperationCCW(sw::OPERATION_ZERO);
3800                                         break;
3801                                 case D3DSTENCILOP_REPLACE:
3802                                         renderer->setStencilZFailOperationCCW(sw::OPERATION_REPLACE);
3803                                         break;
3804                                 case D3DSTENCILOP_INCRSAT:
3805                                         renderer->setStencilZFailOperationCCW(sw::OPERATION_INCRSAT);
3806                                         break;
3807                                 case D3DSTENCILOP_DECRSAT:
3808                                         renderer->setStencilZFailOperationCCW(sw::OPERATION_DECRSAT);
3809                                         break;
3810                                 case D3DSTENCILOP_INVERT:
3811                                         renderer->setStencilZFailOperationCCW(sw::OPERATION_INVERT);
3812                                         break;
3813                                 case D3DSTENCILOP_INCR:
3814                                         renderer->setStencilZFailOperationCCW(sw::OPERATION_INCR);
3815                                         break;
3816                                 case D3DSTENCILOP_DECR:
3817                                         renderer->setStencilZFailOperationCCW(sw::OPERATION_DECR);
3818                                         break;
3819                                 default:
3820                                         ASSERT(false);
3821                                 }
3822                                 break;
3823                         case D3DRS_CCW_STENCILPASS:
3824                                 switch(value)
3825                                 {
3826                                 case D3DSTENCILOP_KEEP:
3827                                         renderer->setStencilPassOperationCCW(sw::OPERATION_KEEP);
3828                                         break;
3829                                 case D3DSTENCILOP_ZERO:
3830                                         renderer->setStencilPassOperationCCW(sw::OPERATION_ZERO);
3831                                         break;
3832                                 case D3DSTENCILOP_REPLACE:
3833                                         renderer->setStencilPassOperationCCW(sw::OPERATION_REPLACE);
3834                                         break;
3835                                 case D3DSTENCILOP_INCRSAT:
3836                                         renderer->setStencilPassOperationCCW(sw::OPERATION_INCRSAT);
3837                                         break;
3838                                 case D3DSTENCILOP_DECRSAT:
3839                                         renderer->setStencilPassOperationCCW(sw::OPERATION_DECRSAT);
3840                                         break;
3841                                 case D3DSTENCILOP_INVERT:
3842                                         renderer->setStencilPassOperationCCW(sw::OPERATION_INVERT);
3843                                         break;
3844                                 case D3DSTENCILOP_INCR:
3845                                         renderer->setStencilPassOperationCCW(sw::OPERATION_INCR);
3846                                         break;
3847                                 case D3DSTENCILOP_DECR:
3848                                         renderer->setStencilPassOperationCCW(sw::OPERATION_DECR);
3849                                         break;
3850                                 default:
3851                                         ASSERT(false);
3852                                 }
3853                                 break;
3854                         case D3DRS_CCW_STENCILFUNC:
3855                                 switch(value)
3856                                 {
3857                                 case D3DCMP_NEVER:
3858                                         renderer->setStencilCompareCCW(sw::STENCIL_NEVER);
3859                                         break;
3860                                 case D3DCMP_LESS:
3861                                         renderer->setStencilCompareCCW(sw::STENCIL_LESS);
3862                                         break;
3863                                 case D3DCMP_EQUAL:
3864                                         renderer->setStencilCompareCCW(sw::STENCIL_EQUAL);
3865                                         break;
3866                                 case D3DCMP_LESSEQUAL:
3867                                         renderer->setStencilCompareCCW(sw::STENCIL_LESSEQUAL);
3868                                         break;
3869                                 case D3DCMP_GREATER:
3870                                         renderer->setStencilCompareCCW(sw::STENCIL_GREATER);
3871                                         break;
3872                                 case D3DCMP_NOTEQUAL:
3873                                         renderer->setStencilCompareCCW(sw::STENCIL_NOTEQUAL);
3874                                         break;
3875                                 case D3DCMP_GREATEREQUAL:
3876                                         renderer->setStencilCompareCCW(sw::STENCIL_GREATEREQUAL);
3877                                         break;
3878                                 case D3DCMP_ALWAYS:
3879                                         renderer->setStencilCompareCCW(sw::STENCIL_ALWAYS);
3880                                         break;
3881                                 default:
3882                                         ASSERT(false);
3883                                 }
3884                                 break;
3885                         case D3DRS_COLORWRITEENABLE1:
3886                                 renderer->setColorWriteMask(1, value);
3887                                 break;
3888                         case D3DRS_COLORWRITEENABLE2:
3889                                 renderer->setColorWriteMask(2, value);
3890                                 break;
3891                         case D3DRS_COLORWRITEENABLE3:
3892                                 renderer->setColorWriteMask(3, value);
3893                                 break;
3894                         case D3DRS_BLENDFACTOR:
3895                                 renderer->setBlendConstant(sw::Color<float>(value));
3896                                 break;
3897                         case D3DRS_SRGBWRITEENABLE:
3898                                 renderer->setWriteSRGB(value != FALSE);
3899                                 break;
3900                         case D3DRS_DEPTHBIAS:
3901                                 renderer->setDepthBias((float&)value);
3902                                 break;
3903                         case D3DRS_WRAP8:
3904                                 renderer->setTextureWrap(8, value);
3905                                 break;
3906                         case D3DRS_WRAP9:
3907                                 renderer->setTextureWrap(9, value);
3908                                 break;
3909                         case D3DRS_WRAP10:
3910                                 renderer->setTextureWrap(10, value);
3911                                 break;
3912                         case D3DRS_WRAP11:
3913                                 renderer->setTextureWrap(11, value);
3914                                 break;
3915                         case D3DRS_WRAP12:
3916                                 renderer->setTextureWrap(12, value);
3917                                 break;
3918                         case D3DRS_WRAP13:
3919                                 renderer->setTextureWrap(13, value);
3920                                 break;
3921                         case D3DRS_WRAP14:
3922                                 renderer->setTextureWrap(14, value);
3923                                 break;
3924                         case D3DRS_WRAP15:
3925                                 renderer->setTextureWrap(15, value);
3926                                 break;
3927                         case D3DRS_SEPARATEALPHABLENDENABLE:
3928                                 renderer->setSeparateAlphaBlendEnable(value != FALSE);
3929                                 break;
3930                         case D3DRS_SRCBLENDALPHA:
3931                                 switch(value)
3932                                 {
3933                                 case D3DBLEND_ZERO:
3934                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_ZERO);
3935                                         break;
3936                                 case D3DBLEND_ONE:
3937                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_ONE);
3938                                         break;
3939                                 case D3DBLEND_SRCCOLOR:
3940                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCE);
3941                                         break;
3942                                 case D3DBLEND_INVSRCCOLOR:
3943                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCE);
3944                                         break;
3945                                 case D3DBLEND_SRCALPHA:
3946                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
3947                                         break;
3948                                 case D3DBLEND_INVSRCALPHA:
3949                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
3950                                         break;
3951                                 case D3DBLEND_DESTALPHA:
3952                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_DESTALPHA);
3953                                         break;
3954                                 case D3DBLEND_INVDESTALPHA:
3955                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_INVDESTALPHA);
3956                                         break;
3957                                 case D3DBLEND_DESTCOLOR:
3958                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_DEST);
3959                                         break;
3960                                 case D3DBLEND_INVDESTCOLOR:
3961                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_INVDEST);
3962                                         break;
3963                                 case D3DBLEND_SRCALPHASAT:
3964                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_SRCALPHASAT);
3965                                         break;
3966                                 case D3DBLEND_BOTHSRCALPHA:
3967                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
3968                                         renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
3969                                         break;
3970                                 case D3DBLEND_BOTHINVSRCALPHA:
3971                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
3972                                         renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
3973                                         break;
3974                                 case D3DBLEND_BLENDFACTOR:
3975                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_CONSTANT);
3976                                         break;
3977                                 case D3DBLEND_INVBLENDFACTOR:
3978                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_INVCONSTANT);
3979                                         break;
3980                                 default:
3981                                         ASSERT(false);
3982                                 }
3983                                 break;
3984                         case D3DRS_DESTBLENDALPHA:
3985                                 switch(value)
3986                                 {
3987                                 case D3DBLEND_ZERO:
3988                                         renderer->setDestBlendFactorAlpha(sw::BLEND_ZERO);
3989                                         break;
3990                                 case D3DBLEND_ONE:
3991                                         renderer->setDestBlendFactorAlpha(sw::BLEND_ONE);
3992                                         break;
3993                                 case D3DBLEND_SRCCOLOR:
3994                                         renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCE);
3995                                         break;
3996                                 case D3DBLEND_INVSRCCOLOR:
3997                                         renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCE);
3998                                         break;
3999                                 case D3DBLEND_SRCALPHA:
4000                                         renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
4001                                         break;
4002                                 case D3DBLEND_INVSRCALPHA:
4003                                         renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
4004                                         break;
4005                                 case D3DBLEND_DESTALPHA:
4006                                         renderer->setDestBlendFactorAlpha(sw::BLEND_DESTALPHA);
4007                                         break;
4008                                 case D3DBLEND_INVDESTALPHA:
4009                                         renderer->setDestBlendFactorAlpha(sw::BLEND_INVDESTALPHA);
4010                                         break;
4011                                 case D3DBLEND_DESTCOLOR:
4012                                         renderer->setDestBlendFactorAlpha(sw::BLEND_DEST);
4013                                         break;
4014                                 case D3DBLEND_INVDESTCOLOR:
4015                                         renderer->setDestBlendFactorAlpha(sw::BLEND_INVDEST);
4016                                         break;
4017                                 case D3DBLEND_SRCALPHASAT:
4018                                         renderer->setDestBlendFactorAlpha(sw::BLEND_SRCALPHASAT);
4019                                         break;
4020                                 case D3DBLEND_BOTHSRCALPHA:
4021                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
4022                                         renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
4023                                         break;
4024                                 case D3DBLEND_BOTHINVSRCALPHA:
4025                                         renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
4026                                         renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
4027                                         break;
4028                                 case D3DBLEND_BLENDFACTOR:
4029                                         renderer->setDestBlendFactorAlpha(sw::BLEND_CONSTANT);
4030                                         break;
4031                                 case D3DBLEND_INVBLENDFACTOR:
4032                                         renderer->setDestBlendFactorAlpha(sw::BLEND_INVCONSTANT);
4033                                         break;
4034                                 default:
4035                                         ASSERT(false);
4036                                 }
4037                                 break;
4038                         case D3DRS_BLENDOPALPHA:
4039                                 switch(value)
4040                                 {
4041                                 case D3DBLENDOP_ADD:
4042                                         renderer->setBlendOperationAlpha(sw::BLENDOP_ADD);
4043                                         break;
4044                                 case D3DBLENDOP_SUBTRACT:
4045                                         renderer->setBlendOperationAlpha(sw::BLENDOP_SUB);
4046                                         break;
4047                                 case D3DBLENDOP_REVSUBTRACT:
4048                                         renderer->setBlendOperationAlpha(sw::BLENDOP_INVSUB);
4049                                         break;
4050                                 case D3DBLENDOP_MIN:
4051                                         renderer->setBlendOperationAlpha(sw::BLENDOP_MIN);
4052                                         break;
4053                                 case D3DBLENDOP_MAX:
4054                                         renderer->setBlendOperationAlpha(sw::BLENDOP_MAX);
4055                                         break;
4056                                 default:
4057                                         ASSERT(false);
4058                                 }
4059                                 break;
4060                         default:
4061                                 ASSERT(false);
4062                         }
4063                 }
4064                 else   // stateRecorder
4065                 {
4066                         stateRecorder->setRenderState(state, value);
4067                 }
4068
4069                 return D3D_OK;
4070         }
4071
4072         long Direct3DDevice9::SetRenderTarget(unsigned long index, IDirect3DSurface9 *iRenderTarget)
4073         {
4074                 CriticalSection cs(this);
4075
4076                 TRACE("unsigned long index = %d, IDirect3DSurface9 *newRenderTarget = 0x%0.8p", index, iRenderTarget);
4077
4078                 // FIXME: Check for D3DUSAGE_RENDERTARGET
4079
4080                 if(index >= 4 || (index == 0 && !iRenderTarget))
4081                 {
4082                         return INVALIDCALL();
4083                 }
4084
4085                 Direct3DSurface9 *renderTarget = static_cast<Direct3DSurface9*>(iRenderTarget);
4086
4087                 if(renderTarget)
4088                 {
4089                         renderTarget->bind();
4090                 }
4091
4092                 if(this->renderTarget[index])
4093                 {
4094                         this->renderTarget[index]->unbind();
4095                 }
4096
4097                 this->renderTarget[index] = renderTarget;
4098
4099                 if(renderTarget && index == 0)
4100                 {
4101                         D3DSURFACE_DESC renderTargetDesc;
4102                         renderTarget->GetDesc(&renderTargetDesc);
4103
4104                         // Reset viewport to size of current render target
4105                         viewport.X = 0;
4106                         viewport.Y = 0;
4107                         viewport.Width = renderTargetDesc.Width;
4108                         viewport.Height = renderTargetDesc.Height;
4109                         viewport.MinZ = 0;
4110                         viewport.MaxZ = 1;
4111
4112                         // Reset scissor rectangle to size of current render target
4113                         scissorRect.left = 0;
4114                         scissorRect.top = 0;
4115                         scissorRect.right = renderTargetDesc.Width;
4116                         scissorRect.bottom = renderTargetDesc.Height;
4117
4118                         // Set the multi-sample mask, if maskable
4119                         if(renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONE &&
4120                            renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONMASKABLE)
4121                         {
4122                                 renderer->setMultiSampleMask(renderState[D3DRS_MULTISAMPLEMASK]);
4123                         }
4124                         else
4125                         {
4126                                 renderer->setMultiSampleMask(0xFFFFFFFF);
4127                         }
4128                 }
4129
4130                 renderer->setRenderTarget(index, renderTarget);
4131
4132                 return D3D_OK;
4133         }
4134
4135         long Direct3DDevice9::SetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long value)
4136         {
4137                 CriticalSection cs(this);
4138
4139                 TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE state = %d, unsigned long value = %d", sampler, state, value);
4140
4141                 if(state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET)
4142                 {
4143                         return INVALIDCALL();
4144                 }
4145
4146                 if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
4147                 {
4148                         return INVALIDCALL();
4149                 }
4150
4151                 if(sampler >= D3DVERTEXTEXTURESAMPLER0)
4152                 {
4153                         sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
4154                 }
4155
4156                 if(!stateRecorder)
4157                 {
4158                         if(!init && samplerState[sampler][state] == value)
4159                         {
4160                                 return D3D_OK;
4161                         }
4162
4163                         samplerState[sampler][state] = value;
4164
4165                         sw::SamplerType type = sampler < 16 ? sw::SAMPLER_PIXEL : sw::SAMPLER_VERTEX;
4166                         int index = sampler < 16 ? sampler : sampler - 16;   // Sampler index within type group
4167
4168                         switch(state)
4169                         {
4170                         case D3DSAMP_ADDRESSU:
4171                                 switch(value)
4172                                 {
4173                                 case D3DTADDRESS_WRAP:
4174                                         renderer->setAddressingModeU(type, index, sw::ADDRESSING_WRAP);
4175                                         break;
4176                                 case D3DTADDRESS_MIRROR:
4177                                         renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRROR);
4178                                         break;
4179                                 case D3DTADDRESS_CLAMP:
4180                                         renderer->setAddressingModeU(type, index, sw::ADDRESSING_CLAMP);
4181                                         break;
4182                                 case D3DTADDRESS_BORDER:
4183                                         renderer->setAddressingModeU(type, index, sw::ADDRESSING_BORDER);
4184                                         break;
4185                                 case D3DTADDRESS_MIRRORONCE:
4186                                         renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRRORONCE);
4187                                         break;
4188                                 default:
4189                                         ASSERT(false);
4190                                 }
4191                                 break;
4192                         case D3DSAMP_ADDRESSV:
4193                                 switch(value)
4194                                 {
4195                                 case D3DTADDRESS_WRAP:
4196                                         renderer->setAddressingModeV(type, index, sw::ADDRESSING_WRAP);
4197                                         break;
4198                                 case D3DTADDRESS_MIRROR:
4199                                         renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRROR);
4200                                         break;
4201                                 case D3DTADDRESS_CLAMP:
4202                                         renderer->setAddressingModeV(type, index, sw::ADDRESSING_CLAMP);
4203                                         break;
4204                                 case D3DTADDRESS_BORDER:
4205                                         renderer->setAddressingModeV(type, index, sw::ADDRESSING_BORDER);
4206                                         break;
4207                                 case D3DTADDRESS_MIRRORONCE:
4208                                         renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRRORONCE);
4209                                         break;
4210                                 default:
4211                                         ASSERT(false);
4212                                 }
4213                                 break;
4214                         case D3DSAMP_ADDRESSW:
4215                                 switch(value)
4216                                 {
4217                                 case D3DTADDRESS_WRAP:
4218                                         renderer->setAddressingModeW(type, index, sw::ADDRESSING_WRAP);
4219                                         break;
4220                                 case D3DTADDRESS_MIRROR:
4221                                         renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRROR);
4222                                         break;
4223                                 case D3DTADDRESS_CLAMP:
4224                                         renderer->setAddressingModeW(type, index, sw::ADDRESSING_CLAMP);
4225                                         break;
4226                                 case D3DTADDRESS_BORDER:
4227                                         renderer->setAddressingModeW(type, index, sw::ADDRESSING_BORDER);
4228                                         break;
4229                                 case D3DTADDRESS_MIRRORONCE:
4230                                         renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRRORONCE);
4231                                         break;
4232                                 default:
4233                                         ASSERT(false);
4234                                 }
4235                                 break;
4236                         case D3DSAMP_BORDERCOLOR:
4237                                 renderer->setBorderColor(type, index, value);
4238                                 break;
4239                         case D3DSAMP_MAGFILTER:
4240                                 // NOTE: SwiftShader does not differentiate between minification and magnification filter
4241                                 switch(value)
4242                                 {
4243                                 case D3DTEXF_NONE:
4244                                         renderer->setTextureFilter(type, index, sw::FILTER_POINT);   // FIXME: Only for mipmap filter
4245                                         break;
4246                                 case D3DTEXF_POINT:
4247                                         renderer->setTextureFilter(type, index, sw::FILTER_POINT);
4248                                         break;
4249                                 case D3DTEXF_LINEAR:
4250                                         renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);
4251                                         break;
4252                                 case D3DTEXF_ANISOTROPIC:
4253                                         renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);
4254                                         break;
4255                                 case D3DTEXF_PYRAMIDALQUAD:
4256                                         renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
4257                                         break;
4258                                 case D3DTEXF_GAUSSIANQUAD:
4259                                         renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
4260                                         break;
4261                                 default:
4262                                         return INVALIDCALL();
4263                                 };
4264                                 break;
4265                         case D3DSAMP_MINFILTER:
4266                                 // NOTE: SwiftShader does not differentiate between minification and magnification filter
4267                                 switch(value)
4268                                 {
4269                                 case D3DTEXF_NONE:
4270                                         renderer->setTextureFilter(type, index, sw::FILTER_POINT);   // FIXME: Only for mipmap filter
4271                                         break;
4272                                 case D3DTEXF_POINT:
4273                                         renderer->setTextureFilter(type, index, sw::FILTER_POINT);
4274                                         break;
4275                                 case D3DTEXF_LINEAR:
4276                                         renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);
4277                                         break;
4278                                 case D3DTEXF_ANISOTROPIC:
4279                                         renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);
4280                                         break;
4281                                 case D3DTEXF_PYRAMIDALQUAD:
4282                                         renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
4283                                         break;
4284                                 case D3DTEXF_GAUSSIANQUAD:
4285                                         renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);   // FIXME: Unimplemented, fail silently
4286                                         break;
4287                                 default:
4288                                         return INVALIDCALL();
4289                                 };
4290                                 break;
4291                         case D3DSAMP_MIPFILTER:
4292                                 switch(value)
4293                                 {
4294                                 case D3DTEXF_NONE:
4295                                         renderer->setMipmapFilter(type, index, sw::MIPMAP_NONE);
4296                                         break;
4297                                 case D3DTEXF_POINT:
4298                                         renderer->setMipmapFilter(type, index, sw::MIPMAP_POINT);
4299                                         break;
4300                                 case D3DTEXF_LINEAR:
4301                                         renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);
4302                                         break;
4303                                 case D3DTEXF_ANISOTROPIC:
4304                                         renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter
4305                                         break;
4306                                 case D3DTEXF_PYRAMIDALQUAD:
4307                                         renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter
4308                                         break;
4309                                 case D3DTEXF_GAUSSIANQUAD:
4310                                         renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);   // FIXME: Only for texture filter
4311                                         break;
4312                                 default:
4313                                         return INVALIDCALL();
4314                                 };
4315                                 break;
4316                         case D3DSAMP_MIPMAPLODBIAS:
4317                                 if(value == D3DFMT_GET4)   // ATI hack to enable Fetch4
4318                                 {
4319                                         renderer->setGatherEnable(type, index, true);
4320                                 }
4321                                 else if(value == D3DFMT_GET1)   // ATI hack to disable Fetch4
4322                                 {
4323                                         renderer->setGatherEnable(type, index, false);
4324                                 }
4325                                 else
4326                                 {
4327                                         float LOD = (float&)value - sw::log2((float)context->renderTarget[0]->getSuperSampleCount());   // FIXME: Update when render target changes
4328                                         renderer->setMipmapLOD(type, index, LOD);
4329                                 }
4330                                 break;
4331                         case D3DSAMP_MAXMIPLEVEL:
4332                                 break;
4333                         case D3DSAMP_MAXANISOTROPY:
4334                                 renderer->setMaxAnisotropy(type, index, sw::clamp((unsigned int)value, (unsigned int)1, maxAnisotropy));
4335                                 break;
4336                         case D3DSAMP_SRGBTEXTURE:
4337                                 renderer->setReadSRGB(type, index, value != FALSE);
4338                                 break;
4339                         case D3DSAMP_ELEMENTINDEX:
4340                                 if(!init) UNIMPLEMENTED();   // Multi-element textures deprecated in favor of multiple render targets
4341                                 break;
4342                         case D3DSAMP_DMAPOFFSET:
4343                         //      if(!init) UNIMPLEMENTED();
4344                                 break;
4345                         default:
4346                                 ASSERT(false);
4347                         }
4348                 }
4349                 else   // stateRecorder
4350                 {
4351                         stateRecorder->setSamplerState(sampler, state, value);
4352                 }
4353
4354                 return D3D_OK;
4355         }
4356
4357         long Direct3DDevice9::SetScissorRect(const RECT *rect)
4358         {
4359                 CriticalSection cs(this);
4360
4361                 TRACE("const RECT *rect = 0x%0.8p", rect);
4362
4363                 if(!rect)
4364                 {
4365                         return INVALIDCALL();
4366                 }
4367
4368                 if(!stateRecorder)
4369                 {
4370                         scissorRect = *rect;
4371                 }
4372                 else
4373                 {
4374                         stateRecorder->setScissorRect(rect);
4375                 }
4376
4377                 return D3D_OK;
4378         }
4379
4380         long Direct3DDevice9::SetSoftwareVertexProcessing(int software)
4381         {
4382                 CriticalSection cs(this);
4383
4384                 TRACE("int software = %d", software);
4385
4386                 if(behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING && software == FALSE)
4387                 {
4388                         return INVALIDCALL();
4389                 }
4390
4391                 if(behaviourFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING && software == TRUE)
4392                 {
4393                         return INVALIDCALL();
4394                 }
4395
4396                 softwareVertexProcessing = (software != FALSE);
4397
4398                 return D3D_OK;
4399         }
4400
4401         long Direct3DDevice9::SetStreamSource(unsigned int stream, IDirect3DVertexBuffer9 *iVertexBuffer, unsigned int offset, unsigned int stride)
4402         {
4403                 CriticalSection cs(this);
4404
4405                 TRACE("unsigned int stream = %d, IDirect3DVertexBuffer9 *data = 0x%0.8p, unsigned int offset = %d, unsigned int stride = %d", stream, iVertexBuffer, offset, stride);
4406
4407                 Direct3DVertexBuffer9 *vertexBuffer = static_cast<Direct3DVertexBuffer9*>(iVertexBuffer);
4408
4409                 if(!stateRecorder)
4410                 {
4411                         if(dataStream[stream] == vertexBuffer && streamOffset[stream] == offset && streamStride[stream] == stride)
4412                         {
4413                                 return D3D_OK;
4414                         }
4415
4416                         if(vertexBuffer)
4417                         {
4418                                 vertexBuffer->bind();
4419                         }
4420
4421                         if(dataStream[stream])
4422                         {
4423                                 dataStream[stream]->unbind();
4424                         }
4425
4426                         dataStream[stream] = vertexBuffer;
4427                         streamOffset[stream] = offset;
4428                         streamStride[stream] = stride;
4429                 }
4430                 else
4431                 {
4432                         stateRecorder->setStreamSource(stream, vertexBuffer, offset, stride);
4433                 }
4434
4435                 return D3D_OK;
4436         }
4437
4438         long Direct3DDevice9::SetStreamSourceFreq(unsigned int streamNumber, unsigned int divider)
4439         {
4440                 CriticalSection cs(this);
4441
4442                 TRACE("unsigned int streamNumber = %d, unsigned int divider = %d", streamNumber, divider);
4443
4444                 if(!instancingEnabled)
4445                 {
4446                         return INVALIDCALL();
4447                 }
4448
4449                 if(!stateRecorder)
4450                 {
4451                         streamSourceFreq[streamNumber] = divider;
4452                 }
4453                 else
4454                 {
4455                         stateRecorder->setStreamSourceFreq(streamNumber, divider);
4456                 }
4457
4458                 return D3D_OK;
4459         }
4460
4461         long Direct3DDevice9::SetTexture(unsigned long sampler, IDirect3DBaseTexture9 *iBaseTexture)
4462         {
4463                 CriticalSection cs(this);
4464
4465                 TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 *texture = 0x%0.8p", sampler, iBaseTexture);
4466
4467                 if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
4468                 {
4469                         return INVALIDCALL();
4470                 }
4471
4472                 if(sampler >= D3DVERTEXTEXTURESAMPLER0)
4473                 {
4474                         sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
4475                 }
4476
4477                 Direct3DBaseTexture9 *baseTexture = dynamic_cast<Direct3DBaseTexture9*>(iBaseTexture);
4478
4479                 if(!stateRecorder)
4480                 {
4481                         if(texture[sampler] == baseTexture)
4482                         {
4483                                 return D3D_OK;
4484                         }
4485
4486                         if(baseTexture)
4487                         {
4488                                 baseTexture->bind();   // FIXME: Bind individual sub-surfaces?
4489                         }
4490
4491                         if(texture[sampler])
4492                         {
4493                                 texture[sampler]->unbind();
4494                         }
4495
4496                         texture[sampler] = baseTexture;
4497                 }
4498                 else
4499                 {
4500                         stateRecorder->setTexture(sampler, baseTexture);
4501                 }
4502
4503                 return D3D_OK;
4504         }
4505
4506         long Direct3DDevice9::SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value)
4507         {
4508                 CriticalSection cs(this);
4509
4510                 TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long value = %d", stage, type, value);
4511
4512                 if(stage < 0 || stage >= 8 || type < D3DTSS_COLOROP || type > D3DTSS_CONSTANT)
4513                 {
4514                         return INVALIDCALL();
4515                 }
4516
4517                 if(!stateRecorder)
4518                 {
4519                         if(!init && textureStageState[stage][type] == value)
4520                         {
4521                                 return D3D_OK;
4522                         }
4523
4524                         textureStageState[stage][type] = value;
4525
4526                         switch(type)
4527                         {
4528                         case D3DTSS_COLOROP:
4529                                 switch(value)
4530                                 {
4531                                 case D3DTOP_DISABLE:
4532                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_DISABLE);
4533                                         break;
4534                                 case D3DTOP_SELECTARG1:
4535                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG1);
4536                                         break;
4537                                 case D3DTOP_SELECTARG2:
4538                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG2);
4539                                         break;
4540                                 case D3DTOP_MODULATE:
4541                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE);
4542                                         break;
4543                                 case D3DTOP_MODULATE2X:
4544                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE2X);
4545                                         break;
4546                                 case D3DTOP_MODULATE4X:
4547                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE4X);
4548                                         break;
4549                                 case D3DTOP_ADD:
4550                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADD);
4551                                         break;
4552                                 case D3DTOP_ADDSIGNED:
4553                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED);
4554                                         break;
4555                                 case D3DTOP_ADDSIGNED2X:
4556                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
4557                                         break;
4558                                 case D3DTOP_SUBTRACT:
4559                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_SUBTRACT);
4560                                         break;
4561                                 case D3DTOP_ADDSMOOTH:
4562                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSMOOTH);
4563                                         break;
4564                                 case D3DTOP_BLENDDIFFUSEALPHA:
4565                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
4566                                         break;
4567                                 case D3DTOP_BLENDTEXTUREALPHA:
4568                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
4569                                         break;
4570                                 case D3DTOP_BLENDFACTORALPHA:
4571                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
4572                                         break;
4573                                 case D3DTOP_BLENDTEXTUREALPHAPM:
4574                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
4575                                         break;
4576                                 case D3DTOP_BLENDCURRENTALPHA:
4577                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
4578                                         break;
4579                                 case D3DTOP_PREMODULATE:
4580                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_PREMODULATE);
4581                                         break;
4582                                 case D3DTOP_MODULATEALPHA_ADDCOLOR:
4583                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
4584                                         break;
4585                                 case D3DTOP_MODULATECOLOR_ADDALPHA:
4586                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
4587                                         break;
4588                                 case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
4589                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
4590                                         break;
4591                                 case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
4592                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
4593                                         break;
4594                                 case D3DTOP_BUMPENVMAP:
4595                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAP);
4596                                         break;
4597                                 case D3DTOP_BUMPENVMAPLUMINANCE:
4598                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
4599                                         break;
4600                                 case D3DTOP_DOTPRODUCT3:
4601                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_DOT3);
4602                                         break;
4603                                 case D3DTOP_MULTIPLYADD:
4604                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_MULTIPLYADD);
4605                                         break;
4606                                 case D3DTOP_LERP:
4607                                         renderer->setStageOperation(stage, sw::TextureStage::STAGE_LERP);
4608                                         break;
4609                                 default:
4610                                         ASSERT(false);
4611                                 }
4612                                 break;
4613                         case D3DTSS_COLORARG1:
4614                                 switch(value & D3DTA_SELECTMASK)
4615                                 {
4616                                 case D3DTA_DIFFUSE:
4617                                         renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
4618                                         break;
4619                                 case D3DTA_CURRENT:
4620                                         renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CURRENT);
4621                                         break;
4622                                 case D3DTA_TEXTURE:
4623                                         renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
4624                                         break;
4625                                 case D3DTA_TFACTOR:
4626                                         renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
4627                                         break;
4628                                 case D3DTA_SPECULAR:
4629                                         renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
4630                                         break;
4631                                 case D3DTA_TEMP:
4632                                         renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEMP);
4633                                         break;
4634                                 case D3DTA_CONSTANT:
4635                                         renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CONSTANT);
4636                                         break;
4637                                 default:
4638                                         ASSERT(false);
4639                                 }
4640
4641                                 switch(value & ~D3DTA_SELECTMASK)
4642                                 {
4643                                 case 0:
4644                                         renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_COLOR);
4645                                         break;
4646                                 case D3DTA_COMPLEMENT:
4647                                         renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
4648                                         break;
4649                                 case D3DTA_ALPHAREPLICATE:
4650                                         renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
4651                                         break;
4652                                 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
4653                                         renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
4654                                         break;
4655                                 default:
4656                                         ASSERT(false);
4657                                 }
4658                                 break;
4659                         case D3DTSS_COLORARG2:
4660                                 switch(value & D3DTA_SELECTMASK)
4661                                 {
4662                                 case D3DTA_DIFFUSE:
4663                                         renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
4664                                         break;
4665                                 case D3DTA_CURRENT:
4666                                         renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CURRENT);
4667                                         break;
4668                                 case D3DTA_TEXTURE:
4669                                         renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
4670                                         break;
4671                                 case D3DTA_TFACTOR:
4672                                         renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
4673                                         break;
4674                                 case D3DTA_SPECULAR:
4675                                         renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
4676                                         break;
4677                                 case D3DTA_TEMP:
4678                                         renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEMP);
4679                                         break;
4680                                 case D3DTA_CONSTANT:
4681                                         renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CONSTANT);
4682                                         break;
4683                                 default:
4684                                         ASSERT(false);
4685                                 }
4686
4687                                 switch(value & ~D3DTA_SELECTMASK)
4688                                 {
4689                                 case 0:
4690                                         renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_COLOR);
4691                                         break;
4692                                 case D3DTA_COMPLEMENT:
4693                                         renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
4694                                         break;
4695                                 case D3DTA_ALPHAREPLICATE:
4696                                         renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
4697                                         break;
4698                                 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
4699                                         renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
4700                                         break;
4701                                 default:
4702                                         ASSERT(false);
4703                                 }
4704                                 break;
4705                         case D3DTSS_ALPHAOP:
4706                                 switch(value)
4707                                 {
4708                                 case D3DTOP_DISABLE:
4709                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DISABLE);
4710                                         break;
4711                                 case D3DTOP_SELECTARG1:
4712                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG1);
4713                                         break;
4714                                 case D3DTOP_SELECTARG2:
4715                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG2);
4716                                         break;
4717                                 case D3DTOP_MODULATE:
4718                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE);
4719                                         break;
4720                                 case D3DTOP_MODULATE2X:
4721                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE2X);
4722                                         break;
4723                                 case D3DTOP_MODULATE4X:
4724                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE4X);
4725                                         break;
4726                                 case D3DTOP_ADD:
4727                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADD);
4728                                         break;
4729                                 case D3DTOP_ADDSIGNED:
4730                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED);
4731                                         break;
4732                                 case D3DTOP_ADDSIGNED2X:
4733                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
4734                                         break;
4735                                 case D3DTOP_SUBTRACT:
4736                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SUBTRACT);
4737                                         break;
4738                                 case D3DTOP_ADDSMOOTH:
4739                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSMOOTH);
4740                                         break;
4741                                 case D3DTOP_BLENDDIFFUSEALPHA:
4742                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
4743                                         break;
4744                                 case D3DTOP_BLENDTEXTUREALPHA:
4745                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
4746                                         break;
4747                                 case D3DTOP_BLENDFACTORALPHA:
4748                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
4749                                         break;
4750                                 case D3DTOP_BLENDTEXTUREALPHAPM:
4751                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
4752                                         break;
4753                                 case D3DTOP_BLENDCURRENTALPHA:
4754                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
4755                                         break;
4756                                 case D3DTOP_PREMODULATE:
4757                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_PREMODULATE);
4758                                         break;
4759                                 case D3DTOP_MODULATEALPHA_ADDCOLOR:
4760                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
4761                                         break;
4762                                 case D3DTOP_MODULATECOLOR_ADDALPHA:
4763                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
4764                                         break;
4765                                 case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
4766                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
4767                                         break;
4768                                 case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
4769                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
4770                                         break;
4771                                 case D3DTOP_BUMPENVMAP:
4772                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAP);
4773                                         break;
4774                                 case D3DTOP_BUMPENVMAPLUMINANCE:
4775                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
4776                                         break;
4777                                 case D3DTOP_DOTPRODUCT3:
4778                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DOT3);
4779                                         break;
4780                                 case D3DTOP_MULTIPLYADD:
4781                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MULTIPLYADD);
4782                                         break;
4783                                 case D3DTOP_LERP:
4784                                         renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_LERP);
4785                                         break;
4786                                 default:
4787                                         ASSERT(false);
4788                                 }
4789                                 break;
4790                         case D3DTSS_ALPHAARG1:
4791                                 switch(value & D3DTA_SELECTMASK)
4792                                 {
4793                                 case D3DTA_DIFFUSE:
4794                                         renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
4795                                         break;
4796                                 case D3DTA_CURRENT:
4797                                         renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
4798                                         break;
4799                                 case D3DTA_TEXTURE:
4800                                         renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
4801                                         break;
4802                                 case D3DTA_TFACTOR:
4803                                         renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
4804                                         break;
4805                                 case D3DTA_SPECULAR:
4806                                         renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
4807                                         break;
4808                                 case D3DTA_TEMP:
4809                                         renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
4810                                         break;
4811                                 case D3DTA_CONSTANT:
4812                                         renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
4813                                         break;
4814                                 default:
4815                                         ASSERT(false);
4816                                 }
4817
4818                                 switch(value & ~D3DTA_SELECTMASK)
4819                                 {
4820                                 case 0:
4821                                         renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
4822                                         break;
4823                                 case D3DTA_COMPLEMENT:
4824                                         renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
4825                                         break;
4826                                 case D3DTA_ALPHAREPLICATE:
4827                                         renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
4828                                         break;
4829                                 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
4830                                         renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
4831                                         break;
4832                                 default:
4833                                         ASSERT(false);
4834                                 }
4835                                 break;
4836                         case D3DTSS_ALPHAARG2:
4837                                 switch(value & D3DTA_SELECTMASK)
4838                                 {
4839                                 case D3DTA_DIFFUSE:
4840                                         renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
4841                                         break;
4842                                 case D3DTA_CURRENT:
4843                                         renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
4844                                         break;
4845                                 case D3DTA_TEXTURE:
4846                                         renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
4847                                         break;
4848                                 case D3DTA_TFACTOR:
4849                                         renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
4850                                         break;
4851                                 case D3DTA_SPECULAR:
4852                                         renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
4853                                         break;
4854                                 case D3DTA_TEMP:
4855                                         renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
4856                                         break;
4857                                 case D3DTA_CONSTANT:
4858                                         renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
4859                                         break;
4860                                 default:
4861                                         ASSERT(false);
4862                                 }
4863
4864                                 switch(value & ~D3DTA_SELECTMASK)
4865                                 {
4866                                 case 0:
4867                                         renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
4868                                         break;
4869                                 case D3DTA_COMPLEMENT:
4870                                         renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
4871                                         break;
4872                                 case D3DTA_ALPHAREPLICATE:
4873                                         renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
4874                                         break;
4875                                 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
4876                                         renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
4877                                         break;
4878                                 default:
4879                                         ASSERT(false);
4880                                 }
4881                                 break;
4882                         case D3DTSS_BUMPENVMAT00:
4883                                 renderer->setBumpmapMatrix(stage, 0, (float&)value);
4884                                 break;
4885                         case D3DTSS_BUMPENVMAT01:
4886                                 renderer->setBumpmapMatrix(stage, 1, (float&)value);
4887                                 break;
4888                         case D3DTSS_BUMPENVMAT10:
4889                                 renderer->setBumpmapMatrix(stage, 2, (float&)value);
4890                                 break;
4891                         case D3DTSS_BUMPENVMAT11:
4892                                 renderer->setBumpmapMatrix(stage, 3, (float&)value);
4893                                 break;
4894                         case D3DTSS_TEXCOORDINDEX:
4895                                 renderer->setTexCoordIndex(stage, value & 0x0000FFFF);
4896
4897                                 switch(value & 0xFFFF0000)
4898                                 {
4899                                 case D3DTSS_TCI_PASSTHRU:
4900                                         renderer->setTexGen(stage, sw::TEXGEN_PASSTHRU);
4901                                         break;
4902                                 case D3DTSS_TCI_CAMERASPACENORMAL:
4903                                         renderer->setTexCoordIndex(stage, stage);
4904                                         renderer->setTexGen(stage, sw::TEXGEN_NORMAL);
4905                                         break;
4906                                 case D3DTSS_TCI_CAMERASPACEPOSITION:
4907                                         renderer->setTexCoordIndex(stage, stage);
4908                                         renderer->setTexGen(stage, sw::TEXGEN_POSITION);
4909                                         break;
4910                                 case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
4911                                         renderer->setTexCoordIndex(stage, stage);
4912                                         renderer->setTexGen(stage, sw::TEXGEN_REFLECTION);
4913                                         break;
4914                                 case D3DTSS_TCI_SPHEREMAP:
4915                                         renderer->setTexCoordIndex(stage, stage);
4916                                         renderer->setTexGen(stage, sw::TEXGEN_SPHEREMAP);
4917                                         break;
4918                                 default:
4919                                         ASSERT(false);
4920                                 }
4921                                 break;
4922                         case D3DTSS_BUMPENVLSCALE:
4923                                 renderer->setLuminanceScale(stage, (float&)value);
4924                                 break;
4925                         case D3DTSS_BUMPENVLOFFSET:
4926                                 renderer->setLuminanceOffset(stage, (float&)value);
4927                                 break;
4928                         case D3DTSS_TEXTURETRANSFORMFLAGS:
4929                                 switch(value & ~D3DTTFF_PROJECTED)
4930                                 {
4931                                 case D3DTTFF_DISABLE:
4932                                         renderer->setTextureTransform(stage, 0, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
4933                                         break;
4934                                 case D3DTTFF_COUNT1:
4935                                         renderer->setTextureTransform(stage, 1, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
4936                                         break;
4937                                 case D3DTTFF_COUNT2:
4938                                         renderer->setTextureTransform(stage, 2, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
4939                                         break;
4940                                 case D3DTTFF_COUNT3:
4941                                         renderer->setTextureTransform(stage, 3, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
4942                                         break;
4943                                 case D3DTTFF_COUNT4:
4944                                         renderer->setTextureTransform(stage, 4, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
4945                                         break;
4946                                 default:
4947                                         ASSERT(false);
4948                                 }
4949                                 break;
4950                         case D3DTSS_COLORARG0:
4951                                 switch(value & D3DTA_SELECTMASK)
4952                                 {
4953                                 case D3DTA_CURRENT:
4954                                         renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_CURRENT);
4955                                         break;
4956                                 case D3DTA_DIFFUSE:
4957                                         renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
4958                                         break;
4959                                 case D3DTA_SPECULAR:
4960                                         renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
4961                                         break;
4962                                 case D3DTA_TEMP:
4963                                         renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEMP);
4964                                         break;
4965                                 case D3DTA_TEXTURE:
4966                                         renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
4967                                         break;
4968                                 case D3DTA_TFACTOR:
4969                                         renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
4970                                         break;
4971                                 default:
4972                                         ASSERT(false);
4973                                 }
4974
4975                                 switch(value & ~D3DTA_SELECTMASK)
4976                                 {
4977                                 case 0:
4978                                         renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_COLOR);
4979                                         break;
4980                                 case D3DTA_COMPLEMENT:
4981                                         renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
4982                                         break;
4983                                 case D3DTA_ALPHAREPLICATE:
4984                                         renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
4985                                         break;
4986                                 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
4987                                         renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
4988                                         break;
4989                                 default:
4990                                         ASSERT(false);
4991                                 }
4992                                 break;
4993                         case D3DTSS_ALPHAARG0:
4994                                 switch(value & D3DTA_SELECTMASK)
4995                                 {
4996                                 case D3DTA_DIFFUSE:
4997                                         renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
4998                                         break;
4999                                 case D3DTA_CURRENT:
5000                                         renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
5001                                         break;
5002                                 case D3DTA_TEXTURE:
5003                                         renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
5004                                         break;
5005                                 case D3DTA_TFACTOR:
5006                                         renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
5007                                         break;
5008                                 case D3DTA_SPECULAR:
5009                                         renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
5010                                         break;
5011                                 case D3DTA_TEMP:
5012                                         renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
5013                                         break;
5014                                 case D3DTA_CONSTANT:
5015                                         renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
5016                                         break;
5017                                 default:
5018                                         ASSERT(false);
5019                                 }
5020
5021                                 switch(value & ~D3DTA_SELECTMASK)
5022                                 {
5023                                 case 0:
5024                                         renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
5025                                         break;
5026                                 case D3DTA_COMPLEMENT:
5027                                         renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
5028                                         break;
5029                                 case D3DTA_ALPHAREPLICATE:
5030                                         renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
5031                                         break;
5032                                 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
5033                                         renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
5034                                         break;
5035                                 default:
5036                                         ASSERT(false);
5037                                 }
5038                                 break;
5039                         case D3DTSS_RESULTARG:
5040                                 switch(value & D3DTA_SELECTMASK)
5041                                 {
5042                                 case D3DTA_CURRENT:
5043                                         renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_CURRENT);
5044                                         break;
5045                                 case D3DTA_TEMP:
5046                                         renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_TEMP);
5047                                         break;
5048                                 default:
5049                                         ASSERT(false);
5050                                 }
5051                                 break;
5052                         case D3DTSS_CONSTANT:
5053                                 renderer->setConstantColor(stage, value);
5054                                 break;
5055                         default:
5056                                 ASSERT(false);
5057                         }
5058                 }
5059                 else   // stateRecorder
5060                 {
5061                         stateRecorder->setTextureStageState(stage, type, value);
5062                 }
5063
5064                 return D3D_OK;
5065         }
5066
5067         long Direct3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
5068         {
5069                 CriticalSection cs(this);
5070
5071                 TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
5072
5073                 if(!matrix)
5074                 {
5075                         return INVALIDCALL();
5076                 }
5077
5078                 if(!stateRecorder)
5079                 {
5080                         this->matrix[state] = *matrix;
5081
5082                         sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,
5083                                      matrix->_12, matrix->_22, matrix->_32, matrix->_42,
5084                                      matrix->_13, matrix->_23, matrix->_33, matrix->_43,
5085                                      matrix->_14, matrix->_24, matrix->_34, matrix->_44);
5086
5087                         switch(state)
5088                         {
5089                         case D3DTS_WORLD:
5090                                 renderer->setModelMatrix(M);
5091                                 break;
5092                         case D3DTS_VIEW:
5093                                 renderer->setViewMatrix(M);
5094                                 break;
5095                         case D3DTS_PROJECTION:
5096                                 renderer->setProjectionMatrix(M);
5097                                 break;
5098                         case D3DTS_TEXTURE0:
5099                                 renderer->setTextureMatrix(0, M);
5100                                 break;
5101                         case D3DTS_TEXTURE1:
5102                                 renderer->setTextureMatrix(1, M);
5103                                 break;
5104                         case D3DTS_TEXTURE2:
5105                                 renderer->setTextureMatrix(2, M);
5106                                 break;
5107                         case D3DTS_TEXTURE3:
5108                                 renderer->setTextureMatrix(3, M);
5109                                 break;
5110                         case D3DTS_TEXTURE4:
5111                                 renderer->setTextureMatrix(4, M);
5112                                 break;
5113                         case D3DTS_TEXTURE5:
5114                                 renderer->setTextureMatrix(5, M);
5115                                 break;
5116                         case D3DTS_TEXTURE6:
5117                                 renderer->setTextureMatrix(6, M);
5118                                 break;
5119                         case D3DTS_TEXTURE7:
5120                                 renderer->setTextureMatrix(7, M);
5121                                 break;
5122                         default:
5123                                 if(state > 256 && state < 512)
5124                                 {
5125                                         renderer->setModelMatrix(M, state - 256);
5126                                 }
5127                                 else ASSERT(false);
5128                         }
5129                 }
5130                 else   // stateRecorder
5131                 {
5132                         stateRecorder->setTransform(state, matrix);
5133                 }
5134
5135                 return D3D_OK;
5136         }
5137
5138         long Direct3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9 *iVertexDeclaration)
5139         {
5140                 CriticalSection cs(this);
5141
5142                 TRACE("IDirect3DVertexDeclaration9 *declaration = 0x%0.8p", iVertexDeclaration);
5143
5144                 Direct3DVertexDeclaration9 *vertexDeclaration = static_cast<Direct3DVertexDeclaration9*>(iVertexDeclaration);
5145
5146                 if(!stateRecorder)
5147                 {
5148                         if(this->vertexDeclaration == vertexDeclaration)
5149                         {
5150                                 return D3D_OK;
5151                         }
5152
5153                         if(vertexDeclaration)
5154                         {
5155                                 vertexDeclaration->bind();
5156                         }
5157
5158                         if(this->vertexDeclaration)
5159                         {
5160                                 this->vertexDeclaration->unbind();
5161                         }
5162
5163                         this->vertexDeclaration = vertexDeclaration;
5164                 }
5165                 else
5166                 {
5167                         stateRecorder->setVertexDeclaration(vertexDeclaration);
5168                 }
5169
5170                 return D3D_OK;
5171         }
5172
5173         long Direct3DDevice9::SetVertexShader(IDirect3DVertexShader9 *iVertexShader)
5174         {
5175                 CriticalSection cs(this);
5176
5177                 TRACE("IDirect3DVertexShader9 *shader = 0x%0.8p", iVertexShader);
5178
5179                 Direct3DVertexShader9 *vertexShader = static_cast<Direct3DVertexShader9*>(iVertexShader);
5180
5181                 if(!stateRecorder)
5182                 {
5183                         if(this->vertexShader == vertexShader)
5184                         {
5185                                 return D3D_OK;
5186                         }
5187
5188                         if(vertexShader)
5189                         {
5190                                 vertexShader->bind();
5191                         }
5192
5193                         if(this->vertexShader)
5194                         {
5195                                 this->vertexShader->unbind();
5196                         }
5197
5198                         this->vertexShader = vertexShader;
5199                         vertexShaderDirty = true;
5200                 }
5201                 else
5202                 {
5203                         stateRecorder->setVertexShader(vertexShader);
5204                 }
5205
5206                 return D3D_OK;
5207         }
5208
5209         long Direct3DDevice9::SetVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
5210         {
5211                 CriticalSection cs(this);
5212
5213                 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
5214
5215                 if(!constantData)
5216                 {
5217                         return INVALIDCALL();
5218                 }
5219
5220                 if(!stateRecorder)
5221                 {
5222                         for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
5223                         {
5224                                 vertexShaderConstantB[startRegister + i] = constantData[i];
5225                         }
5226
5227                         vertexShaderConstantsBDirty = sw::max(startRegister + count, vertexShaderConstantsBDirty);
5228                         vertexShaderDirty = true;   // Reload DEF constants
5229                 }
5230                 else
5231                 {
5232                         stateRecorder->setVertexShaderConstantB(startRegister, constantData, count);
5233                 }
5234
5235                 return D3D_OK;
5236         }
5237
5238         long Direct3DDevice9::SetVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
5239         {
5240                 CriticalSection cs(this);
5241
5242                 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
5243
5244                 if(!constantData)
5245                 {
5246                         return INVALIDCALL();
5247                 }
5248
5249                 if(!stateRecorder)
5250                 {
5251                         for(unsigned int i = 0; i < count && startRegister + i < MAX_VERTEX_SHADER_CONST; i++)
5252                         {
5253                                 vertexShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
5254                                 vertexShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
5255                                 vertexShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
5256                                 vertexShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
5257                         }
5258
5259                         vertexShaderConstantsFDirty = sw::max(startRegister + count, vertexShaderConstantsFDirty);
5260                         vertexShaderDirty = true;   // Reload DEF constants
5261                 }
5262                 else
5263                 {
5264                         stateRecorder->setVertexShaderConstantF(startRegister, constantData, count);
5265                 }
5266
5267                 return D3D_OK;
5268         }
5269
5270         long Direct3DDevice9::SetVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
5271         {
5272                 CriticalSection cs(this);
5273
5274                 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
5275
5276                 if(!constantData)
5277                 {
5278                         return INVALIDCALL();
5279                 }
5280
5281                 if(!stateRecorder)
5282                 {
5283                         for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
5284                         {
5285                                 vertexShaderConstantI[startRegister + i][0] = constantData[i * 4 + 0];
5286                                 vertexShaderConstantI[startRegister + i][1] = constantData[i * 4 + 1];
5287                                 vertexShaderConstantI[startRegister + i][2] = constantData[i * 4 + 2];
5288                                 vertexShaderConstantI[startRegister + i][3] = constantData[i * 4 + 3];
5289                         }
5290
5291                         vertexShaderConstantsIDirty = sw::max(startRegister + count, vertexShaderConstantsIDirty);
5292                         vertexShaderDirty = true;   // Reload DEF constants
5293                 }
5294                 else
5295                 {
5296                         stateRecorder->setVertexShaderConstantI(startRegister, constantData, count);
5297                 }
5298
5299                 return D3D_OK;
5300         }
5301
5302         long Direct3DDevice9::SetViewport(const D3DVIEWPORT9 *viewport)
5303         {
5304                 CriticalSection cs(this);
5305
5306                 TRACE("const D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
5307
5308                 if(!viewport)   // FIXME: Check if valid
5309                 {
5310                         return INVALIDCALL();
5311                 }
5312
5313                 if(!stateRecorder)
5314                 {
5315                         this->viewport = *viewport;
5316                 }
5317                 else
5318                 {
5319                         stateRecorder->setViewport(viewport);
5320                 }
5321
5322                 return D3D_OK;
5323         }
5324
5325         int Direct3DDevice9::ShowCursor(int show)
5326         {
5327                 CriticalSection cs(this);
5328
5329                 TRACE("int show = %d", show);
5330
5331                 int oldValue = showCursor ? TRUE : FALSE;
5332                 showCursor = show != FALSE;
5333
5334                 if(showCursor)
5335                 {
5336                         sw::FrameBuffer::setCursorImage(cursor);
5337                 }
5338                 else
5339                 {
5340                         sw::FrameBuffer::setCursorImage(0);
5341                 }
5342
5343                 return oldValue;
5344         }
5345
5346         long Direct3DDevice9::StretchRect(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)
5347         {
5348                 CriticalSection cs(this);
5349
5350                 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);
5351
5352                 if(!sourceSurface || !destSurface || !validRectangle(sourceRect, sourceSurface) || !validRectangle(destRect, destSurface))
5353                 {
5354                         return INVALIDCALL();
5355                 }
5356
5357                 D3DSURFACE_DESC sourceDescription;
5358                 D3DSURFACE_DESC destDescription;
5359
5360                 sourceSurface->GetDesc(&sourceDescription);
5361                 destSurface->GetDesc(&destDescription);
5362
5363                 if(sourceDescription.Pool != D3DPOOL_DEFAULT || destDescription.Pool != D3DPOOL_DEFAULT)
5364                 {
5365                         return INVALIDCALL();
5366                 }
5367
5368                 Direct3DSurface9 *source = static_cast<Direct3DSurface9*>(sourceSurface);
5369                 Direct3DSurface9 *dest = static_cast<Direct3DSurface9*>(destSurface);
5370
5371                 stretchRect(source, sourceRect, dest, destRect, filter);
5372
5373                 return D3D_OK;
5374         }
5375
5376         long Direct3DDevice9::TestCooperativeLevel()
5377         {
5378                 CriticalSection cs(this);
5379
5380                 TRACE("void");
5381
5382                 return D3D_OK;
5383         }
5384
5385         long Direct3DDevice9::UpdateSurface(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destinationSurface, const POINT *destPoint)
5386         {
5387                 CriticalSection cs(this);
5388
5389                 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);
5390
5391                 if(!sourceSurface || !destinationSurface)
5392                 {
5393                         return INVALIDCALL();
5394                 }
5395
5396                 D3DSURFACE_DESC sourceDescription;
5397                 D3DSURFACE_DESC destinationDescription;
5398
5399                 sourceSurface->GetDesc(&sourceDescription);
5400                 destinationSurface->GetDesc(&destinationDescription);
5401
5402                 RECT sRect;
5403                 RECT dRect;
5404
5405                 if(sourceRect)
5406                 {
5407                         sRect.left = sourceRect->left;
5408                         sRect.top = sourceRect->top;
5409                         sRect.right = sourceRect->right;
5410                         sRect.bottom = sourceRect->bottom;
5411                 }
5412                 else
5413                 {
5414                         sRect.left = 0;
5415                         sRect.top = 0;
5416                         sRect.right = sourceDescription.Width;
5417                         sRect.bottom = sourceDescription.Height;
5418                 }
5419
5420                 if(destPoint)
5421                 {
5422                         dRect.left = destPoint->x;
5423                         dRect.top = destPoint->y;
5424                         dRect.right = destPoint->x + sRect.right - sRect.left;
5425                         dRect.bottom = destPoint->y + sRect.bottom - sRect.top;
5426                 }
5427                 else
5428                 {
5429                         dRect.left = 0;
5430                         dRect.top = 0;
5431                         dRect.right = sRect.right - sRect.left;
5432                         dRect.bottom = sRect.bottom - sRect.top;
5433                 }
5434
5435                 if(!validRectangle(&sRect, sourceSurface) || !validRectangle(&dRect, destinationSurface))
5436                 {
5437                         return INVALIDCALL();
5438                 }
5439
5440                 int sWidth = sRect.right - sRect.left;
5441                 int sHeight = sRect.bottom - sRect.top;
5442
5443                 int dWidth = dRect.right - dRect.left;
5444                 int dHeight = dRect.bottom - dRect.top;
5445
5446                 if(sourceDescription.MultiSampleType      != D3DMULTISAMPLE_NONE ||
5447                    destinationDescription.MultiSampleType != D3DMULTISAMPLE_NONE ||
5448                 // sourceDescription.Pool      != D3DPOOL_SYSTEMMEM ||   // FIXME: Check back buffer and depth buffer memory pool flags
5449                 // destinationDescription.Pool != D3DPOOL_DEFAULT ||
5450                    sourceDescription.Format != destinationDescription.Format)
5451                 {
5452                         return INVALIDCALL();
5453                 }
5454
5455                 sw::Surface *source = static_cast<Direct3DSurface9*>(sourceSurface);
5456                 sw::Surface *dest = static_cast<Direct3DSurface9*>(destinationSurface);
5457
5458                 unsigned char *sBuffer = (unsigned char*)source->lockExternal(sRect.left, sRect.top, 0, sw::LOCK_READONLY, sw::PUBLIC);
5459                 unsigned char *dBuffer = (unsigned char*)dest->lockExternal(dRect.left, dRect.top, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
5460                 int sPitch = source->getExternalPitchB();
5461                 int dPitch = dest->getExternalPitchB();
5462
5463                 unsigned int width;
5464                 unsigned int height;
5465                 unsigned int bytes;
5466
5467                 switch(sourceDescription.Format)
5468                 {
5469                 case D3DFMT_DXT1:
5470                 case D3DFMT_ATI1:
5471                         width = (dWidth + 3) / 4;
5472                         height = (dHeight + 3) / 4;
5473                         bytes = width * 8;   // 64 bit per 4x4 block
5474                         break;
5475                 case D3DFMT_DXT2:
5476                 case D3DFMT_DXT3:
5477                 case D3DFMT_DXT4:
5478                 case D3DFMT_DXT5:
5479                 case D3DFMT_ATI2:
5480                         width = (dWidth + 3) / 4;
5481                         height = (dHeight + 3) / 4;
5482                         bytes = width * 16;   // 128 bit per 4x4 block
5483                         break;
5484                 default:
5485                         width = dWidth;
5486                         height = dHeight;
5487                         bytes = width * Direct3DSurface9::bytes(sourceDescription.Format);
5488                 }
5489
5490                 if(sourceDescription.Format == D3DFMT_ATI1 || sourceDescription.Format == D3DFMT_ATI2)
5491                 {
5492                         // Make the pitch correspond to 4 rows
5493                         sPitch *= 4;
5494                         dPitch *= 4;
5495                 }
5496
5497                 for(unsigned int y = 0; y < height; y++)
5498                 {
5499                         memcpy(dBuffer, sBuffer, bytes);
5500
5501                         sBuffer += sPitch;
5502                         dBuffer += dPitch;
5503                 }
5504
5505                 source->unlockExternal();
5506                 dest->unlockExternal();
5507
5508                 return D3D_OK;
5509         }
5510
5511         long Direct3DDevice9::UpdateTexture(IDirect3DBaseTexture9 *sourceTexture, IDirect3DBaseTexture9 *destinationTexture)
5512         {
5513                 CriticalSection cs(this);
5514
5515                 TRACE("IDirect3DBaseTexture9 *sourceTexture = 0x%0.8p, IDirect3DBaseTexture9 *destinationTexture = 0x%0.8p", sourceTexture, destinationTexture);
5516
5517                 if(!sourceTexture || !destinationTexture)
5518                 {
5519                         return INVALIDCALL();
5520                 }
5521
5522                 // FIXME: Check memory pools
5523
5524                 D3DRESOURCETYPE type = sourceTexture->GetType();
5525
5526                 if(type != destinationTexture->GetType())
5527                 {
5528                         return INVALIDCALL();
5529                 }
5530
5531                 switch(type)
5532                 {
5533                 case D3DRTYPE_TEXTURE:
5534                         {
5535                                 IDirect3DTexture9 *source;
5536                                 IDirect3DTexture9 *dest;
5537
5538                                 sourceTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&source);
5539                                 destinationTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&dest);
5540
5541                                 ASSERT(source && dest);
5542
5543                                 for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination
5544                                 {
5545                                         IDirect3DSurface9 *sourceSurface;
5546                                         IDirect3DSurface9 *destinationSurface;
5547
5548                                         source->GetSurfaceLevel(level, &sourceSurface);
5549                                         dest->GetSurfaceLevel(level, &destinationSurface);
5550
5551                                         UpdateSurface(sourceSurface, 0, destinationSurface, 0);
5552
5553                                         sourceSurface->Release();
5554                                         destinationSurface->Release();
5555                                 }
5556
5557                                 source->Release();
5558                                 dest->Release();
5559                         }
5560                         break;
5561                 case D3DRTYPE_VOLUMETEXTURE:
5562                         {
5563                                 IDirect3DVolumeTexture9 *source;
5564                                 IDirect3DVolumeTexture9 *dest;
5565
5566                                 sourceTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&source);
5567                                 destinationTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&dest);
5568
5569                                 ASSERT(source && dest);
5570
5571                                 for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination
5572                                 {
5573                                         IDirect3DVolume9 *sourceVolume;
5574                                         IDirect3DVolume9 *destinationVolume;
5575
5576                                         source->GetVolumeLevel(level, &sourceVolume);
5577                                         dest->GetVolumeLevel(level, &destinationVolume);
5578
5579                                         updateVolume(sourceVolume, destinationVolume);
5580
5581                                         sourceVolume->Release();
5582                                         destinationVolume->Release();
5583                                 }
5584
5585                                 source->Release();
5586                                 dest->Release();
5587                         }
5588                         break;
5589                 case D3DRTYPE_CUBETEXTURE:
5590                         {
5591                                 IDirect3DCubeTexture9 *source;
5592                                 IDirect3DCubeTexture9 *dest;
5593
5594                                 sourceTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&source);
5595                                 destinationTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&dest);
5596
5597                                 ASSERT(source && dest);
5598
5599                                 for(int face = 0; face < 6; face++)
5600                                 {
5601                                         for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)   // FIXME: Fail when source texture has fewer levels than the destination
5602                                         {
5603                                                 IDirect3DSurface9 *sourceSurface;
5604                                                 IDirect3DSurface9 *destinationSurface;
5605
5606                                                 source->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &sourceSurface);
5607                                                 dest->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &destinationSurface);
5608
5609                                                 UpdateSurface(sourceSurface, 0, destinationSurface, 0);
5610
5611                                                 sourceSurface->Release();
5612                                                 destinationSurface->Release();
5613                                         }
5614                                 }
5615
5616                                 source->Release();
5617                                 dest->Release();
5618                         }
5619                         break;
5620                 default:
5621                         UNIMPLEMENTED();
5622                 }
5623
5624                 return D3D_OK;
5625         }
5626
5627         long Direct3DDevice9::ValidateDevice(unsigned long *numPasses)
5628         {
5629                 CriticalSection cs(this);
5630
5631                 TRACE("unsigned long *numPasses = 0x%0.8p", numPasses);
5632
5633                 if(!numPasses)
5634                 {
5635                         return INVALIDCALL();
5636                 }
5637
5638                 *numPasses = 1;
5639
5640                 return D3D_OK;
5641         }
5642
5643         long Direct3DDevice9::getAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode)
5644         {
5645                 return d3d9->GetAdapterDisplayMode(adapter, mode);
5646         }
5647
5648         int Direct3DDevice9::typeStride(unsigned char streamType)
5649         {
5650                 static int LUT[] =
5651                 {
5652                         4,      // D3DDECLTYPE_FLOAT1    =  0,  // 1D float expanded to (value, 0., 0., 1.)
5653                         8,      // D3DDECLTYPE_FLOAT2    =  1,  // 2D float expanded to (value, value, 0., 1.)
5654                         12,     // D3DDECLTYPE_FLOAT3    =  2,  // 3D float expanded to (value, value, value, 1.)
5655                         16,     // D3DDECLTYPE_FLOAT4    =  3,  // 4D float
5656                         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)
5657                         4,      // D3DDECLTYPE_UBYTE4    =  5,  // 4D unsigned byte
5658                         4,      // D3DDECLTYPE_SHORT2    =  6,  // 2D signed short expanded to (value, value, 0., 1.)
5659                         8,      // D3DDECLTYPE_SHORT4    =  7,  // 4D signed short
5660                         4,      // D3DDECLTYPE_UBYTE4N   =  8,  // Each of 4 bytes is normalized by dividing to 255.0
5661                         4,      // D3DDECLTYPE_SHORT2N   =  9,  // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1)
5662                         8,      // D3DDECLTYPE_SHORT4N   = 10,  // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)
5663                         4,      // D3DDECLTYPE_USHORT2N  = 11,  // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1)
5664                         8,      // D3DDECLTYPE_USHORT4N  = 12,  // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0)
5665                         4,      // D3DDECLTYPE_UDEC3     = 13,  // 3D unsigned 10 10 10 format expanded to (value, value, value, 1)
5666                         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)
5667                         4,      // D3DDECLTYPE_FLOAT16_2 = 15,  // Two 16-bit floating point values, expanded to (value, value, 0, 1)
5668                         8,      // D3DDECLTYPE_FLOAT16_4 = 16,  // Four 16-bit floating point values
5669                         0,      // D3DDECLTYPE_UNUSED    = 17,  // When the type field in a decl is unused.
5670                 };
5671
5672                 return LUT[streamType];
5673         }
5674
5675         bool Direct3DDevice9::instanceData()
5676         {
5677                 ASSERT(vertexDeclaration);
5678
5679                 D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];
5680                 unsigned int numElements;
5681                 vertexDeclaration->GetDeclaration(vertexElement, &numElements);
5682
5683                 bool instanceData = false;
5684
5685                 for(unsigned int i = 0; i < numElements - 1; i++)
5686                 {
5687                         unsigned short stream = vertexElement[i].Stream;
5688
5689                         if(stream != 0)
5690                         {
5691                                 instanceData = instanceData || (streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA) != 0;
5692                         }
5693                 }
5694
5695                 return instanceData;
5696         }
5697
5698         bool Direct3DDevice9::bindResources(Direct3DIndexBuffer9 *indexBuffer)
5699         {
5700                 if(!bindViewport())
5701                 {
5702                         return false;   // Zero-area target region
5703                 }
5704
5705                 bindTextures();
5706                 bindIndexBuffer(indexBuffer);
5707                 bindShaderConstants();
5708                 bindLights();
5709
5710                 return true;
5711         }
5712
5713         void Direct3DDevice9::bindVertexStreams(int base, bool instancing, int instance)
5714         {
5715                 ASSERT(vertexDeclaration);
5716
5717                 renderer->resetInputStreams(vertexDeclaration->isPreTransformed());
5718
5719                 D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];
5720                 unsigned int numElements;
5721                 vertexDeclaration->GetDeclaration(vertexElement, &numElements);
5722
5723                 // Bind vertex data streams
5724                 for(unsigned int i = 0; i < numElements - 1; i++)
5725                 {
5726                         unsigned short stream = vertexElement[i].Stream;
5727                         unsigned short offset = vertexElement[i].Offset;
5728                         unsigned char type = vertexElement[i].Type;
5729                         unsigned char method = vertexElement[i].Method;
5730                         unsigned char usage = vertexElement[i].Usage;
5731                         unsigned char index = vertexElement[i].UsageIndex;
5732
5733                         ASSERT(method == D3DDECLMETHOD_DEFAULT);        // FIXME: Unimplemented
5734
5735                         if(!dataStream[stream])
5736                         {
5737                                 continue;
5738                         }
5739
5740                         Direct3DVertexBuffer9 *streamBuffer = dataStream[stream];
5741                         sw::Resource *resource = streamBuffer->getResource();
5742                         const void *buffer = ((char*)resource->data() + streamOffset[stream]) + offset;
5743
5744                         int stride = streamStride[stream];
5745
5746                         if(instancing && streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA)
5747                         {
5748                                 int instanceFrequency = streamSourceFreq[stream] & ~D3DSTREAMSOURCE_INSTANCEDATA;
5749                                 buffer = (char*)buffer + stride * (instance / instanceFrequency);
5750
5751                                 stride = 0;
5752                         }
5753                         else
5754                         {
5755                                 buffer = (char*)buffer + stride * base;
5756                         }
5757
5758                         sw::Stream attribute(resource, buffer, stride);
5759
5760                         switch(type)
5761                         {
5762                         case D3DDECLTYPE_FLOAT1:    attribute.define(sw::STREAMTYPE_FLOAT, 1, false);  break;
5763                         case D3DDECLTYPE_FLOAT2:    attribute.define(sw::STREAMTYPE_FLOAT, 2, false);  break;
5764                         case D3DDECLTYPE_FLOAT3:    attribute.define(sw::STREAMTYPE_FLOAT, 3, false);  break;
5765                         case D3DDECLTYPE_FLOAT4:    attribute.define(sw::STREAMTYPE_FLOAT, 4, false);  break;
5766                         case D3DDECLTYPE_D3DCOLOR:  attribute.define(sw::STREAMTYPE_COLOR, 4, false);  break;
5767                         case D3DDECLTYPE_UBYTE4:    attribute.define(sw::STREAMTYPE_BYTE, 4, false);   break;
5768                         case D3DDECLTYPE_SHORT2:    attribute.define(sw::STREAMTYPE_SHORT, 2, false);  break;
5769                         case D3DDECLTYPE_SHORT4:    attribute.define(sw::STREAMTYPE_SHORT, 4, false);  break;
5770                         case D3DDECLTYPE_UBYTE4N:   attribute.define(sw::STREAMTYPE_BYTE, 4, true);    break;
5771                         case D3DDECLTYPE_SHORT2N:   attribute.define(sw::STREAMTYPE_SHORT, 2, true);   break;
5772                         case D3DDECLTYPE_SHORT4N:   attribute.define(sw::STREAMTYPE_SHORT, 4, true);   break;
5773                         case D3DDECLTYPE_USHORT2N:  attribute.define(sw::STREAMTYPE_USHORT, 2, true);  break;
5774                         case D3DDECLTYPE_USHORT4N:  attribute.define(sw::STREAMTYPE_USHORT, 4, true);  break;
5775                         case D3DDECLTYPE_UDEC3:     attribute.define(sw::STREAMTYPE_UDEC3, 3, false);  break;
5776                         case D3DDECLTYPE_DEC3N:     attribute.define(sw::STREAMTYPE_DEC3N, 3, true);   break;
5777                         case D3DDECLTYPE_FLOAT16_2: attribute.define(sw::STREAMTYPE_HALF, 2, false);   break;
5778                         case D3DDECLTYPE_FLOAT16_4: attribute.define(sw::STREAMTYPE_HALF, 4, false);   break;
5779                         case D3DDECLTYPE_UNUSED:    attribute.defaults();                              break;
5780                         default:
5781                                 ASSERT(false);
5782                         }
5783
5784                         if(vertexShader)
5785                         {
5786                                 const sw::VertexShader *shader = vertexShader->getVertexShader();
5787
5788                                 if(!vertexDeclaration->isPreTransformed())
5789                                 {
5790                                         for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
5791                                         {
5792                                                 const sw::Shader::Semantic& input = shader->getInput(i);
5793                                                 if((usage == input.usage) && (index == input.index))
5794                                                 {
5795                                                         renderer->setInputStream(i, attribute);
5796
5797                                                         break;
5798                                                 }
5799                                         }
5800                                 }
5801                                 else   // Bind directly to the output
5802                                 {
5803                                         for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
5804                                         {
5805                                                 const sw::Shader::Semantic& output = shader->getOutput(i, 0);
5806                                                 if(((usage == output.usage) || (usage == D3DDECLUSAGE_POSITIONT && output.usage == D3DDECLUSAGE_POSITION)) &&
5807                                                    (index == output.index))
5808                                                 {
5809                                                         renderer->setInputStream(i, attribute);
5810
5811                                                         break;
5812                                                 }
5813                                         }
5814                                 }
5815                         }
5816                         else
5817                         {
5818                                 switch(usage)
5819                                 {
5820                                 case D3DDECLUSAGE_POSITION:     renderer->setInputStream(sw::Position, attribute);                                       break;
5821                                 case D3DDECLUSAGE_BLENDWEIGHT:  renderer->setInputStream(sw::BlendWeight, attribute);                                    break;
5822                                 case D3DDECLUSAGE_BLENDINDICES: renderer->setInputStream(sw::BlendIndices, attribute.define(sw::STREAMTYPE_INDICES, 1)); break;
5823                                 case D3DDECLUSAGE_NORMAL:       renderer->setInputStream(sw::Normal, attribute.define(sw::STREAMTYPE_FLOAT, 3));         break;
5824                                 case D3DDECLUSAGE_PSIZE:        renderer->setInputStream(sw::PointSize, attribute.define(sw::STREAMTYPE_FLOAT, 1));      break;
5825                                 case D3DDECLUSAGE_TEXCOORD:     renderer->setInputStream(sw::TexCoord0 + index, attribute);                              break;
5826                                 case D3DDECLUSAGE_TANGENT:      /* Ignored */                                                                            break;
5827                                 case D3DDECLUSAGE_BINORMAL:     /* Ignored */                                                                            break;
5828                                 case D3DDECLUSAGE_TESSFACTOR:   UNIMPLEMENTED();                                                                         break;
5829                                 case D3DDECLUSAGE_POSITIONT:    renderer->setInputStream(sw::PositionT, attribute.define(sw::STREAMTYPE_FLOAT, 4));      break;
5830                                 case D3DDECLUSAGE_COLOR:        renderer->setInputStream(sw::Color0 + index, attribute.define(sw::STREAMTYPE_COLOR, 4)); break;
5831                                 case D3DDECLUSAGE_FOG:          /* Ignored */                                                                            break;
5832                                 case D3DDECLUSAGE_DEPTH:        /* Ignored */                                                                            break;
5833                                 case D3DDECLUSAGE_SAMPLE:       UNIMPLEMENTED();                                                                         break;
5834                                 default:
5835                                         ASSERT(false);
5836                                 }
5837                         }
5838                 }
5839         }
5840
5841         void Direct3DDevice9::bindIndexBuffer(Direct3DIndexBuffer9 *indexBuffer)
5842         {
5843                 sw::Resource *resource = 0;
5844
5845                 if(indexBuffer)
5846                 {
5847                         resource = indexBuffer->getResource();
5848                 }
5849
5850                 renderer->setIndexBuffer(resource);
5851         }
5852
5853         void Direct3DDevice9::bindShaderConstants()
5854         {
5855                 if(pixelShaderDirty)
5856                 {
5857                         if(pixelShader)
5858                         {
5859                                 if(pixelShaderConstantsBDirty)
5860                                 {
5861                                         renderer->setPixelShaderConstantB(0, pixelShaderConstantB, pixelShaderConstantsBDirty);
5862                                 }
5863
5864                                 if(pixelShaderConstantsFDirty)
5865                                 {
5866                                         renderer->setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty);
5867                                 }
5868
5869                                 if(pixelShaderConstantsIDirty)
5870                                 {
5871                                         renderer->setPixelShaderConstantI(0, pixelShaderConstantI[0], pixelShaderConstantsIDirty);
5872                                 }
5873
5874                                 renderer->setPixelShader(pixelShader->getPixelShader());   // Loads shader constants set with DEF
5875                                 pixelShaderConstantsBDirty = pixelShader->getPixelShader()->dirtyConstantsB;   // Shader DEF'ed constants are dirty
5876                                 pixelShaderConstantsFDirty = pixelShader->getPixelShader()->dirtyConstantsF;   // Shader DEF'ed constants are dirty
5877                                 pixelShaderConstantsIDirty = pixelShader->getPixelShader()->dirtyConstantsI;   // Shader DEF'ed constants are dirty
5878                         }
5879                         else
5880                         {
5881                                 renderer->setPixelShader(0);
5882                         }
5883
5884                         pixelShaderDirty = false;
5885                 }
5886
5887                 if(vertexShaderDirty)
5888                 {
5889                         if(vertexShader)
5890                         {
5891                                 if(vertexShaderConstantsBDirty)
5892                                 {
5893                                         renderer->setVertexShaderConstantB(0, vertexShaderConstantB, vertexShaderConstantsBDirty);
5894                                 }
5895
5896                                 if(vertexShaderConstantsFDirty)
5897                                 {
5898                                         renderer->setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty);
5899                                 }
5900
5901                                 if(vertexShaderConstantsIDirty)
5902                                 {
5903                                         renderer->setVertexShaderConstantI(0, vertexShaderConstantI[0], vertexShaderConstantsIDirty);
5904                                 }
5905
5906                                 renderer->setVertexShader(vertexShader->getVertexShader());   // Loads shader constants set with DEF
5907                                 vertexShaderConstantsBDirty = vertexShader->getVertexShader()->dirtyConstantsB;   // Shader DEF'ed constants are dirty
5908                                 vertexShaderConstantsFDirty = vertexShader->getVertexShader()->dirtyConstantsF;   // Shader DEF'ed constants are dirty
5909                                 vertexShaderConstantsIDirty = vertexShader->getVertexShader()->dirtyConstantsI;   // Shader DEF'ed constants are dirty
5910                         }
5911                         else
5912                         {
5913                                 renderer->setVertexShader(0);
5914                         }
5915
5916                         vertexShaderDirty = false;
5917                 }
5918         }
5919
5920         void Direct3DDevice9::bindLights()
5921         {
5922                 if(!lightsDirty) return;
5923
5924                 Lights::iterator i = light.begin();
5925                 int active = 0;
5926
5927                 // Set and enable renderer lights
5928                 while(active < 8)
5929                 {
5930                         while(i != light.end() && !i->second.enable)
5931                         {
5932                                 i++;
5933                         }
5934
5935                         if(i == light.end())
5936                         {
5937                                 break;
5938                         }
5939
5940                         const Light &l = i->second;
5941
5942                         sw::Point position(l.Position.x, l.Position.y, l.Position.z);
5943                         sw::Color<float> diffuse(l.Diffuse.r, l.Diffuse.g, l.Diffuse.b, l.Diffuse.a);
5944                         sw::Color<float> specular(l.Specular.r, l.Specular.g, l.Specular.b, l.Specular.a);
5945                         sw::Color<float> ambient(l.Ambient.r, l.Ambient.g, l.Ambient.b, l.Ambient.a);
5946                         sw::Vector direction(l.Direction.x, l.Direction.y, l.Direction.z);
5947
5948                         renderer->setLightDiffuse(active, diffuse);
5949                         renderer->setLightSpecular(active, specular);
5950                         renderer->setLightAmbient(active, ambient);
5951
5952                         if(l.Type == D3DLIGHT_DIRECTIONAL)
5953                         {
5954                                 // FIXME: Unsupported, make it a positional light far away without falloff
5955                                 renderer->setLightPosition(active, -1e10f * direction);
5956                                 renderer->setLightRange(active, l.Range);
5957                                 renderer->setLightAttenuation(active, 1, 0, 0);
5958                         }
5959                         else if(l.Type == D3DLIGHT_SPOT)
5960                         {
5961                                 // FIXME: Unsupported, make it a positional light
5962                                 renderer->setLightPosition(active, position);
5963                                 renderer->setLightRange(active, l.Range);
5964                                 renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);
5965                         }
5966                         else
5967                         {
5968                                 renderer->setLightPosition(active, position);
5969                                 renderer->setLightRange(active, l.Range);
5970                                 renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);
5971                         }
5972
5973                         renderer->setLightEnable(active, true);
5974
5975                         active++;
5976                         i++;
5977                 }
5978
5979                 // Remaining lights are disabled
5980                 while(active < 8)
5981                 {
5982                         renderer->setLightEnable(active, false);
5983
5984                         active++;
5985                 }
5986
5987                 lightsDirty = false;
5988         }
5989
5990         bool Direct3DDevice9::bindViewport()
5991         {
5992                 if(viewport.Width <= 0 || viewport.Height <= 0)
5993                 {
5994                         return false;
5995                 }
5996
5997                 if(scissorEnable)
5998                 {
5999                         if(scissorRect.left >= scissorRect.right || scissorRect.top >= scissorRect.bottom)
6000                         {
6001                                 return false;
6002                         }
6003
6004                         sw::Rect scissor;
6005                         scissor.x0 = scissorRect.left;
6006                         scissor.x1 = scissorRect.right;
6007                         scissor.y0 = scissorRect.top;
6008                         scissor.y1 = scissorRect.bottom;
6009
6010                         renderer->setScissor(scissor);
6011                 }
6012                 else
6013                 {
6014                         sw::Rect scissor;
6015                         scissor.x0 = viewport.X;
6016                         scissor.x1 = viewport.X + viewport.Width;
6017                         scissor.y0 = viewport.Y;
6018                         scissor.y1 = viewport.Y + viewport.Height;
6019
6020                         renderer->setScissor(scissor);
6021                 }
6022
6023                 sw::Viewport view;
6024                 view.x0 = (float)viewport.X;
6025                 view.y0 = (float)viewport.Y + viewport.Height;
6026                 view.width = (float)viewport.Width;
6027                 view.height = -(float)viewport.Height;
6028                 view.minZ = viewport.MinZ;
6029                 view.maxZ = viewport.MaxZ;
6030
6031                 renderer->setViewport(view);
6032
6033                 return true;
6034         }
6035
6036         void Direct3DDevice9::bindTextures()
6037         {
6038                 for(int sampler = 0; sampler < 16 + 4; sampler++)
6039                 {
6040                         Direct3DBaseTexture9 *baseTexture = texture[sampler];
6041
6042                         sw::SamplerType type = sampler < 16 ? sw::SAMPLER_PIXEL : sw::SAMPLER_VERTEX;
6043                         int index = sampler < 16 ? sampler : sampler - 16;   // Sampler index within type group
6044
6045                         bool textureUsed = false;
6046
6047                         if(type == sw::SAMPLER_PIXEL && pixelShader)
6048                         {
6049                                 textureUsed = pixelShader->getPixelShader()->usesSampler(index);
6050                         }
6051                         else if(type == sw::SAMPLER_VERTEX && vertexShader)
6052                         {
6053                                 textureUsed = vertexShader->getVertexShader()->usesSampler(index);
6054                         }
6055                         else
6056                         {
6057                                 textureUsed = true;   // FIXME: Check fixed-function use?
6058                         }
6059
6060                         sw::Resource *resource = 0;
6061
6062                         if(baseTexture && textureUsed)
6063                         {
6064                                 resource = baseTexture->getResource();
6065                         }
6066
6067                         renderer->setTextureResource(sampler, resource);
6068
6069                         if(baseTexture && textureUsed)
6070                         {
6071                                 baseTexture->GenerateMipSubLevels();
6072                         }
6073
6074                         if(baseTexture && textureUsed)
6075                         {
6076                                 int levelCount = baseTexture->getInternalLevelCount();
6077
6078                                 int textureLOD = baseTexture->GetLOD();
6079                                 int samplerLOD = samplerState[sampler][D3DSAMP_MAXMIPLEVEL];
6080                                 int LOD = textureLOD > samplerLOD ? textureLOD : samplerLOD;
6081
6082                                 if(samplerState[sampler][D3DSAMP_MIPFILTER] == D3DTEXF_NONE)
6083                                 {
6084                                         LOD = 0;
6085                                 }
6086
6087                                 switch(baseTexture->GetType())
6088                                 {
6089                                 case D3DRTYPE_TEXTURE:
6090                                         {
6091                                                 Direct3DTexture9 *texture = dynamic_cast<Direct3DTexture9*>(baseTexture);
6092                                                 Direct3DSurface9 *surface;
6093
6094                                                 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
6095                                                 {
6096                                                         int surfaceLevel = mipmapLevel;
6097
6098                                                         if(surfaceLevel < LOD)
6099                                                         {
6100                                                                 surfaceLevel = LOD;
6101                                                         }
6102
6103                                                         if(surfaceLevel < 0)
6104                                                         {
6105                                                                 surfaceLevel = 0;
6106                                                         }
6107                                                         else if(surfaceLevel >= levelCount)
6108                                                         {
6109                                                                 surfaceLevel = levelCount - 1;
6110                                                         }
6111
6112                                                         surface = texture->getInternalSurfaceLevel(surfaceLevel);
6113                                                         renderer->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
6114                                                 }
6115                                         }
6116                                         break;
6117                                 case D3DRTYPE_CUBETEXTURE:
6118                                         for(int face = 0; face < 6; face++)
6119                                         {
6120                                                 Direct3DCubeTexture9 *cubeTexture = dynamic_cast<Direct3DCubeTexture9*>(baseTexture);
6121                                                 Direct3DSurface9 *surface;
6122
6123                                                 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
6124                                                 {
6125                                                         int surfaceLevel = mipmapLevel;
6126
6127                                                         if(surfaceLevel < LOD)
6128                                                         {
6129                                                                 surfaceLevel = LOD;
6130                                                         }
6131
6132                                                         if(surfaceLevel < 0)
6133                                                         {
6134                                                                 surfaceLevel = 0;
6135                                                         }
6136                                                         else if(surfaceLevel >= levelCount)
6137                                                         {
6138                                                                 surfaceLevel = levelCount - 1;
6139                                                         }
6140
6141                                                         surface = cubeTexture->getInternalCubeMapSurface((D3DCUBEMAP_FACES)face, surfaceLevel);
6142                                                         renderer->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
6143                                                 }
6144                                         }
6145                                         break;
6146                                 case D3DRTYPE_VOLUMETEXTURE:
6147                                         {
6148                                                 Direct3DVolumeTexture9 *volumeTexture = dynamic_cast<Direct3DVolumeTexture9*>(baseTexture);
6149                                                 Direct3DVolume9 *volume;
6150
6151                                                 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
6152                                                 {
6153                                                         int surfaceLevel = mipmapLevel;
6154
6155                                                         if(surfaceLevel < LOD)
6156                                                         {
6157                                                                 surfaceLevel = LOD;
6158                                                         }
6159
6160                                                         if(surfaceLevel < 0)
6161                                                         {
6162                                                                 surfaceLevel = 0;
6163                                                         }
6164                                                         else if(surfaceLevel >= levelCount)
6165                                                         {
6166                                                                 surfaceLevel = levelCount - 1;
6167                                                         }
6168
6169                                                         volume = volumeTexture->getInternalVolumeLevel(surfaceLevel);
6170                                                         renderer->setTextureLevel(sampler, 0, mipmapLevel, volume, sw::TEXTURE_3D);
6171                                                 }
6172                                         }
6173                                         break;
6174                                 default:
6175                                         UNIMPLEMENTED();
6176                                 }
6177                         }
6178                         else
6179                         {
6180                                 renderer->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
6181                         }
6182                 }
6183         }
6184
6185         bool Direct3DDevice9::isRecording() const
6186         {
6187                 return stateRecorder != 0;
6188         }
6189
6190         void Direct3DDevice9::setOcclusionEnabled(bool enable)
6191         {
6192                 renderer->setOcclusionEnabled(enable);
6193         }
6194
6195         void Direct3DDevice9::removeQuery(sw::Query *query)
6196         {
6197                 renderer->removeQuery(query);
6198         }
6199
6200         void Direct3DDevice9::addQuery(sw::Query *query)
6201         {
6202                 renderer->addQuery(query);
6203         }
6204
6205         void Direct3DDevice9::stretchRect(Direct3DSurface9 *source, const RECT *sourceRect, Direct3DSurface9 *dest, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)
6206         {
6207                 D3DSURFACE_DESC sourceDescription;
6208                 D3DSURFACE_DESC destDescription;
6209
6210                 source->GetDesc(&sourceDescription);
6211                 dest->GetDesc(&destDescription);
6212
6213                 int sWidth = source->getWidth();
6214                 int sHeight = source->getHeight();
6215                 int dWidth = dest->getWidth();
6216                 int dHeight = dest->getHeight();
6217
6218                 sw::Rect sRect(0, 0, sWidth, sHeight);
6219                 sw::Rect dRect(0, 0, dWidth, dHeight);
6220
6221                 if(sourceRect)
6222                 {
6223                         sRect.x0 = sourceRect->left;
6224                         sRect.y0 = sourceRect->top;
6225                         sRect.x1 = sourceRect->right;
6226                         sRect.y1 = sourceRect->bottom;
6227                 }
6228
6229                 if(destRect)
6230                 {
6231                         dRect.x0 = destRect->left;
6232                         dRect.y0 = destRect->top;
6233                         dRect.x1 = destRect->right;
6234                         dRect.y1 = destRect->bottom;
6235                 }
6236
6237                 bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);
6238                 bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
6239                 bool depthStencil = (sourceDescription.Usage & D3DUSAGE_DEPTHSTENCIL) == D3DUSAGE_DEPTHSTENCIL;
6240                 bool alpha0xFF = false;
6241
6242                 if((sourceDescription.Format == D3DFMT_A8R8G8B8 && destDescription.Format == D3DFMT_X8R8G8B8) ||
6243                    (sourceDescription.Format == D3DFMT_X8R8G8B8 && destDescription.Format == D3DFMT_A8R8G8B8))
6244                 {
6245                         equalFormats = true;
6246                         alpha0xFF = true;
6247                 }
6248
6249                 if(depthStencil)   // Copy entirely, internally   // FIXME: Check
6250                 {
6251                         if(source->hasDepth())
6252                         {
6253                                 byte *sourceBuffer = (byte*)source->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
6254                                 byte *destBuffer = (byte*)dest->lockInternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
6255
6256                                 unsigned int width = source->getWidth();
6257                                 unsigned int height = source->getHeight();
6258                                 unsigned int pitch = source->getInternalPitchB();
6259
6260                                 for(unsigned int y = 0; y < height; y++)
6261                                 {
6262                                         memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
6263
6264                                         sourceBuffer += pitch;
6265                                         destBuffer += pitch;
6266                                 }
6267
6268                                 source->unlockInternal();
6269                                 dest->unlockInternal();
6270                         }
6271
6272                         if(source->hasStencil())
6273                         {
6274                                 byte *sourceBuffer = (byte*)source->lockStencil(0, 0, 0, sw::PUBLIC);
6275                                 byte *destBuffer = (byte*)dest->lockStencil(0, 0, 0, sw::PUBLIC);
6276
6277                                 unsigned int width = source->getWidth();
6278                                 unsigned int height = source->getHeight();
6279                                 unsigned int pitch = source->getStencilPitchB();
6280
6281                                 for(unsigned int y = 0; y < height; y++)
6282                                 {
6283                                         memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
6284
6285                                         sourceBuffer += pitch;
6286                                         destBuffer += pitch;
6287                                 }
6288
6289                                 source->unlockStencil();
6290                                 dest->unlockStencil();
6291                         }
6292                 }
6293                 else if(!scaling && equalFormats)
6294                 {
6295                         unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, 0, sw::LOCK_READONLY, sw::PUBLIC);
6296                         unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, 0, sw::LOCK_READWRITE, sw::PUBLIC);
6297                         unsigned int sourcePitch = source->getInternalPitchB();
6298                         unsigned int destPitch = dest->getInternalPitchB();
6299
6300                         unsigned int width = dRect.x1 - dRect.x0;
6301                         unsigned int height = dRect.y1 - dRect.y0;
6302                         unsigned int bytes = width * sw::Surface::bytes(source->getInternalFormat());
6303
6304                         for(unsigned int y = 0; y < height; y++)
6305                         {
6306                                 memcpy(destBytes, sourceBytes, bytes);
6307
6308                                 if(alpha0xFF)
6309                                 {
6310                                         for(unsigned int x = 0; x < width; x++)
6311                                         {
6312                                                 destBytes[4 * x + 3] = 0xFF;
6313                                         }
6314                                 }
6315
6316                                 sourceBytes += sourcePitch;
6317                                 destBytes += destPitch;
6318                         }
6319
6320                         source->unlockInternal();
6321                         dest->unlockInternal();
6322                 }
6323                 else
6324                 {
6325                         renderer->blit(source, sRect, dest, dRect, filter >= D3DTEXF_LINEAR);
6326                 }
6327         }
6328
6329         long Direct3DDevice9::updateVolume(IDirect3DVolume9 *sourceVolume, IDirect3DVolume9 *destinationVolume)
6330         {
6331                 TRACE("IDirect3DVolume9 *sourceVolume = 0x%0.8p, IDirect3DVolume9 *destinationVolume = 0x%0.8p", sourceVolume, destinationVolume);
6332
6333                 if(!sourceVolume || !destinationVolume)
6334                 {
6335                         return INVALIDCALL();
6336                 }
6337
6338                 D3DVOLUME_DESC sourceDescription;
6339                 D3DVOLUME_DESC destinationDescription;
6340
6341                 sourceVolume->GetDesc(&sourceDescription);
6342                 destinationVolume->GetDesc(&destinationDescription);
6343
6344                 if(sourceDescription.Pool      != D3DPOOL_SYSTEMMEM ||
6345                    destinationDescription.Pool != D3DPOOL_DEFAULT ||
6346                    sourceDescription.Format != destinationDescription.Format ||
6347                    sourceDescription.Width  != destinationDescription.Width ||
6348                    sourceDescription.Height != destinationDescription.Height ||
6349                    sourceDescription.Depth  != destinationDescription.Depth)
6350                 {
6351                         return INVALIDCALL();
6352                 }
6353
6354                 sw::Surface *source = static_cast<Direct3DVolume9*>(sourceVolume);
6355                 sw::Surface *dest = static_cast<Direct3DVolume9*>(destinationVolume);
6356
6357                 if(source->getExternalPitchB() != dest->getExternalPitchB() ||
6358                    source->getExternalSliceB() != dest->getExternalSliceB())
6359                 {
6360                         UNIMPLEMENTED();
6361                 }
6362
6363                 void *sBuffer = source->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
6364                 void *dBuffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
6365
6366                 memcpy(dBuffer, sBuffer, source->getExternalSliceB() * sourceDescription.Depth);
6367
6368                 source->unlockExternal();
6369                 dest->unlockExternal();
6370
6371                 return D3D_OK;
6372         }
6373
6374         bool Direct3DDevice9::validRectangle(const RECT *rect, IDirect3DSurface9 *surface)
6375         {
6376                 if(!rect)
6377                 {
6378                         return true;
6379                 }
6380
6381                 if(rect->right <= rect->left || rect->bottom <= rect->top)
6382                 {
6383                         return false;
6384                 }
6385
6386                 if(rect->left < 0 || rect->top < 0)
6387                 {
6388                         return false;
6389                 }
6390
6391                 D3DSURFACE_DESC description;
6392                 surface->GetDesc(&description);
6393
6394                 if(rect->right > (int)description.Width || rect->bottom > (int)description.Height)
6395                 {
6396                         return false;
6397                 }
6398
6399                 return true;
6400         }
6401
6402         void Direct3DDevice9::configureFPU()
6403         {
6404         //      _controlfp(_PC_24, _MCW_PC);     // Single-precision
6405                 _controlfp(_MCW_EM, _MCW_EM);    // Mask all exceptions
6406                 _controlfp(_RC_NEAR, _MCW_RC);   // Round to nearest
6407         }
6408 }