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 "Direct3DDevice8.hpp"
17 #include "Direct3D8.hpp"
18 #include "Direct3DSurface8.hpp"
19 #include "Direct3DIndexBuffer8.hpp"
20 #include "Direct3DVertexBuffer8.hpp"
21 #include "Direct3DTexture8.hpp"
22 #include "Direct3DVolumeTexture8.hpp"
23 #include "Direct3DCubeTexture8.hpp"
24 #include "Direct3DSwapChain8.hpp"
25 #include "Direct3DPixelShader8.hpp"
26 #include "Direct3DVertexShader8.hpp"
27 #include "Direct3DVolume8.hpp"
30 #include "Capabilities.hpp"
31 #include "Renderer.hpp"
33 #include "FrameBuffer.hpp"
34 #include "Clipper.hpp"
35 #include "Configurator.hpp"
37 #include "Resource.hpp"
41 bool localShaderConstants = false;
45 inline unsigned long FtoDW(float f) // FIXME: Deprecate
47 return (unsigned long&)f;
50 Direct3DDevice8::Direct3DDevice8(const HINSTANCE instance, Direct3D8 *d3d8, unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviourFlags, D3DPRESENT_PARAMETERS *presentParameters) : instance(instance), d3d8(d3d8), adapter(adapter), deviceType(deviceType), focusWindow(focusWindow), behaviourFlags(behaviourFlags), presentParameters(*presentParameters)
57 context = new sw::Context();
58 renderer = new sw::Renderer(context, sw::Direct3D, false);
60 swapChain.push_back(0);
64 for(int i = 0; i < 8; i++)
70 unsigned char one[32 * 32 / sizeof(unsigned char)];
71 memset(one, 0xFFFFFFFF, sizeof(one));
72 unsigned char zero[32 * 32 / sizeof(unsigned char)] = {0};
73 nullCursor = CreateCursor(instance, 0, 0, 32, 32, one, zero);
74 win32Cursor = GetCursor();
76 Reset(presentParameters);
78 pixelShader.push_back(0); // pixelShader[0] = 0
79 vertexShader.push_back(0); // vertexShader[0] = 0
80 vertexShaderHandle = 0;
81 pixelShaderHandle = 0;
85 for(int i = 0; i < 16; i++)
96 D3DMATERIAL8 material;
98 material.Diffuse.r = 1.0f;
99 material.Diffuse.g = 1.0f;
100 material.Diffuse.b = 1.0f;
101 material.Diffuse.a = 0.0f;
102 material.Ambient.r = 0.0f;
103 material.Ambient.g = 0.0f;
104 material.Ambient.b = 0.0f;
105 material.Ambient.a = 0.0f;
106 material.Emissive.r = 0.0f;
107 material.Emissive.g = 0.0f;
108 material.Emissive.b = 0.0f;
109 material.Emissive.a = 0.0f;
110 material.Specular.r = 0.0f;
111 material.Specular.g = 0.0f;
112 material.Specular.b = 0.0f;
113 material.Specular.a = 0.0f;
114 material.Power = 0.0f;
116 SetMaterial(&material);
118 D3DMATRIX identity = {1, 0, 0, 0,
123 SetTransform(D3DTS_VIEW, &identity);
124 SetTransform(D3DTS_PROJECTION, &identity);
125 SetTransform(D3DTS_TEXTURE0, &identity);
126 SetTransform(D3DTS_TEXTURE1, &identity);
127 SetTransform(D3DTS_TEXTURE2, &identity);
128 SetTransform(D3DTS_TEXTURE3, &identity);
129 SetTransform(D3DTS_TEXTURE4, &identity);
130 SetTransform(D3DTS_TEXTURE5, &identity);
131 SetTransform(D3DTS_TEXTURE6, &identity);
132 SetTransform(D3DTS_TEXTURE7, &identity);
134 for(int i = 0; i < 12; i++)
136 SetTransform(D3DTS_WORLDMATRIX(i), &identity);
139 for(int i = 0; i < 8; i++)
141 float zero[4] = {0, 0, 0, 0};
143 SetPixelShaderConstant(i, zero, 1);
146 for(int i = 0; i < 256; i++)
148 float zero[4] = {0, 0, 0, 0};
150 SetVertexShaderConstant(i, zero, 1);
155 if(!(behaviourFlags & D3DCREATE_FPU_PRESERVE))
161 Direct3DDevice8::~Direct3DDevice8()
171 for(unsigned int i = 0; i < swapChain.size(); i++)
175 swapChain[i]->unbind();
182 depthStencil->unbind();
188 renderTarget->unbind();
192 for(int i = 0; i < 8; i++)
196 texture[i]->unbind();
201 for(int i = 0; i < 16; i++)
205 dataStream[i]->unbind();
216 for(unsigned int i = 0; i < pixelShader.size(); i++)
220 pixelShader[i]->unbind();
225 for(unsigned int i = 0; i < vertexShader.size(); i++)
229 vertexShader[i]->unbind();
234 for(unsigned int i = 0; i < stateRecorder.size(); i++)
238 stateRecorder[i]->unbind();
239 stateRecorder[i] = 0;
246 DestroyCursor(nullCursor);
249 long Direct3DDevice8::QueryInterface(const IID &iid, void **object)
253 if(iid == IID_IDirect3DDevice8 ||
264 return NOINTERFACE(iid);
267 unsigned long Direct3DDevice8::AddRef()
271 return Unknown::AddRef();
274 unsigned long Direct3DDevice8::Release()
278 return Unknown::Release();
281 long Direct3DDevice8::ApplyStateBlock(unsigned long token)
285 stateRecorder[token]->Apply();
290 long Direct3DDevice8::BeginScene()
297 long Direct3DDevice8::BeginStateBlock()
302 Direct3DStateBlock8 *stateBlock = new Direct3DStateBlock8(this, (D3DSTATEBLOCKTYPE)0);
304 stateRecorder.push_back(stateBlock);
309 long Direct3DDevice8::CaptureStateBlock(unsigned long token)
313 stateRecorder[token]->Capture();
318 long Direct3DDevice8::Clear(unsigned long count, const D3DRECT *rects, unsigned long flags, unsigned long color, float z, unsigned long stencil)
320 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);
322 if(!rects && count != 0)
324 return INVALIDCALL();
327 if(flags & (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL) && !depthStencil)
329 return INVALIDCALL();
332 if(flags & D3DCLEAR_STENCIL) // Check for stencil component
334 D3DSURFACE_DESC description;
335 depthStencil->GetDesc(&description);
337 switch(description.Format)
344 case D3DFMT_D16_LOCKABLE:
347 return INVALIDCALL();
358 rect.x1 = viewport.X;
359 rect.x2 = viewport.X + viewport.Width;
360 rect.y1 = viewport.Y;
361 rect.y2 = viewport.Y + viewport.Height;
366 for(unsigned int i = 0; i < count; i++)
368 sw::Rect clearRect(rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
370 clearRect.clip(viewport.X, viewport.Y, viewport.X + viewport.Width, viewport.Y + viewport.Height);
372 if(flags & D3DCLEAR_TARGET)
376 D3DSURFACE_DESC description;
377 renderTarget->GetDesc(&description);
380 rgba[0] = (float)(color & 0x00FF0000) / 0x00FF0000;
381 rgba[1] = (float)(color & 0x0000FF00) / 0x0000FF00;
382 rgba[2] = (float)(color & 0x000000FF) / 0x000000FF;
383 rgba[3] = (float)(color & 0xFF000000) / 0xFF000000;
385 renderer->clear(rgba, sw::FORMAT_A32B32G32R32F, renderTarget, clearRect, 0xF);
389 if(flags & D3DCLEAR_ZBUFFER)
392 depthStencil->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
395 if(flags & D3DCLEAR_STENCIL)
397 depthStencil->clearStencil(stencil, 0xFF, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
404 long Direct3DDevice8::CopyRects(IDirect3DSurface8 *sourceSurface, const RECT *sourceRectsArray, unsigned int rects, IDirect3DSurface8 *destinationSurface, const POINT *destPointsArray)
408 if(!sourceSurface || !destinationSurface)
410 return INVALIDCALL();
413 if(sourceRectsArray && rects == 0 || !sourceRectsArray && rects > 0)
415 return INVALIDCALL(); // FIXME: Verify REF behaviour
418 D3DSURFACE_DESC sourceDescription;
419 D3DSURFACE_DESC destDescription;
421 sourceSurface->GetDesc(&sourceDescription);
422 destinationSurface->GetDesc(&destDescription);
424 if(sourceDescription.Format != destDescription.Format)
426 return INVALIDCALL();
429 int sWidth = sourceDescription.Width;
430 int sHeight = sourceDescription.Height;
431 int dWidth = destDescription.Width;
432 int dHeight = destDescription.Height;
434 RECT sRect = {0, 0, sWidth, sHeight};
435 POINT dPoint = {0, 0};
437 if(!sourceRectsArray || !destPointsArray)
439 sourceRectsArray = &sRect;
440 destPointsArray = &dPoint;
445 int bpp = 8 * Direct3DSurface8::bytes(sourceDescription.Format);
447 for(unsigned int i = 0; i < rects; i++)
449 const RECT &sRect = sourceRectsArray[i];
450 const POINT &dPoint = destPointsArray[i];
452 int rWidth = sRect.right - sRect.left;
453 int rHeight = sRect.bottom - sRect.top;
457 dRect.top = dPoint.y;
458 dRect.left = dPoint.x;
459 dRect.bottom = dPoint.y + rHeight;
460 dRect.right = dPoint.x + rWidth;
462 D3DLOCKED_RECT sourceLock;
463 D3DLOCKED_RECT destLock;
465 sourceSurface->LockRect(&sourceLock, &sRect, D3DLOCK_READONLY);
466 destinationSurface->LockRect(&destLock, &dRect, D3DLOCK_DISCARD);
468 for(int y = 0; y < rHeight; y++)
470 switch(sourceDescription.Format)
477 memcpy(destLock.pBits, sourceLock.pBits, rWidth * bpp / 8);
478 y += 3; // Advance four lines at once
481 memcpy(destLock.pBits, sourceLock.pBits, rWidth * bpp / 8);
484 (char*&)sourceLock.pBits += sourceLock.Pitch;
485 (char*&)destLock.pBits += destLock.Pitch;
488 sourceSurface->UnlockRect();
489 destinationSurface->UnlockRect();
495 long Direct3DDevice8::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *presentParameters, IDirect3DSwapChain8 **swapChain)
501 if(!presentParameters || !swapChain)
503 return INVALIDCALL();
506 if(presentParameters->BackBufferCount > 3)
508 return INVALIDCALL(); // Maximum of three back buffers
511 if(presentParameters->BackBufferCount == 0)
513 presentParameters->BackBufferCount = 1;
516 D3DPRESENT_PARAMETERS present = *presentParameters;
518 *swapChain = new Direct3DSwapChain8(this, &present);
522 return OUTOFMEMORY();
525 if(GetAvailableTextureMem() == 0)
529 return OUTOFVIDEOMEMORY();
532 this->swapChain.push_back(static_cast<Direct3DSwapChain8*>(*swapChain));
534 (*swapChain)->AddRef();
539 long Direct3DDevice8::CreateCubeTexture(unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture8 **cubeTexture)
545 if(edgeLength == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_CUBETEXTURE, format) != D3D_OK)
547 return INVALIDCALL();
550 *cubeTexture = new Direct3DCubeTexture8(this, edgeLength, levels, usage, format, pool);
554 return OUTOFMEMORY();
557 if(GetAvailableTextureMem() == 0)
561 return OUTOFVIDEOMEMORY();
564 (*cubeTexture)->AddRef();
569 long Direct3DDevice8::CreateDepthStencilSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, IDirect3DSurface8 **surface)
575 if(width == 0 || height == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION)
577 return INVALIDCALL();
580 *surface = new Direct3DSurface8(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, format == D3DFMT_D16_LOCKABLE, D3DUSAGE_DEPTHSTENCIL);
584 return OUTOFMEMORY();
587 if(GetAvailableTextureMem() == 0)
591 return OUTOFVIDEOMEMORY();
594 (*surface)->AddRef();
599 long Direct3DDevice8::CreateImageSurface(unsigned int width, unsigned int height, D3DFORMAT format, IDirect3DSurface8 **surface)
605 if(width == 0 || height == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, format) != D3D_OK)
607 return INVALIDCALL();
610 *surface = new Direct3DSurface8(this, this, width, height, format, D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, true, 0);
614 return OUTOFMEMORY();
617 if(GetAvailableTextureMem() == 0)
621 return OUTOFVIDEOMEMORY();
624 (*surface)->AddRef();
629 long Direct3DDevice8::CreateIndexBuffer(unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer8 **indexBuffer)
633 *indexBuffer = new Direct3DIndexBuffer8(this, length, usage, format, pool);
637 return OUTOFMEMORY();
640 if(GetAvailableTextureMem() == 0)
644 return OUTOFVIDEOMEMORY();
647 (*indexBuffer)->AddRef();
652 long Direct3DDevice8::CreatePixelShader(const unsigned long *function, unsigned long *handle)
656 if(!function || !handle || function[0] > pixelShaderVersion)
658 return INVALIDCALL();
663 for(index = 1; index < pixelShader.size(); index++) // Skip NULL handle
665 if(pixelShader[index] == 0)
667 pixelShader[index] = new Direct3DPixelShader8(this, function); // FIXME: Check for null
673 if(index == pixelShader.size())
675 pixelShader.push_back(new Direct3DPixelShader8(this, function));
678 pixelShader[index]->AddRef();
685 long Direct3DDevice8::CreateRenderTarget(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, int lockable, IDirect3DSurface8 **surface)
691 if(width == 0 || height == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION)
693 return INVALIDCALL();
696 *surface = new Direct3DSurface8(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, lockable != FALSE, D3DUSAGE_RENDERTARGET);
700 return OUTOFMEMORY();
703 if(GetAvailableTextureMem() == 0)
707 return OUTOFVIDEOMEMORY();
710 (*surface)->AddRef();
715 long Direct3DDevice8::CreateStateBlock(D3DSTATEBLOCKTYPE type, unsigned long *token)
721 return INVALIDCALL();
724 Direct3DStateBlock8 *stateBlock = new Direct3DStateBlock8(this, type);
726 stateRecorder.push_back(stateBlock);
727 *token = (unsigned long)(stateRecorder.size() - 1);
732 long Direct3DDevice8::CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture8 **texture)
738 if(width == 0 || height == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_TEXTURE, format) != D3D_OK)
740 return INVALIDCALL();
743 *texture = new Direct3DTexture8(this, width, height, levels, usage, format, pool);
747 return OUTOFMEMORY();
750 if(GetAvailableTextureMem() == 0)
754 return OUTOFVIDEOMEMORY();
757 (*texture)->AddRef();
762 long Direct3DDevice8::CreateVertexBuffer(unsigned int length, unsigned long usage, unsigned long FVF, D3DPOOL pool, IDirect3DVertexBuffer8 **vertexBuffer)
766 *vertexBuffer = new Direct3DVertexBuffer8(this, length, usage, FVF, pool);
770 return OUTOFMEMORY();
773 if(GetAvailableTextureMem() == 0)
775 delete *vertexBuffer;
777 return OUTOFVIDEOMEMORY();
780 (*vertexBuffer)->AddRef();
785 long Direct3DDevice8::CreateVertexShader(const unsigned long *declaration, const unsigned long *function, unsigned long *handle, unsigned long usage)
787 TRACE("const unsigned long *declaration = 0x%0.8p, const unsigned long *function = 0x%0.8p, unsigned long *handle = 0x%0.8p, unsigned long usage = %d", declaration, function, handle, usage);
789 if(!declaration || !handle || (function && function[0] > vertexShaderVersion))
791 return INVALIDCALL();
796 for(index = 1; index < vertexShader.size(); index++) // NOTE: skip NULL handle
798 if(vertexShader[index] == 0)
800 vertexShader[index] = new Direct3DVertexShader8(this, declaration, function); // FIXME: Check for null
806 if(index == vertexShader.size())
808 vertexShader.push_back(new Direct3DVertexShader8(this, declaration, function));
811 vertexShader[index]->AddRef();
813 *handle = (index << 16) + 1;
818 long Direct3DDevice8::CreateVolumeTexture(unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DVolumeTexture8 **volumeTexture)
824 if(width == 0 || height == 0 || depth == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_VOLUMETEXTURE, format) != D3D_OK)
826 return INVALIDCALL();
829 *volumeTexture = new Direct3DVolumeTexture8(this, width, height, depth, levels, usage, format, pool);
833 return OUTOFMEMORY();
836 if(GetAvailableTextureMem() == 0)
838 delete *volumeTexture;
840 return OUTOFVIDEOMEMORY();
843 (*volumeTexture)->AddRef();
848 long Direct3DDevice8::DeletePatch(unsigned int handle)
857 long Direct3DDevice8::DeleteStateBlock(unsigned long token)
861 if(token >= stateRecorder.size() || !stateRecorder[token])
863 return INVALIDCALL();
866 stateRecorder[token]->unbind();
867 stateRecorder[token] = 0;
872 long Direct3DDevice8::DeleteVertexShader(unsigned long handle)
876 unsigned int index = handle >> 16;
878 if(index >= vertexShader.size() || !vertexShader[index])
880 return INVALIDCALL();
883 vertexShader[index]->Release();
884 vertexShader[index] = 0;
889 long Direct3DDevice8::DrawIndexedPrimitive(D3DPRIMITIVETYPE type, unsigned int minIndex, unsigned int numVertices, unsigned int startIndex, unsigned int primitiveCount)
895 return INVALIDCALL();
898 if(!bindData(indexData, baseVertexIndex) || !primitiveCount)
903 unsigned int indexOffset = startIndex * (indexData->is32Bit() ? 4 : 2); // FIXME: Doesn't take stream frequencies into account
905 sw::DrawType drawType;
907 if(indexData->is32Bit())
911 case D3DPT_POINTLIST: drawType = sw::DRAW_INDEXEDPOINTLIST32; break;
912 case D3DPT_LINELIST: drawType = sw::DRAW_INDEXEDLINELIST32; break;
913 case D3DPT_LINESTRIP: drawType = sw::DRAW_INDEXEDLINESTRIP32; break;
914 case D3DPT_TRIANGLELIST: drawType = sw::DRAW_INDEXEDTRIANGLELIST32; break;
915 case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break;
916 case D3DPT_TRIANGLEFAN: drawType = sw::DRAW_INDEXEDTRIANGLEFAN32; break;
925 case D3DPT_POINTLIST: drawType = sw::DRAW_INDEXEDPOINTLIST16; break;
926 case D3DPT_LINELIST: drawType = sw::DRAW_INDEXEDLINELIST16; break;
927 case D3DPT_LINESTRIP: drawType = sw::DRAW_INDEXEDLINESTRIP16; break;
928 case D3DPT_TRIANGLELIST: drawType = sw::DRAW_INDEXEDTRIANGLELIST16; break;
929 case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break;
930 case D3DPT_TRIANGLEFAN: drawType = sw::DRAW_INDEXEDTRIANGLEFAN16; break;
936 bindData(indexData, baseVertexIndex);
938 renderer->draw(drawType, indexOffset, primitiveCount);
943 long Direct3DDevice8::DeletePixelShader(unsigned long handle)
947 if(handle >= pixelShader.size() || !pixelShader[handle])
949 return INVALIDCALL();
952 pixelShader[handle]->Release();
953 pixelShader[handle] = 0;
958 long Direct3DDevice8::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE type, unsigned int minIndex, unsigned int numVertices, unsigned int primitiveCount, const void *indexData, D3DFORMAT indexDataFormat, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)
962 if(!vertexStreamZeroData || !indexData)
964 return INVALIDCALL();
967 int length = (minIndex + numVertices) * vertexStreamZeroStride;
969 Direct3DVertexBuffer8 *vertexBuffer = new Direct3DVertexBuffer8(this, length, 0, 0, D3DPOOL_DEFAULT);
972 vertexBuffer->Lock(0, 0, &data, 0);
973 memcpy(data, vertexStreamZeroData, length);
974 vertexBuffer->Unlock();
976 SetStreamSource(0, vertexBuffer, vertexStreamZeroStride);
980 case D3DPT_POINTLIST: length = primitiveCount; break;
981 case D3DPT_LINELIST: length = primitiveCount * 2; break;
982 case D3DPT_LINESTRIP: length = primitiveCount + 1; break;
983 case D3DPT_TRIANGLELIST: length = primitiveCount * 3; break;
984 case D3DPT_TRIANGLESTRIP: length = primitiveCount + 2; break;
985 case D3DPT_TRIANGLEFAN: length = primitiveCount + 2; break;
990 length *= indexDataFormat == D3DFMT_INDEX32 ? 4 : 2;
992 Direct3DIndexBuffer8 *indexBuffer = new Direct3DIndexBuffer8(this, length, 0, indexDataFormat, D3DPOOL_DEFAULT);
994 indexBuffer->Lock(0, 0, &data, 0);
995 memcpy(data, indexData, length);
996 indexBuffer->Unlock();
998 SetIndices(indexBuffer, 0);
1000 if(!bindData(indexBuffer, 0) || !primitiveCount)
1002 vertexBuffer->Release();
1007 sw::DrawType drawType;
1009 if(indexDataFormat == D3DFMT_INDEX32)
1013 case D3DPT_POINTLIST: drawType = sw::DRAW_INDEXEDPOINTLIST32; break;
1014 case D3DPT_LINELIST: drawType = sw::DRAW_INDEXEDLINELIST32; break;
1015 case D3DPT_LINESTRIP: drawType = sw::DRAW_INDEXEDLINESTRIP32; break;
1016 case D3DPT_TRIANGLELIST: drawType = sw::DRAW_INDEXEDTRIANGLELIST32; break;
1017 case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break;
1018 case D3DPT_TRIANGLEFAN: drawType = sw::DRAW_INDEXEDTRIANGLEFAN32; break;
1027 case D3DPT_POINTLIST: drawType = sw::DRAW_INDEXEDPOINTLIST16; break;
1028 case D3DPT_LINELIST: drawType = sw::DRAW_INDEXEDLINELIST16; break;
1029 case D3DPT_LINESTRIP: drawType = sw::DRAW_INDEXEDLINESTRIP16; break;
1030 case D3DPT_TRIANGLELIST: drawType = sw::DRAW_INDEXEDTRIANGLELIST16; break;
1031 case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break;
1032 case D3DPT_TRIANGLEFAN: drawType = sw::DRAW_INDEXEDTRIANGLEFAN16; break;
1038 renderer->draw(drawType, 0, primitiveCount);
1040 SetStreamSource(0, 0, 0);
1046 long Direct3DDevice8::DrawPrimitive(D3DPRIMITIVETYPE primitiveType, unsigned int startVertex, unsigned int primitiveCount)
1050 if(!bindData(0, startVertex) || !primitiveCount)
1055 sw::DrawType drawType;
1057 switch(primitiveType)
1059 case D3DPT_POINTLIST: drawType = sw::DRAW_POINTLIST; break;
1060 case D3DPT_LINELIST: drawType = sw::DRAW_LINELIST; break;
1061 case D3DPT_LINESTRIP: drawType = sw::DRAW_LINESTRIP; break;
1062 case D3DPT_TRIANGLELIST: drawType = sw::DRAW_TRIANGLELIST; break;
1063 case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break;
1064 case D3DPT_TRIANGLEFAN: drawType = sw::DRAW_TRIANGLEFAN; break;
1069 renderer->draw(drawType, 0, primitiveCount);
1074 long Direct3DDevice8::DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType, unsigned int primitiveCount, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride)
1078 if(!vertexStreamZeroData)
1080 return INVALIDCALL();
1083 IDirect3DVertexBuffer8 *vertexBuffer = 0;
1086 switch(primitiveType)
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 *= vertexStreamZeroStride;
1100 CreateVertexBuffer(length, 0, 0, D3DPOOL_DEFAULT, &vertexBuffer);
1102 unsigned char *data;
1103 vertexBuffer->Lock(0, 0, &data, 0);
1104 memcpy(data, vertexStreamZeroData, length);
1105 vertexBuffer->Unlock();
1107 SetStreamSource(0, vertexBuffer, vertexStreamZeroStride);
1109 if(!bindData(0, 0) || !primitiveCount)
1111 vertexBuffer->Release();
1116 sw::DrawType drawType;
1118 switch(primitiveType)
1120 case D3DPT_POINTLIST: drawType = sw::DRAW_POINTLIST; break;
1121 case D3DPT_LINELIST: drawType = sw::DRAW_LINELIST; break;
1122 case D3DPT_LINESTRIP: drawType = sw::DRAW_LINESTRIP; break;
1123 case D3DPT_TRIANGLELIST: drawType = sw::DRAW_TRIANGLELIST; break;
1124 case D3DPT_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break;
1125 case D3DPT_TRIANGLEFAN: drawType = sw::DRAW_TRIANGLEFAN; break;
1130 renderer->draw(drawType, 0, primitiveCount);
1132 SetStreamSource(0, 0, 0);
1133 vertexBuffer->Release();
1138 long Direct3DDevice8::DrawRectPatch(unsigned int handle, const float *numSegs, const D3DRECTPATCH_INFO *rectPatchInfo)
1142 if(!numSegs || !rectPatchInfo)
1144 return INVALIDCALL();
1152 long Direct3DDevice8::DrawTriPatch(unsigned int handle, const float *numSegs, const D3DTRIPATCH_INFO *triPatchInfo)
1156 if(!numSegs || !triPatchInfo)
1158 return INVALIDCALL();
1166 long Direct3DDevice8::EndScene()
1173 long Direct3DDevice8::EndStateBlock(unsigned long *token)
1179 return INVALIDCALL();
1182 recordState = false;
1183 *token = (unsigned long)(stateRecorder.size() - 1);
1188 unsigned int Direct3DDevice8::GetAvailableTextureMem()
1192 int availableMemory = textureMemory - Direct3DResource8::getMemoryUsage();
1193 if(availableMemory < 0) availableMemory = 0;
1195 // Round to nearest MB
1196 return (availableMemory + 0x80000) & 0xFFF00000;
1199 long Direct3DDevice8::GetBackBuffer(unsigned int index, D3DBACKBUFFER_TYPE type, IDirect3DSurface8 **backBuffer)
1203 if(!backBuffer/* || type != D3DBACKBUFFER_TYPE_MONO*/)
1205 return INVALIDCALL();
1208 swapChain[index]->GetBackBuffer(index, type, backBuffer);
1213 long Direct3DDevice8::GetClipPlane(unsigned long index, float *plane)
1217 if(!plane || index >= 6)
1219 return INVALIDCALL();
1222 plane[0] = this->plane[index][0];
1223 plane[1] = this->plane[index][1];
1224 plane[2] = this->plane[index][2];
1225 plane[3] = this->plane[index][3];
1230 long Direct3DDevice8::GetClipStatus(D3DCLIPSTATUS8 *clipStatus)
1236 return INVALIDCALL();
1239 *clipStatus = this->clipStatus;
1244 long Direct3DDevice8::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *parameters)
1250 return INVALIDCALL();
1253 parameters->AdapterOrdinal = adapter;
1254 parameters->BehaviorFlags = behaviourFlags;
1255 parameters->DeviceType = deviceType;
1256 parameters->hFocusWindow = focusWindow;
1261 long Direct3DDevice8::GetCurrentTexturePalette(unsigned int *paletteNumber)
1267 return INVALIDCALL();
1270 *paletteNumber = currentPalette;
1275 long Direct3DDevice8::GetDepthStencilSurface(IDirect3DSurface8 **depthStencilSurface)
1279 if(!depthStencilSurface)
1281 return INVALIDCALL();
1284 *depthStencilSurface = depthStencil;
1288 depthStencil->AddRef();
1291 return D3D_OK; // FIXME: Return NOTFOUND() when no depthStencil?
1294 long Direct3DDevice8::GetDeviceCaps(D3DCAPS8 *caps)
1298 return d3d8->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, caps);
1301 long Direct3DDevice8::GetDirect3D(IDirect3D8 **d3d8)
1307 return INVALIDCALL();
1313 this->d3d8->AddRef();
1318 long Direct3DDevice8::GetDisplayMode(D3DDISPLAYMODE *mode)
1324 return INVALIDCALL();
1327 d3d8->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, mode);
1332 long Direct3DDevice8::GetFrontBuffer(IDirect3DSurface8 *destSurface)
1338 return INVALIDCALL();
1341 D3DLOCKED_RECT description;
1342 destSurface->LockRect(&description, 0, 0);
1344 swapChain[0]->screenshot(description.pBits);
1346 destSurface->UnlockRect();
1351 void Direct3DDevice8::GetGammaRamp(D3DGAMMARAMP *ramp)
1360 swapChain[0]->getGammaRamp((sw::GammaRamp*)ramp);
1363 long Direct3DDevice8::GetIndices(IDirect3DIndexBuffer8 **indexData, unsigned int *baseVertexIndex)
1367 if(!indexData || !baseVertexIndex)
1369 return INVALIDCALL();
1372 *indexData = this->indexData;
1376 this->indexData->AddRef();
1379 *baseVertexIndex = this->baseVertexIndex;
1384 long Direct3DDevice8::GetInfo(unsigned long devInfoID, void *devInfoStruct, unsigned long devInfoStructSize)
1388 if(!devInfoStruct || devInfoStructSize == 0)
1390 return INVALIDCALL();
1395 case 0: return E_FAIL;
1396 case 1: return E_FAIL;
1397 case 2: return E_FAIL;
1398 case 3: return E_FAIL;
1399 case 4: return S_FALSE;
1400 case 5: UNIMPLEMENTED(); // FIXME: D3DDEVINFOID_RESOURCEMANAGER
1401 case 6: UNIMPLEMENTED(); // FIXME: D3DDEVINFOID_D3DVERTEXSTATS
1402 case 7: return E_FAIL;
1408 long Direct3DDevice8::GetLight(unsigned long index, D3DLIGHT8 *light)
1414 return INVALIDCALL();
1417 if(!this->light.exists(index))
1419 return INVALIDCALL();
1422 *light = this->light[index];
1427 long Direct3DDevice8::GetLightEnable(unsigned long index , int *enable)
1433 return INVALIDCALL();
1436 if(!light.exists(index))
1438 return INVALIDCALL();
1441 *enable = light[index].enable;
1446 long Direct3DDevice8::GetMaterial(D3DMATERIAL8 *material)
1452 return INVALIDCALL();
1455 *material = this->material;
1460 long Direct3DDevice8::GetPaletteEntries(unsigned int paletteNumber, PALETTEENTRY *entries)
1464 if(paletteNumber > 0xFFFF || !entries)
1466 return INVALIDCALL();
1469 for(int i = 0; i < 256; i++)
1471 entries[i] = palette[paletteNumber].entry[i];
1477 long Direct3DDevice8::GetPixelShader(unsigned long *handle)
1483 return INVALIDCALL();
1486 *handle = pixelShaderHandle;
1491 long Direct3DDevice8::GetPixelShaderFunction(unsigned long handle, void *data, unsigned long *size)
1497 return INVALIDCALL();
1505 long Direct3DDevice8::GetPixelShaderConstant(unsigned long startRegister, void *constantData, unsigned long count)
1511 return INVALIDCALL();
1514 for(unsigned int i = 0; i < count; i++)
1516 ((float*)constantData)[i * 4 + 0] = pixelShaderConstant[startRegister + i][0];
1517 ((float*)constantData)[i * 4 + 1] = pixelShaderConstant[startRegister + i][1];
1518 ((float*)constantData)[i * 4 + 2] = pixelShaderConstant[startRegister + i][2];
1519 ((float*)constantData)[i * 4 + 3] = pixelShaderConstant[startRegister + i][3];
1525 long Direct3DDevice8::GetRasterStatus(D3DRASTER_STATUS *rasterStatus)
1531 return INVALIDCALL();
1539 long Direct3DDevice8::GetRenderState(D3DRENDERSTATETYPE state, unsigned long *value)
1545 return INVALIDCALL();
1548 *value = renderState[state];
1553 long Direct3DDevice8::GetRenderTarget(IDirect3DSurface8 **renderTarget)
1559 return INVALIDCALL();
1562 *renderTarget = this->renderTarget;
1563 this->renderTarget->AddRef();
1568 long Direct3DDevice8::GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer8 **streamData, unsigned int *stride)
1572 if(streamNumber >= 16 || !streamData || !stride)
1574 return INVALIDCALL();
1577 *streamData = dataStream[streamNumber];
1579 if(dataStream[streamNumber])
1581 dataStream[streamNumber]->AddRef();
1584 *stride = 0; // NOTE: Unimplemented
1589 long Direct3DDevice8::GetTexture(unsigned long stage, IDirect3DBaseTexture8 **texture)
1593 if(!texture || stage >= 8)
1595 return INVALIDCALL();
1598 *texture = this->texture[stage];
1600 if(this->texture[stage])
1602 this->texture[stage]->AddRef();
1608 long Direct3DDevice8::GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE state, unsigned long *value)
1612 if(!value || stage < 0 || stage >= 8 || state < 0 || state > D3DTSS_RESULTARG) // FIXME: Set *value to 0?
1614 return INVALIDCALL();
1617 *value = textureStageState[stage][state];
1622 long Direct3DDevice8::GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix)
1626 if(!matrix || state < 0 || state > 511)
1628 return INVALIDCALL();
1631 *matrix = this->matrix[state];
1636 long Direct3DDevice8::GetVertexShader(unsigned long *handle)
1642 return INVALIDCALL();
1645 *handle = vertexShaderHandle;
1650 long Direct3DDevice8::GetVertexShaderConstant(unsigned long startRegister, void *constantData, unsigned long count)
1656 return INVALIDCALL();
1659 for(unsigned int i = 0; i < count; i++)
1661 ((float*)constantData)[i * 4 + 0] = vertexShaderConstant[startRegister + i][0];
1662 ((float*)constantData)[i * 4 + 1] = vertexShaderConstant[startRegister + i][1];
1663 ((float*)constantData)[i * 4 + 2] = vertexShaderConstant[startRegister + i][2];
1664 ((float*)constantData)[i * 4 + 3] = vertexShaderConstant[startRegister + i][3];
1670 long Direct3DDevice8::GetVertexShaderDeclaration(unsigned long handle, void *data, unsigned long *size)
1676 return INVALIDCALL();
1684 long Direct3DDevice8::GetVertexShaderFunction(unsigned long handle, void *data, unsigned long *size)
1690 return INVALIDCALL();
1698 long Direct3DDevice8::GetViewport(D3DVIEWPORT8 *viewport)
1704 return INVALIDCALL();
1707 *viewport = this->viewport;
1712 long Direct3DDevice8::LightEnable(unsigned long index, int enable)
1718 if(!light.exists(index)) // Insert default light
1722 light.Type = D3DLIGHT_DIRECTIONAL;
1723 light.Diffuse.r = 1;
1724 light.Diffuse.g = 1;
1725 light.Diffuse.b = 1;
1726 light.Diffuse.a = 0;
1727 light.Specular.r = 0;
1728 light.Specular.g = 0;
1729 light.Specular.b = 0;
1730 light.Specular.a = 0;
1731 light.Ambient.r = 0;
1732 light.Ambient.g = 0;
1733 light.Ambient.b = 0;
1734 light.Ambient.a = 0;
1735 light.Position.x = 0;
1736 light.Position.y = 0;
1737 light.Position.z = 0;
1738 light.Direction.x = 0;
1739 light.Direction.y = 0;
1740 light.Direction.z = 1;
1743 light.Attenuation0 = 0;
1744 light.Attenuation1 = 0;
1745 light.Attenuation2 = 0;
1749 SetLight(index, &light);
1752 light[index].enable = (enable != FALSE);
1758 stateRecorder.back()->lightEnable(index, enable);
1764 long Direct3DDevice8::MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
1770 return INVALIDCALL();
1773 D3DMATRIX *current = &this->matrix[state];
1775 sw::Matrix C(current->_11, current->_21, current->_31, current->_41,
1776 current->_12, current->_22, current->_32, current->_42,
1777 current->_13, current->_23, current->_33, current->_43,
1778 current->_14, current->_24, current->_34, current->_44);
1780 sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,
1781 matrix->_12, matrix->_22, matrix->_32, matrix->_42,
1782 matrix->_13, matrix->_23, matrix->_33, matrix->_43,
1783 matrix->_14, matrix->_24, matrix->_34, matrix->_44);
1788 renderer->setModelMatrix(C * M);
1791 renderer->setViewMatrix(C * M);
1793 case D3DTS_PROJECTION:
1794 renderer->setProjectionMatrix(C * M);
1796 case D3DTS_TEXTURE0:
1797 renderer->setTextureMatrix(0, C * M);
1799 case D3DTS_TEXTURE1:
1800 renderer->setTextureMatrix(1, C * M);
1802 case D3DTS_TEXTURE2:
1803 renderer->setTextureMatrix(2, C * M);
1805 case D3DTS_TEXTURE3:
1806 renderer->setTextureMatrix(3, C * M);
1808 case D3DTS_TEXTURE4:
1809 renderer->setTextureMatrix(4, C * M);
1811 case D3DTS_TEXTURE5:
1812 renderer->setTextureMatrix(5, C * M);
1814 case D3DTS_TEXTURE6:
1815 renderer->setTextureMatrix(6, C * M);
1817 case D3DTS_TEXTURE7:
1818 renderer->setTextureMatrix(7, C * M);
1821 if(state > 256 && state < 512)
1823 renderer->setModelMatrix(C * M, state - 256);
1831 long Direct3DDevice8::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion)
1835 // NOTE: sourceRect and destRect can be null, dirtyRegion has to be null
1837 HWND windowHandle = presentParameters.hDeviceWindow ? presentParameters.hDeviceWindow : focusWindow;
1839 if(destWindowOverride && destWindowOverride != windowHandle)
1846 return INVALIDCALL();
1849 swapChain[0]->Present(sourceRect, destRect, destWindowOverride, dirtyRegion);
1854 long Direct3DDevice8::ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer8 *destBuffer, unsigned long flags)
1860 return INVALIDCALL();
1868 long Direct3DDevice8::Reset(D3DPRESENT_PARAMETERS *presentParameters)
1872 if(!presentParameters)
1874 return INVALIDCALL();
1879 swapChain[0]->unbind();
1885 depthStencil->unbind();
1891 renderTarget->unbind();
1895 D3DPRESENT_PARAMETERS present = *presentParameters;
1899 swapChain[0] = new Direct3DSwapChain8(this, &present);
1900 swapChain[0]->bind();
1904 swapChain[0]->reset(&present);
1907 HWND windowHandle = presentParameters->hDeviceWindow ? presentParameters->hDeviceWindow : focusWindow;
1912 if(presentParameters->Windowed && (presentParameters->BackBufferHeight == 0 || presentParameters->BackBufferWidth == 0))
1915 GetClientRect(windowHandle, &rectangle);
1917 width = rectangle.right - rectangle.left;
1918 height = rectangle.bottom - rectangle.top;
1922 width = presentParameters->BackBufferWidth;
1923 height = presentParameters->BackBufferHeight;
1926 if(presentParameters->EnableAutoDepthStencil != FALSE)
1928 depthStencil = new Direct3DSurface8(this, this, width, height, presentParameters->AutoDepthStencilFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, presentParameters->AutoDepthStencilFormat == D3DFMT_D16_LOCKABLE, D3DUSAGE_DEPTHSTENCIL);
1929 depthStencil->bind();
1932 IDirect3DSurface8 *renderTarget;
1933 swapChain[0]->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &renderTarget);
1934 SetRenderTarget(renderTarget, depthStencil);
1935 renderTarget->Release();
1937 SetRenderState(D3DRS_ZENABLE, presentParameters->EnableAutoDepthStencil != FALSE ? D3DZB_TRUE : D3DZB_FALSE);
1938 SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
1939 SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
1940 SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
1941 SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
1942 SetRenderState(D3DRS_LASTPIXEL, TRUE);
1943 SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
1944 SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
1945 SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
1946 SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1947 SetRenderState(D3DRS_ALPHAREF, 0);
1948 SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
1949 SetRenderState(D3DRS_DITHERENABLE, FALSE);
1950 SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
1951 SetRenderState(D3DRS_FOGENABLE, FALSE);
1952 SetRenderState(D3DRS_SPECULARENABLE, FALSE);
1953 // SetRenderState(D3DRS_ZVISIBLE, 0);
1954 SetRenderState(D3DRS_FOGCOLOR, 0);
1955 SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1956 SetRenderState(D3DRS_FOGSTART, FtoDW(0.0f));
1957 SetRenderState(D3DRS_FOGEND, FtoDW(1.0f));
1958 SetRenderState(D3DRS_FOGDENSITY, FtoDW(1.0f));
1959 SetRenderState(D3DRS_EDGEANTIALIAS, FALSE);
1960 SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
1961 SetRenderState(D3DRS_ZBIAS, 0);
1962 SetRenderState(D3DRS_STENCILENABLE, FALSE);
1963 SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
1964 SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
1965 SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
1966 SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
1967 SetRenderState(D3DRS_STENCILREF, 0);
1968 SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF);
1969 SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
1970 SetRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
1971 SetRenderState(D3DRS_WRAP0, 0);
1972 SetRenderState(D3DRS_WRAP1, 0);
1973 SetRenderState(D3DRS_WRAP2, 0);
1974 SetRenderState(D3DRS_WRAP3, 0);
1975 SetRenderState(D3DRS_WRAP4, 0);
1976 SetRenderState(D3DRS_WRAP5, 0);
1977 SetRenderState(D3DRS_WRAP6, 0);
1978 SetRenderState(D3DRS_WRAP7, 0);
1979 SetRenderState(D3DRS_CLIPPING, TRUE);
1980 SetRenderState(D3DRS_LIGHTING, TRUE);
1981 SetRenderState(D3DRS_AMBIENT, 0);
1982 SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1983 SetRenderState(D3DRS_COLORVERTEX, TRUE);
1984 SetRenderState(D3DRS_LOCALVIEWER, TRUE);
1985 SetRenderState(D3DRS_NORMALIZENORMALS, FALSE);
1986 SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
1987 SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
1988 SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
1989 SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
1990 SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
1991 SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
1992 SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
1993 SetRenderState(D3DRS_POINTSIZE, FtoDW(1.0f));
1994 SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(0.0f));
1995 SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
1996 SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
1997 SetRenderState(D3DRS_POINTSCALE_A, FtoDW(1.0f));
1998 SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.0f));
1999 SetRenderState(D3DRS_POINTSCALE_C, FtoDW(0.0f));
2000 SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
2001 SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
2002 SetRenderState(D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
2003 SetRenderState(D3DRS_DEBUGMONITORTOKEN, D3DDMT_ENABLE);
2004 SetRenderState(D3DRS_POINTSIZE_MAX, FtoDW(64.0f));
2005 SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
2006 SetRenderState(D3DRS_COLORWRITEENABLE, 0x0000000F);
2007 SetRenderState(D3DRS_TWEENFACTOR, FtoDW(0.0f));
2008 SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
2009 SetRenderState(D3DRS_POSITIONORDER, D3DORDER_CUBIC);
2010 SetRenderState(D3DRS_NORMALORDER, D3DORDER_LINEAR);
2012 for(int i = 0; i < 8; i++)
2016 SetTextureStageState(i, D3DTSS_COLOROP, i == 0 ? D3DTOP_MODULATE : D3DTOP_DISABLE);
2017 SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE); // TODO: D3DTA_DIFFUSE when no texture assigned
2018 SetTextureStageState(i, D3DTSS_COLORARG2, D3DTA_CURRENT);
2019 SetTextureStageState(i, D3DTSS_ALPHAOP, i == 0 ? D3DTOP_SELECTARG1 : D3DTOP_DISABLE);
2020 SetTextureStageState(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); // TODO: D3DTA_DIFFUSE when no texture assigned
2021 SetTextureStageState(i, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
2022 SetTextureStageState(i, D3DTSS_BUMPENVMAT00, FtoDW(0.0f));
2023 SetTextureStageState(i, D3DTSS_BUMPENVMAT01, FtoDW(0.0f));
2024 SetTextureStageState(i, D3DTSS_BUMPENVMAT10, FtoDW(0.0f));
2025 SetTextureStageState(i, D3DTSS_BUMPENVMAT11, FtoDW(0.0f));
2026 SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, i);
2027 SetTextureStageState(i, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
2028 SetTextureStageState(i, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
2029 SetTextureStageState(i, D3DTSS_ADDRESSW, D3DTADDRESS_WRAP);
2030 SetTextureStageState(i, D3DTSS_BORDERCOLOR, 0x00000000);
2031 SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_POINT);
2032 SetTextureStageState(i, D3DTSS_MINFILTER, D3DTEXF_POINT);
2033 SetTextureStageState(i, D3DTSS_MIPFILTER, D3DTEXF_NONE);
2034 SetTextureStageState(i, D3DTSS_MIPMAPLODBIAS, 0);
2035 SetTextureStageState(i, D3DTSS_MAXMIPLEVEL, 0);
2036 SetTextureStageState(i, D3DTSS_MAXANISOTROPY, 1);
2037 SetTextureStageState(i, D3DTSS_BUMPENVLSCALE, FtoDW(0.0f));
2038 SetTextureStageState(i, D3DTSS_BUMPENVLOFFSET, FtoDW(0.0f));
2039 SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
2040 SetTextureStageState(i, D3DTSS_COLORARG0, D3DTA_CURRENT);
2041 SetTextureStageState(i, D3DTSS_ALPHAARG0, D3DTA_CURRENT);
2042 SetTextureStageState(i, D3DTSS_RESULTARG, D3DTA_CURRENT);
2045 currentPalette = 0xFFFF;
2053 long Direct3DDevice8::ResourceManagerDiscardBytes(unsigned long bytes)
2060 long Direct3DDevice8::SetClipPlane(unsigned long index, const float *plane)
2064 if(!plane || index > 6)
2066 return INVALIDCALL();
2071 this->plane[index][0] = plane[0];
2072 this->plane[index][1] = plane[1];
2073 this->plane[index][2] = plane[2];
2074 this->plane[index][3] = plane[3];
2076 renderer->setClipPlane(index, plane);
2080 stateRecorder.back()->setClipPlane(index, plane);
2086 long Direct3DDevice8::SetClipStatus(const D3DCLIPSTATUS8 *clipStatus)
2092 return INVALIDCALL();
2095 this->clipStatus = *clipStatus;
2102 long Direct3DDevice8::SetCurrentTexturePalette(unsigned int paletteNumber)
2106 if(paletteNumber > 0xFFFF || palette.find(paletteNumber) == palette.end())
2108 return INVALIDCALL();
2113 currentPalette = paletteNumber;
2115 sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
2119 stateRecorder.back()->setCurrentTexturePalette(paletteNumber);
2125 void Direct3DDevice8::SetCursorPosition(int x, int y, unsigned long flags)
2129 POINT point = {x, y};
2130 HWND window = focusWindow ? focusWindow : presentParameters.hDeviceWindow;
2131 ScreenToClient(window, &point);
2133 sw::FrameBuffer::setCursorPosition(point.x, point.y);
2136 long Direct3DDevice8::SetCursorProperties(unsigned int x0, unsigned int y0, IDirect3DSurface8 *cursorBitmap)
2142 return INVALIDCALL();
2145 D3DSURFACE_DESC desc;
2146 D3DLOCKED_RECT lock;
2148 cursorBitmap->GetDesc(&desc);
2149 cursorBitmap->LockRect(&lock, 0, 0);
2152 cursor = sw::Surface::create(0, desc.Width, desc.Height, 1, sw::FORMAT_A8R8G8B8, false, false);
2154 void *buffer = cursor->lockExternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
2155 memcpy(buffer, lock.pBits, desc.Width * desc.Height * sizeof(unsigned int));
2156 cursor->unlockExternal();
2158 cursorBitmap->UnlockRect();
2160 sw::FrameBuffer::setCursorOrigin(x0, y0);
2167 void Direct3DDevice8::SetGammaRamp(unsigned long flags, const D3DGAMMARAMP *ramp)
2176 swapChain[0]->setGammaRamp((sw::GammaRamp*)ramp, flags & D3DSGR_CALIBRATE);
2181 long Direct3DDevice8::SetLight(unsigned long index, const D3DLIGHT8 *light)
2187 return INVALIDCALL();
2192 this->light[index] = *light;
2198 stateRecorder.back()->setLight(index, light);
2204 long Direct3DDevice8::SetMaterial(const D3DMATERIAL8 *material)
2210 return INVALIDCALL(); // FIXME: Correct behaviour?
2215 this->material = *material;
2217 renderer->setMaterialAmbient(sw::Color<float>(material->Ambient.r, material->Ambient.g, material->Ambient.b, material->Ambient.a));
2218 renderer->setMaterialDiffuse(sw::Color<float>(material->Diffuse.r, material->Diffuse.g, material->Diffuse.b, material->Diffuse.a));
2219 renderer->setMaterialEmission(sw::Color<float>(material->Emissive.r, material->Emissive.g, material->Emissive.b, material->Emissive.a));
2220 renderer->setMaterialShininess(material->Power);
2221 renderer->setMaterialSpecular(sw::Color<float>(material->Specular.r, material->Specular.g, material->Specular.b, material->Specular.a));
2225 stateRecorder.back()->setMaterial(material);
2231 long Direct3DDevice8::SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries)
2235 if(paletteNumber > 0xFFFF || !entries)
2237 return INVALIDCALL();
2240 for(int i = 0; i < 256; i++)
2242 palette[paletteNumber].entry[i] = entries[i];
2245 if(paletteNumber == currentPalette)
2247 sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]);
2253 long Direct3DDevice8::SetPixelShader(unsigned long handle)
2259 if(pixelShader[handle])
2261 pixelShader[handle]->bind();
2264 if(pixelShader[pixelShaderHandle])
2266 pixelShader[pixelShaderHandle]->unbind();
2269 pixelShaderHandle = handle;
2273 renderer->setPixelShader(pixelShader[handle]->getPixelShader());
2277 renderer->setPixelShader(0);
2282 stateRecorder.back()->setPixelShader(handle);
2288 long Direct3DDevice8::SetPixelShaderConstant(unsigned long startRegister, const void *constantData, unsigned long count)
2294 for(unsigned int i = 0; i < count; i++)
2296 pixelShaderConstant[startRegister + i][0] = ((float*)constantData)[i * 4 + 0];
2297 pixelShaderConstant[startRegister + i][1] = ((float*)constantData)[i * 4 + 1];
2298 pixelShaderConstant[startRegister + i][2] = ((float*)constantData)[i * 4 + 2];
2299 pixelShaderConstant[startRegister + i][3] = ((float*)constantData)[i * 4 + 3];
2302 renderer->setPixelShaderConstantF(startRegister, (const float*)constantData, count);
2306 stateRecorder.back()->setPixelShaderConstant(startRegister, constantData, count);
2312 long Direct3DDevice8::SetRenderState(D3DRENDERSTATETYPE state, unsigned long value)
2314 TRACE("D3DRENDERSTATETYPE state = %d, unsigned long value = %d", state, value);
2316 if(state < D3DRS_ZENABLE || state > D3DRS_NORMALORDER)
2318 return D3D_OK; // FIXME: Warning
2323 if(!init && renderState[state] == value)
2328 renderState[state] = value;
2337 renderer->setDepthBufferEnable(true);
2340 renderer->setDepthBufferEnable(false);
2346 case D3DRS_FILLMODE:
2350 renderer->setFillMode(sw::FILL_VERTEX);
2352 case D3DFILL_WIREFRAME:
2353 renderer->setFillMode(sw::FILL_WIREFRAME);
2356 renderer->setFillMode(sw::FILL_SOLID);
2362 case D3DRS_SHADEMODE:
2366 renderer->setShadingMode(sw::SHADING_FLAT);
2368 case D3DSHADE_GOURAUD:
2369 renderer->setShadingMode(sw::SHADING_GOURAUD);
2371 case D3DSHADE_PHONG:
2372 // FIXME: Unimplemented (should set gouraud)?
2378 case D3DRS_LINEPATTERN:
2379 if(!init) UNIMPLEMENTED();
2381 case D3DRS_ZWRITEENABLE:
2382 renderer->setDepthWriteEnable(value != FALSE);
2384 case D3DRS_ALPHATESTENABLE:
2385 renderer->setAlphaTestEnable(value != FALSE);
2387 case D3DRS_LASTPIXEL:
2388 if(!init) UNIMPLEMENTED();
2390 case D3DRS_SRCBLEND:
2394 renderer->setSourceBlendFactor(sw::BLEND_ZERO);
2397 renderer->setSourceBlendFactor(sw::BLEND_ONE);
2399 case D3DBLEND_SRCCOLOR:
2400 renderer->setSourceBlendFactor(sw::BLEND_SOURCE);
2402 case D3DBLEND_INVSRCCOLOR:
2403 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCE);
2405 case D3DBLEND_SRCALPHA:
2406 renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
2408 case D3DBLEND_INVSRCALPHA:
2409 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
2411 case D3DBLEND_DESTALPHA:
2412 renderer->setSourceBlendFactor(sw::BLEND_DESTALPHA);
2414 case D3DBLEND_INVDESTALPHA:
2415 renderer->setSourceBlendFactor(sw::BLEND_INVDESTALPHA);
2417 case D3DBLEND_DESTCOLOR:
2418 renderer->setSourceBlendFactor(sw::BLEND_DEST);
2420 case D3DBLEND_INVDESTCOLOR:
2421 renderer->setSourceBlendFactor(sw::BLEND_INVDEST);
2423 case D3DBLEND_SRCALPHASAT:
2424 renderer->setSourceBlendFactor(sw::BLEND_SRCALPHASAT);
2426 case D3DBLEND_BOTHSRCALPHA:
2427 renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
2428 renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
2430 case D3DBLEND_BOTHINVSRCALPHA:
2431 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
2432 renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
2438 case D3DRS_DESTBLEND:
2442 renderer->setDestBlendFactor(sw::BLEND_ZERO);
2445 renderer->setDestBlendFactor(sw::BLEND_ONE);
2447 case D3DBLEND_SRCCOLOR:
2448 renderer->setDestBlendFactor(sw::BLEND_SOURCE);
2450 case D3DBLEND_INVSRCCOLOR:
2451 renderer->setDestBlendFactor(sw::BLEND_INVSOURCE);
2453 case D3DBLEND_SRCALPHA:
2454 renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
2456 case D3DBLEND_INVSRCALPHA:
2457 renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
2459 case D3DBLEND_DESTALPHA:
2460 renderer->setDestBlendFactor(sw::BLEND_DESTALPHA);
2462 case D3DBLEND_INVDESTALPHA:
2463 renderer->setDestBlendFactor(sw::BLEND_INVDESTALPHA);
2465 case D3DBLEND_DESTCOLOR:
2466 renderer->setDestBlendFactor(sw::BLEND_DEST);
2468 case D3DBLEND_INVDESTCOLOR:
2469 renderer->setDestBlendFactor(sw::BLEND_INVDEST);
2471 case D3DBLEND_SRCALPHASAT:
2472 renderer->setDestBlendFactor(sw::BLEND_SRCALPHASAT);
2474 case D3DBLEND_BOTHSRCALPHA:
2475 renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA);
2476 renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA);
2478 case D3DBLEND_BOTHINVSRCALPHA:
2479 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA);
2480 renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA);
2486 case D3DRS_CULLMODE:
2490 renderer->setCullMode(sw::CULL_NONE);
2493 renderer->setCullMode(sw::CULL_COUNTERCLOCKWISE);
2496 renderer->setCullMode(sw::CULL_CLOCKWISE);
2506 renderer->setDepthCompare(sw::DEPTH_NEVER);
2509 renderer->setDepthCompare(sw::DEPTH_LESS);
2512 renderer->setDepthCompare(sw::DEPTH_EQUAL);
2514 case D3DCMP_LESSEQUAL:
2515 renderer->setDepthCompare(sw::DEPTH_LESSEQUAL);
2517 case D3DCMP_GREATER:
2518 renderer->setDepthCompare(sw::DEPTH_GREATER);
2520 case D3DCMP_NOTEQUAL:
2521 renderer->setDepthCompare(sw::DEPTH_NOTEQUAL);
2523 case D3DCMP_GREATEREQUAL:
2524 renderer->setDepthCompare(sw::DEPTH_GREATEREQUAL);
2527 renderer->setDepthCompare(sw::DEPTH_ALWAYS);
2533 case D3DRS_ALPHAREF:
2534 renderer->setAlphaReference(value & 0x000000FF);
2536 case D3DRS_ALPHAFUNC:
2540 renderer->setAlphaCompare(sw::ALPHA_NEVER);
2543 renderer->setAlphaCompare(sw::ALPHA_LESS);
2546 renderer->setAlphaCompare(sw::ALPHA_EQUAL);
2548 case D3DCMP_LESSEQUAL:
2549 renderer->setAlphaCompare(sw::ALPHA_LESSEQUAL);
2551 case D3DCMP_GREATER:
2552 renderer->setAlphaCompare(sw::ALPHA_GREATER);
2554 case D3DCMP_NOTEQUAL:
2555 renderer->setAlphaCompare(sw::ALPHA_NOTEQUAL);
2557 case D3DCMP_GREATEREQUAL:
2558 renderer->setAlphaCompare(sw::ALPHA_GREATEREQUAL);
2561 renderer->setAlphaCompare(sw::ALPHA_ALWAYS);
2567 case D3DRS_DITHERENABLE:
2568 // if(!init && value == 1) UNIMPLEMENTED(); // FIXME: Unimplemented
2570 case D3DRS_ALPHABLENDENABLE:
2571 renderer->setAlphaBlendEnable(value != FALSE);
2573 case D3DRS_FOGENABLE:
2574 renderer->setFogEnable(value != FALSE);
2576 case D3DRS_ZVISIBLE:
2577 break; // Not supported
2578 case D3DRS_FOGCOLOR:
2579 renderer->setFogColor(value);
2581 case D3DRS_FOGTABLEMODE:
2585 renderer->setPixelFogMode(sw::FOG_NONE);
2588 renderer->setPixelFogMode(sw::FOG_LINEAR);
2591 renderer->setPixelFogMode(sw::FOG_EXP);
2594 renderer->setPixelFogMode(sw::FOG_EXP2);
2600 case D3DRS_FOGSTART:
2601 renderer->setFogStart((float&)value);
2604 renderer->setFogEnd((float&)value);
2606 case D3DRS_FOGDENSITY:
2607 renderer->setFogDensity((float&)value);
2609 case D3DRS_EDGEANTIALIAS:
2610 if(!init) if(value != FALSE) UNIMPLEMENTED();
2613 renderer->setDepthBias(-2.0e-6f * value);
2614 renderer->setSlopeDepthBias(0.0f);
2616 case D3DRS_RANGEFOGENABLE:
2617 renderer->setRangeFogEnable(value != FALSE);
2619 case D3DRS_SPECULARENABLE:
2620 renderer->setSpecularEnable(value != FALSE);
2622 case D3DRS_STENCILENABLE:
2623 renderer->setStencilEnable(value != FALSE);
2625 case D3DRS_STENCILFAIL:
2628 case D3DSTENCILOP_KEEP:
2629 renderer->setStencilFailOperation(sw::OPERATION_KEEP);
2631 case D3DSTENCILOP_ZERO:
2632 renderer->setStencilFailOperation(sw::OPERATION_ZERO);
2634 case D3DSTENCILOP_REPLACE:
2635 renderer->setStencilFailOperation(sw::OPERATION_REPLACE);
2637 case D3DSTENCILOP_INCRSAT:
2638 renderer->setStencilFailOperation(sw::OPERATION_INCRSAT);
2640 case D3DSTENCILOP_DECRSAT:
2641 renderer->setStencilFailOperation(sw::OPERATION_DECRSAT);
2643 case D3DSTENCILOP_INVERT:
2644 renderer->setStencilFailOperation(sw::OPERATION_INVERT);
2646 case D3DSTENCILOP_INCR:
2647 renderer->setStencilFailOperation(sw::OPERATION_INCR);
2649 case D3DSTENCILOP_DECR:
2650 renderer->setStencilFailOperation(sw::OPERATION_DECR);
2656 case D3DRS_STENCILZFAIL:
2659 case D3DSTENCILOP_KEEP:
2660 renderer->setStencilZFailOperation(sw::OPERATION_KEEP);
2662 case D3DSTENCILOP_ZERO:
2663 renderer->setStencilZFailOperation(sw::OPERATION_ZERO);
2665 case D3DSTENCILOP_REPLACE:
2666 renderer->setStencilZFailOperation(sw::OPERATION_REPLACE);
2668 case D3DSTENCILOP_INCRSAT:
2669 renderer->setStencilZFailOperation(sw::OPERATION_INCRSAT);
2671 case D3DSTENCILOP_DECRSAT:
2672 renderer->setStencilZFailOperation(sw::OPERATION_DECRSAT);
2674 case D3DSTENCILOP_INVERT:
2675 renderer->setStencilZFailOperation(sw::OPERATION_INVERT);
2677 case D3DSTENCILOP_INCR:
2678 renderer->setStencilZFailOperation(sw::OPERATION_INCR);
2680 case D3DSTENCILOP_DECR:
2681 renderer->setStencilZFailOperation(sw::OPERATION_DECR);
2687 case D3DRS_STENCILPASS:
2690 case D3DSTENCILOP_KEEP:
2691 renderer->setStencilPassOperation(sw::OPERATION_KEEP);
2693 case D3DSTENCILOP_ZERO:
2694 renderer->setStencilPassOperation(sw::OPERATION_ZERO);
2696 case D3DSTENCILOP_REPLACE:
2697 renderer->setStencilPassOperation(sw::OPERATION_REPLACE);
2699 case D3DSTENCILOP_INCRSAT:
2700 renderer->setStencilPassOperation(sw::OPERATION_INCRSAT);
2702 case D3DSTENCILOP_DECRSAT:
2703 renderer->setStencilPassOperation(sw::OPERATION_DECRSAT);
2705 case D3DSTENCILOP_INVERT:
2706 renderer->setStencilPassOperation(sw::OPERATION_INVERT);
2708 case D3DSTENCILOP_INCR:
2709 renderer->setStencilPassOperation(sw::OPERATION_INCR);
2711 case D3DSTENCILOP_DECR:
2712 renderer->setStencilPassOperation(sw::OPERATION_DECR);
2718 case D3DRS_STENCILFUNC:
2722 renderer->setStencilCompare(sw::STENCIL_NEVER);
2725 renderer->setStencilCompare(sw::STENCIL_LESS);
2728 renderer->setStencilCompare(sw::STENCIL_EQUAL);
2730 case D3DCMP_LESSEQUAL:
2731 renderer->setStencilCompare(sw::STENCIL_LESSEQUAL);
2733 case D3DCMP_GREATER:
2734 renderer->setStencilCompare(sw::STENCIL_GREATER);
2736 case D3DCMP_NOTEQUAL:
2737 renderer->setStencilCompare(sw::STENCIL_NOTEQUAL);
2739 case D3DCMP_GREATEREQUAL:
2740 renderer->setStencilCompare(sw::STENCIL_GREATEREQUAL);
2743 renderer->setStencilCompare(sw::STENCIL_ALWAYS);
2749 case D3DRS_STENCILREF:
2750 renderer->setStencilReference(value);
2751 renderer->setStencilReferenceCCW(value);
2753 case D3DRS_STENCILMASK:
2754 renderer->setStencilMask(value);
2755 renderer->setStencilMaskCCW(value);
2757 case D3DRS_STENCILWRITEMASK:
2758 renderer->setStencilWriteMask(value);
2759 renderer->setStencilWriteMaskCCW(value);
2761 case D3DRS_TEXTUREFACTOR:
2762 renderer->setTextureFactor(value);
2765 renderer->setTextureWrap(0, value);
2768 renderer->setTextureWrap(1, value);
2771 renderer->setTextureWrap(2, value);
2774 renderer->setTextureWrap(3, value);
2777 renderer->setTextureWrap(4, value);
2780 renderer->setTextureWrap(5, value);
2783 renderer->setTextureWrap(6, value);
2786 renderer->setTextureWrap(7, value);
2788 case D3DRS_CLIPPING:
2789 // Ignored, clipping is always performed
2791 case D3DRS_LIGHTING:
2792 renderer->setLightingEnable(value != FALSE);
2795 renderer->setGlobalAmbient(value);
2797 case D3DRS_FOGVERTEXMODE:
2801 renderer->setVertexFogMode(sw::FOG_NONE);
2804 renderer->setVertexFogMode(sw::FOG_LINEAR);
2807 renderer->setVertexFogMode(sw::FOG_EXP);
2810 renderer->setVertexFogMode(sw::FOG_EXP2);
2816 case D3DRS_COLORVERTEX:
2817 renderer->setColorVertexEnable(value != FALSE);
2819 case D3DRS_LOCALVIEWER:
2820 renderer->setLocalViewer(value != FALSE);
2822 case D3DRS_NORMALIZENORMALS:
2823 renderer->setNormalizeNormals(value != FALSE);
2825 case D3DRS_DIFFUSEMATERIALSOURCE:
2828 case D3DMCS_MATERIAL:
2829 renderer->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
2832 renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
2835 renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR2);
2841 case D3DRS_SPECULARMATERIALSOURCE:
2844 case D3DMCS_MATERIAL:
2845 renderer->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
2848 renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR1);
2851 renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR2);
2857 case D3DRS_AMBIENTMATERIALSOURCE:
2860 case D3DMCS_MATERIAL:
2861 renderer->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
2864 renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
2867 renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR2);
2873 case D3DRS_EMISSIVEMATERIALSOURCE:
2876 case D3DMCS_MATERIAL:
2877 renderer->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
2880 renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);
2883 renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR2);
2889 case D3DRS_VERTEXBLEND:
2892 case D3DVBF_DISABLE:
2893 renderer->setVertexBlendMatrixCount(0);
2895 case D3DVBF_1WEIGHTS:
2896 renderer->setVertexBlendMatrixCount(2);
2898 case D3DVBF_2WEIGHTS:
2899 renderer->setVertexBlendMatrixCount(3);
2901 case D3DVBF_3WEIGHTS:
2902 renderer->setVertexBlendMatrixCount(4);
2904 case D3DVBF_TWEENING:
2907 case D3DVBF_0WEIGHTS:
2908 renderer->setVertexBlendMatrixCount(1);
2914 case D3DRS_CLIPPLANEENABLE:
2915 renderer->setClipFlags(value);
2917 case D3DRS_SOFTWAREVERTEXPROCESSING:
2919 case D3DRS_POINTSIZE:
2920 renderer->setPointSize((float&)value);
2922 case D3DRS_POINTSIZE_MIN:
2923 renderer->setPointSizeMin((float&)value);
2925 case D3DRS_POINTSPRITEENABLE:
2926 renderer->setPointSpriteEnable(value != FALSE);
2928 case D3DRS_POINTSCALEENABLE:
2929 renderer->setPointScaleEnable(value != FALSE);
2931 case D3DRS_POINTSCALE_A:
2932 renderer->setPointScaleA((float&)value);
2934 case D3DRS_POINTSCALE_B:
2935 renderer->setPointScaleB((float&)value);
2937 case D3DRS_POINTSCALE_C:
2938 renderer->setPointScaleC((float&)value);
2940 case D3DRS_MULTISAMPLEANTIALIAS:
2941 // if(!init) UNIMPLEMENTED();
2943 case D3DRS_MULTISAMPLEMASK:
2944 SetRenderTarget(renderTarget, depthStencil); // Sets the multi-sample mask, if maskable
2946 case D3DRS_PATCHEDGESTYLE:
2947 // if(!init) UNIMPLEMENTED();
2949 case D3DRS_PATCHSEGMENTS:
2950 // UNIMPLEMENTED(); // FIXME
2952 case D3DRS_DEBUGMONITORTOKEN:
2953 if(!init) UNIMPLEMENTED();
2955 case D3DRS_POINTSIZE_MAX:
2956 renderer->setPointSizeMax((float&)value);
2958 case D3DRS_INDEXEDVERTEXBLENDENABLE:
2959 renderer->setIndexedVertexBlendEnable(value != FALSE);
2961 case D3DRS_COLORWRITEENABLE:
2962 renderer->setColorWriteMask(0, value);
2964 case D3DRS_TWEENFACTOR:
2965 if(!init) UNIMPLEMENTED();
2970 case D3DBLENDOP_ADD:
2971 renderer->setBlendOperation(sw::BLENDOP_ADD);
2973 case D3DBLENDOP_SUBTRACT:
2974 renderer->setBlendOperation(sw::BLENDOP_SUB);
2976 case D3DBLENDOP_REVSUBTRACT:
2977 renderer->setBlendOperation(sw::BLENDOP_INVSUB);
2979 case D3DBLENDOP_MIN:
2980 renderer->setBlendOperation(sw::BLENDOP_MIN);
2982 case D3DBLENDOP_MAX:
2983 renderer->setBlendOperation(sw::BLENDOP_MAX);
2989 case D3DRS_POSITIONORDER:
2990 if(!init) UNIMPLEMENTED();
2992 case D3DRS_NORMALORDER:
2993 if(!init) UNIMPLEMENTED();
2999 else // stateRecorder
3001 stateRecorder.back()->setRenderState(state, value);
3007 long Direct3DDevice8::SetRenderTarget(IDirect3DSurface8 *newRenderTarget, IDirect3DSurface8 *newDepthStencil)
3011 Direct3DSurface8 *renderTarget = static_cast<Direct3DSurface8*>(newRenderTarget);
3013 if(renderTarget) // FIXME: Check for D3DUSAGE_RENDERTARGET
3015 renderTarget->bind();
3018 if(this->renderTarget)
3020 this->renderTarget->unbind();
3023 this->renderTarget = renderTarget;
3025 Direct3DSurface8 *depthStencil = static_cast<Direct3DSurface8*>(newDepthStencil);
3027 if(depthStencil) // FIXME: Check for D3DUSAGE_DEPTHSTENCIL and D3DPOOL_DEFAULT
3029 depthStencil->bind();
3032 if(this->depthStencil)
3034 this->depthStencil->unbind();
3037 this->depthStencil = depthStencil;
3039 // Reset viewport to size of current render target
3040 D3DSURFACE_DESC renderTargetDesc;
3041 renderTarget->GetDesc(&renderTargetDesc);
3043 D3DVIEWPORT8 viewport;
3046 viewport.Width = renderTargetDesc.Width;
3047 viewport.Height = renderTargetDesc.Height;
3051 SetViewport(&viewport);
3053 // Set the multi-sample mask, if maskable
3054 if(renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONE)
3056 renderer->setMultiSampleMask(renderState[D3DRS_MULTISAMPLEMASK]);
3060 renderer->setMultiSampleMask(0xFFFFFFFF);
3063 renderer->setRenderTarget(0, renderTarget);
3064 renderer->setDepthBuffer(depthStencil);
3065 renderer->setStencilBuffer(depthStencil);
3070 long Direct3DDevice8::SetStreamSource(unsigned int stream, IDirect3DVertexBuffer8 *iVertexBuffer, unsigned int stride)
3074 Direct3DVertexBuffer8 *vertexBuffer = static_cast<Direct3DVertexBuffer8*>(iVertexBuffer);
3080 vertexBuffer->bind();
3083 if(dataStream[stream])
3085 dataStream[stream]->unbind();
3086 streamStride[stream] = 0;
3089 dataStream[stream] = vertexBuffer;
3090 streamStride[stream] = stride;
3094 stateRecorder.back()->setStreamSource(stream, vertexBuffer, stride);
3100 long Direct3DDevice8::SetTexture(unsigned long stage, IDirect3DBaseTexture8 *iBaseTexture)
3106 return INVALIDCALL();
3109 Direct3DBaseTexture8 *baseTexture = dynamic_cast<Direct3DBaseTexture8*>(iBaseTexture);
3113 if(texture[stage] == baseTexture)
3120 baseTexture->bind();
3125 texture[stage]->unbind();
3128 texture[stage] = baseTexture;
3132 stateRecorder.back()->setTexture(stage, baseTexture);
3138 long Direct3DDevice8::SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value)
3140 TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long value = %d", stage, type, value);
3142 if(stage >= 8 || type < 0 || type > D3DTSS_RESULTARG)
3144 return INVALIDCALL();
3149 if(!init && textureStageState[stage][type] == value)
3154 textureStageState[stage][type] = value;
3158 case D3DTSS_COLOROP:
3161 case D3DTOP_DISABLE:
3162 renderer->setStageOperation(stage, sw::TextureStage::STAGE_DISABLE);
3164 case D3DTOP_SELECTARG1:
3165 renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG1);
3167 case D3DTOP_SELECTARG2:
3168 renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG2);
3170 case D3DTOP_MODULATE:
3171 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE);
3173 case D3DTOP_MODULATE2X:
3174 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE2X);
3176 case D3DTOP_MODULATE4X:
3177 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE4X);
3180 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADD);
3182 case D3DTOP_ADDSIGNED:
3183 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED);
3185 case D3DTOP_ADDSIGNED2X:
3186 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
3188 case D3DTOP_SUBTRACT:
3189 renderer->setStageOperation(stage, sw::TextureStage::STAGE_SUBTRACT);
3191 case D3DTOP_ADDSMOOTH:
3192 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSMOOTH);
3194 case D3DTOP_BLENDDIFFUSEALPHA:
3195 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
3197 case D3DTOP_BLENDTEXTUREALPHA:
3198 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
3200 case D3DTOP_BLENDFACTORALPHA:
3201 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
3203 case D3DTOP_BLENDTEXTUREALPHAPM:
3204 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
3206 case D3DTOP_BLENDCURRENTALPHA:
3207 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
3209 case D3DTOP_PREMODULATE:
3210 renderer->setStageOperation(stage, sw::TextureStage::STAGE_PREMODULATE);
3212 case D3DTOP_MODULATEALPHA_ADDCOLOR:
3213 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
3215 case D3DTOP_MODULATECOLOR_ADDALPHA:
3216 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
3218 case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
3219 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
3221 case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
3222 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
3224 case D3DTOP_BUMPENVMAP:
3225 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAP);
3227 case D3DTOP_BUMPENVMAPLUMINANCE:
3228 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
3230 case D3DTOP_DOTPRODUCT3:
3231 renderer->setStageOperation(stage, sw::TextureStage::STAGE_DOT3);
3233 case D3DTOP_MULTIPLYADD:
3234 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MULTIPLYADD);
3237 renderer->setStageOperation(stage, sw::TextureStage::STAGE_LERP);
3243 case D3DTSS_COLORARG1:
3244 switch(value & D3DTA_SELECTMASK)
3247 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
3250 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CURRENT);
3253 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
3256 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
3258 case D3DTA_SPECULAR:
3259 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
3262 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEMP);
3268 switch(value & ~D3DTA_SELECTMASK)
3271 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_COLOR);
3273 case D3DTA_COMPLEMENT:
3274 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
3276 case D3DTA_ALPHAREPLICATE:
3277 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
3279 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
3280 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
3286 case D3DTSS_COLORARG2:
3287 switch(value & D3DTA_SELECTMASK)
3290 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
3293 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CURRENT);
3296 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
3299 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
3301 case D3DTA_SPECULAR:
3302 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
3305 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEMP);
3311 switch(value & ~D3DTA_SELECTMASK)
3314 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_COLOR);
3316 case D3DTA_COMPLEMENT:
3317 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
3319 case D3DTA_ALPHAREPLICATE:
3320 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
3322 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
3323 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
3329 case D3DTSS_ALPHAOP:
3332 case D3DTOP_DISABLE:
3333 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DISABLE);
3335 case D3DTOP_SELECTARG1:
3336 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG1);
3338 case D3DTOP_SELECTARG2:
3339 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG2);
3341 case D3DTOP_MODULATE:
3342 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE);
3344 case D3DTOP_MODULATE2X:
3345 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE2X);
3347 case D3DTOP_MODULATE4X:
3348 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE4X);
3351 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADD);
3353 case D3DTOP_ADDSIGNED:
3354 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED);
3356 case D3DTOP_ADDSIGNED2X:
3357 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED2X);
3359 case D3DTOP_SUBTRACT:
3360 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SUBTRACT);
3362 case D3DTOP_ADDSMOOTH:
3363 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSMOOTH);
3365 case D3DTOP_BLENDDIFFUSEALPHA:
3366 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA);
3368 case D3DTOP_BLENDTEXTUREALPHA:
3369 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);
3371 case D3DTOP_BLENDFACTORALPHA:
3372 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA);
3374 case D3DTOP_BLENDTEXTUREALPHAPM:
3375 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM);
3377 case D3DTOP_BLENDCURRENTALPHA:
3378 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA);
3380 case D3DTOP_PREMODULATE:
3381 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_PREMODULATE);
3383 case D3DTOP_MODULATEALPHA_ADDCOLOR:
3384 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR);
3386 case D3DTOP_MODULATECOLOR_ADDALPHA:
3387 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA);
3389 case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
3390 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR);
3392 case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
3393 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA);
3395 case D3DTOP_BUMPENVMAP:
3396 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAP);
3398 case D3DTOP_BUMPENVMAPLUMINANCE:
3399 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE);
3401 case D3DTOP_DOTPRODUCT3:
3402 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DOT3);
3404 case D3DTOP_MULTIPLYADD:
3405 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MULTIPLYADD);
3408 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_LERP);
3414 case D3DTSS_ALPHAARG1:
3415 switch(value & D3DTA_SELECTMASK)
3418 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
3421 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
3424 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
3427 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
3429 case D3DTA_SPECULAR:
3430 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
3433 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
3439 switch(value & ~D3DTA_SELECTMASK)
3442 renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
3444 case D3DTA_COMPLEMENT:
3445 renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
3447 case D3DTA_ALPHAREPLICATE:
3448 renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
3450 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
3451 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
3457 case D3DTSS_ALPHAARG2:
3458 switch(value & D3DTA_SELECTMASK)
3461 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
3464 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
3467 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
3470 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
3472 case D3DTA_SPECULAR:
3473 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
3476 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
3482 switch(value & ~D3DTA_SELECTMASK)
3485 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
3487 case D3DTA_COMPLEMENT:
3488 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
3490 case D3DTA_ALPHAREPLICATE:
3491 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
3493 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
3494 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
3500 case D3DTSS_BUMPENVMAT00:
3501 renderer->setBumpmapMatrix(stage, 0, (float&)value);
3503 case D3DTSS_BUMPENVMAT01:
3504 renderer->setBumpmapMatrix(stage, 1, (float&)value);
3506 case D3DTSS_BUMPENVMAT10:
3507 renderer->setBumpmapMatrix(stage, 2, (float&)value);
3509 case D3DTSS_BUMPENVMAT11:
3510 renderer->setBumpmapMatrix(stage, 3, (float&)value);
3512 case D3DTSS_TEXCOORDINDEX:
3513 renderer->setTexCoordIndex(stage, value & 0xFFFF);
3515 switch(value & 0xFFFF0000)
3517 case D3DTSS_TCI_PASSTHRU:
3518 renderer->setTexGen(stage, sw::TEXGEN_PASSTHRU);
3520 case D3DTSS_TCI_CAMERASPACENORMAL:
3521 renderer->setTexCoordIndex(stage, stage);
3522 renderer->setTexGen(stage, sw::TEXGEN_NORMAL);
3524 case D3DTSS_TCI_CAMERASPACEPOSITION:
3525 renderer->setTexCoordIndex(stage, stage);
3526 renderer->setTexGen(stage, sw::TEXGEN_POSITION);
3528 case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3529 renderer->setTexCoordIndex(stage, stage);
3530 renderer->setTexGen(stage, sw::TEXGEN_REFLECTION);
3536 case D3DTSS_ADDRESSU:
3539 case D3DTADDRESS_WRAP:
3540 renderer->setAddressingModeU(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_WRAP);
3542 case D3DTADDRESS_MIRROR:
3543 renderer->setAddressingModeU(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRROR);
3545 case D3DTADDRESS_CLAMP:
3546 renderer->setAddressingModeU(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_CLAMP);
3548 case D3DTADDRESS_BORDER:
3549 renderer->setAddressingModeU(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_BORDER);
3551 case D3DTADDRESS_MIRRORONCE:
3552 renderer->setAddressingModeU(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRRORONCE);
3558 case D3DTSS_ADDRESSV:
3561 case D3DTADDRESS_WRAP:
3562 renderer->setAddressingModeV(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_WRAP);
3564 case D3DTADDRESS_MIRROR:
3565 renderer->setAddressingModeV(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRROR);
3567 case D3DTADDRESS_CLAMP:
3568 renderer->setAddressingModeV(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_CLAMP);
3570 case D3DTADDRESS_BORDER:
3571 renderer->setAddressingModeV(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_BORDER);
3573 case D3DTADDRESS_MIRRORONCE:
3574 renderer->setAddressingModeV(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRRORONCE);
3580 case D3DTSS_BORDERCOLOR:
3581 renderer->setBorderColor(sw::SAMPLER_PIXEL, stage, value);
3583 case D3DTSS_MAGFILTER:
3584 // NOTE: SwiftShader does not differentiate between minification and magnification filter
3588 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_POINT);
3591 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_POINT);
3593 case D3DTEXF_LINEAR:
3594 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR);
3596 case D3DTEXF_ANISOTROPIC:
3597 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_ANISOTROPIC);
3599 case D3DTEXF_FLATCUBIC:
3600 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR); // NOTE: Unimplemented, fail silently
3602 case D3DTEXF_GAUSSIANCUBIC:
3603 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR); // NOTE: Unimplemented, fail silently
3606 return INVALIDCALL();
3609 case D3DTSS_MINFILTER:
3610 // NOTE: SwiftShader does not differentiate between minification and magnification filter
3614 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_POINT);
3617 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_POINT);
3619 case D3DTEXF_LINEAR:
3620 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR);
3622 case D3DTEXF_ANISOTROPIC:
3623 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_ANISOTROPIC);
3625 case D3DTEXF_FLATCUBIC:
3626 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR); // NOTE: Unimplemented, fail silently
3628 case D3DTEXF_GAUSSIANCUBIC:
3629 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR); // NOTE: Unimplemented, fail silently
3632 return INVALIDCALL();
3635 case D3DTSS_MIPFILTER:
3639 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_NONE);
3642 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_POINT);
3644 case D3DTEXF_LINEAR:
3645 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_LINEAR);
3647 case D3DTEXF_ANISOTROPIC:
3648 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_LINEAR); // NOTE: Unimplemented, fail silently
3650 case D3DTEXF_FLATCUBIC:
3651 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_LINEAR); // NOTE: Unimplemented, fail silently
3653 case D3DTEXF_GAUSSIANCUBIC:
3654 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_LINEAR); // NOTE: Unimplemented, fail silently
3657 return INVALIDCALL();
3660 case D3DTSS_MIPMAPLODBIAS:
3662 float LOD = (float&)value - sw::log2((float)context->renderTarget[0]->getSuperSampleCount()); // FIXME: Update when render target changes
3663 renderer->setMipmapLOD(sw::SAMPLER_PIXEL, stage, LOD);
3666 case D3DTSS_MAXMIPLEVEL:
3668 case D3DTSS_MAXANISOTROPY:
3669 renderer->setMaxAnisotropy(sw::SAMPLER_PIXEL, stage, sw::clamp((unsigned int)value, (unsigned int)1, maxAnisotropy));
3671 case D3DTSS_BUMPENVLSCALE:
3672 renderer->setLuminanceScale(stage, (float&)value);
3674 case D3DTSS_BUMPENVLOFFSET:
3675 renderer->setLuminanceOffset(stage, (float&)value);
3677 case D3DTSS_TEXTURETRANSFORMFLAGS:
3678 switch(value & ~D3DTTFF_PROJECTED)
3680 case D3DTTFF_DISABLE:
3681 renderer->setTextureTransform(stage, 0, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
3683 case D3DTTFF_COUNT1:
3684 renderer->setTextureTransform(stage, 1, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
3686 case D3DTTFF_COUNT2:
3687 renderer->setTextureTransform(stage, 2, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
3689 case D3DTTFF_COUNT3:
3690 renderer->setTextureTransform(stage, 3, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
3692 case D3DTTFF_COUNT4:
3693 renderer->setTextureTransform(stage, 4, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED);
3699 case D3DTSS_ADDRESSW:
3702 case D3DTADDRESS_WRAP:
3703 renderer->setAddressingModeW(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_WRAP);
3705 case D3DTADDRESS_MIRROR:
3706 renderer->setAddressingModeW(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRROR);
3708 case D3DTADDRESS_CLAMP:
3709 renderer->setAddressingModeW(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_CLAMP);
3711 case D3DTADDRESS_BORDER:
3712 renderer->setAddressingModeW(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_BORDER);
3714 case D3DTADDRESS_MIRRORONCE:
3715 renderer->setAddressingModeW(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRRORONCE);
3721 case D3DTSS_COLORARG0:
3722 switch(value & D3DTA_SELECTMASK)
3725 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_CURRENT);
3728 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_DIFFUSE);
3730 case D3DTA_SPECULAR:
3731 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_SPECULAR);
3734 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEMP);
3737 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEXTURE);
3740 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TFACTOR);
3746 switch(value & ~D3DTA_SELECTMASK)
3749 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_COLOR);
3751 case D3DTA_COMPLEMENT:
3752 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR);
3754 case D3DTA_ALPHAREPLICATE:
3755 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_ALPHA);
3757 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
3758 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVALPHA);
3764 case D3DTSS_ALPHAARG0:
3765 switch(value & D3DTA_SELECTMASK)
3768 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE);
3771 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT);
3774 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE);
3777 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR);
3779 case D3DTA_SPECULAR:
3780 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR);
3783 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP);
3789 switch(value & ~D3DTA_SELECTMASK)
3792 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR);
3794 case D3DTA_COMPLEMENT:
3795 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR);
3797 case D3DTA_ALPHAREPLICATE:
3798 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA);
3800 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE:
3801 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA);
3807 case D3DTSS_RESULTARG:
3808 switch(value & D3DTA_SELECTMASK)
3811 renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_CURRENT);
3814 renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_TEMP);
3824 else // stateRecorder
3826 stateRecorder.back()->setTextureStageState(stage, type, value);
3832 long Direct3DDevice8::SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
3836 if(!matrix || state < 0 || state > 511)
3838 return INVALIDCALL();
3843 this->matrix[state] = *matrix;
3845 sw::Matrix M(matrix->_11, matrix->_21, matrix->_31, matrix->_41,
3846 matrix->_12, matrix->_22, matrix->_32, matrix->_42,
3847 matrix->_13, matrix->_23, matrix->_33, matrix->_43,
3848 matrix->_14, matrix->_24, matrix->_34, matrix->_44);
3853 renderer->setModelMatrix(M);
3856 renderer->setViewMatrix(M);
3858 case D3DTS_PROJECTION:
3859 renderer->setProjectionMatrix(M);
3861 case D3DTS_TEXTURE0:
3862 renderer->setTextureMatrix(0, M);
3864 case D3DTS_TEXTURE1:
3865 renderer->setTextureMatrix(1, M);
3867 case D3DTS_TEXTURE2:
3868 renderer->setTextureMatrix(2, M);
3870 case D3DTS_TEXTURE3:
3871 renderer->setTextureMatrix(3, M);
3873 case D3DTS_TEXTURE4:
3874 renderer->setTextureMatrix(4, M);
3876 case D3DTS_TEXTURE5:
3877 renderer->setTextureMatrix(5, M);
3879 case D3DTS_TEXTURE6:
3880 renderer->setTextureMatrix(6, M);
3882 case D3DTS_TEXTURE7:
3883 renderer->setTextureMatrix(7, M);
3886 if(state > 256 && state < 512)
3888 renderer->setModelMatrix(M, state - 256);
3893 else // stateRecorder
3895 stateRecorder.back()->setTransform(state, matrix);
3901 long Direct3DDevice8::SetVertexShader(unsigned long handle)
3907 if(handle & 0x00000001)
3909 unsigned int index = handle >> 16;
3911 if(vertexShader[index])
3913 vertexShader[index]->bind();
3916 if(vertexShader[vertexShaderHandle >> 16])
3918 vertexShader[vertexShaderHandle >> 16]->unbind();
3921 vertexShaderHandle = handle;
3923 Direct3DVertexShader8 *shader = vertexShader[index];
3924 renderer->setVertexShader(shader->getVertexShader());
3925 declaration = shader->getDeclaration();
3931 renderer->setVertexShader(0);
3939 stateRecorder.back()->setVertexShader(handle);
3945 long Direct3DDevice8::SetVertexShaderConstant(unsigned long startRegister, const void *constantData, unsigned long count)
3951 return INVALIDCALL();
3956 for(unsigned int i = 0; i < count; i++)
3958 vertexShaderConstant[startRegister + i][0] = ((float*)constantData)[i * 4 + 0];
3959 vertexShaderConstant[startRegister + i][1] = ((float*)constantData)[i * 4 + 1];
3960 vertexShaderConstant[startRegister + i][2] = ((float*)constantData)[i * 4 + 2];
3961 vertexShaderConstant[startRegister + i][3] = ((float*)constantData)[i * 4 + 3];
3964 renderer->setVertexShaderConstantF(startRegister, (const float*)constantData, count);
3968 stateRecorder.back()->setVertexShaderConstant(startRegister, constantData, count);
3974 long Direct3DDevice8::SetViewport(const D3DVIEWPORT8 *viewport)
3980 return INVALIDCALL();
3985 this->viewport = *viewport;
3989 stateRecorder.back()->setViewport(viewport);
3995 int Direct3DDevice8::ShowCursor(int show)
3999 int oldValue = showCursor ? TRUE : FALSE;
4001 showCursor = show != FALSE && cursor;
4008 long Direct3DDevice8::TestCooperativeLevel()
4015 long Direct3DDevice8::UpdateTexture(IDirect3DBaseTexture8 *sourceTexture, IDirect3DBaseTexture8 *destinationTexture)
4019 if(!sourceTexture || !destinationTexture)
4021 return INVALIDCALL();
4024 D3DRESOURCETYPE type = sourceTexture->GetType();
4026 if(type != destinationTexture->GetType())
4028 return INVALIDCALL();
4033 case D3DRTYPE_TEXTURE:
4035 IDirect3DTexture8 *source;
4036 IDirect3DTexture8 *dest;
4038 sourceTexture->QueryInterface(IID_IDirect3DTexture8, (void**)&source);
4039 destinationTexture->QueryInterface(IID_IDirect3DTexture8, (void**)&dest);
4041 ASSERT(source && dest);
4043 for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)
4045 IDirect3DSurface8 *sourceSurface;
4046 IDirect3DSurface8 *destinationSurface;
4048 source->GetSurfaceLevel(level, &sourceSurface);
4049 dest->GetSurfaceLevel(level, &destinationSurface);
4051 updateSurface(sourceSurface, 0, destinationSurface, 0);
4053 sourceSurface->Release();
4054 destinationSurface->Release();
4061 case D3DRTYPE_VOLUMETEXTURE:
4063 IDirect3DVolumeTexture8 *source;
4064 IDirect3DVolumeTexture8 *dest;
4066 sourceTexture->QueryInterface(IID_IDirect3DVolumeTexture8, (void**)&source);
4067 destinationTexture->QueryInterface(IID_IDirect3DVolumeTexture8, (void**)&dest);
4069 ASSERT(source && dest);
4071 for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++) // FIXME: Fail when source texture has fewer levels than the destination
4073 IDirect3DVolume8 *sourceVolume;
4074 IDirect3DVolume8 *destinationVolume;
4076 source->GetVolumeLevel(level, &sourceVolume);
4077 dest->GetVolumeLevel(level, &destinationVolume);
4079 updateVolume(sourceVolume, destinationVolume);
4081 sourceVolume->Release();
4082 destinationVolume->Release();
4089 case D3DRTYPE_CUBETEXTURE:
4091 IDirect3DCubeTexture8 *source;
4092 IDirect3DCubeTexture8 *dest;
4094 sourceTexture->QueryInterface(IID_IDirect3DCubeTexture8, (void**)&source);
4095 destinationTexture->QueryInterface(IID_IDirect3DCubeTexture8, (void**)&dest);
4097 ASSERT(source && dest);
4099 for(int face = 0; face < 6; face++)
4101 for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++)
4103 IDirect3DSurface8 *sourceSurface;
4104 IDirect3DSurface8 *destinationSurface;
4106 source->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &sourceSurface);
4107 dest->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &destinationSurface);
4109 updateSurface(sourceSurface, 0, destinationSurface, 0);
4111 sourceSurface->Release();
4112 destinationSurface->Release();
4127 long Direct3DDevice8::ValidateDevice(unsigned long *numPasses)
4133 return INVALIDCALL();
4141 long Direct3DDevice8::updateSurface(IDirect3DSurface8 *sourceSurface, const RECT *sourceRect, IDirect3DSurface8 *destinationSurface, const POINT *destPoint)
4143 TRACE("IDirect3DSurface8 *sourceSurface = 0x%0.8p, const RECT *sourceRect = 0x%0.8p, IDirect3DSurface8 *destinationSurface = 0x%0.8p, const POINT *destPoint = 0x%0.8p", sourceSurface, sourceRect, destinationSurface, destPoint);
4145 if(!sourceSurface || !destinationSurface)
4147 return INVALIDCALL();
4150 D3DSURFACE_DESC sourceDescription;
4151 D3DSURFACE_DESC destinationDescription;
4153 sourceSurface->GetDesc(&sourceDescription);
4154 destinationSurface->GetDesc(&destinationDescription);
4159 if(sourceRect && destPoint)
4161 sRect.left = sourceRect->left;
4162 sRect.top = sourceRect->top;
4163 sRect.right = sourceRect->right;
4164 sRect.bottom = sourceRect->bottom;
4166 dRect.left = destPoint->x;
4167 dRect.top = destPoint->y;
4168 dRect.right = destPoint->x + sourceRect->right - sourceRect->left;
4169 dRect.bottom = destPoint->y + sourceRect->bottom - sourceRect->top;
4175 sRect.right = sourceDescription.Width;
4176 sRect.bottom = sourceDescription.Height;
4180 dRect.right = destinationDescription.Width;
4181 dRect.bottom = destinationDescription.Height;
4184 int sWidth = sRect.right - sRect.left;
4185 int sHeight = sRect.bottom - sRect.top;
4187 int dWidth = dRect.right - dRect.left;
4188 int dHeight = dRect.bottom - dRect.top;
4190 if(sourceDescription.MultiSampleType != D3DMULTISAMPLE_NONE ||
4191 destinationDescription.MultiSampleType != D3DMULTISAMPLE_NONE ||
4192 // sourceDescription.Pool != D3DPOOL_SYSTEMMEM || // FIXME: Check back buffer and depth buffer memory pool flags
4193 // destinationDescription.Pool != D3DPOOL_DEFAULT ||
4194 sourceDescription.Format != destinationDescription.Format ||
4198 return INVALIDCALL();
4201 D3DLOCKED_RECT sourceLock;
4202 D3DLOCKED_RECT destinationLock;
4204 sourceSurface->LockRect(&sourceLock, &sRect, D3DLOCK_READONLY);
4205 destinationSurface->LockRect(&destinationLock, &dRect, 0);
4208 unsigned int height;
4211 switch(sourceDescription.Format)
4214 width = (dWidth + 3) / 4;
4215 height = (dHeight + 3) / 4;
4216 bytes = width * 8; // 64 bit per 4x4 block
4222 width = (dWidth + 3) / 4;
4223 height = (dHeight + 3) / 4;
4224 bytes = width * 16; // 128 bit per 4x4 block
4229 bytes = width * Direct3DSurface8::bytes(sourceDescription.Format);
4232 for(unsigned int y = 0; y < height; y++)
4234 memcpy(destinationLock.pBits, sourceLock.pBits, bytes);
4236 (byte*&)sourceLock.pBits += sourceLock.Pitch;
4237 (byte*&)destinationLock.pBits += destinationLock.Pitch;
4240 sourceSurface->UnlockRect();
4241 destinationSurface->UnlockRect();
4246 long Direct3DDevice8::SetIndices(IDirect3DIndexBuffer8 *iIndexBuffer, unsigned int baseVertexIndex)
4250 Direct3DIndexBuffer8 *indexBuffer = static_cast<Direct3DIndexBuffer8*>(iIndexBuffer);
4256 indexBuffer->bind();
4261 this->indexData->unbind();
4264 this->indexData = indexBuffer;
4265 this->baseVertexIndex = baseVertexIndex;
4269 stateRecorder.back()->setIndices(indexBuffer, baseVertexIndex);
4275 int Direct3DDevice8::FVFStride(unsigned long FVF)
4279 switch(FVF & D3DFVF_POSITION_MASK)
4281 case D3DFVF_XYZ: stride += 12; break;
4282 case D3DFVF_XYZRHW: stride += 16; break;
4283 case D3DFVF_XYZB1: stride += 16; break;
4284 case D3DFVF_XYZB2: stride += 20; break;
4285 case D3DFVF_XYZB3: stride += 24; break;
4286 case D3DFVF_XYZB4: stride += 28; break;
4287 case D3DFVF_XYZB5: stride += 32; break;
4290 if(FVF & D3DFVF_NORMAL) stride += 12;
4291 if(FVF & D3DFVF_PSIZE) stride += 4;
4292 if(FVF & D3DFVF_DIFFUSE) stride += 4;
4293 if(FVF & D3DFVF_SPECULAR) stride += 4;
4295 switch((FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT)
4297 case 8: stride += 4 + 4 * ((1 + (FVF >> 30)) % 4);
4298 case 7: stride += 4 + 4 * ((1 + (FVF >> 28)) % 4);
4299 case 6: stride += 4 + 4 * ((1 + (FVF >> 26)) % 4);
4300 case 5: stride += 4 + 4 * ((1 + (FVF >> 24)) % 4);
4301 case 4: stride += 4 + 4 * ((1 + (FVF >> 22)) % 4);
4302 case 3: stride += 4 + 4 * ((1 + (FVF >> 20)) % 4);
4303 case 2: stride += 4 + 4 * ((1 + (FVF >> 18)) % 4);
4304 case 1: stride += 4 + 4 * ((1 + (FVF >> 16)) % 4);
4313 int Direct3DDevice8::typeStride(unsigned char type)
4315 static const int LUT[] =
4317 4, // D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.)
4318 8, // D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.)
4319 12, // D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.)
4320 16, // D3DDECLTYPE_FLOAT4 = 3, // 4D float
4321 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)
4322 4, // D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte
4323 4, // D3DDECLTYPE_SHORT2 = 6, // 2D signed short expanded to (value, value, 0., 1.)
4324 8 // D3DDECLTYPE_SHORT4 = 7, // 4D signed short
4336 bool Direct3DDevice8::bindData(Direct3DIndexBuffer8 *indexBuffer, int base)
4340 return false; // Zero-area target region
4345 bindIndexBuffer(indexBuffer);
4351 void Direct3DDevice8::bindStreams(int base)
4353 renderer->resetInputStreams((FVF & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW);
4357 if(!declaration) // Fixed-function vertex pipeline
4359 const void *buffer = 0;
4361 ASSERT(dataStream[0]);
4363 Direct3DVertexBuffer8 *stream = dataStream[0];
4364 sw::Resource *resource = stream->getResource();
4365 buffer = (char*)resource->data();
4366 stride = FVFStride(FVF);
4368 ASSERT(stride == streamStride[0]); // FIXME
4369 ASSERT(buffer && stride);
4371 (char*&)buffer += stride * base;
4373 sw::Stream attribute(resource, buffer, stride);
4375 switch(FVF & D3DFVF_POSITION_MASK)
4378 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3));
4379 (char*&)buffer += 12;
4382 renderer->setInputStream(sw::PositionT, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 4));
4383 (char*&)buffer += 16;
4386 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3));
4387 (char*&)buffer += 12;
4389 renderer->setInputStream(sw::BlendWeight, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 1)); // FIXME: Stream type depends on indexed blending active?
4390 (char*&)buffer += 4;
4393 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3));
4394 (char*&)buffer += 12;
4396 renderer->setInputStream(sw::BlendWeight, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 1)); // FIXME: Stream type depends on indexed blending active?
4397 (char*&)buffer += 8;
4400 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3));
4401 (char*&)buffer += 12;
4403 renderer->setInputStream(sw::BlendWeight, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 2)); // FIXME: Stream type depends on indexed blending active?
4404 (char*&)buffer += 12;
4407 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3));
4408 (char*&)buffer += 12;
4410 renderer->setInputStream(sw::BlendWeight, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3)); // FIXME: Stream type depends on indexed blending active?
4411 (char*&)buffer += 16;
4414 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3));
4415 (char*&)buffer += 12;
4417 renderer->setInputStream(sw::BlendWeight, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 4)); // FIXME: Stream type depends on indexed blending active?
4418 (char*&)buffer += 20;
4422 if(FVF & D3DFVF_LASTBETA_UBYTE4)
4424 renderer->setInputStream(sw::BlendIndices, attribute.define((char*&)buffer - 4, sw::STREAMTYPE_INDICES, 1));
4427 if(FVF & D3DFVF_NORMAL)
4429 renderer->setInputStream(sw::Normal, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3));
4430 (char*&)buffer += 12;
4433 if(FVF & D3DFVF_PSIZE)
4435 renderer->setInputStream(sw::PointSize, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 1));
4436 (char*&)buffer += 4;
4439 if(FVF & D3DFVF_DIFFUSE)
4441 renderer->setInputStream(sw::Color0, attribute.define(buffer, sw::STREAMTYPE_COLOR, 4));
4442 (char*&)buffer += 4;
4445 if(FVF & D3DFVF_SPECULAR)
4447 renderer->setInputStream(sw::Color1, attribute.define(buffer, sw::STREAMTYPE_COLOR, 4));
4448 (char*&)buffer += 4;
4451 for(unsigned int i = 0; i < 8; i++)
4453 if((FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT >= i + 1)
4455 renderer->setInputStream(sw::TexCoord0 + i, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 1 + (1 + (FVF >> (16 + i * 2))) % 4));
4456 (char*&)buffer += 4 + 4 * ((1 + (FVF >> (16 + i * 2))) % 4);
4462 const unsigned long *element = declaration;
4464 sw::Resource *resource;
4465 const void *buffer = 0;
4467 while(*element != 0xFFFFFFFF)
4469 switch((*element & 0xE0000000) >> 29)
4472 if(*element != 0x00000000)
4477 case 1: // Stream selector
4478 stream = *element & 0x0000000F;
4480 ASSERT(dataStream[stream]); // Expected a stream
4482 Direct3DVertexBuffer8 *streamBuffer = (Direct3DVertexBuffer8*)dataStream[stream];
4483 resource = streamBuffer->getResource();
4484 buffer = (char*)resource->data();
4486 const unsigned long *streamElement = element + 1;
4489 while((*streamElement & 0xE0000000) >> 29 == 2) // Data definition
4491 if(*streamElement & 0x10000000) // Data skip
4493 int skip = (*streamElement & 0x000F0000) >> 16;
4499 stride += typeStride((unsigned char)((*streamElement & 0x000F0000) >> 16));
4505 // ASSERT(stride == streamStride[stream]); // FIXME: Probably just ignore
4507 (char*&)buffer += stride * base;
4510 case 2: // Data definition
4511 if(*element & 0x10000000) // Data skip
4513 int skip = (*element & 0x000F0000) >> 16;
4515 (char*&)buffer += 4 * skip;
4519 int type = (*element & 0x000F0000) >> 16;
4520 int index = (*element & 0x0000000F) >> 0;
4522 sw::Stream attribute(resource, buffer, stride);
4526 case D3DVSDT_FLOAT1: attribute.define(sw::STREAMTYPE_FLOAT, 1); break;
4527 case D3DVSDT_FLOAT2: attribute.define(sw::STREAMTYPE_FLOAT, 2); break;
4528 case D3DVSDT_FLOAT3: attribute.define(sw::STREAMTYPE_FLOAT, 3); break;
4529 case D3DVSDT_FLOAT4: attribute.define(sw::STREAMTYPE_FLOAT, 4); break;
4530 case D3DVSDT_D3DCOLOR: attribute.define(sw::STREAMTYPE_COLOR, 4); break;
4531 case D3DVSDT_UBYTE4: attribute.define(sw::STREAMTYPE_BYTE, 4); break;
4532 case D3DVSDT_SHORT2: attribute.define(sw::STREAMTYPE_SHORT, 2); break;
4533 case D3DVSDT_SHORT4: attribute.define(sw::STREAMTYPE_SHORT, 4); break;
4534 default: attribute.define(sw::STREAMTYPE_FLOAT, 0); ASSERT(false);
4539 case D3DVSDE_POSITION: renderer->setInputStream(sw::Position, attribute); break;
4540 case D3DVSDE_BLENDWEIGHT: renderer->setInputStream(sw::BlendWeight, attribute); break;
4541 case D3DVSDE_BLENDINDICES: renderer->setInputStream(sw::BlendIndices, attribute); break;
4542 case D3DVSDE_NORMAL: renderer->setInputStream(sw::Normal, attribute); break;
4543 case D3DVSDE_PSIZE: renderer->setInputStream(sw::PointSize, attribute); break;
4544 case D3DVSDE_DIFFUSE: renderer->setInputStream(sw::Color0, attribute); break;
4545 case D3DVSDE_SPECULAR: renderer->setInputStream(sw::Color1, attribute); break;
4546 case D3DVSDE_TEXCOORD0: renderer->setInputStream(sw::TexCoord0, attribute); break;
4547 case D3DVSDE_TEXCOORD1: renderer->setInputStream(sw::TexCoord1, attribute); break;
4548 case D3DVSDE_TEXCOORD2: renderer->setInputStream(sw::TexCoord2, attribute); break;
4549 case D3DVSDE_TEXCOORD3: renderer->setInputStream(sw::TexCoord3, attribute); break;
4550 case D3DVSDE_TEXCOORD4: renderer->setInputStream(sw::TexCoord4, attribute); break;
4551 case D3DVSDE_TEXCOORD5: renderer->setInputStream(sw::TexCoord5, attribute); break;
4552 case D3DVSDE_TEXCOORD6: renderer->setInputStream(sw::TexCoord6, attribute); break;
4553 case D3DVSDE_TEXCOORD7: renderer->setInputStream(sw::TexCoord7, attribute); break;
4554 // case D3DVSDE_POSITION2: renderer->setInputStream(sw::Position1, attribute); break;
4555 // case D3DVSDE_NORMAL2: renderer->setInputStream(sw::Normal1, attribute); break;
4560 (char*&)buffer += typeStride(type);
4563 case 3: // Tesselator data
4566 case 4: // Constant data
4568 int count = (*element & 0x1E000000) >> 25;
4569 int index = (*element & 0x0000007F) >> 0;
4571 SetVertexShaderConstant(index, element + 1, count);
4573 element += 4 * count;
4576 case 5: // Extension
4588 void Direct3DDevice8::bindIndexBuffer(Direct3DIndexBuffer8 *indexBuffer)
4590 sw::Resource *resource = 0;
4594 resource = indexBuffer->getResource();
4597 renderer->setIndexBuffer(resource);
4600 void Direct3DDevice8::bindLights()
4602 if(!lightsDirty) return;
4604 Lights::iterator i = light.begin();
4607 // Set and enable renderer lights
4610 while(i != light.end() && !i->second.enable)
4615 if(i == light.end())
4620 const Light &l = i->second;
4622 sw::Point position(l.Position.x, l.Position.y, l.Position.z);
4623 sw::Color<float> diffuse(l.Diffuse.r, l.Diffuse.g, l.Diffuse.b, l.Diffuse.a);
4624 sw::Color<float> specular(l.Specular.r, l.Specular.g, l.Specular.b, l.Specular.a);
4625 sw::Color<float> ambient(l.Ambient.r, l.Ambient.g, l.Ambient.b, l.Ambient.a);
4626 sw::Vector direction(l.Direction.x, l.Direction.y, l.Direction.z);
4628 renderer->setLightDiffuse(active, diffuse);
4629 renderer->setLightSpecular(active, specular);
4630 renderer->setLightAmbient(active, ambient);
4632 if(l.Type == D3DLIGHT_DIRECTIONAL)
4634 // goto next; // FIXME
4636 // FIXME: Unsupported, make it a positional light far away without falloff
4637 renderer->setLightPosition(active, -1000 * direction);
4638 renderer->setLightRange(active, l.Range);
4639 renderer->setLightAttenuation(active, 1, 0, 0);
4641 else if(l.Type == D3DLIGHT_SPOT)
4643 // goto next; // FIXME
4645 // FIXME: Unsupported, make it a positional light
4646 renderer->setLightPosition(active, position);
4647 renderer->setLightRange(active, l.Range);
4648 renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);
4652 renderer->setLightPosition(active, position);
4653 renderer->setLightRange(active, l.Range);
4654 renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2);
4657 renderer->setLightEnable(active, true);
4665 // Remaining lights are disabled
4668 renderer->setLightEnable(active, false);
4676 bool Direct3DDevice8::bindViewport()
4678 if(viewport.Width == 0 || viewport.Height == 0)
4684 view.x0 = (float)viewport.X;
4685 view.y0 = (float)viewport.Y + viewport.Height;
4686 view.width = (float)viewport.Width;
4687 view.height = -(float)viewport.Height;
4688 view.minZ = viewport.MinZ;
4689 view.maxZ = viewport.MaxZ;
4691 renderer->setViewport(view);
4694 scissor.x0 = viewport.X;
4695 scissor.x1 = viewport.X + viewport.Width;
4696 scissor.y0 = viewport.Y;
4697 scissor.y1 = viewport.Y + viewport.Height;
4699 renderer->setScissor(scissor);
4704 void Direct3DDevice8::bindTextures()
4706 for(int stage = 0; stage < 8; stage++)
4708 Direct3DBaseTexture8 *baseTexture = texture[stage];
4709 sw::Resource *resource = 0;
4711 bool textureUsed = false;
4713 if(pixelShader[pixelShaderHandle])
4715 textureUsed = pixelShader[pixelShaderHandle]->getPixelShader()->usesSampler(stage);
4719 textureUsed = true; // FIXME: Check fixed-function use?
4722 if(baseTexture && textureUsed)
4724 resource = baseTexture->getResource();
4727 renderer->setTextureResource(stage, resource);
4729 if(baseTexture && textureUsed)
4731 int levelCount = baseTexture->getInternalLevelCount();
4733 int textureLOD = baseTexture->GetLOD();
4734 int stageLOD = textureStageState[stage][D3DTSS_MAXMIPLEVEL];
4735 int LOD = textureLOD > stageLOD ? textureLOD : stageLOD;
4737 if(textureStageState[stage][D3DTSS_MIPFILTER] == D3DTEXF_NONE)
4742 switch(baseTexture->GetType())
4744 case D3DRTYPE_TEXTURE:
4746 Direct3DTexture8 *texture = dynamic_cast<Direct3DTexture8*>(baseTexture);
4747 Direct3DSurface8 *surface;
4749 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
4751 int surfaceLevel = mipmapLevel;
4753 if(surfaceLevel < LOD)
4758 if(surfaceLevel < 0)
4762 else if(surfaceLevel >= levelCount)
4764 surfaceLevel = levelCount - 1;
4767 surface = texture->getInternalSurfaceLevel(surfaceLevel);
4768 renderer->setTextureLevel(stage, 0, mipmapLevel, surface, sw::TEXTURE_2D);
4772 case D3DRTYPE_CUBETEXTURE:
4773 for(int face = 0; face < 6; face++)
4775 Direct3DCubeTexture8 *cubeTexture = dynamic_cast<Direct3DCubeTexture8*>(baseTexture);
4776 Direct3DSurface8 *surface;
4778 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
4780 int surfaceLevel = mipmapLevel;
4782 if(surfaceLevel < LOD)
4787 if(surfaceLevel < 0)
4791 else if(surfaceLevel >= levelCount)
4793 surfaceLevel = levelCount - 1;
4796 surface = cubeTexture->getInternalCubeMapSurface((D3DCUBEMAP_FACES)face, surfaceLevel);
4797 renderer->setTextureLevel(stage, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
4801 case D3DRTYPE_VOLUMETEXTURE:
4803 Direct3DVolumeTexture8 *volumeTexture = dynamic_cast<Direct3DVolumeTexture8*>(baseTexture);
4804 Direct3DVolume8 *volume;
4806 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
4808 int surfaceLevel = mipmapLevel;
4810 if(surfaceLevel < LOD)
4815 if(surfaceLevel < 0)
4819 else if(surfaceLevel >= levelCount)
4821 surfaceLevel = levelCount - 1;
4824 volume = volumeTexture->getInternalVolumeLevel(surfaceLevel);
4825 renderer->setTextureLevel(stage, 0, mipmapLevel, volume, sw::TEXTURE_3D);
4835 renderer->setTextureLevel(stage, 0, 0, 0, sw::TEXTURE_NULL);
4840 void Direct3DDevice8::bindCursor()
4844 sw::FrameBuffer::setCursorImage(cursor);
4846 HCURSOR oldCursor = SetCursor(nullCursor);
4848 if(oldCursor != nullCursor)
4850 win32Cursor = oldCursor;
4855 sw::FrameBuffer::setCursorImage(0);
4857 if(GetCursor() == nullCursor)
4859 SetCursor(win32Cursor);
4864 long Direct3DDevice8::updateVolume(IDirect3DVolume8 *sourceVolume, IDirect3DVolume8 *destinationVolume)
4866 TRACE("IDirect3DVolume8 *sourceVolume = 0x%0.8p, IDirect3DVolume8 *destinationVolume = 0x%0.8p", sourceVolume, destinationVolume);
4868 if(!sourceVolume || !destinationVolume)
4870 return INVALIDCALL();
4873 D3DVOLUME_DESC sourceDescription;
4874 D3DVOLUME_DESC destinationDescription;
4876 sourceVolume->GetDesc(&sourceDescription);
4877 destinationVolume->GetDesc(&destinationDescription);
4879 if(sourceDescription.Pool != D3DPOOL_SYSTEMMEM ||
4880 destinationDescription.Pool != D3DPOOL_DEFAULT ||
4881 sourceDescription.Format != destinationDescription.Format ||
4882 sourceDescription.Width != destinationDescription.Width ||
4883 sourceDescription.Height != destinationDescription.Height)
4885 return INVALIDCALL();
4888 D3DLOCKED_BOX sourceLock;
4889 D3DLOCKED_BOX destinationLock;
4891 sourceVolume->LockBox(&sourceLock, 0, 0);
4892 destinationVolume->LockBox(&destinationLock, 0, 0);
4894 if(sourceLock.RowPitch != destinationLock.RowPitch ||
4895 sourceLock.SlicePitch != destinationLock.SlicePitch)
4900 memcpy(destinationLock.pBits, sourceLock.pBits, sourceLock.SlicePitch * sourceDescription.Depth);
4902 sourceVolume->UnlockBox();
4903 destinationVolume->UnlockBox();
4908 void Direct3DDevice8::configureFPU()
4915 and cw, 0xFCFC // Single-precision
4916 or cw, 0x003F // Mask all exceptions
4917 and cw, 0xF3FF // Round to nearest