1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #include "Direct3DDevice9.hpp"
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"
33 #include "Capabilities.hpp"
35 #include "Renderer.hpp"
37 #include "FrameBuffer.hpp"
38 #include "Clipper.hpp"
39 #include "Configurator.hpp"
41 #include "Resource.hpp"
45 bool localShaderConstants = true;
49 inline unsigned long FtoDW(float f)
51 return (unsigned long&)f;
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)
56 InitializeCriticalSection(&criticalSection);
63 context = new sw::Context();
64 renderer = new sw::Renderer(context, sw::Direct3D, false);
74 for(int i = 0; i < 16 + 4; i++)
81 Reset(presentParameters);
87 pixelShaderDirty = true;
88 pixelShaderConstantsBDirty = 0;
89 pixelShaderConstantsFDirty = 0;
90 pixelShaderConstantsIDirty = 0;
91 vertexShaderDirty = true;
92 vertexShaderConstantsBDirty = 0;
93 vertexShaderConstantsFDirty = 0;
94 vertexShaderConstantsIDirty = 0;
96 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
102 streamSourceFreq[i] = 1;
106 vertexDeclaration = 0;
108 D3DMATERIAL9 material;
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;
128 SetMaterial(&material);
130 D3DMATRIX identity = {1, 0, 0, 0,
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);
146 for(int i = 0; i < 12; i++)
148 SetTransform(D3DTS_WORLDMATRIX(i), &identity);
151 for(int i = 0; i < MAX_PIXEL_SHADER_CONST; i++)
153 float zero[4] = {0, 0, 0, 0};
155 SetPixelShaderConstantF(i, zero, 1);
158 for(int i = 0; i < MAX_VERTEX_SHADER_CONST; i++)
160 float zero[4] = {0, 0, 0, 0};
162 SetVertexShaderConstantF(i, zero, 1);
165 for(int i = 0; i < 16; i++)
167 int zero[4] = {0, 0, 0, 0};
169 SetPixelShaderConstantI(i, zero, 1);
170 SetVertexShaderConstantI(i, zero, 1);
171 SetPixelShaderConstantB(i, &zero[0], 1);
172 SetVertexShaderConstantB(i, &zero[0], 1);
177 if(!(behaviourFlags & D3DCREATE_FPU_PRESERVE))
182 instancingEnabled = pixelShaderVersionX >= D3DPS_VERSION(3, 0);
185 Direct3DDevice9::~Direct3DDevice9()
200 depthStencil->unbind();
206 autoDepthStencil->unbind();
207 autoDepthStencil = 0;
210 for(int index = 0; index < 4; index++)
212 if(renderTarget[index])
214 renderTarget[index]->unbind();
215 renderTarget[index] = 0;
219 if(vertexDeclaration)
221 vertexDeclaration->unbind();
222 vertexDeclaration = 0;
225 for(int i = 0; i < 16 + 4; i++)
229 texture[i]->unbind();
234 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
238 dataStream[i]->unbind();
251 pixelShader->unbind();
257 vertexShader->unbind();
263 stateRecorder->unbind();
271 DeleteCriticalSection(&criticalSection);
274 long Direct3DDevice9::QueryInterface(const IID &iid, void **object)
276 CriticalSection cs(this);
278 TRACE("const IID &iid = 0x%0.8p, void **object = 0x%0.8p", iid, object);
280 if(iid == IID_IDirect3DDevice9 ||
291 return NOINTERFACE(iid);
294 unsigned long Direct3DDevice9::AddRef()
298 return Unknown::AddRef();
301 unsigned long Direct3DDevice9::Release()
305 return Unknown::Release();
308 long Direct3DDevice9::BeginScene()
310 CriticalSection cs(this);
317 long Direct3DDevice9::BeginStateBlock()
319 CriticalSection cs(this);
325 return INVALIDCALL();
328 stateRecorder = new Direct3DStateBlock9(this, (D3DSTATEBLOCKTYPE)0);
332 return OUTOFMEMORY();
335 stateRecorder->bind();
340 long Direct3DDevice9::Clear(unsigned long count, const D3DRECT *rects, unsigned long flags, unsigned long color, float z, unsigned long stencil)
342 CriticalSection cs(this);
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);
346 if(!rects && count != 0)
348 return INVALIDCALL();
351 if(flags & (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL) && !depthStencil)
353 return INVALIDCALL();
356 if(flags & D3DCLEAR_STENCIL) // Check for stencil component
358 D3DSURFACE_DESC description;
359 depthStencil->GetDesc(&description);
361 switch(description.Format)
368 case D3DFMT_S8_LOCKABLE: // FIXME: INVALIDCALL when trying to clear depth?
373 case D3DFMT_D16_LOCKABLE:
376 case D3DFMT_D32F_LOCKABLE:
377 case D3DFMT_D32_LOCKABLE:
378 return INVALIDCALL();
389 rect.x1 = viewport.X;
390 rect.x2 = viewport.X + viewport.Width;
391 rect.y1 = viewport.Y;
392 rect.y2 = viewport.Y + viewport.Height;
397 for(unsigned int i = 0; i < count; i++)
399 sw::SliceRect clearRect(rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2, 0);
401 clearRect.clip(viewport.X, viewport.Y, viewport.X + viewport.Width, viewport.Y + viewport.Height);
405 clearRect.clip(scissorRect.left, scissorRect.top, scissorRect.right, scissorRect.bottom);
408 if(flags & D3DCLEAR_TARGET)
410 for(int index = 0; index < 4; index++)
412 if(renderTarget[index])
414 D3DSURFACE_DESC description;
415 renderTarget[index]->GetDesc(&description);
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;
423 if(renderState[D3DRS_SRGBWRITEENABLE] != FALSE && index == 0 && Capabilities::isSRGBwritable(description.Format))
425 rgba[0] = sw::linearToSRGB(rgba[0]);
426 rgba[1] = sw::linearToSRGB(rgba[1]);
427 rgba[2] = sw::linearToSRGB(rgba[2]);
430 renderer->clear(rgba, sw::FORMAT_A32B32G32R32F, renderTarget[index], clearRect, 0xF);
435 if(flags & D3DCLEAR_ZBUFFER)
438 depthStencil->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
441 if(flags & D3DCLEAR_STENCIL)
443 depthStencil->clearStencil(stencil, 0xFF, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
450 long Direct3DDevice9::ColorFill(IDirect3DSurface9 *surface, const RECT *rect, D3DCOLOR color)
452 CriticalSection cs(this);
454 TRACE("IDirect3DSurface9 *surface = 0x%0.8p, const RECT *rect = 0x%0.8p, D3DCOLOR color = 0x%0.8X", surface, rect, color);
458 return INVALIDCALL();
461 D3DSURFACE_DESC description;
463 surface->GetDesc(&description);
465 if(description.Pool != D3DPOOL_DEFAULT)
467 return INVALIDCALL();
476 lock.right = description.Width;
477 lock.bottom = description.Height;
482 static_cast<Direct3DSurface9*>(surface)->fill(color, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top);
487 long Direct3DDevice9::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *presentParameters, IDirect3DSwapChain9 **swapChain)
489 CriticalSection cs(this);
491 TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p, IDirect3DSwapChain9 **swapChain = 0x%0.8p", presentParameters, swapChain);
495 return INVALIDCALL();
500 if(!presentParameters)
502 return INVALIDCALL();
505 if(presentParameters->BackBufferCount > 3)
507 return INVALIDCALL(); // Maximum of three back buffers
510 *swapChain = new Direct3DSwapChain9(this, presentParameters);
514 return OUTOFMEMORY();
517 if(GetAvailableTextureMem() == 0)
522 return OUTOFVIDEOMEMORY();
525 (*swapChain)->AddRef();
530 long Direct3DDevice9::CreateCubeTexture(unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture9 **cubeTexture, void **sharedHandle)
532 CriticalSection cs(this);
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);
538 if(edgeLength == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_CUBETEXTURE, format) != D3D_OK)
540 return INVALIDCALL();
543 *cubeTexture = new Direct3DCubeTexture9(this, edgeLength, levels, usage, format, pool);
547 return OUTOFMEMORY();
550 if(GetAvailableTextureMem() == 0)
555 return OUTOFVIDEOMEMORY();
558 (*cubeTexture)->AddRef();
563 long Direct3DDevice9::CreateDepthStencilSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int discard, IDirect3DSurface9 **surface, void **sharedHandle)
565 CriticalSection cs(this);
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);
571 if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION)
573 return INVALIDCALL();
576 bool lockable = false;
592 case D3DFMT_S8_LOCKABLE:
593 case D3DFMT_D16_LOCKABLE:
594 case D3DFMT_D32F_LOCKABLE:
595 case D3DFMT_D32_LOCKABLE:
602 *surface = new Direct3DSurface9(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, multiSampleQuality, lockable, D3DUSAGE_DEPTHSTENCIL);
606 return OUTOFMEMORY();
609 if(GetAvailableTextureMem() == 0)
614 return OUTOFVIDEOMEMORY();
617 (*surface)->AddRef();
622 long Direct3DDevice9::CreateIndexBuffer(unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **indexBuffer, void **sharedHandle)
624 CriticalSection cs(this);
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);
628 *indexBuffer = new Direct3DIndexBuffer9(this, length, usage, format, pool);
632 return OUTOFMEMORY();
635 if(GetAvailableTextureMem() == 0)
640 return OUTOFVIDEOMEMORY();
643 (*indexBuffer)->AddRef();
648 long Direct3DDevice9::CreateOffscreenPlainSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, void **sharedHandle)
650 CriticalSection cs(this);
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);
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
658 return INVALIDCALL();
661 if(pool == D3DPOOL_MANAGED)
663 return INVALIDCALL();
666 *surface = new Direct3DSurface9(this, this, width, height, format, pool, D3DMULTISAMPLE_NONE, 0, true, 0);
670 return OUTOFMEMORY();
673 if(GetAvailableTextureMem() == 0)
678 return OUTOFVIDEOMEMORY();
681 (*surface)->AddRef();
686 long Direct3DDevice9::CreatePixelShader(const unsigned long *function, IDirect3DPixelShader9 **shader)
688 CriticalSection cs(this);
690 TRACE("const unsigned long *function = 0x%0.8p, IDirect3DPixelShader9 **shader = 0x%0.8p", function, shader);
694 return INVALIDCALL();
699 if(!sw::PixelShader::validate(function) || function[0] > pixelShaderVersionX)
701 return INVALIDCALL(); // Shader contains unsupported operations
704 *shader = new Direct3DPixelShader9(this, function);
708 return OUTOFMEMORY();
716 long Direct3DDevice9::CreateQuery(D3DQUERYTYPE type, IDirect3DQuery9 **query)
718 CriticalSection cs(this);
720 TRACE("D3DQUERYTYPE type = %d, IDirect3DQuery9 **query = 0x%0.8p", type, query);
722 if(query == 0) // Support checked
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();
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();
764 *query = new Direct3DQuery9(this, type);
768 return OUTOFMEMORY();
777 long Direct3DDevice9::CreateRenderTarget(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int lockable, IDirect3DSurface9 **surface, void **sharedHandle)
779 CriticalSection cs(this);
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);
785 if(width == 0 || height == 0 || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION)
787 return INVALIDCALL();
790 *surface = new Direct3DSurface9(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, multiSampleQuality, lockable != FALSE, D3DUSAGE_RENDERTARGET);
794 return OUTOFMEMORY();
797 if(GetAvailableTextureMem() == 0)
802 return OUTOFVIDEOMEMORY();
805 (*surface)->AddRef();
810 long Direct3DDevice9::CreateStateBlock(D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateBlock)
812 CriticalSection cs(this);
814 TRACE("D3DSTATEBLOCKTYPE type = %d, IDirect3DStateBlock9 **stateBlock = 0x%0.8p", type, stateBlock);
816 *stateBlock = new Direct3DStateBlock9(this, type);
820 return OUTOFMEMORY();
823 (*stateBlock)->AddRef();
828 long Direct3DDevice9::CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture9 **texture, void **sharedHandle)
830 CriticalSection cs(this);
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);
836 if(width == 0 || height == 0 || (usage & D3DUSAGE_AUTOGENMIPMAP && levels > 1) || d3d9->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_TEXTURE, format) != D3D_OK)
838 return INVALIDCALL();
841 *texture = new Direct3DTexture9(this, width, height, levels, usage, format, pool);
845 return OUTOFMEMORY();
848 if(GetAvailableTextureMem() == 0)
853 return OUTOFVIDEOMEMORY();
856 (*texture)->AddRef();
861 long Direct3DDevice9::CreateVertexBuffer(unsigned int length, unsigned long usage, unsigned long FVF, D3DPOOL pool, IDirect3DVertexBuffer9 **vertexBuffer, void **sharedHandle)
863 CriticalSection cs(this);
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);
867 *vertexBuffer = new Direct3DVertexBuffer9(this, length, usage, FVF, pool);
871 return OUTOFMEMORY();
874 if(GetAvailableTextureMem() == 0)
876 delete *vertexBuffer;
879 return OUTOFVIDEOMEMORY();
882 (*vertexBuffer)->AddRef();
887 long Direct3DDevice9::CreateVertexDeclaration(const D3DVERTEXELEMENT9 *vertexElements, IDirect3DVertexDeclaration9 **declaration)
889 CriticalSection cs(this);
891 TRACE("const D3DVERTEXELEMENT9 *vertexElements = 0x%0.8p, IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", vertexElements, declaration);
895 return INVALIDCALL();
898 const D3DVERTEXELEMENT9 *element = vertexElements;
900 while(element->Stream != 0xFF)
902 if(element->Type > D3DDECLTYPE_UNUSED) // FIXME: Check other fields too
910 *declaration = new Direct3DVertexDeclaration9(this, vertexElements);
914 return OUTOFMEMORY();
917 (*declaration)->AddRef();
922 long Direct3DDevice9::CreateVertexShader(const unsigned long *function, IDirect3DVertexShader9 **shader)
924 CriticalSection cs(this);
926 TRACE("const unsigned long *function = 0x%0.8p, IDirect3DVertexShader9 **shader = 0x%0.8p", function, shader);
930 return INVALIDCALL();
935 if(!sw::VertexShader::validate(function) || function[0] > vertexShaderVersionX)
937 return INVALIDCALL(); // Shader contains unsupported operations
940 *shader = new Direct3DVertexShader9(this, function);
944 return OUTOFMEMORY();
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)
954 CriticalSection cs(this);
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);
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)
962 return INVALIDCALL();
965 *volumeTexture = new Direct3DVolumeTexture9(this, width, height, depth, levels, usage, format, pool);
969 return OUTOFMEMORY();
972 if(GetAvailableTextureMem() == 0)
974 delete *volumeTexture;
977 return OUTOFVIDEOMEMORY();
980 (*volumeTexture)->AddRef();
985 long Direct3DDevice9::DeletePatch(unsigned int handle)
987 CriticalSection cs(this);
989 TRACE("unsigned int handle = %d", handle);
996 long Direct3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE type, int baseVertexIndex, unsigned int minIndex, unsigned int numVertices, unsigned int startIndex, unsigned int primitiveCount)
998 CriticalSection cs(this);
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);
1004 return INVALIDCALL();
1007 if(!bindResources(indexData) || !primitiveCount)
1012 unsigned int indexOffset = startIndex * (indexData->is32Bit() ? 4 : 2); // FIXME: Doesn't take stream frequencies into account
1014 sw::DrawType drawType;
1016 if(indexData->is32Bit())
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;
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;
1045 if((streamSourceFreq[0] & D3DSTREAMSOURCE_INDEXEDDATA) && instanceData())
1047 int instanceCount = (streamSourceFreq[0] & ~D3DSTREAMSOURCE_INDEXEDDATA);
1049 for(int instance = 0; instance < instanceCount; instance++)
1051 bindVertexStreams(baseVertexIndex, true, instance);
1052 renderer->draw(drawType, indexOffset, primitiveCount, instance == 0);
1057 bindVertexStreams(baseVertexIndex, false, 0);
1058 renderer->draw(drawType, indexOffset, primitiveCount);
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)
1066 CriticalSection cs(this);
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);
1070 if(!vertexStreamZeroData || !indexData)
1072 return INVALIDCALL();
1075 int length = (minIndex + numVertices) * vertexStreamZeroStride;
1077 Direct3DVertexBuffer9 *vertexBuffer = new Direct3DVertexBuffer9(this, length, 0, 0, D3DPOOL_DEFAULT);
1080 vertexBuffer->Lock(0, 0, &data, 0);
1081 memcpy(data, vertexStreamZeroData, length);
1082 vertexBuffer->Unlock();
1084 SetStreamSource(0, vertexBuffer, 0, vertexStreamZeroStride);
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;
1098 length *= indexDataFormat == D3DFMT_INDEX32 ? 4 : 2;
1100 Direct3DIndexBuffer9 *indexBuffer = new Direct3DIndexBuffer9(this, length, 0, indexDataFormat, D3DPOOL_DEFAULT);
1102 indexBuffer->Lock(0, 0, &data, 0);
1103 memcpy(data, indexData, length);
1104 indexBuffer->Unlock();
1106 SetIndices(indexBuffer);
1108 if(!bindResources(indexBuffer) || !primitiveCount)
1110 vertexBuffer->Release();
1115 sw::DrawType drawType;
1117 if(indexDataFormat == D3DFMT_INDEX32)
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;
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;
1146 bindVertexStreams(0, false, 0);
1147 renderer->draw(drawType, 0, primitiveCount);
1149 SetStreamSource(0, 0, 0, 0);
1155 long Direct3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE primitiveType, unsigned int startVertex, unsigned int primitiveCount)
1157 CriticalSection cs(this);
1159 TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int startVertex = %d, unsigned int primitiveCount = %d", primitiveType, startVertex, primitiveCount);
1161 if(!bindResources(0) || !primitiveCount)
1166 sw::DrawType drawType;
1168 switch(primitiveType)
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;
1180 bindVertexStreams(startVertex, false, 0);
1181 renderer->draw(drawType, 0, primitiveCount);
1186 long Direct3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType, unsigned int primitiveCount, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)
1188 CriticalSection cs(this);
1190 TRACE("D3DPRIMITIVETYPE primitiveType = %d, unsigned int primitiveCount = %d, const void *vertexStreamZeroData = 0x%0.8p, unsigned int vertexStreamZeroStride = %d", primitiveType, primitiveCount, vertexStreamZeroData, vertexStreamZeroStride);
1192 if(!vertexStreamZeroData)
1194 return INVALIDCALL();
1197 IDirect3DVertexBuffer9 *vertexBuffer = 0;
1200 switch(primitiveType)
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;
1212 length *= vertexStreamZeroStride;
1214 CreateVertexBuffer(length, 0, 0, D3DPOOL_DEFAULT, &vertexBuffer, 0);
1217 vertexBuffer->Lock(0, 0, &data, 0);
1218 memcpy(data, vertexStreamZeroData, length);
1219 vertexBuffer->Unlock();
1221 SetStreamSource(0, vertexBuffer, 0, vertexStreamZeroStride);
1223 if(!bindResources(0) || !primitiveCount)
1225 vertexBuffer->Release();
1230 sw::DrawType drawType;
1232 switch(primitiveType)
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;
1244 bindVertexStreams(0, false, 0);
1245 renderer->draw(drawType, 0, primitiveCount);
1247 SetStreamSource(0, 0, 0, 0);
1248 vertexBuffer->Release();
1253 long Direct3DDevice9::DrawRectPatch(unsigned int handle, const float *numSegs, const D3DRECTPATCH_INFO *rectPatchInfo)
1255 CriticalSection cs(this);
1257 TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DRECTPATCH_INFO *rectPatchInfo = 0x%0.8p", handle, numSegs, rectPatchInfo);
1259 if(!numSegs || !rectPatchInfo)
1261 return INVALIDCALL();
1269 long Direct3DDevice9::DrawTriPatch(unsigned int handle, const float *numSegs, const D3DTRIPATCH_INFO *triPatchInfo)
1271 CriticalSection cs(this);
1273 TRACE("unsigned int handle = %d, const float *numSegs = 0x%0.8p, const D3DTRIPATCH_INFO *triPatchInfo = 0x%0.8p", handle, numSegs, triPatchInfo);
1275 if(!numSegs || !triPatchInfo)
1277 return INVALIDCALL();
1285 long Direct3DDevice9::EndScene()
1287 CriticalSection cs(this);
1294 long Direct3DDevice9::EndStateBlock(IDirect3DStateBlock9 **stateBlock)
1296 CriticalSection cs(this);
1298 TRACE("IDirect3DStateBlock9 **stateBlock = 0x%0.8p", stateBlock);
1302 return INVALIDCALL();
1309 return INVALIDCALL();
1312 *stateBlock = stateRecorder;
1313 stateRecorder->AddRef();
1314 stateRecorder->unbind();
1315 stateRecorder = 0; // Stop recording
1320 long Direct3DDevice9::EvictManagedResources()
1322 CriticalSection cs(this);
1326 // UNIMPLEMENTED(); // FIXME
1331 unsigned int Direct3DDevice9::GetAvailableTextureMem()
1333 CriticalSection cs(this);
1337 int availableMemory = textureMemory - Direct3DResource9::getMemoryUsage();
1338 if(availableMemory < 0) availableMemory = 0;
1340 // Round to nearest MB
1341 return (availableMemory + 0x80000) & 0xFFF00000;
1344 long Direct3DDevice9::GetBackBuffer(unsigned int swapChainIndex, unsigned int backBufferIndex, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer)
1346 CriticalSection cs(this);
1348 TRACE("unsigned int swapChainIndex = %d, unsigned int backBufferIndex = %d, D3DBACKBUFFER_TYPE type = %d, IDirect3DSurface9 **backBuffer = 0x%0.8p", swapChainIndex, backBufferIndex, type, backBuffer);
1350 if(swapChainIndex >= GetNumberOfSwapChains())
1352 return INVALIDCALL();
1355 return swapChain->GetBackBuffer(backBufferIndex, type, backBuffer);
1358 long Direct3DDevice9::GetClipPlane(unsigned long index, float *plane)
1360 CriticalSection cs(this);
1362 TRACE("unsigned long index = %d, float *plane = 0x%0.8p", index, plane);
1364 if(!plane || index >= 6)
1366 return INVALIDCALL();
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];
1377 long Direct3DDevice9::GetClipStatus(D3DCLIPSTATUS9 *clipStatus)
1379 CriticalSection cs(this);
1381 TRACE("D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);
1385 return INVALIDCALL();
1388 *clipStatus = this->clipStatus;
1393 long Direct3DDevice9::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *parameters)
1395 CriticalSection cs(this);
1397 TRACE("D3DDEVICE_CREATION_PARAMETERS *parameters = 0x%0.8p", parameters);
1401 return INVALIDCALL();
1404 parameters->AdapterOrdinal = adapter;
1405 parameters->BehaviorFlags = behaviourFlags;
1406 parameters->DeviceType = deviceType;
1407 parameters->hFocusWindow = focusWindow;
1412 long Direct3DDevice9::GetCurrentTexturePalette(unsigned int *paletteNumber)
1414 CriticalSection cs(this);
1416 TRACE("unsigned int *paletteNumber = 0x%0.8p", paletteNumber);
1420 return INVALIDCALL();
1423 *paletteNumber = currentPalette;
1428 long Direct3DDevice9::GetDepthStencilSurface(IDirect3DSurface9 **depthStencilSurface)
1430 CriticalSection cs(this);
1432 TRACE("IDirect3DSurface9 **depthStencilSurface = 0x%0.8p", depthStencilSurface);
1434 if(!depthStencilSurface)
1436 return INVALIDCALL();
1439 *depthStencilSurface = depthStencil;
1443 depthStencil->AddRef();
1453 long Direct3DDevice9::GetDeviceCaps(D3DCAPS9 *caps)
1455 CriticalSection cs(this);
1457 TRACE("D3DCAPS9 *caps = 0x%0.8p", caps);
1459 return d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, caps);
1462 long Direct3DDevice9::GetDirect3D(IDirect3D9 **d3d9)
1464 CriticalSection cs(this);
1466 TRACE("IDirect3D9 **d3d9 = 0x%0.8p", d3d9);
1470 return INVALIDCALL();
1474 this->d3d9->AddRef();
1479 long Direct3DDevice9::GetDisplayMode(unsigned int index, D3DDISPLAYMODE *mode)
1481 CriticalSection cs(this);
1483 TRACE("unsigned int index = %d, D3DDISPLAYMODE *mode = 0x%0.8p", index, mode);
1485 if(index >= GetNumberOfSwapChains())
1487 return INVALIDCALL();
1490 return swapChain->GetDisplayMode(mode);
1493 long Direct3DDevice9::GetFrontBufferData(unsigned int index, IDirect3DSurface9 *destSurface)
1495 CriticalSection cs(this);
1497 TRACE("unsigned int index = %d, IDirect3DSurface9 *destSurface = %p", index, destSurface);
1499 if(index >= GetNumberOfSwapChains())
1501 return INVALIDCALL();
1504 return swapChain->GetFrontBufferData(destSurface);
1507 long Direct3DDevice9::GetFVF(unsigned long *FVF)
1509 CriticalSection cs(this);
1511 TRACE("unsigned long *FVF = 0x%0.8p", FVF);
1515 return INVALIDCALL();
1518 if(vertexDeclaration)
1520 *FVF = vertexDeclaration->getFVF();
1530 void Direct3DDevice9::GetGammaRamp(unsigned int index, D3DGAMMARAMP *ramp)
1532 CriticalSection cs(this);
1534 TRACE("unsigned int index = %d, D3DGAMMARAMP *ramp = 0x%0.8p", index, ramp);
1536 if(!ramp || index >= GetNumberOfSwapChains())
1541 swapChain->getGammaRamp((sw::GammaRamp*)ramp);
1544 long Direct3DDevice9::GetIndices(IDirect3DIndexBuffer9 **indexData)
1546 CriticalSection cs(this);
1548 TRACE("IDirect3DIndexBuffer9 **indexData = 0x%0.8p", indexData);
1552 return INVALIDCALL();
1555 *indexData = this->indexData;
1559 this->indexData->AddRef();
1565 long Direct3DDevice9::GetLight(unsigned long index, D3DLIGHT9 *light)
1567 CriticalSection cs(this);
1569 TRACE("unsigned long index = %d, D3DLIGHT9 *light = 0x%0.8p", index, light);
1573 return INVALIDCALL();
1576 if(!this->light.exists(index))
1578 return INVALIDCALL();
1581 *light = this->light[index];
1586 long Direct3DDevice9::GetLightEnable(unsigned long index, int *enable)
1588 CriticalSection cs(this);
1590 TRACE("unsigned long index = %d, int *enable = 0x%0.8p", index, enable);
1594 return INVALIDCALL();
1597 if(!light.exists(index))
1599 return INVALIDCALL();
1602 *enable = light[index].enable ? 128 : 0;
1607 long Direct3DDevice9::GetMaterial(D3DMATERIAL9 *material)
1609 CriticalSection cs(this);
1611 TRACE("D3DMATERIAL9 *material = 0x%0.8p", material);
1615 return INVALIDCALL();
1618 *material = this->material;
1623 float Direct3DDevice9::GetNPatchMode()
1625 CriticalSection cs(this);
1629 return 0.0f; // FIXME: Unimplemented
1632 unsigned int Direct3DDevice9::GetNumberOfSwapChains()
1634 CriticalSection cs(this);
1641 long Direct3DDevice9::GetPaletteEntries(unsigned int paletteNumber, PALETTEENTRY *entries)
1643 CriticalSection cs(this);
1645 TRACE("unsigned int paletteNumber = %d, PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);
1647 if(paletteNumber > 0xFFFF || !entries)
1649 return INVALIDCALL();
1652 for(int i = 0; i < 256; i++)
1654 entries[i] = palette[paletteNumber].entry[i];
1660 long Direct3DDevice9::GetPixelShader(IDirect3DPixelShader9 **shader)
1662 CriticalSection cs(this);
1664 TRACE("IDirect3DPixelShader9 **shader = 0x%0.8p", shader);
1668 return INVALIDCALL();
1673 pixelShader->AddRef();
1676 *shader = pixelShader;
1681 long Direct3DDevice9::GetPixelShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)
1683 CriticalSection cs(this);
1685 TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
1689 return INVALIDCALL();
1692 for(unsigned int i = 0; i < count; i++)
1694 constantData[i] = pixelShaderConstantB[startRegister + i];
1700 long Direct3DDevice9::GetPixelShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)
1702 CriticalSection cs(this);
1704 TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
1708 return INVALIDCALL();
1711 for(unsigned int i = 0; i < count; i++)
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];
1722 long Direct3DDevice9::GetPixelShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)
1724 CriticalSection cs(this);
1726 TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
1730 return INVALIDCALL();
1733 for(unsigned int i = 0; i < count; i++)
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];
1744 long Direct3DDevice9::GetRasterStatus(unsigned int index, D3DRASTER_STATUS *rasterStatus)
1746 CriticalSection cs(this);
1748 TRACE("unsigned int swapChain = %d, D3DRASTER_STATUS *rasterStatus = 0x%0.8p", index, rasterStatus);
1750 if(index >= GetNumberOfSwapChains())
1752 return INVALIDCALL();
1755 return swapChain->GetRasterStatus(rasterStatus);
1758 long Direct3DDevice9::GetRenderState(D3DRENDERSTATETYPE state, unsigned long *value)
1760 CriticalSection cs(this);
1762 TRACE("D3DRENDERSTATETYPE state = %d, unsigned long *value = 0x%0.8p", state, value);
1766 return INVALIDCALL();
1769 *value = renderState[state];
1774 long Direct3DDevice9::GetRenderTarget(unsigned long index, IDirect3DSurface9 **renderTarget)
1776 CriticalSection cs(this);
1778 TRACE("unsigned long index = %d, IDirect3DSurface9 **renderTarget = 0x%0.8p", index, renderTarget);
1780 if(index >= 4 || !renderTarget)
1782 return INVALIDCALL();
1787 if(!this->renderTarget[index])
1792 *renderTarget = this->renderTarget[index];
1793 this->renderTarget[index]->AddRef();
1798 long Direct3DDevice9::GetRenderTargetData(IDirect3DSurface9 *renderTarget, IDirect3DSurface9 *destSurface)
1800 CriticalSection cs(this);
1802 TRACE("IDirect3DSurface9 *renderTarget = 0x%0.8p, IDirect3DSurface9 *destSurface = 0x%0.8p", renderTarget, destSurface);
1804 if(!renderTarget || !destSurface)
1806 return INVALIDCALL();
1809 D3DSURFACE_DESC sourceDescription;
1810 D3DSURFACE_DESC destinationDescription;
1812 renderTarget->GetDesc(&sourceDescription);
1813 destSurface->GetDesc(&destinationDescription);
1815 if(sourceDescription.Width != destinationDescription.Width ||
1816 sourceDescription.Height != destinationDescription.Height ||
1817 sourceDescription.Format != destinationDescription.Format ||
1818 sourceDescription.MultiSampleType != D3DMULTISAMPLE_NONE)
1820 return INVALIDCALL();
1823 if(sourceDescription.Format == D3DFMT_A8R8G8B8 ||
1824 sourceDescription.Format == D3DFMT_X8R8G8B8)
1826 sw::Surface *source = static_cast<Direct3DSurface9*>(renderTarget);
1827 sw::Surface *dest = static_cast<Direct3DSurface9*>(destSurface);
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);
1832 static void (__cdecl *blitFunction)(void *dst, void *src);
1833 static sw::Routine *blitRoutine;
1834 static sw::BlitState blitState = {0};
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;
1845 if(memcmp(&blitState, &update, sizeof(sw::BlitState)) != 0)
1850 blitRoutine = sw::FrameBuffer::copyRoutine(blitState);
1851 blitFunction = (void(__cdecl*)(void*, void*))blitRoutine->getEntry();
1854 blitFunction(destBuffer, sourceBuffer);
1856 dest->unlockExternal();
1857 source->unlockExternal();
1861 return UpdateSurface(renderTarget, 0, destSurface, 0);
1867 long Direct3DDevice9::GetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long *value)
1869 CriticalSection cs(this);
1871 TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE type = %d, unsigned long *value = 0x%0.8p", sampler, state, value);
1873 if(!value || state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET) // FIXME: Set *value to 0?
1875 return INVALIDCALL();
1878 if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
1880 return INVALIDCALL();
1883 if(sampler >= D3DVERTEXTEXTURESAMPLER0)
1885 sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
1888 *value = samplerState[sampler][state];
1893 long Direct3DDevice9::GetScissorRect(RECT *rect)
1895 CriticalSection cs(this);
1897 TRACE("RECT *rect = 0x%0.8p", rect);
1901 return INVALIDCALL();
1904 *rect = scissorRect;
1909 int Direct3DDevice9::GetSoftwareVertexProcessing()
1911 CriticalSection cs(this);
1915 return softwareVertexProcessing ? TRUE : FALSE;
1918 long Direct3DDevice9::GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer9 **streamData, unsigned int *offset, unsigned int *stride)
1920 CriticalSection cs(this);
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);
1924 if(streamNumber >= 16 || !streamData || !offset || !stride)
1926 return INVALIDCALL();
1929 *streamData = dataStream[streamNumber];
1931 if(dataStream[streamNumber])
1933 dataStream[streamNumber]->AddRef();
1936 *offset = streamOffset[streamNumber];
1937 *stride = streamStride[streamNumber];
1942 long Direct3DDevice9::GetStreamSourceFreq(unsigned int streamNumber, unsigned int *divider)
1944 CriticalSection cs(this);
1946 TRACE("unsigned int streamNumber = %d, unsigned int *divider = 0x%0.8p", streamNumber, divider);
1948 if(streamNumber >= 16 || !divider)
1950 return INVALIDCALL();
1953 *divider = streamSourceFreq[streamNumber];
1958 long Direct3DDevice9::GetSwapChain(unsigned int index, IDirect3DSwapChain9 **swapChain)
1960 CriticalSection cs(this);
1962 TRACE("unsigned int index = %d, IDirect3DSwapChain9 **swapChain = 0x%0.8p", index, swapChain);
1964 if(!swapChain || index >= GetNumberOfSwapChains())
1966 return INVALIDCALL();
1969 *swapChain = this->swapChain;
1973 (*swapChain)->AddRef();
1979 long Direct3DDevice9::GetTexture(unsigned long sampler, IDirect3DBaseTexture9 **texture)
1981 CriticalSection cs(this);
1983 TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 **texture = 0x%0.8p", sampler, texture);
1987 return INVALIDCALL();
1992 if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
1994 return INVALIDCALL();
1997 *texture = this->texture[sampler];
1999 if(this->texture[sampler])
2001 this->texture[sampler]->AddRef();
2007 long Direct3DDevice9::GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long *value)
2009 CriticalSection cs(this);
2011 TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long *value = 0x%0.8p", stage, type, value);
2015 return INVALIDCALL();
2018 *value = textureStageState[stage][type];
2023 long Direct3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix)
2025 CriticalSection cs(this);
2027 TRACE("D3DTRANSFORMSTATETYPE state = %d, D3DMATRIX *matrix = 0x%0.8p", state, matrix);
2029 if(!matrix || state < 0 || state > 511)
2031 return INVALIDCALL();
2034 *matrix = this->matrix[state];
2039 long Direct3DDevice9::GetVertexDeclaration(IDirect3DVertexDeclaration9 **declaration)
2041 CriticalSection cs(this);
2043 TRACE("IDirect3DVertexDeclaration9 **declaration = 0x%0.8p", declaration);
2047 return INVALIDCALL();
2050 *declaration = vertexDeclaration;
2052 if(vertexDeclaration)
2054 vertexDeclaration->AddRef();
2060 long Direct3DDevice9::GetVertexShader(IDirect3DVertexShader9 **shader)
2062 CriticalSection cs(this);
2064 TRACE("IDirect3DVertexShader9 **shader = 0x%0.8p", shader);
2068 return INVALIDCALL();
2071 *shader = vertexShader;
2075 vertexShader->AddRef();
2081 long Direct3DDevice9::GetVertexShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count)
2083 CriticalSection cs(this);
2085 TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
2089 return INVALIDCALL();
2092 for(unsigned int i = 0; i < count; i++)
2094 constantData[i] = vertexShaderConstantB[startRegister + i];
2100 long Direct3DDevice9::GetVertexShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count)
2102 CriticalSection cs(this);
2104 TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
2108 return INVALIDCALL();
2111 for(unsigned int i = 0; i < count; i++)
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];
2122 long Direct3DDevice9::GetVertexShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count)
2124 CriticalSection cs(this);
2126 TRACE("unsigned int startRegister = %d, int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
2130 return INVALIDCALL();
2133 for(unsigned int i = 0; i < count; i++)
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];
2144 long Direct3DDevice9::GetViewport(D3DVIEWPORT9 *viewport)
2146 CriticalSection cs(this);
2148 TRACE("D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
2152 return INVALIDCALL();
2155 *viewport = this->viewport;
2160 long Direct3DDevice9::LightEnable(unsigned long index, int enable)
2162 CriticalSection cs(this);
2164 TRACE("unsigned long index = %d, int enable = %d", index, enable);
2166 if(!light.exists(index)) // Insert default light
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;
2191 light.Attenuation0 = 0;
2192 light.Attenuation1 = 0;
2193 light.Attenuation2 = 0;
2197 this->light[index] = light;
2198 this->light[index].enable = false;
2203 light[index].enable = (enable != FALSE);
2209 stateRecorder->lightEnable(index, enable);
2215 long Direct3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
2217 CriticalSection cs(this);
2219 TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
2223 return INVALIDCALL();
2226 D3DMATRIX *current = &this->matrix[state];
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);
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);
2241 renderer->setModelMatrix(C * M);
2244 renderer->setViewMatrix(C * M);
2246 case D3DTS_PROJECTION:
2247 renderer->setProjectionMatrix(C * M);
2249 case D3DTS_TEXTURE0:
2250 renderer->setTextureMatrix(0, C * M);
2252 case D3DTS_TEXTURE1:
2253 renderer->setTextureMatrix(1, C * M);
2255 case D3DTS_TEXTURE2:
2256 renderer->setTextureMatrix(2, C * M);
2258 case D3DTS_TEXTURE3:
2259 renderer->setTextureMatrix(3, C * M);
2261 case D3DTS_TEXTURE4:
2262 renderer->setTextureMatrix(4, C * M);
2264 case D3DTS_TEXTURE5:
2265 renderer->setTextureMatrix(5, C * M);
2267 case D3DTS_TEXTURE6:
2268 renderer->setTextureMatrix(6, C * M);
2270 case D3DTS_TEXTURE7:
2271 renderer->setTextureMatrix(7, C * M);
2274 if(state > 256 && state < 512)
2276 renderer->setModelMatrix(C * M, state - 256);
2284 long Direct3DDevice9::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion)
2286 CriticalSection cs(this);
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);
2290 return swapChain->Present(sourceRect, destRect, destWindowOverride, dirtyRegion, 0);
2293 long Direct3DDevice9::ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer9 *destBuffer, IDirect3DVertexDeclaration9 *vertexDeclaration, unsigned long flags)
2295 CriticalSection cs(this);
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);
2301 return INVALIDCALL();
2309 long Direct3DDevice9::Reset(D3DPRESENT_PARAMETERS *presentParameters)
2311 CriticalSection cs(this);
2313 TRACE("D3DPRESENT_PARAMETERS *presentParameters = 0x%0.8p", presentParameters);
2315 if(!presentParameters)
2317 return INVALIDCALL();
2320 deviceWindow = presentParameters->hDeviceWindow;
2324 depthStencil->unbind();
2328 if(autoDepthStencil)
2330 autoDepthStencil->unbind();
2331 autoDepthStencil = 0;
2334 for(int index = 0; index < 4; index++)
2336 if(renderTarget[index])
2338 renderTarget[index]->unbind();
2339 renderTarget[index] = 0;
2345 swapChain = new Direct3DSwapChain9(this, presentParameters);
2350 swapChain->reset(presentParameters);
2353 if(presentParameters->EnableAutoDepthStencil != FALSE)
2355 bool lockable = false;
2357 switch(presentParameters->AutoDepthStencilFormat)
2362 case D3DFMT_D24X4S4:
2371 case D3DFMT_S8_LOCKABLE:
2372 case D3DFMT_D16_LOCKABLE:
2373 case D3DFMT_D32F_LOCKABLE:
2374 case D3DFMT_D32_LOCKABLE:
2381 autoDepthStencil = new Direct3DSurface9(this, this, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->AutoDepthStencilFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, presentParameters->MultiSampleQuality, lockable, D3DUSAGE_DEPTHSTENCIL);
2382 autoDepthStencil->bind();
2384 SetDepthStencilSurface(autoDepthStencil);
2387 IDirect3DSurface9 *renderTarget;
2388 swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &renderTarget);
2389 SetRenderTarget(0, renderTarget);
2390 renderTarget->Release();
2392 SetRenderTarget(1, 0);
2393 SetRenderTarget(2, 0);
2394 SetRenderTarget(3, 0);
2396 softwareVertexProcessing = (behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) == D3DCREATE_SOFTWARE_VERTEXPROCESSING;
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);
2503 for(int i = 0; i < 8; i++)
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);
2525 for(int i = 0; i <= D3DVERTEXTEXTURESAMPLER3; i = (i != 15) ? (i + 1) : D3DVERTEXTEXTURESAMPLER0)
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);
2544 for(int i = 0; i < 6; i++)
2546 float plane[4] = {0, 0, 0, 0};
2548 SetClipPlane(i, plane);
2551 currentPalette = 0xFFFF;
2560 long Direct3DDevice9::SetClipPlane(unsigned long index, const float *plane)
2562 CriticalSection cs(this);
2564 TRACE("unsigned long index = %d, const float *plane = 0x%0.8p", index, plane);
2566 if(!plane || index >= 6)
2568 return INVALIDCALL();
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];
2578 renderer->setClipPlane(index, plane);
2582 stateRecorder->setClipPlane(index, plane);
2588 long Direct3DDevice9::SetClipStatus(const D3DCLIPSTATUS9 *clipStatus)
2590 CriticalSection cs(this);
2592 TRACE("const D3DCLIPSTATUS9 *clipStatus = 0x%0.8p", clipStatus);
2596 return INVALIDCALL();
2599 this->clipStatus = *clipStatus;
2606 long Direct3DDevice9::SetCurrentTexturePalette(unsigned int paletteNumber)
2608 CriticalSection cs(this);
2610 TRACE("unsigned int paletteNumber = %d", paletteNumber);
2612 if(paletteNumber > 0xFFFF || palette.find(paletteNumber) == palette.end())
2614 return INVALIDCALL();
2619 currentPalette = paletteNumber;
2621 sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
2625 stateRecorder->setCurrentTexturePalette(paletteNumber);
2631 void Direct3DDevice9::SetCursorPosition(int x, int y, unsigned long flags)
2633 CriticalSection cs(this);
2635 TRACE("int x = %d, int y = %d, unsigned long flags = 0x%0.8X", x, y, flags);
2637 POINT point = {x, y};
2638 HWND window = deviceWindow ? deviceWindow : focusWindow;
2639 ScreenToClient(window, &point);
2641 sw::FrameBuffer::setCursorPosition(point.x, point.y);
2644 long Direct3DDevice9::SetCursorProperties(unsigned int x0, unsigned int y0, IDirect3DSurface9 *cursorBitmap)
2646 CriticalSection cs(this);
2648 TRACE("unsigned int x0 = %d, unsigned int y0 = %d, IDirect3DSurface9 *cursorBitmap = 0x%0.8p", x0, y0, cursorBitmap);
2652 return INVALIDCALL();
2655 sw::Surface *cursorSurface = static_cast<Direct3DSurface9*>(cursorBitmap);
2657 int width = cursorSurface->getWidth();
2658 int height = cursorSurface->getHeight();
2659 void *bitmap = cursorSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
2662 cursor = sw::Surface::create(0, width, height, 1, sw::FORMAT_A8R8G8B8, false, false);
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();
2668 cursorSurface->unlockExternal();
2672 sw::FrameBuffer::setCursorImage(cursor);
2676 sw::FrameBuffer::setCursorImage(0);
2679 sw::FrameBuffer::setCursorOrigin(x0, y0);
2684 long Direct3DDevice9::SetDepthStencilSurface(IDirect3DSurface9 *iDepthStencil)
2686 CriticalSection cs(this);
2688 TRACE("IDirect3DSurface9 *newDepthStencil = 0x%0.8p", iDepthStencil);
2690 Direct3DSurface9 *depthStencil = static_cast<Direct3DSurface9*>(iDepthStencil);
2692 if(this->depthStencil == depthStencil)
2699 depthStencil->bind();
2702 if(this->depthStencil)
2704 this->depthStencil->unbind();
2707 this->depthStencil = depthStencil;
2709 renderer->setDepthBuffer(depthStencil);
2710 renderer->setStencilBuffer(depthStencil);
2715 long Direct3DDevice9::SetDialogBoxMode(int enableDialogs)
2717 CriticalSection cs(this);
2719 TRACE("int enableDialogs = %d", enableDialogs);
2726 long Direct3DDevice9::SetFVF(unsigned long FVF)
2728 CriticalSection cs(this);
2730 TRACE("unsigned long FVF = 0x%0.8X", FVF);
2734 if(FVF != 0 || !this->vertexDeclaration)
2736 Direct3DVertexDeclaration9 *vertexDeclaration = new Direct3DVertexDeclaration9(this, FVF);
2737 vertexDeclaration->bind();
2739 if(this->vertexDeclaration)
2741 this->vertexDeclaration->unbind();
2744 this->vertexDeclaration = vertexDeclaration;
2749 stateRecorder->setFVF(FVF);
2755 void Direct3DDevice9::SetGammaRamp(unsigned int index, unsigned long flags, const D3DGAMMARAMP *ramp)
2757 CriticalSection cs(this);
2759 TRACE("unsigned int index = %d, unsigned long flags = 0x%0.8X, const D3DGAMMARAMP *ramp = 0x%0.8p", index, flags, ramp);
2761 if(!ramp || index >= GetNumberOfSwapChains())
2766 swapChain->setGammaRamp((sw::GammaRamp*)ramp, flags & D3DSGR_CALIBRATE);
2769 long Direct3DDevice9::SetIndices(IDirect3DIndexBuffer9* iIndexBuffer)
2771 CriticalSection cs(this);
2773 TRACE("IDirect3DIndexBuffer9* indexData = 0x%0.8p", iIndexBuffer);
2775 Direct3DIndexBuffer9 *indexBuffer = static_cast<Direct3DIndexBuffer9*>(iIndexBuffer);
2779 if(this->indexData == indexBuffer)
2786 indexBuffer->bind();
2791 this->indexData->unbind();
2794 this->indexData = indexBuffer;
2798 stateRecorder->setIndices(indexBuffer);
2804 long Direct3DDevice9::SetLight(unsigned long index, const D3DLIGHT9 *light)
2806 CriticalSection cs(this);
2808 TRACE("unsigned long index = %d, const D3DLIGHT9 *light = 0x%0.8p", index, light);
2812 return INVALIDCALL();
2817 this->light[index] = *light;
2823 stateRecorder->setLight(index, light);
2829 long Direct3DDevice9::SetMaterial(const D3DMATERIAL9 *material)
2831 CriticalSection cs(this);
2833 TRACE("const D3DMATERIAL9 *material = 0x%0.8p", material);
2837 return INVALIDCALL(); // FIXME: Correct behaviour?
2842 this->material = *material;
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));
2852 stateRecorder->setMaterial(material);
2858 long Direct3DDevice9::SetNPatchMode(float segments)
2860 CriticalSection cs(this);
2862 TRACE("float segments = %f", segments);
2877 stateRecorder->setNPatchMode(segments);
2883 long Direct3DDevice9::SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries)
2885 CriticalSection cs(this);
2887 TRACE("unsigned int paletteNumber = %d, const PALETTEENTRY *entries = 0x%0.8p", paletteNumber, entries);
2889 if(paletteNumber > 0xFFFF || !entries)
2891 return INVALIDCALL();
2894 for(int i = 0; i < 256; i++)
2896 palette[paletteNumber].entry[i] = entries[i];
2899 if(paletteNumber == currentPalette)
2901 sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
2907 long Direct3DDevice9::SetPixelShader(IDirect3DPixelShader9 *iPixelShader)
2909 CriticalSection cs(this);
2911 TRACE("IDirect3DPixelShader9 *shader = 0x%0.8p", iPixelShader);
2913 Direct3DPixelShader9 *pixelShader = static_cast<Direct3DPixelShader9*>(iPixelShader);
2917 if(this->pixelShader == pixelShader)
2924 pixelShader->bind();
2927 if(this->pixelShader)
2929 this->pixelShader->unbind();
2932 this->pixelShader = pixelShader;
2933 pixelShaderDirty = true;
2937 stateRecorder->setPixelShader(pixelShader);
2943 long Direct3DDevice9::SetPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
2945 CriticalSection cs(this);
2947 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
2951 for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
2953 pixelShaderConstantB[startRegister + i] = constantData[i];
2956 pixelShaderConstantsBDirty = sw::max(startRegister + count, pixelShaderConstantsBDirty);
2957 pixelShaderDirty = true; // Reload DEF constants
2961 stateRecorder->setPixelShaderConstantB(startRegister, constantData, count);
2967 long Direct3DDevice9::SetPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
2969 CriticalSection cs(this);
2971 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
2975 for(unsigned int i = 0; i < count && startRegister + i < MAX_PIXEL_SHADER_CONST; i++)
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];
2983 pixelShaderConstantsFDirty = sw::max(startRegister + count, pixelShaderConstantsFDirty);
2984 pixelShaderDirty = true; // Reload DEF constants
2988 stateRecorder->setPixelShaderConstantF(startRegister, constantData, count);
2994 long Direct3DDevice9::SetPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
2996 CriticalSection cs(this);
2998 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
3002 for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
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];
3010 pixelShaderConstantsIDirty = sw::max(startRegister + count, pixelShaderConstantsIDirty);
3011 pixelShaderDirty = true; // Reload DEF constants
3015 stateRecorder->setPixelShaderConstantI(startRegister, constantData, count);
3021 long Direct3DDevice9::SetRenderState(D3DRENDERSTATETYPE state, unsigned long value)
3023 CriticalSection cs(this);
3025 TRACE("D3DRENDERSTATETYPE state = %d, unsigned long value = %d", state, value);
3027 if(state < D3DRS_ZENABLE || state > D3DRS_BLENDOPALPHA)
3029 return D3D_OK; // FIXME: Warning
3034 if(!init && renderState[state] == value)
3039 renderState[state] = value;
3048 renderer->setDepthBufferEnable(true);
3051 renderer->setDepthBufferEnable(false);
3057 case D3DRS_FILLMODE:
3061 renderer->setFillMode(sw::FILL_VERTEX);
3063 case D3DFILL_WIREFRAME:
3064 renderer->setFillMode(sw::FILL_WIREFRAME);
3067 renderer->setFillMode(sw::FILL_SOLID);
3073 case D3DRS_SHADEMODE:
3077 renderer->setShadingMode(sw::SHADING_FLAT);
3079 case D3DSHADE_GOURAUD:
3080 renderer->setShadingMode(sw::SHADING_GOURAUD);
3082 case D3DSHADE_PHONG:
3088 case D3DRS_ZWRITEENABLE:
3089 renderer->setDepthWriteEnable(value != FALSE);
3091 case D3DRS_ALPHATESTENABLE:
3092 renderer->setAlphaTestEnable(value != FALSE);
3094 case D3DRS_LASTPIXEL:
3095 // if(!init) UNIMPLEMENTED(); // FIXME
3097 case D3DRS_SRCBLEND:
3101 renderer->setSourceBlendFactor(sw::BLEND_ZERO);
3104 renderer->setSourceBlendFactor(sw::BLEND_ONE);
3106 case D3DBLEND_SRCCOLOR:
3107 renderer->setSourceBlendFactor(sw::BLEND_SOURCE);
3109 case D3DBLEND_INVSRCCOLOR:
3110 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCE);
3112 case D3DBLEND_SRCALPHA:
3113 renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
3115 case D3DBLEND_INVSRCALPHA:
3116 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
3118 case D3DBLEND_DESTALPHA:
3119 renderer->setSourceBlendFactor(sw::BLEND_DESTALPHA);
3121 case D3DBLEND_INVDESTALPHA:
3122 renderer->setSourceBlendFactor(sw::BLEND_INVDESTALPHA);
3124 case D3DBLEND_DESTCOLOR:
3125 renderer->setSourceBlendFactor(sw::BLEND_DEST);
3127 case D3DBLEND_INVDESTCOLOR:
3128 renderer->setSourceBlendFactor(sw::BLEND_INVDEST);
3130 case D3DBLEND_SRCALPHASAT:
3131 renderer->setSourceBlendFactor(sw::BLEND_SRCALPHASAT);
3133 case D3DBLEND_BOTHSRCALPHA:
3134 renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
3135 renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
3137 case D3DBLEND_BOTHINVSRCALPHA:
3138 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
3139 renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
3141 case D3DBLEND_BLENDFACTOR:
3142 renderer->setSourceBlendFactor(sw::BLEND_CONSTANT);
3144 case D3DBLEND_INVBLENDFACTOR:
3145 renderer->setSourceBlendFactor(sw::BLEND_INVCONSTANT);
3151 case D3DRS_DESTBLEND:
3155 renderer->setDestBlendFactor(sw::BLEND_ZERO);
3158 renderer->setDestBlendFactor(sw::BLEND_ONE);
3160 case D3DBLEND_SRCCOLOR:
3161 renderer->setDestBlendFactor(sw::BLEND_SOURCE);
3163 case D3DBLEND_INVSRCCOLOR:
3164 renderer->setDestBlendFactor(sw::BLEND_INVSOURCE);
3166 case D3DBLEND_SRCALPHA:
3167 renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
3169 case D3DBLEND_INVSRCALPHA:
3170 renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
3172 case D3DBLEND_DESTALPHA:
3173 renderer->setDestBlendFactor(sw::BLEND_DESTALPHA);
3175 case D3DBLEND_INVDESTALPHA:
3176 renderer->setDestBlendFactor(sw::BLEND_INVDESTALPHA);
3178 case D3DBLEND_DESTCOLOR:
3179 renderer->setDestBlendFactor(sw::BLEND_DEST);
3181 case D3DBLEND_INVDESTCOLOR:
3182 renderer->setDestBlendFactor(sw::BLEND_INVDEST);
3184 case D3DBLEND_SRCALPHASAT:
3185 renderer->setDestBlendFactor(sw::BLEND_SRCALPHASAT);
3187 case D3DBLEND_BOTHSRCALPHA:
3188 renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
3189 renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
3191 case D3DBLEND_BOTHINVSRCALPHA:
3192 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
3193 renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
3195 case D3DBLEND_BLENDFACTOR:
3196 renderer->setDestBlendFactor(sw::BLEND_CONSTANT);
3198 case D3DBLEND_INVBLENDFACTOR:
3199 renderer->setDestBlendFactor(sw::BLEND_INVCONSTANT);
3205 case D3DRS_CULLMODE:
3209 renderer->setCullMode(sw::CULL_NONE);
3212 renderer->setCullMode(sw::CULL_COUNTERCLOCKWISE);
3215 renderer->setCullMode(sw::CULL_CLOCKWISE);
3225 renderer->setDepthCompare(sw::DEPTH_NEVER);
3228 renderer->setDepthCompare(sw::DEPTH_LESS);
3231 renderer->setDepthCompare(sw::DEPTH_EQUAL);
3233 case D3DCMP_LESSEQUAL:
3234 renderer->setDepthCompare(sw::DEPTH_LESSEQUAL);
3236 case D3DCMP_GREATER:
3237 renderer->setDepthCompare(sw::DEPTH_GREATER);
3239 case D3DCMP_NOTEQUAL:
3240 renderer->setDepthCompare(sw::DEPTH_NOTEQUAL);
3242 case D3DCMP_GREATEREQUAL:
3243 renderer->setDepthCompare(sw::DEPTH_GREATEREQUAL);
3246 renderer->setDepthCompare(sw::DEPTH_ALWAYS);
3252 case D3DRS_ALPHAREF:
3253 renderer->setAlphaReference(value & 0x000000FF);
3255 case D3DRS_ALPHAFUNC:
3259 renderer->setAlphaCompare(sw::ALPHA_NEVER);
3262 renderer->setAlphaCompare(sw::ALPHA_LESS);
3265 renderer->setAlphaCompare(sw::ALPHA_EQUAL);
3267 case D3DCMP_LESSEQUAL:
3268 renderer->setAlphaCompare(sw::ALPHA_LESSEQUAL);
3270 case D3DCMP_GREATER:
3271 renderer->setAlphaCompare(sw::ALPHA_GREATER);
3273 case D3DCMP_NOTEQUAL:
3274 renderer->setAlphaCompare(sw::ALPHA_NOTEQUAL);
3276 case D3DCMP_GREATEREQUAL:
3277 renderer->setAlphaCompare(sw::ALPHA_GREATEREQUAL);
3280 renderer->setAlphaCompare(sw::ALPHA_ALWAYS);
3286 case D3DRS_DITHERENABLE:
3287 // if(!init) UNIMPLEMENTED();
3289 case D3DRS_ALPHABLENDENABLE:
3290 renderer->setAlphaBlendEnable(value != FALSE);
3292 case D3DRS_FOGENABLE:
3293 renderer->setFogEnable(value != FALSE);
3295 case D3DRS_FOGCOLOR:
3296 renderer->setFogColor(value);
3298 case D3DRS_FOGTABLEMODE:
3302 renderer->setPixelFogMode(sw::FOG_NONE);
3305 renderer->setPixelFogMode(sw::FOG_LINEAR);
3308 renderer->setPixelFogMode(sw::FOG_EXP);
3311 renderer->setPixelFogMode(sw::FOG_EXP2);
3317 case D3DRS_FOGSTART:
3318 renderer->setFogStart((float&)value);
3321 renderer->setFogEnd((float&)value);
3323 case D3DRS_FOGDENSITY:
3324 renderer->setFogDensity((float&)value);
3326 case D3DRS_RANGEFOGENABLE:
3327 renderer->setRangeFogEnable(value != FALSE);
3329 case D3DRS_SPECULARENABLE:
3330 renderer->setSpecularEnable(value != FALSE);
3332 case D3DRS_STENCILENABLE:
3333 renderer->setStencilEnable(value != FALSE);
3335 case D3DRS_STENCILFAIL:
3338 case D3DSTENCILOP_KEEP:
3339 renderer->setStencilFailOperation(sw::OPERATION_KEEP);
3341 case D3DSTENCILOP_ZERO:
3342 renderer->setStencilFailOperation(sw::OPERATION_ZERO);
3344 case D3DSTENCILOP_REPLACE:
3345 renderer->setStencilFailOperation(sw::OPERATION_REPLACE);
3347 case D3DSTENCILOP_INCRSAT:
3348 renderer->setStencilFailOperation(sw::OPERATION_INCRSAT);
3350 case D3DSTENCILOP_DECRSAT:
3351 renderer->setStencilFailOperation(sw::OPERATION_DECRSAT);
3353 case D3DSTENCILOP_INVERT:
3354 renderer->setStencilFailOperation(sw::OPERATION_INVERT);
3356 case D3DSTENCILOP_INCR:
3357 renderer->setStencilFailOperation(sw::OPERATION_INCR);
3359 case D3DSTENCILOP_DECR:
3360 renderer->setStencilFailOperation(sw::OPERATION_DECR);
3366 case D3DRS_STENCILZFAIL:
3369 case D3DSTENCILOP_KEEP:
3370 renderer->setStencilZFailOperation(sw::OPERATION_KEEP);
3372 case D3DSTENCILOP_ZERO:
3373 renderer->setStencilZFailOperation(sw::OPERATION_ZERO);
3375 case D3DSTENCILOP_REPLACE:
3376 renderer->setStencilZFailOperation(sw::OPERATION_REPLACE);
3378 case D3DSTENCILOP_INCRSAT:
3379 renderer->setStencilZFailOperation(sw::OPERATION_INCRSAT);
3381 case D3DSTENCILOP_DECRSAT:
3382 renderer->setStencilZFailOperation(sw::OPERATION_DECRSAT);
3384 case D3DSTENCILOP_INVERT:
3385 renderer->setStencilZFailOperation(sw::OPERATION_INVERT);
3387 case D3DSTENCILOP_INCR:
3388 renderer->setStencilZFailOperation(sw::OPERATION_INCR);
3390 case D3DSTENCILOP_DECR:
3391 renderer->setStencilZFailOperation(sw::OPERATION_DECR);
3397 case D3DRS_STENCILPASS:
3400 case D3DSTENCILOP_KEEP:
3401 renderer->setStencilPassOperation(sw::OPERATION_KEEP);
3403 case D3DSTENCILOP_ZERO:
3404 renderer->setStencilPassOperation(sw::OPERATION_ZERO);
3406 case D3DSTENCILOP_REPLACE:
3407 renderer->setStencilPassOperation(sw::OPERATION_REPLACE);
3409 case D3DSTENCILOP_INCRSAT:
3410 renderer->setStencilPassOperation(sw::OPERATION_INCRSAT);
3412 case D3DSTENCILOP_DECRSAT:
3413 renderer->setStencilPassOperation(sw::OPERATION_DECRSAT);
3415 case D3DSTENCILOP_INVERT:
3416 renderer->setStencilPassOperation(sw::OPERATION_INVERT);
3418 case D3DSTENCILOP_INCR:
3419 renderer->setStencilPassOperation(sw::OPERATION_INCR);
3421 case D3DSTENCILOP_DECR:
3422 renderer->setStencilPassOperation(sw::OPERATION_DECR);
3428 case D3DRS_STENCILFUNC:
3432 renderer->setStencilCompare(sw::STENCIL_NEVER);
3435 renderer->setStencilCompare(sw::STENCIL_LESS);
3438 renderer->setStencilCompare(sw::STENCIL_EQUAL);
3440 case D3DCMP_LESSEQUAL:
3441 renderer->setStencilCompare(sw::STENCIL_LESSEQUAL);
3443 case D3DCMP_GREATER:
3444 renderer->setStencilCompare(sw::STENCIL_GREATER);
3446 case D3DCMP_NOTEQUAL:
3447 renderer->setStencilCompare(sw::STENCIL_NOTEQUAL);
3449 case D3DCMP_GREATEREQUAL:
3450 renderer->setStencilCompare(sw::STENCIL_GREATEREQUAL);
3453 renderer->setStencilCompare(sw::STENCIL_ALWAYS);
3459 case D3DRS_STENCILREF:
3460 renderer->setStencilReference(value);
3461 renderer->setStencilReferenceCCW(value);
3463 case D3DRS_STENCILMASK:
3464 renderer->setStencilMask(value);
3465 renderer->setStencilMaskCCW(value);
3467 case D3DRS_STENCILWRITEMASK:
3468 renderer->setStencilWriteMask(value);
3469 renderer->setStencilWriteMaskCCW(value);
3471 case D3DRS_TEXTUREFACTOR:
3472 renderer->setTextureFactor(value);
3475 renderer->setTextureWrap(0, value);
3478 renderer->setTextureWrap(1, value);
3481 renderer->setTextureWrap(2, value);
3484 renderer->setTextureWrap(3, value);
3487 renderer->setTextureWrap(4, value);
3490 renderer->setTextureWrap(5, value);
3493 renderer->setTextureWrap(6, value);
3496 renderer->setTextureWrap(7, value);
3498 case D3DRS_CLIPPING:
3499 // Ignored, clipping is always performed
3501 case D3DRS_LIGHTING:
3502 renderer->setLightingEnable(value != FALSE);
3505 renderer->setGlobalAmbient(value);
3507 case D3DRS_FOGVERTEXMODE:
3511 renderer->setVertexFogMode(sw::FOG_NONE);
3514 renderer->setVertexFogMode(sw::FOG_LINEAR);
3517 renderer->setVertexFogMode(sw::FOG_EXP);
3520 renderer->setVertexFogMode(sw::FOG_EXP2);
3526 case D3DRS_COLORVERTEX:
3527 renderer->setColorVertexEnable(value != FALSE);
3529 case D3DRS_LOCALVIEWER:
3530 renderer->setLocalViewer(value != FALSE);
3532 case D3DRS_NORMALIZENORMALS:
3533 renderer->setNormalizeNormals(value != FALSE);
3535 case D3DRS_DIFFUSEMATERIALSOURCE:
3538 case D3DMCS_MATERIAL:
3539 renderer->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
3542 renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
3545 renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR2);
3551 case D3DRS_SPECULARMATERIALSOURCE:
3554 case D3DMCS_MATERIAL:
3555 renderer->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3558 renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR1);
3561 renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR2);
3567 case D3DRS_AMBIENTMATERIALSOURCE:
3570 case D3DMCS_MATERIAL:
3571 renderer->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
3574 renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
3577 renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR2);
3583 case D3DRS_EMISSIVEMATERIALSOURCE:
3586 case D3DMCS_MATERIAL:
3587 renderer->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3590 renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);
3593 renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR2);
3599 case D3DRS_VERTEXBLEND:
3602 case D3DVBF_DISABLE:
3603 renderer->setVertexBlendMatrixCount(0);
3605 case D3DVBF_1WEIGHTS:
3606 renderer->setVertexBlendMatrixCount(2);
3608 case D3DVBF_2WEIGHTS:
3609 renderer->setVertexBlendMatrixCount(3);
3611 case D3DVBF_3WEIGHTS:
3612 renderer->setVertexBlendMatrixCount(4);
3614 case D3DVBF_TWEENING:
3617 case D3DVBF_0WEIGHTS:
3618 renderer->setVertexBlendMatrixCount(1);
3624 case D3DRS_CLIPPLANEENABLE:
3625 renderer->setClipFlags(value);
3627 case D3DRS_POINTSIZE:
3628 if(value == D3DFMT_INST && pixelShaderVersionX >= D3DPS_VERSION(2, 0)) // ATI hack to enable instancing on SM 2.0 hardware
3630 instancingEnabled = true;
3632 else if(value == D3DFMT_A2M1) // ATI hack to enable transparency anti-aliasing
3634 renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
3635 renderer->setAlphaTestEnable(true);
3637 else if(value == D3DFMT_A2M0) // ATI hack to disable transparency anti-aliasing
3639 renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
3640 renderer->setAlphaTestEnable(false);
3644 renderer->setPointSize((float&)value);
3647 case D3DRS_POINTSIZE_MIN:
3648 renderer->setPointSizeMin((float&)value);
3650 case D3DRS_POINTSPRITEENABLE:
3651 renderer->setPointSpriteEnable(value != FALSE);
3653 case D3DRS_POINTSCALEENABLE:
3654 renderer->setPointScaleEnable(value != FALSE);
3656 case D3DRS_POINTSCALE_A:
3657 renderer->setPointScaleA((float&)value);
3659 case D3DRS_POINTSCALE_B:
3660 renderer->setPointScaleB((float&)value);
3662 case D3DRS_POINTSCALE_C:
3663 renderer->setPointScaleC((float&)value);
3665 case D3DRS_MULTISAMPLEANTIALIAS:
3666 // if(!init) UNIMPLEMENTED();
3668 case D3DRS_MULTISAMPLEMASK:
3669 SetRenderTarget(0, renderTarget[0]); // Sets the multi-sample mask, if maskable
3671 case D3DRS_PATCHEDGESTYLE:
3672 if(!init) if(value != D3DPATCHEDGE_DISCRETE) UNIMPLEMENTED();
3674 case D3DRS_DEBUGMONITORTOKEN:
3675 if(!init) UNIMPLEMENTED();
3677 case D3DRS_POINTSIZE_MAX:
3678 renderer->setPointSizeMax((float&)value);
3680 case D3DRS_INDEXEDVERTEXBLENDENABLE:
3681 renderer->setIndexedVertexBlendEnable(value != FALSE);
3683 case D3DRS_COLORWRITEENABLE:
3684 renderer->setColorWriteMask(0, value & 0x0000000F);
3686 case D3DRS_TWEENFACTOR:
3687 if(!init) UNIMPLEMENTED();
3692 case D3DBLENDOP_ADD:
3693 renderer->setBlendOperation(sw::BLENDOP_ADD);
3695 case D3DBLENDOP_SUBTRACT:
3696 renderer->setBlendOperation(sw::BLENDOP_SUB);
3698 case D3DBLENDOP_REVSUBTRACT:
3699 renderer->setBlendOperation(sw::BLENDOP_INVSUB);
3701 case D3DBLENDOP_MIN:
3702 renderer->setBlendOperation(sw::BLENDOP_MIN);
3704 case D3DBLENDOP_MAX:
3705 renderer->setBlendOperation(sw::BLENDOP_MAX);
3711 case D3DRS_POSITIONDEGREE:
3712 if(!init) UNIMPLEMENTED();
3714 case D3DRS_NORMALDEGREE:
3715 if(!init) UNIMPLEMENTED();
3717 case D3DRS_SCISSORTESTENABLE:
3718 scissorEnable = (value != FALSE);
3720 case D3DRS_SLOPESCALEDEPTHBIAS:
3721 renderer->setSlopeDepthBias((float&)value);
3723 case D3DRS_ANTIALIASEDLINEENABLE:
3724 if(!init) if(value != FALSE) UNIMPLEMENTED();
3726 case D3DRS_MINTESSELLATIONLEVEL:
3727 if(!init) UNIMPLEMENTED();
3729 case D3DRS_MAXTESSELLATIONLEVEL:
3730 if(!init) UNIMPLEMENTED();
3732 case D3DRS_ADAPTIVETESS_X:
3733 if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
3735 case D3DRS_ADAPTIVETESS_Y:
3736 if(value == D3DFMT_ATOC) // NVIDIA hack to enable transparency anti-aliasing
3738 renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
3740 else if(value == D3DFMT_UNKNOWN) // NVIDIA hack to disable transparency anti-aliasing
3742 renderer->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
3746 if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
3749 case D3DRS_ADAPTIVETESS_Z:
3750 if(!init) if((float&)value != 1.0f) UNIMPLEMENTED();
3752 case D3DRS_ADAPTIVETESS_W:
3753 if(!init) if((float&)value != 0.0f) UNIMPLEMENTED();
3755 case D3DRS_ENABLEADAPTIVETESSELLATION:
3756 if(!init) UNIMPLEMENTED();
3758 case D3DRS_TWOSIDEDSTENCILMODE:
3759 renderer->setTwoSidedStencil(value != FALSE);
3761 case D3DRS_CCW_STENCILFAIL:
3764 case D3DSTENCILOP_KEEP:
3765 renderer->setStencilFailOperationCCW(sw::OPERATION_KEEP);
3767 case D3DSTENCILOP_ZERO:
3768 renderer->setStencilFailOperationCCW(sw::OPERATION_ZERO);
3770 case D3DSTENCILOP_REPLACE:
3771 renderer->setStencilFailOperationCCW(sw::OPERATION_REPLACE);
3773 case D3DSTENCILOP_INCRSAT:
3774 renderer->setStencilFailOperationCCW(sw::OPERATION_INCRSAT);
3776 case D3DSTENCILOP_DECRSAT:
3777 renderer->setStencilFailOperationCCW(sw::OPERATION_DECRSAT);
3779 case D3DSTENCILOP_INVERT:
3780 renderer->setStencilFailOperationCCW(sw::OPERATION_INVERT);
3782 case D3DSTENCILOP_INCR:
3783 renderer->setStencilFailOperationCCW(sw::OPERATION_INCR);
3785 case D3DSTENCILOP_DECR:
3786 renderer->setStencilFailOperationCCW(sw::OPERATION_DECR);
3792 case D3DRS_CCW_STENCILZFAIL:
3795 case D3DSTENCILOP_KEEP:
3796 renderer->setStencilZFailOperationCCW(sw::OPERATION_KEEP);
3798 case D3DSTENCILOP_ZERO:
3799 renderer->setStencilZFailOperationCCW(sw::OPERATION_ZERO);
3801 case D3DSTENCILOP_REPLACE:
3802 renderer->setStencilZFailOperationCCW(sw::OPERATION_REPLACE);
3804 case D3DSTENCILOP_INCRSAT:
3805 renderer->setStencilZFailOperationCCW(sw::OPERATION_INCRSAT);
3807 case D3DSTENCILOP_DECRSAT:
3808 renderer->setStencilZFailOperationCCW(sw::OPERATION_DECRSAT);
3810 case D3DSTENCILOP_INVERT:
3811 renderer->setStencilZFailOperationCCW(sw::OPERATION_INVERT);
3813 case D3DSTENCILOP_INCR:
3814 renderer->setStencilZFailOperationCCW(sw::OPERATION_INCR);
3816 case D3DSTENCILOP_DECR:
3817 renderer->setStencilZFailOperationCCW(sw::OPERATION_DECR);
3823 case D3DRS_CCW_STENCILPASS:
3826 case D3DSTENCILOP_KEEP:
3827 renderer->setStencilPassOperationCCW(sw::OPERATION_KEEP);
3829 case D3DSTENCILOP_ZERO:
3830 renderer->setStencilPassOperationCCW(sw::OPERATION_ZERO);
3832 case D3DSTENCILOP_REPLACE:
3833 renderer->setStencilPassOperationCCW(sw::OPERATION_REPLACE);
3835 case D3DSTENCILOP_INCRSAT:
3836 renderer->setStencilPassOperationCCW(sw::OPERATION_INCRSAT);
3838 case D3DSTENCILOP_DECRSAT:
3839 renderer->setStencilPassOperationCCW(sw::OPERATION_DECRSAT);
3841 case D3DSTENCILOP_INVERT:
3842 renderer->setStencilPassOperationCCW(sw::OPERATION_INVERT);
3844 case D3DSTENCILOP_INCR:
3845 renderer->setStencilPassOperationCCW(sw::OPERATION_INCR);
3847 case D3DSTENCILOP_DECR:
3848 renderer->setStencilPassOperationCCW(sw::OPERATION_DECR);
3854 case D3DRS_CCW_STENCILFUNC:
3858 renderer->setStencilCompareCCW(sw::STENCIL_NEVER);
3861 renderer->setStencilCompareCCW(sw::STENCIL_LESS);
3864 renderer->setStencilCompareCCW(sw::STENCIL_EQUAL);
3866 case D3DCMP_LESSEQUAL:
3867 renderer->setStencilCompareCCW(sw::STENCIL_LESSEQUAL);
3869 case D3DCMP_GREATER:
3870 renderer->setStencilCompareCCW(sw::STENCIL_GREATER);
3872 case D3DCMP_NOTEQUAL:
3873 renderer->setStencilCompareCCW(sw::STENCIL_NOTEQUAL);
3875 case D3DCMP_GREATEREQUAL:
3876 renderer->setStencilCompareCCW(sw::STENCIL_GREATEREQUAL);
3879 renderer->setStencilCompareCCW(sw::STENCIL_ALWAYS);
3885 case D3DRS_COLORWRITEENABLE1:
3886 renderer->setColorWriteMask(1, value);
3888 case D3DRS_COLORWRITEENABLE2:
3889 renderer->setColorWriteMask(2, value);
3891 case D3DRS_COLORWRITEENABLE3:
3892 renderer->setColorWriteMask(3, value);
3894 case D3DRS_BLENDFACTOR:
3895 renderer->setBlendConstant(sw::Color<float>(value));
3897 case D3DRS_SRGBWRITEENABLE:
3898 renderer->setWriteSRGB(value != FALSE);
3900 case D3DRS_DEPTHBIAS:
3901 renderer->setDepthBias((float&)value);
3904 renderer->setTextureWrap(8, value);
3907 renderer->setTextureWrap(9, value);
3910 renderer->setTextureWrap(10, value);
3913 renderer->setTextureWrap(11, value);
3916 renderer->setTextureWrap(12, value);
3919 renderer->setTextureWrap(13, value);
3922 renderer->setTextureWrap(14, value);
3925 renderer->setTextureWrap(15, value);
3927 case D3DRS_SEPARATEALPHABLENDENABLE:
3928 renderer->setSeparateAlphaBlendEnable(value != FALSE);
3930 case D3DRS_SRCBLENDALPHA:
3934 renderer->setSourceBlendFactorAlpha(sw::BLEND_ZERO);
3937 renderer->setSourceBlendFactorAlpha(sw::BLEND_ONE);
3939 case D3DBLEND_SRCCOLOR:
3940 renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCE);
3942 case D3DBLEND_INVSRCCOLOR:
3943 renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCE);
3945 case D3DBLEND_SRCALPHA:
3946 renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
3948 case D3DBLEND_INVSRCALPHA:
3949 renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
3951 case D3DBLEND_DESTALPHA:
3952 renderer->setSourceBlendFactorAlpha(sw::BLEND_DESTALPHA);
3954 case D3DBLEND_INVDESTALPHA:
3955 renderer->setSourceBlendFactorAlpha(sw::BLEND_INVDESTALPHA);
3957 case D3DBLEND_DESTCOLOR:
3958 renderer->setSourceBlendFactorAlpha(sw::BLEND_DEST);
3960 case D3DBLEND_INVDESTCOLOR:
3961 renderer->setSourceBlendFactorAlpha(sw::BLEND_INVDEST);
3963 case D3DBLEND_SRCALPHASAT:
3964 renderer->setSourceBlendFactorAlpha(sw::BLEND_SRCALPHASAT);
3966 case D3DBLEND_BOTHSRCALPHA:
3967 renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
3968 renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
3970 case D3DBLEND_BOTHINVSRCALPHA:
3971 renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
3972 renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
3974 case D3DBLEND_BLENDFACTOR:
3975 renderer->setSourceBlendFactorAlpha(sw::BLEND_CONSTANT);
3977 case D3DBLEND_INVBLENDFACTOR:
3978 renderer->setSourceBlendFactorAlpha(sw::BLEND_INVCONSTANT);
3984 case D3DRS_DESTBLENDALPHA:
3988 renderer->setDestBlendFactorAlpha(sw::BLEND_ZERO);
3991 renderer->setDestBlendFactorAlpha(sw::BLEND_ONE);
3993 case D3DBLEND_SRCCOLOR:
3994 renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCE);
3996 case D3DBLEND_INVSRCCOLOR:
3997 renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCE);
3999 case D3DBLEND_SRCALPHA:
4000 renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
4002 case D3DBLEND_INVSRCALPHA:
4003 renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
4005 case D3DBLEND_DESTALPHA:
4006 renderer->setDestBlendFactorAlpha(sw::BLEND_DESTALPHA);
4008 case D3DBLEND_INVDESTALPHA:
4009 renderer->setDestBlendFactorAlpha(sw::BLEND_INVDESTALPHA);
4011 case D3DBLEND_DESTCOLOR:
4012 renderer->setDestBlendFactorAlpha(sw::BLEND_DEST);
4014 case D3DBLEND_INVDESTCOLOR:
4015 renderer->setDestBlendFactorAlpha(sw::BLEND_INVDEST);
4017 case D3DBLEND_SRCALPHASAT:
4018 renderer->setDestBlendFactorAlpha(sw::BLEND_SRCALPHASAT);
4020 case D3DBLEND_BOTHSRCALPHA:
4021 renderer->setSourceBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
4022 renderer->setDestBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
4024 case D3DBLEND_BOTHINVSRCALPHA:
4025 renderer->setSourceBlendFactorAlpha(sw::BLEND_INVSOURCEALPHA);
4026 renderer->setDestBlendFactorAlpha(sw::BLEND_SOURCEALPHA);
4028 case D3DBLEND_BLENDFACTOR:
4029 renderer->setDestBlendFactorAlpha(sw::BLEND_CONSTANT);
4031 case D3DBLEND_INVBLENDFACTOR:
4032 renderer->setDestBlendFactorAlpha(sw::BLEND_INVCONSTANT);
4038 case D3DRS_BLENDOPALPHA:
4041 case D3DBLENDOP_ADD:
4042 renderer->setBlendOperationAlpha(sw::BLENDOP_ADD);
4044 case D3DBLENDOP_SUBTRACT:
4045 renderer->setBlendOperationAlpha(sw::BLENDOP_SUB);
4047 case D3DBLENDOP_REVSUBTRACT:
4048 renderer->setBlendOperationAlpha(sw::BLENDOP_INVSUB);
4050 case D3DBLENDOP_MIN:
4051 renderer->setBlendOperationAlpha(sw::BLENDOP_MIN);
4053 case D3DBLENDOP_MAX:
4054 renderer->setBlendOperationAlpha(sw::BLENDOP_MAX);
4064 else // stateRecorder
4066 stateRecorder->setRenderState(state, value);
4072 long Direct3DDevice9::SetRenderTarget(unsigned long index, IDirect3DSurface9 *iRenderTarget)
4074 CriticalSection cs(this);
4076 TRACE("unsigned long index = %d, IDirect3DSurface9 *newRenderTarget = 0x%0.8p", index, iRenderTarget);
4078 // FIXME: Check for D3DUSAGE_RENDERTARGET
4080 if(index >= 4 || (index == 0 && !iRenderTarget))
4082 return INVALIDCALL();
4085 Direct3DSurface9 *renderTarget = static_cast<Direct3DSurface9*>(iRenderTarget);
4089 renderTarget->bind();
4092 if(this->renderTarget[index])
4094 this->renderTarget[index]->unbind();
4097 this->renderTarget[index] = renderTarget;
4099 if(renderTarget && index == 0)
4101 D3DSURFACE_DESC renderTargetDesc;
4102 renderTarget->GetDesc(&renderTargetDesc);
4104 // Reset viewport to size of current render target
4107 viewport.Width = renderTargetDesc.Width;
4108 viewport.Height = renderTargetDesc.Height;
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;
4118 // Set the multi-sample mask, if maskable
4119 if(renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONE &&
4120 renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONMASKABLE)
4122 renderer->setMultiSampleMask(renderState[D3DRS_MULTISAMPLEMASK]);
4126 renderer->setMultiSampleMask(0xFFFFFFFF);
4130 renderer->setRenderTarget(index, renderTarget);
4135 long Direct3DDevice9::SetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long value)
4137 CriticalSection cs(this);
4139 TRACE("unsigned long sampler = %d, D3DSAMPLERSTATETYPE state = %d, unsigned long value = %d", sampler, state, value);
4141 if(state < D3DSAMP_ADDRESSU || state > D3DSAMP_DMAPOFFSET)
4143 return INVALIDCALL();
4146 if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
4148 return INVALIDCALL();
4151 if(sampler >= D3DVERTEXTEXTURESAMPLER0)
4153 sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
4158 if(!init && samplerState[sampler][state] == value)
4163 samplerState[sampler][state] = value;
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
4170 case D3DSAMP_ADDRESSU:
4173 case D3DTADDRESS_WRAP:
4174 renderer->setAddressingModeU(type, index, sw::ADDRESSING_WRAP);
4176 case D3DTADDRESS_MIRROR:
4177 renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRROR);
4179 case D3DTADDRESS_CLAMP:
4180 renderer->setAddressingModeU(type, index, sw::ADDRESSING_CLAMP);
4182 case D3DTADDRESS_BORDER:
4183 renderer->setAddressingModeU(type, index, sw::ADDRESSING_BORDER);
4185 case D3DTADDRESS_MIRRORONCE:
4186 renderer->setAddressingModeU(type, index, sw::ADDRESSING_MIRRORONCE);
4192 case D3DSAMP_ADDRESSV:
4195 case D3DTADDRESS_WRAP:
4196 renderer->setAddressingModeV(type, index, sw::ADDRESSING_WRAP);
4198 case D3DTADDRESS_MIRROR:
4199 renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRROR);
4201 case D3DTADDRESS_CLAMP:
4202 renderer->setAddressingModeV(type, index, sw::ADDRESSING_CLAMP);
4204 case D3DTADDRESS_BORDER:
4205 renderer->setAddressingModeV(type, index, sw::ADDRESSING_BORDER);
4207 case D3DTADDRESS_MIRRORONCE:
4208 renderer->setAddressingModeV(type, index, sw::ADDRESSING_MIRRORONCE);
4214 case D3DSAMP_ADDRESSW:
4217 case D3DTADDRESS_WRAP:
4218 renderer->setAddressingModeW(type, index, sw::ADDRESSING_WRAP);
4220 case D3DTADDRESS_MIRROR:
4221 renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRROR);
4223 case D3DTADDRESS_CLAMP:
4224 renderer->setAddressingModeW(type, index, sw::ADDRESSING_CLAMP);
4226 case D3DTADDRESS_BORDER:
4227 renderer->setAddressingModeW(type, index, sw::ADDRESSING_BORDER);
4229 case D3DTADDRESS_MIRRORONCE:
4230 renderer->setAddressingModeW(type, index, sw::ADDRESSING_MIRRORONCE);
4236 case D3DSAMP_BORDERCOLOR:
4237 renderer->setBorderColor(type, index, value);
4239 case D3DSAMP_MAGFILTER:
4240 // NOTE: SwiftShader does not differentiate between minification and magnification filter
4244 renderer->setTextureFilter(type, index, sw::FILTER_POINT); // FIXME: Only for mipmap filter
4247 renderer->setTextureFilter(type, index, sw::FILTER_POINT);
4249 case D3DTEXF_LINEAR:
4250 renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);
4252 case D3DTEXF_ANISOTROPIC:
4253 renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);
4255 case D3DTEXF_PYRAMIDALQUAD:
4256 renderer->setTextureFilter(type, index, sw::FILTER_LINEAR); // FIXME: Unimplemented, fail silently
4258 case D3DTEXF_GAUSSIANQUAD:
4259 renderer->setTextureFilter(type, index, sw::FILTER_LINEAR); // FIXME: Unimplemented, fail silently
4262 return INVALIDCALL();
4265 case D3DSAMP_MINFILTER:
4266 // NOTE: SwiftShader does not differentiate between minification and magnification filter
4270 renderer->setTextureFilter(type, index, sw::FILTER_POINT); // FIXME: Only for mipmap filter
4273 renderer->setTextureFilter(type, index, sw::FILTER_POINT);
4275 case D3DTEXF_LINEAR:
4276 renderer->setTextureFilter(type, index, sw::FILTER_LINEAR);
4278 case D3DTEXF_ANISOTROPIC:
4279 renderer->setTextureFilter(type, index, sw::FILTER_ANISOTROPIC);
4281 case D3DTEXF_PYRAMIDALQUAD:
4282 renderer->setTextureFilter(type, index, sw::FILTER_LINEAR); // FIXME: Unimplemented, fail silently
4284 case D3DTEXF_GAUSSIANQUAD:
4285 renderer->setTextureFilter(type, index, sw::FILTER_LINEAR); // FIXME: Unimplemented, fail silently
4288 return INVALIDCALL();
4291 case D3DSAMP_MIPFILTER:
4295 renderer->setMipmapFilter(type, index, sw::MIPMAP_NONE);
4298 renderer->setMipmapFilter(type, index, sw::MIPMAP_POINT);
4300 case D3DTEXF_LINEAR:
4301 renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR);
4303 case D3DTEXF_ANISOTROPIC:
4304 renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR); // FIXME: Only for texture filter
4306 case D3DTEXF_PYRAMIDALQUAD:
4307 renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR); // FIXME: Only for texture filter
4309 case D3DTEXF_GAUSSIANQUAD:
4310 renderer->setMipmapFilter(type, index, sw::MIPMAP_LINEAR); // FIXME: Only for texture filter
4313 return INVALIDCALL();
4316 case D3DSAMP_MIPMAPLODBIAS:
4317 if(value == D3DFMT_GET4) // ATI hack to enable Fetch4
4319 renderer->setGatherEnable(type, index, true);
4321 else if(value == D3DFMT_GET1) // ATI hack to disable Fetch4
4323 renderer->setGatherEnable(type, index, false);
4327 float LOD = (float&)value - sw::log2((float)context->renderTarget[0]->getSuperSampleCount()); // FIXME: Update when render target changes
4328 renderer->setMipmapLOD(type, index, LOD);
4331 case D3DSAMP_MAXMIPLEVEL:
4333 case D3DSAMP_MAXANISOTROPY:
4334 renderer->setMaxAnisotropy(type, index, sw::clamp((unsigned int)value, (unsigned int)1, maxAnisotropy));
4336 case D3DSAMP_SRGBTEXTURE:
4337 renderer->setReadSRGB(type, index, value != FALSE);
4339 case D3DSAMP_ELEMENTINDEX:
4340 if(!init) UNIMPLEMENTED(); // Multi-element textures deprecated in favor of multiple render targets
4342 case D3DSAMP_DMAPOFFSET:
4343 // if(!init) UNIMPLEMENTED();
4349 else // stateRecorder
4351 stateRecorder->setSamplerState(sampler, state, value);
4357 long Direct3DDevice9::SetScissorRect(const RECT *rect)
4359 CriticalSection cs(this);
4361 TRACE("const RECT *rect = 0x%0.8p", rect);
4365 return INVALIDCALL();
4370 scissorRect = *rect;
4374 stateRecorder->setScissorRect(rect);
4380 long Direct3DDevice9::SetSoftwareVertexProcessing(int software)
4382 CriticalSection cs(this);
4384 TRACE("int software = %d", software);
4386 if(behaviourFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING && software == FALSE)
4388 return INVALIDCALL();
4391 if(behaviourFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING && software == TRUE)
4393 return INVALIDCALL();
4396 softwareVertexProcessing = (software != FALSE);
4401 long Direct3DDevice9::SetStreamSource(unsigned int stream, IDirect3DVertexBuffer9 *iVertexBuffer, unsigned int offset, unsigned int stride)
4403 CriticalSection cs(this);
4405 TRACE("unsigned int stream = %d, IDirect3DVertexBuffer9 *data = 0x%0.8p, unsigned int offset = %d, unsigned int stride = %d", stream, iVertexBuffer, offset, stride);
4407 Direct3DVertexBuffer9 *vertexBuffer = static_cast<Direct3DVertexBuffer9*>(iVertexBuffer);
4411 if(dataStream[stream] == vertexBuffer && streamOffset[stream] == offset && streamStride[stream] == stride)
4418 vertexBuffer->bind();
4421 if(dataStream[stream])
4423 dataStream[stream]->unbind();
4426 dataStream[stream] = vertexBuffer;
4427 streamOffset[stream] = offset;
4428 streamStride[stream] = stride;
4432 stateRecorder->setStreamSource(stream, vertexBuffer, offset, stride);
4438 long Direct3DDevice9::SetStreamSourceFreq(unsigned int streamNumber, unsigned int divider)
4440 CriticalSection cs(this);
4442 TRACE("unsigned int streamNumber = %d, unsigned int divider = %d", streamNumber, divider);
4444 if(!instancingEnabled)
4446 return INVALIDCALL();
4451 streamSourceFreq[streamNumber] = divider;
4455 stateRecorder->setStreamSourceFreq(streamNumber, divider);
4461 long Direct3DDevice9::SetTexture(unsigned long sampler, IDirect3DBaseTexture9 *iBaseTexture)
4463 CriticalSection cs(this);
4465 TRACE("unsigned long sampler = %d, IDirect3DBaseTexture9 *texture = 0x%0.8p", sampler, iBaseTexture);
4467 if((sampler >= 16 && sampler <= D3DDMAPSAMPLER) || sampler > D3DVERTEXTEXTURESAMPLER3)
4469 return INVALIDCALL();
4472 if(sampler >= D3DVERTEXTEXTURESAMPLER0)
4474 sampler = 16 + (sampler - D3DVERTEXTEXTURESAMPLER0);
4477 Direct3DBaseTexture9 *baseTexture = dynamic_cast<Direct3DBaseTexture9*>(iBaseTexture);
4481 if(texture[sampler] == baseTexture)
4488 baseTexture->bind(); // FIXME: Bind individual sub-surfaces?
4491 if(texture[sampler])
4493 texture[sampler]->unbind();
4496 texture[sampler] = baseTexture;
4500 stateRecorder->setTexture(sampler, baseTexture);
4506 long Direct3DDevice9::SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value)
4508 CriticalSection cs(this);
4510 TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long value = %d", stage, type, value);
4512 if(stage < 0 || stage >= 8 || type < D3DTSS_COLOROP || type > D3DTSS_CONSTANT)
4514 return INVALIDCALL();
4519 if(!init && textureStageState[stage][type] == value)
4524 textureStageState[stage][type] = value;
4528 case D3DTSS_COLOROP:
4531 case D3DTOP_DISABLE:
4532 renderer->setStageOperation(stage, sw::TextureStage::STAGE_DISABLE);
4534 case D3DTOP_SELECTARG1:
4535 renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG1);
4537 case D3DTOP_SELECTARG2:
4538 renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG2);
4540 case D3DTOP_MODULATE:
4541 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE);
4543 case D3DTOP_MODULATE2X:
4544 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE2X);
4546 case D3DTOP_MODULATE4X:
4547 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE4X);
4550 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADD);
4552 case D3DTOP_ADDSIGNED:
4553 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED);
4555 case D3DTOP_ADDSIGNED2X:
4556 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
4558 case D3DTOP_SUBTRACT:
4559 renderer->setStageOperation(stage, sw::TextureStage::STAGE_SUBTRACT);
4561 case D3DTOP_ADDSMOOTH:
4562 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSMOOTH);
4564 case D3DTOP_BLENDDIFFUSEALPHA:
4565 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
4567 case D3DTOP_BLENDTEXTUREALPHA:
4568 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
4570 case D3DTOP_BLENDFACTORALPHA:
4571 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
4573 case D3DTOP_BLENDTEXTUREALPHAPM:
4574 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
4576 case D3DTOP_BLENDCURRENTALPHA:
4577 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
4579 case D3DTOP_PREMODULATE:
4580 renderer->setStageOperation(stage, sw::TextureStage::STAGE_PREMODULATE);
4582 case D3DTOP_MODULATEALPHA_ADDCOLOR:
4583 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
4585 case D3DTOP_MODULATECOLOR_ADDALPHA:
4586 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
4588 case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
4589 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
4591 case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
4592 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
4594 case D3DTOP_BUMPENVMAP:
4595 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAP);
4597 case D3DTOP_BUMPENVMAPLUMINANCE:
4598 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
4600 case D3DTOP_DOTPRODUCT3:
4601 renderer->setStageOperation(stage, sw::TextureStage::STAGE_DOT3);
4603 case D3DTOP_MULTIPLYADD:
4604 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MULTIPLYADD);
4607 renderer->setStageOperation(stage, sw::TextureStage::STAGE_LERP);
4613 case D3DTSS_COLORARG1:
4614 switch(value & D3DTA_SELECTMASK)
4617 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
4620 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CURRENT);
4623 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
4626 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
4628 case D3DTA_SPECULAR:
4629 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
4632 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEMP);
4634 case D3DTA_CONSTANT:
4635 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CONSTANT);
4641 switch(value & ~D3DTA_SELECTMASK)
4644 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_COLOR);
4646 case D3DTA_COMPLEMENT:
4647 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
4649 case D3DTA_ALPHAREPLICATE:
4650 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
4652 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
4653 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
4659 case D3DTSS_COLORARG2:
4660 switch(value & D3DTA_SELECTMASK)
4663 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
4666 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CURRENT);
4669 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
4672 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
4674 case D3DTA_SPECULAR:
4675 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
4678 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEMP);
4680 case D3DTA_CONSTANT:
4681 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CONSTANT);
4687 switch(value & ~D3DTA_SELECTMASK)
4690 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_COLOR);
4692 case D3DTA_COMPLEMENT:
4693 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
4695 case D3DTA_ALPHAREPLICATE:
4696 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
4698 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
4699 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
4705 case D3DTSS_ALPHAOP:
4708 case D3DTOP_DISABLE:
4709 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DISABLE);
4711 case D3DTOP_SELECTARG1:
4712 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG1);
4714 case D3DTOP_SELECTARG2:
4715 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG2);
4717 case D3DTOP_MODULATE:
4718 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE);
4720 case D3DTOP_MODULATE2X:
4721 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE2X);
4723 case D3DTOP_MODULATE4X:
4724 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE4X);
4727 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADD);
4729 case D3DTOP_ADDSIGNED:
4730 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED);
4732 case D3DTOP_ADDSIGNED2X:
4733 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
4735 case D3DTOP_SUBTRACT:
4736 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SUBTRACT);
4738 case D3DTOP_ADDSMOOTH:
4739 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSMOOTH);
4741 case D3DTOP_BLENDDIFFUSEALPHA:
4742 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
4744 case D3DTOP_BLENDTEXTUREALPHA:
4745 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
4747 case D3DTOP_BLENDFACTORALPHA:
4748 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
4750 case D3DTOP_BLENDTEXTUREALPHAPM:
4751 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
4753 case D3DTOP_BLENDCURRENTALPHA:
4754 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
4756 case D3DTOP_PREMODULATE:
4757 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_PREMODULATE);
4759 case D3DTOP_MODULATEALPHA_ADDCOLOR:
4760 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
4762 case D3DTOP_MODULATECOLOR_ADDALPHA:
4763 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
4765 case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
4766 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
4768 case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
4769 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
4771 case D3DTOP_BUMPENVMAP:
4772 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAP);
4774 case D3DTOP_BUMPENVMAPLUMINANCE:
4775 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
4777 case D3DTOP_DOTPRODUCT3:
4778 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DOT3);
4780 case D3DTOP_MULTIPLYADD:
4781 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MULTIPLYADD);
4784 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_LERP);
4790 case D3DTSS_ALPHAARG1:
4791 switch(value & D3DTA_SELECTMASK)
4794 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
4797 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
4800 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
4803 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
4805 case D3DTA_SPECULAR:
4806 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
4809 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
4811 case D3DTA_CONSTANT:
4812 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
4818 switch(value & ~D3DTA_SELECTMASK)
4821 renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
4823 case D3DTA_COMPLEMENT:
4824 renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
4826 case D3DTA_ALPHAREPLICATE:
4827 renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
4829 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
4830 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
4836 case D3DTSS_ALPHAARG2:
4837 switch(value & D3DTA_SELECTMASK)
4840 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
4843 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
4846 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
4849 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
4851 case D3DTA_SPECULAR:
4852 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
4855 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
4857 case D3DTA_CONSTANT:
4858 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
4864 switch(value & ~D3DTA_SELECTMASK)
4867 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
4869 case D3DTA_COMPLEMENT:
4870 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
4872 case D3DTA_ALPHAREPLICATE:
4873 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
4875 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
4876 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
4882 case D3DTSS_BUMPENVMAT00:
4883 renderer->setBumpmapMatrix(stage, 0, (float&)value);
4885 case D3DTSS_BUMPENVMAT01:
4886 renderer->setBumpmapMatrix(stage, 1, (float&)value);
4888 case D3DTSS_BUMPENVMAT10:
4889 renderer->setBumpmapMatrix(stage, 2, (float&)value);
4891 case D3DTSS_BUMPENVMAT11:
4892 renderer->setBumpmapMatrix(stage, 3, (float&)value);
4894 case D3DTSS_TEXCOORDINDEX:
4895 renderer->setTexCoordIndex(stage, value & 0x0000FFFF);
4897 switch(value & 0xFFFF0000)
4899 case D3DTSS_TCI_PASSTHRU:
4900 renderer->setTexGen(stage, sw::TEXGEN_PASSTHRU);
4902 case D3DTSS_TCI_CAMERASPACENORMAL:
4903 renderer->setTexCoordIndex(stage, stage);
4904 renderer->setTexGen(stage, sw::TEXGEN_NORMAL);
4906 case D3DTSS_TCI_CAMERASPACEPOSITION:
4907 renderer->setTexCoordIndex(stage, stage);
4908 renderer->setTexGen(stage, sw::TEXGEN_POSITION);
4910 case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
4911 renderer->setTexCoordIndex(stage, stage);
4912 renderer->setTexGen(stage, sw::TEXGEN_REFLECTION);
4914 case D3DTSS_TCI_SPHEREMAP:
4915 renderer->setTexCoordIndex(stage, stage);
4916 renderer->setTexGen(stage, sw::TEXGEN_SPHEREMAP);
4922 case D3DTSS_BUMPENVLSCALE:
4923 renderer->setLuminanceScale(stage, (float&)value);
4925 case D3DTSS_BUMPENVLOFFSET:
4926 renderer->setLuminanceOffset(stage, (float&)value);
4928 case D3DTSS_TEXTURETRANSFORMFLAGS:
4929 switch(value & ~D3DTTFF_PROJECTED)
4931 case D3DTTFF_DISABLE:
4932 renderer->setTextureTransform(stage, 0, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
4934 case D3DTTFF_COUNT1:
4935 renderer->setTextureTransform(stage, 1, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
4937 case D3DTTFF_COUNT2:
4938 renderer->setTextureTransform(stage, 2, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
4940 case D3DTTFF_COUNT3:
4941 renderer->setTextureTransform(stage, 3, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
4943 case D3DTTFF_COUNT4:
4944 renderer->setTextureTransform(stage, 4, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
4950 case D3DTSS_COLORARG0:
4951 switch(value & D3DTA_SELECTMASK)
4954 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_CURRENT);
4957 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
4959 case D3DTA_SPECULAR:
4960 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
4963 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEMP);
4966 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
4969 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
4975 switch(value & ~D3DTA_SELECTMASK)
4978 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_COLOR);
4980 case D3DTA_COMPLEMENT:
4981 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
4983 case D3DTA_ALPHAREPLICATE:
4984 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
4986 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
4987 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
4993 case D3DTSS_ALPHAARG0:
4994 switch(value & D3DTA_SELECTMASK)
4997 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
5000 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
5003 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
5006 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
5008 case D3DTA_SPECULAR:
5009 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
5012 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
5014 case D3DTA_CONSTANT:
5015 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CONSTANT);
5021 switch(value & ~D3DTA_SELECTMASK)
5024 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
5026 case D3DTA_COMPLEMENT:
5027 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
5029 case D3DTA_ALPHAREPLICATE:
5030 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
5032 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
5033 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
5039 case D3DTSS_RESULTARG:
5040 switch(value & D3DTA_SELECTMASK)
5043 renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_CURRENT);
5046 renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_TEMP);
5052 case D3DTSS_CONSTANT:
5053 renderer->setConstantColor(stage, value);
5059 else // stateRecorder
5061 stateRecorder->setTextureStageState(stage, type, value);
5067 long Direct3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
5069 CriticalSection cs(this);
5071 TRACE("D3DTRANSFORMSTATETYPE state = %d, const D3DMATRIX *matrix = 0x%0.8p", state, matrix);
5075 return INVALIDCALL();
5080 this->matrix[state] = *matrix;
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);
5090 renderer->setModelMatrix(M);
5093 renderer->setViewMatrix(M);
5095 case D3DTS_PROJECTION:
5096 renderer->setProjectionMatrix(M);
5098 case D3DTS_TEXTURE0:
5099 renderer->setTextureMatrix(0, M);
5101 case D3DTS_TEXTURE1:
5102 renderer->setTextureMatrix(1, M);
5104 case D3DTS_TEXTURE2:
5105 renderer->setTextureMatrix(2, M);
5107 case D3DTS_TEXTURE3:
5108 renderer->setTextureMatrix(3, M);
5110 case D3DTS_TEXTURE4:
5111 renderer->setTextureMatrix(4, M);
5113 case D3DTS_TEXTURE5:
5114 renderer->setTextureMatrix(5, M);
5116 case D3DTS_TEXTURE6:
5117 renderer->setTextureMatrix(6, M);
5119 case D3DTS_TEXTURE7:
5120 renderer->setTextureMatrix(7, M);
5123 if(state > 256 && state < 512)
5125 renderer->setModelMatrix(M, state - 256);
5130 else // stateRecorder
5132 stateRecorder->setTransform(state, matrix);
5138 long Direct3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9 *iVertexDeclaration)
5140 CriticalSection cs(this);
5142 TRACE("IDirect3DVertexDeclaration9 *declaration = 0x%0.8p", iVertexDeclaration);
5144 Direct3DVertexDeclaration9 *vertexDeclaration = static_cast<Direct3DVertexDeclaration9*>(iVertexDeclaration);
5148 if(this->vertexDeclaration == vertexDeclaration)
5153 if(vertexDeclaration)
5155 vertexDeclaration->bind();
5158 if(this->vertexDeclaration)
5160 this->vertexDeclaration->unbind();
5163 this->vertexDeclaration = vertexDeclaration;
5167 stateRecorder->setVertexDeclaration(vertexDeclaration);
5173 long Direct3DDevice9::SetVertexShader(IDirect3DVertexShader9 *iVertexShader)
5175 CriticalSection cs(this);
5177 TRACE("IDirect3DVertexShader9 *shader = 0x%0.8p", iVertexShader);
5179 Direct3DVertexShader9 *vertexShader = static_cast<Direct3DVertexShader9*>(iVertexShader);
5183 if(this->vertexShader == vertexShader)
5190 vertexShader->bind();
5193 if(this->vertexShader)
5195 this->vertexShader->unbind();
5198 this->vertexShader = vertexShader;
5199 vertexShaderDirty = true;
5203 stateRecorder->setVertexShader(vertexShader);
5209 long Direct3DDevice9::SetVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
5211 CriticalSection cs(this);
5213 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
5217 return INVALIDCALL();
5222 for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
5224 vertexShaderConstantB[startRegister + i] = constantData[i];
5227 vertexShaderConstantsBDirty = sw::max(startRegister + count, vertexShaderConstantsBDirty);
5228 vertexShaderDirty = true; // Reload DEF constants
5232 stateRecorder->setVertexShaderConstantB(startRegister, constantData, count);
5238 long Direct3DDevice9::SetVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
5240 CriticalSection cs(this);
5242 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
5246 return INVALIDCALL();
5251 for(unsigned int i = 0; i < count && startRegister + i < MAX_VERTEX_SHADER_CONST; i++)
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];
5259 vertexShaderConstantsFDirty = sw::max(startRegister + count, vertexShaderConstantsFDirty);
5260 vertexShaderDirty = true; // Reload DEF constants
5264 stateRecorder->setVertexShaderConstantF(startRegister, constantData, count);
5270 long Direct3DDevice9::SetVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
5272 CriticalSection cs(this);
5274 TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
5278 return INVALIDCALL();
5283 for(unsigned int i = 0; i < count && startRegister + i < 16; i++)
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];
5291 vertexShaderConstantsIDirty = sw::max(startRegister + count, vertexShaderConstantsIDirty);
5292 vertexShaderDirty = true; // Reload DEF constants
5296 stateRecorder->setVertexShaderConstantI(startRegister, constantData, count);
5302 long Direct3DDevice9::SetViewport(const D3DVIEWPORT9 *viewport)
5304 CriticalSection cs(this);
5306 TRACE("const D3DVIEWPORT9 *viewport = 0x%0.8p", viewport);
5308 if(!viewport) // FIXME: Check if valid
5310 return INVALIDCALL();
5315 this->viewport = *viewport;
5319 stateRecorder->setViewport(viewport);
5325 int Direct3DDevice9::ShowCursor(int show)
5327 CriticalSection cs(this);
5329 TRACE("int show = %d", show);
5331 int oldValue = showCursor ? TRUE : FALSE;
5332 showCursor = show != FALSE;
5336 sw::FrameBuffer::setCursorImage(cursor);
5340 sw::FrameBuffer::setCursorImage(0);
5346 long Direct3DDevice9::StretchRect(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)
5348 CriticalSection cs(this);
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);
5352 if(!sourceSurface || !destSurface || !validRectangle(sourceRect, sourceSurface) || !validRectangle(destRect, destSurface))
5354 return INVALIDCALL();
5357 D3DSURFACE_DESC sourceDescription;
5358 D3DSURFACE_DESC destDescription;
5360 sourceSurface->GetDesc(&sourceDescription);
5361 destSurface->GetDesc(&destDescription);
5363 if(sourceDescription.Pool != D3DPOOL_DEFAULT || destDescription.Pool != D3DPOOL_DEFAULT)
5365 return INVALIDCALL();
5368 Direct3DSurface9 *source = static_cast<Direct3DSurface9*>(sourceSurface);
5369 Direct3DSurface9 *dest = static_cast<Direct3DSurface9*>(destSurface);
5371 stretchRect(source, sourceRect, dest, destRect, filter);
5376 long Direct3DDevice9::TestCooperativeLevel()
5378 CriticalSection cs(this);
5385 long Direct3DDevice9::UpdateSurface(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destinationSurface, const POINT *destPoint)
5387 CriticalSection cs(this);
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);
5391 if(!sourceSurface || !destinationSurface)
5393 return INVALIDCALL();
5396 D3DSURFACE_DESC sourceDescription;
5397 D3DSURFACE_DESC destinationDescription;
5399 sourceSurface->GetDesc(&sourceDescription);
5400 destinationSurface->GetDesc(&destinationDescription);
5407 sRect.left = sourceRect->left;
5408 sRect.top = sourceRect->top;
5409 sRect.right = sourceRect->right;
5410 sRect.bottom = sourceRect->bottom;
5416 sRect.right = sourceDescription.Width;
5417 sRect.bottom = sourceDescription.Height;
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;
5431 dRect.right = sRect.right - sRect.left;
5432 dRect.bottom = sRect.bottom - sRect.top;
5435 if(!validRectangle(&sRect, sourceSurface) || !validRectangle(&dRect, destinationSurface))
5437 return INVALIDCALL();
5440 int sWidth = sRect.right - sRect.left;
5441 int sHeight = sRect.bottom - sRect.top;
5443 int dWidth = dRect.right - dRect.left;
5444 int dHeight = dRect.bottom - dRect.top;
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)
5452 return INVALIDCALL();
5455 sw::Surface *source = static_cast<Direct3DSurface9*>(sourceSurface);
5456 sw::Surface *dest = static_cast<Direct3DSurface9*>(destinationSurface);
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();
5464 unsigned int height;
5467 switch(sourceDescription.Format)
5471 width = (dWidth + 3) / 4;
5472 height = (dHeight + 3) / 4;
5473 bytes = width * 8; // 64 bit per 4x4 block
5480 width = (dWidth + 3) / 4;
5481 height = (dHeight + 3) / 4;
5482 bytes = width * 16; // 128 bit per 4x4 block
5487 bytes = width * Direct3DSurface9::bytes(sourceDescription.Format);
5490 if(sourceDescription.Format == D3DFMT_ATI1 || sourceDescription.Format == D3DFMT_ATI2)
5492 // Make the pitch correspond to 4 rows
5497 for(unsigned int y = 0; y < height; y++)
5499 memcpy(dBuffer, sBuffer, bytes);
5505 source->unlockExternal();
5506 dest->unlockExternal();
5511 long Direct3DDevice9::UpdateTexture(IDirect3DBaseTexture9 *sourceTexture, IDirect3DBaseTexture9 *destinationTexture)
5513 CriticalSection cs(this);
5515 TRACE("IDirect3DBaseTexture9 *sourceTexture = 0x%0.8p, IDirect3DBaseTexture9 *destinationTexture = 0x%0.8p", sourceTexture, destinationTexture);
5517 if(!sourceTexture || !destinationTexture)
5519 return INVALIDCALL();
5522 // FIXME: Check memory pools
5524 D3DRESOURCETYPE type = sourceTexture->GetType();
5526 if(type != destinationTexture->GetType())
5528 return INVALIDCALL();
5533 case D3DRTYPE_TEXTURE:
5535 IDirect3DTexture9 *source;
5536 IDirect3DTexture9 *dest;
5538 sourceTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&source);
5539 destinationTexture->QueryInterface(IID_IDirect3DTexture9, (void**)&dest);
5541 ASSERT(source && dest);
5543 for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++) // FIXME: Fail when source texture has fewer levels than the destination
5545 IDirect3DSurface9 *sourceSurface;
5546 IDirect3DSurface9 *destinationSurface;
5548 source->GetSurfaceLevel(level, &sourceSurface);
5549 dest->GetSurfaceLevel(level, &destinationSurface);
5551 UpdateSurface(sourceSurface, 0, destinationSurface, 0);
5553 sourceSurface->Release();
5554 destinationSurface->Release();
5561 case D3DRTYPE_VOLUMETEXTURE:
5563 IDirect3DVolumeTexture9 *source;
5564 IDirect3DVolumeTexture9 *dest;
5566 sourceTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&source);
5567 destinationTexture->QueryInterface(IID_IDirect3DVolumeTexture9, (void**)&dest);
5569 ASSERT(source && dest);
5571 for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++) // FIXME: Fail when source texture has fewer levels than the destination
5573 IDirect3DVolume9 *sourceVolume;
5574 IDirect3DVolume9 *destinationVolume;
5576 source->GetVolumeLevel(level, &sourceVolume);
5577 dest->GetVolumeLevel(level, &destinationVolume);
5579 updateVolume(sourceVolume, destinationVolume);
5581 sourceVolume->Release();
5582 destinationVolume->Release();
5589 case D3DRTYPE_CUBETEXTURE:
5591 IDirect3DCubeTexture9 *source;
5592 IDirect3DCubeTexture9 *dest;
5594 sourceTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&source);
5595 destinationTexture->QueryInterface(IID_IDirect3DCubeTexture9, (void**)&dest);
5597 ASSERT(source && dest);
5599 for(int face = 0; face < 6; face++)
5601 for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++) // FIXME: Fail when source texture has fewer levels than the destination
5603 IDirect3DSurface9 *sourceSurface;
5604 IDirect3DSurface9 *destinationSurface;
5606 source->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &sourceSurface);
5607 dest->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &destinationSurface);
5609 UpdateSurface(sourceSurface, 0, destinationSurface, 0);
5611 sourceSurface->Release();
5612 destinationSurface->Release();
5627 long Direct3DDevice9::ValidateDevice(unsigned long *numPasses)
5629 CriticalSection cs(this);
5631 TRACE("unsigned long *numPasses = 0x%0.8p", numPasses);
5635 return INVALIDCALL();
5643 long Direct3DDevice9::getAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode)
5645 return d3d9->GetAdapterDisplayMode(adapter, mode);
5648 int Direct3DDevice9::typeStride(unsigned char streamType)
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.
5672 return LUT[streamType];
5675 bool Direct3DDevice9::instanceData()
5677 ASSERT(vertexDeclaration);
5679 D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];
5680 unsigned int numElements;
5681 vertexDeclaration->GetDeclaration(vertexElement, &numElements);
5683 bool instanceData = false;
5685 for(unsigned int i = 0; i < numElements - 1; i++)
5687 unsigned short stream = vertexElement[i].Stream;
5691 instanceData = instanceData || (streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA) != 0;
5695 return instanceData;
5698 bool Direct3DDevice9::bindResources(Direct3DIndexBuffer9 *indexBuffer)
5702 return false; // Zero-area target region
5706 bindIndexBuffer(indexBuffer);
5707 bindShaderConstants();
5713 void Direct3DDevice9::bindVertexStreams(int base, bool instancing, int instance)
5715 ASSERT(vertexDeclaration);
5717 renderer->resetInputStreams(vertexDeclaration->isPreTransformed());
5719 D3DVERTEXELEMENT9 vertexElement[MAXD3DDECLLENGTH + 1];
5720 unsigned int numElements;
5721 vertexDeclaration->GetDeclaration(vertexElement, &numElements);
5723 // Bind vertex data streams
5724 for(unsigned int i = 0; i < numElements - 1; i++)
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;
5733 ASSERT(method == D3DDECLMETHOD_DEFAULT); // FIXME: Unimplemented
5735 if(!dataStream[stream])
5740 Direct3DVertexBuffer9 *streamBuffer = dataStream[stream];
5741 sw::Resource *resource = streamBuffer->getResource();
5742 const void *buffer = ((char*)resource->data() + streamOffset[stream]) + offset;
5744 int stride = streamStride[stream];
5746 if(instancing && streamSourceFreq[stream] & D3DSTREAMSOURCE_INSTANCEDATA)
5748 int instanceFrequency = streamSourceFreq[stream] & ~D3DSTREAMSOURCE_INSTANCEDATA;
5749 buffer = (char*)buffer + stride * (instance / instanceFrequency);
5755 buffer = (char*)buffer + stride * base;
5758 sw::Stream attribute(resource, buffer, stride);
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;
5786 const sw::VertexShader *shader = vertexShader->getVertexShader();
5788 if(!vertexDeclaration->isPreTransformed())
5790 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
5792 const sw::Shader::Semantic& input = shader->getInput(i);
5793 if((usage == input.usage) && (index == input.index))
5795 renderer->setInputStream(i, attribute);
5801 else // Bind directly to the output
5803 for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
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))
5809 renderer->setInputStream(i, attribute);
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;
5841 void Direct3DDevice9::bindIndexBuffer(Direct3DIndexBuffer9 *indexBuffer)
5843 sw::Resource *resource = 0;
5847 resource = indexBuffer->getResource();
5850 renderer->setIndexBuffer(resource);
5853 void Direct3DDevice9::bindShaderConstants()
5855 if(pixelShaderDirty)
5859 if(pixelShaderConstantsBDirty)
5861 renderer->setPixelShaderConstantB(0, pixelShaderConstantB, pixelShaderConstantsBDirty);
5864 if(pixelShaderConstantsFDirty)
5866 renderer->setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty);
5869 if(pixelShaderConstantsIDirty)
5871 renderer->setPixelShaderConstantI(0, pixelShaderConstantI[0], pixelShaderConstantsIDirty);
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
5881 renderer->setPixelShader(0);
5884 pixelShaderDirty = false;
5887 if(vertexShaderDirty)
5891 if(vertexShaderConstantsBDirty)
5893 renderer->setVertexShaderConstantB(0, vertexShaderConstantB, vertexShaderConstantsBDirty);
5896 if(vertexShaderConstantsFDirty)
5898 renderer->setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty);
5901 if(vertexShaderConstantsIDirty)
5903 renderer->setVertexShaderConstantI(0, vertexShaderConstantI[0], vertexShaderConstantsIDirty);
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
5913 renderer->setVertexShader(0);
5916 vertexShaderDirty = false;
5920 void Direct3DDevice9::bindLights()
5922 if(!lightsDirty) return;
5924 Lights::iterator i = light.begin();
5927 // Set and enable renderer lights
5930 while(i != light.end() && !i->second.enable)
5935 if(i == light.end())
5940 const Light &l = i->second;
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);
5948 renderer->setLightDiffuse(active, diffuse);
5949 renderer->setLightSpecular(active, specular);
5950 renderer->setLightAmbient(active, ambient);
5952 if(l.Type == D3DLIGHT_DIRECTIONAL)
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);
5959 else if(l.Type == D3DLIGHT_SPOT)
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);
5968 renderer->setLightPosition(active, position);
5969 renderer->setLightRange(active, l.Range);
5970 renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);
5973 renderer->setLightEnable(active, true);
5979 // Remaining lights are disabled
5982 renderer->setLightEnable(active, false);
5987 lightsDirty = false;
5990 bool Direct3DDevice9::bindViewport()
5992 if(viewport.Width <= 0 || viewport.Height <= 0)
5999 if(scissorRect.left >= scissorRect.right || scissorRect.top >= scissorRect.bottom)
6005 scissor.x0 = scissorRect.left;
6006 scissor.x1 = scissorRect.right;
6007 scissor.y0 = scissorRect.top;
6008 scissor.y1 = scissorRect.bottom;
6010 renderer->setScissor(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;
6020 renderer->setScissor(scissor);
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;
6031 renderer->setViewport(view);
6036 void Direct3DDevice9::bindTextures()
6038 for(int sampler = 0; sampler < 16 + 4; sampler++)
6040 Direct3DBaseTexture9 *baseTexture = texture[sampler];
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
6045 bool textureUsed = false;
6047 if(type == sw::SAMPLER_PIXEL && pixelShader)
6049 textureUsed = pixelShader->getPixelShader()->usesSampler(index);
6051 else if(type == sw::SAMPLER_VERTEX && vertexShader)
6053 textureUsed = vertexShader->getVertexShader()->usesSampler(index);
6057 textureUsed = true; // FIXME: Check fixed-function use?
6060 sw::Resource *resource = 0;
6062 if(baseTexture && textureUsed)
6064 resource = baseTexture->getResource();
6067 renderer->setTextureResource(sampler, resource);
6069 if(baseTexture && textureUsed)
6071 baseTexture->GenerateMipSubLevels();
6074 if(baseTexture && textureUsed)
6076 int levelCount = baseTexture->getInternalLevelCount();
6078 int textureLOD = baseTexture->GetLOD();
6079 int samplerLOD = samplerState[sampler][D3DSAMP_MAXMIPLEVEL];
6080 int LOD = textureLOD > samplerLOD ? textureLOD : samplerLOD;
6082 if(samplerState[sampler][D3DSAMP_MIPFILTER] == D3DTEXF_NONE)
6087 switch(baseTexture->GetType())
6089 case D3DRTYPE_TEXTURE:
6091 Direct3DTexture9 *texture = dynamic_cast<Direct3DTexture9*>(baseTexture);
6092 Direct3DSurface9 *surface;
6094 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
6096 int surfaceLevel = mipmapLevel;
6098 if(surfaceLevel < LOD)
6103 if(surfaceLevel < 0)
6107 else if(surfaceLevel >= levelCount)
6109 surfaceLevel = levelCount - 1;
6112 surface = texture->getInternalSurfaceLevel(surfaceLevel);
6113 renderer->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
6117 case D3DRTYPE_CUBETEXTURE:
6118 for(int face = 0; face < 6; face++)
6120 Direct3DCubeTexture9 *cubeTexture = dynamic_cast<Direct3DCubeTexture9*>(baseTexture);
6121 Direct3DSurface9 *surface;
6123 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
6125 int surfaceLevel = mipmapLevel;
6127 if(surfaceLevel < LOD)
6132 if(surfaceLevel < 0)
6136 else if(surfaceLevel >= levelCount)
6138 surfaceLevel = levelCount - 1;
6141 surface = cubeTexture->getInternalCubeMapSurface((D3DCUBEMAP_FACES)face, surfaceLevel);
6142 renderer->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
6146 case D3DRTYPE_VOLUMETEXTURE:
6148 Direct3DVolumeTexture9 *volumeTexture = dynamic_cast<Direct3DVolumeTexture9*>(baseTexture);
6149 Direct3DVolume9 *volume;
6151 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
6153 int surfaceLevel = mipmapLevel;
6155 if(surfaceLevel < LOD)
6160 if(surfaceLevel < 0)
6164 else if(surfaceLevel >= levelCount)
6166 surfaceLevel = levelCount - 1;
6169 volume = volumeTexture->getInternalVolumeLevel(surfaceLevel);
6170 renderer->setTextureLevel(sampler, 0, mipmapLevel, volume, sw::TEXTURE_3D);
6180 renderer->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
6185 bool Direct3DDevice9::isRecording() const
6187 return stateRecorder != 0;
6190 void Direct3DDevice9::setOcclusionEnabled(bool enable)
6192 renderer->setOcclusionEnabled(enable);
6195 void Direct3DDevice9::removeQuery(sw::Query *query)
6197 renderer->removeQuery(query);
6200 void Direct3DDevice9::addQuery(sw::Query *query)
6202 renderer->addQuery(query);
6205 void Direct3DDevice9::stretchRect(Direct3DSurface9 *source, const RECT *sourceRect, Direct3DSurface9 *dest, const RECT *destRect, D3DTEXTUREFILTERTYPE filter)
6207 D3DSURFACE_DESC sourceDescription;
6208 D3DSURFACE_DESC destDescription;
6210 source->GetDesc(&sourceDescription);
6211 dest->GetDesc(&destDescription);
6213 int sWidth = source->getWidth();
6214 int sHeight = source->getHeight();
6215 int dWidth = dest->getWidth();
6216 int dHeight = dest->getHeight();
6218 sw::Rect sRect(0, 0, sWidth, sHeight);
6219 sw::Rect dRect(0, 0, dWidth, dHeight);
6223 sRect.x0 = sourceRect->left;
6224 sRect.y0 = sourceRect->top;
6225 sRect.x1 = sourceRect->right;
6226 sRect.y1 = sourceRect->bottom;
6231 dRect.x0 = destRect->left;
6232 dRect.y0 = destRect->top;
6233 dRect.x1 = destRect->right;
6234 dRect.y1 = destRect->bottom;
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;
6242 if((sourceDescription.Format == D3DFMT_A8R8G8B8 && destDescription.Format == D3DFMT_X8R8G8B8) ||
6243 (sourceDescription.Format == D3DFMT_X8R8G8B8 && destDescription.Format == D3DFMT_A8R8G8B8))
6245 equalFormats = true;
6249 if(depthStencil) // Copy entirely, internally // FIXME: Check
6251 if(source->hasDepth())
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);
6256 unsigned int width = source->getWidth();
6257 unsigned int height = source->getHeight();
6258 unsigned int pitch = source->getInternalPitchB();
6260 for(unsigned int y = 0; y < height; y++)
6262 memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes
6264 sourceBuffer += pitch;
6265 destBuffer += pitch;
6268 source->unlockInternal();
6269 dest->unlockInternal();
6272 if(source->hasStencil())
6274 byte *sourceBuffer = (byte*)source->lockStencil(0, 0, 0, sw::PUBLIC);
6275 byte *destBuffer = (byte*)dest->lockStencil(0, 0, 0, sw::PUBLIC);
6277 unsigned int width = source->getWidth();
6278 unsigned int height = source->getHeight();
6279 unsigned int pitch = source->getStencilPitchB();
6281 for(unsigned int y = 0; y < height; y++)
6283 memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes
6285 sourceBuffer += pitch;
6286 destBuffer += pitch;
6289 source->unlockStencil();
6290 dest->unlockStencil();
6293 else if(!scaling && equalFormats)
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();
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());
6304 for(unsigned int y = 0; y < height; y++)
6306 memcpy(destBytes, sourceBytes, bytes);
6310 for(unsigned int x = 0; x < width; x++)
6312 destBytes[4 * x + 3] = 0xFF;
6316 sourceBytes += sourcePitch;
6317 destBytes += destPitch;
6320 source->unlockInternal();
6321 dest->unlockInternal();
6325 renderer->blit(source, sRect, dest, dRect, filter >= D3DTEXF_LINEAR);
6329 long Direct3DDevice9::updateVolume(IDirect3DVolume9 *sourceVolume, IDirect3DVolume9 *destinationVolume)
6331 TRACE("IDirect3DVolume9 *sourceVolume = 0x%0.8p, IDirect3DVolume9 *destinationVolume = 0x%0.8p", sourceVolume, destinationVolume);
6333 if(!sourceVolume || !destinationVolume)
6335 return INVALIDCALL();
6338 D3DVOLUME_DESC sourceDescription;
6339 D3DVOLUME_DESC destinationDescription;
6341 sourceVolume->GetDesc(&sourceDescription);
6342 destinationVolume->GetDesc(&destinationDescription);
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)
6351 return INVALIDCALL();
6354 sw::Surface *source = static_cast<Direct3DVolume9*>(sourceVolume);
6355 sw::Surface *dest = static_cast<Direct3DVolume9*>(destinationVolume);
6357 if(source->getExternalPitchB() != dest->getExternalPitchB() ||
6358 source->getExternalSliceB() != dest->getExternalSliceB())
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);
6366 memcpy(dBuffer, sBuffer, source->getExternalSliceB() * sourceDescription.Depth);
6368 source->unlockExternal();
6369 dest->unlockExternal();
6374 bool Direct3DDevice9::validRectangle(const RECT *rect, IDirect3DSurface9 *surface)
6381 if(rect->right <= rect->left || rect->bottom <= rect->top)
6386 if(rect->left < 0 || rect->top < 0)
6391 D3DSURFACE_DESC description;
6392 surface->GetDesc(&description);
6394 if(rect->right > (int)description.Width || rect->bottom > (int)description.Height)
6402 void Direct3DDevice9::configureFPU()
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