1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "Direct3DDevice8.hpp" 16 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" 28 29 #include "Debug.hpp" 30 #include "Capabilities.hpp" 31 #include "Renderer.hpp" 32 #include "Config.hpp" 33 #include "FrameBuffer.hpp" 34 #include "Clipper.hpp" 35 #include "Configurator.hpp" 36 #include "Timer.hpp" 37 #include "Resource.hpp" 38 39 #include <assert.h> 40 41 bool localShaderConstants = false; 42 43 namespace D3D8 44 { FtoDW(float f)45 inline unsigned long FtoDW(float f) // FIXME: Deprecate 46 { 47 return (unsigned long&)f; 48 } 49 Direct3DDevice8(const HINSTANCE instance,Direct3D8 * d3d8,unsigned int adapter,D3DDEVTYPE deviceType,HWND focusWindow,unsigned long behaviourFlags,D3DPRESENT_PARAMETERS * presentParameters)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) 51 { 52 init = true; 53 recordState = false; 54 55 d3d8->AddRef(); 56 57 context = new sw::Context(); 58 renderer = new sw::Renderer(context, sw::Direct3D, false); 59 60 swapChain.push_back(0); 61 depthStencil = 0; 62 renderTarget = 0; 63 64 for(int i = 0; i < 8; i++) 65 { 66 texture[i] = 0; 67 } 68 69 cursor = 0; 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(); 75 76 Reset(presentParameters); 77 78 pixelShader.push_back(0); // pixelShader[0] = 0 79 vertexShader.push_back(0); // vertexShader[0] = 0 80 vertexShaderHandle = 0; 81 pixelShaderHandle = 0; 82 83 lightsDirty = true; 84 85 for(int i = 0; i < 16; i++) 86 { 87 dataStream[i] = 0; 88 streamStride[i] = 0; 89 } 90 91 indexData = 0; 92 baseVertexIndex = 0; 93 declaration = 0; 94 FVF = 0; 95 96 D3DMATERIAL8 material; 97 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; 115 116 SetMaterial(&material); 117 118 D3DMATRIX identity = {1, 0, 0, 0, 119 0, 1, 0, 0, 120 0, 0, 1, 0, 121 0, 0, 0, 1}; 122 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); 133 134 for(int i = 0; i < 12; i++) 135 { 136 SetTransform(D3DTS_WORLDMATRIX(i), &identity); 137 } 138 139 for(int i = 0; i < 8; i++) 140 { 141 float zero[4] = {0, 0, 0, 0}; 142 143 SetPixelShaderConstant(i, zero, 1); 144 } 145 146 for(int i = 0; i < 256; i++) 147 { 148 float zero[4] = {0, 0, 0, 0}; 149 150 SetVertexShaderConstant(i, zero, 1); 151 } 152 153 init = false; 154 155 if(!(behaviourFlags & D3DCREATE_FPU_PRESERVE)) 156 { 157 configureFPU(); 158 } 159 } 160 ~Direct3DDevice8()161 Direct3DDevice8::~Direct3DDevice8() 162 { 163 delete renderer; 164 renderer = 0; 165 delete context; 166 context = 0; 167 168 d3d8->Release(); 169 d3d8 = 0; 170 171 for(unsigned int i = 0; i < swapChain.size(); i++) 172 { 173 if(swapChain[i]) 174 { 175 swapChain[i]->unbind(); 176 swapChain[i] = 0; 177 } 178 } 179 180 if(depthStencil) 181 { 182 depthStencil->unbind(); 183 depthStencil = 0; 184 } 185 186 if(renderTarget) 187 { 188 renderTarget->unbind(); 189 renderTarget = 0; 190 } 191 192 for(int i = 0; i < 8; i++) 193 { 194 if(texture[i]) 195 { 196 texture[i]->unbind(); 197 texture[i] = 0; 198 } 199 } 200 201 for(int i = 0; i < 16; i++) 202 { 203 if(dataStream[i]) 204 { 205 dataStream[i]->unbind(); 206 dataStream[i] = 0; 207 } 208 } 209 210 if(indexData) 211 { 212 indexData->unbind(); 213 indexData = 0; 214 } 215 216 for(unsigned int i = 0; i < pixelShader.size(); i++) 217 { 218 if(pixelShader[i]) 219 { 220 pixelShader[i]->unbind(); 221 pixelShader[i] = 0; 222 } 223 } 224 225 for(unsigned int i = 0; i < vertexShader.size(); i++) 226 { 227 if(vertexShader[i]) 228 { 229 vertexShader[i]->unbind(); 230 vertexShader[i] = 0; 231 } 232 } 233 234 for(unsigned int i = 0; i < stateRecorder.size(); i++) 235 { 236 if(stateRecorder[i]) 237 { 238 stateRecorder[i]->unbind(); 239 stateRecorder[i] = 0; 240 } 241 } 242 243 palette.clear(); 244 245 delete cursor; 246 DestroyCursor(nullCursor); 247 } 248 QueryInterface(const IID & iid,void ** object)249 long Direct3DDevice8::QueryInterface(const IID &iid, void **object) 250 { 251 TRACE(""); 252 253 if(iid == IID_IDirect3DDevice8 || 254 iid == IID_IUnknown) 255 { 256 AddRef(); 257 *object = this; 258 259 return S_OK; 260 } 261 262 *object = 0; 263 264 return NOINTERFACE(iid); 265 } 266 AddRef()267 unsigned long Direct3DDevice8::AddRef() 268 { 269 TRACE(""); 270 271 return Unknown::AddRef(); 272 } 273 Release()274 unsigned long Direct3DDevice8::Release() 275 { 276 TRACE(""); 277 278 return Unknown::Release(); 279 } 280 ApplyStateBlock(unsigned long token)281 long Direct3DDevice8::ApplyStateBlock(unsigned long token) 282 { 283 TRACE(""); 284 285 stateRecorder[token]->Apply(); 286 287 return D3D_OK; 288 } 289 BeginScene()290 long Direct3DDevice8::BeginScene() 291 { 292 TRACE(""); 293 294 return D3D_OK; 295 } 296 BeginStateBlock()297 long Direct3DDevice8::BeginStateBlock() 298 { 299 TRACE(""); 300 301 recordState = true; 302 Direct3DStateBlock8 *stateBlock = new Direct3DStateBlock8(this, (D3DSTATEBLOCKTYPE)0); 303 stateBlock->bind(); 304 stateRecorder.push_back(stateBlock); 305 306 return D3D_OK; 307 } 308 CaptureStateBlock(unsigned long token)309 long Direct3DDevice8::CaptureStateBlock(unsigned long token) 310 { 311 TRACE(""); 312 313 stateRecorder[token]->Capture(); 314 315 return D3D_OK; 316 } 317 Clear(unsigned long count,const D3DRECT * rects,unsigned long flags,unsigned long color,float z,unsigned long stencil)318 long Direct3DDevice8::Clear(unsigned long count, const D3DRECT *rects, unsigned long flags, unsigned long color, float z, unsigned long stencil) 319 { 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); 321 322 if(!rects && count != 0) 323 { 324 return INVALIDCALL(); 325 } 326 327 if(flags & (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL) && !depthStencil) 328 { 329 return INVALIDCALL(); 330 } 331 332 if(flags & D3DCLEAR_STENCIL) // Check for stencil component 333 { 334 D3DSURFACE_DESC description; 335 depthStencil->GetDesc(&description); 336 337 switch(description.Format) 338 { 339 case D3DFMT_D15S1: 340 case D3DFMT_D24S8: 341 case D3DFMT_D24X8: 342 case D3DFMT_D24X4S4: 343 break; 344 case D3DFMT_D16_LOCKABLE: 345 case D3DFMT_D32: 346 case D3DFMT_D16: 347 return INVALIDCALL(); 348 default: 349 ASSERT(false); 350 } 351 } 352 353 if(!rects) 354 { 355 count = 1; 356 357 D3DRECT rect; 358 rect.x1 = viewport.X; 359 rect.x2 = viewport.X + viewport.Width; 360 rect.y1 = viewport.Y; 361 rect.y2 = viewport.Y + viewport.Height; 362 363 rects = ▭ 364 } 365 366 for(unsigned int i = 0; i < count; i++) 367 { 368 sw::Rect clearRect(rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2); 369 370 clearRect.clip(viewport.X, viewport.Y, viewport.X + viewport.Width, viewport.Y + viewport.Height); 371 372 if(flags & D3DCLEAR_TARGET) 373 { 374 if(renderTarget) 375 { 376 D3DSURFACE_DESC description; 377 renderTarget->GetDesc(&description); 378 379 float rgba[4]; 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; 384 385 renderer->clear(rgba, sw::FORMAT_A32B32G32R32F, renderTarget, clearRect, 0xF); 386 } 387 } 388 389 if(flags & D3DCLEAR_ZBUFFER) 390 { 391 z = sw::clamp01(z); 392 depthStencil->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height()); 393 } 394 395 if(flags & D3DCLEAR_STENCIL) 396 { 397 depthStencil->clearStencil(stencil, 0xFF, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height()); 398 } 399 } 400 401 return D3D_OK; 402 } 403 CopyRects(IDirect3DSurface8 * sourceSurface,const RECT * sourceRectsArray,unsigned int rects,IDirect3DSurface8 * destinationSurface,const POINT * destPointsArray)404 long Direct3DDevice8::CopyRects(IDirect3DSurface8 *sourceSurface, const RECT *sourceRectsArray, unsigned int rects, IDirect3DSurface8 *destinationSurface, const POINT *destPointsArray) 405 { 406 TRACE(""); 407 408 if(!sourceSurface || !destinationSurface) 409 { 410 return INVALIDCALL(); 411 } 412 413 if(sourceRectsArray && rects == 0 || !sourceRectsArray && rects > 0) 414 { 415 return INVALIDCALL(); // FIXME: Verify REF behaviour 416 } 417 418 D3DSURFACE_DESC sourceDescription; 419 D3DSURFACE_DESC destDescription; 420 421 sourceSurface->GetDesc(&sourceDescription); 422 destinationSurface->GetDesc(&destDescription); 423 424 if(sourceDescription.Format != destDescription.Format) 425 { 426 return INVALIDCALL(); 427 } 428 429 int sWidth = sourceDescription.Width; 430 int sHeight = sourceDescription.Height; 431 int dWidth = destDescription.Width; 432 int dHeight = destDescription.Height; 433 434 RECT sRect = {0, 0, sWidth, sHeight}; 435 POINT dPoint = {0, 0}; 436 437 if(!sourceRectsArray || !destPointsArray) 438 { 439 sourceRectsArray = &sRect; 440 destPointsArray = &dPoint; 441 442 rects = 1; 443 } 444 445 int bpp = 8 * Direct3DSurface8::bytes(sourceDescription.Format); 446 447 for(unsigned int i = 0; i < rects; i++) 448 { 449 const RECT &sRect = sourceRectsArray[i]; 450 const POINT &dPoint = destPointsArray[i]; 451 452 int rWidth = sRect.right - sRect.left; 453 int rHeight = sRect.bottom - sRect.top; 454 455 RECT dRect; 456 457 dRect.top = dPoint.y; 458 dRect.left = dPoint.x; 459 dRect.bottom = dPoint.y + rHeight; 460 dRect.right = dPoint.x + rWidth; 461 462 D3DLOCKED_RECT sourceLock; 463 D3DLOCKED_RECT destLock; 464 465 sourceSurface->LockRect(&sourceLock, &sRect, D3DLOCK_READONLY); 466 destinationSurface->LockRect(&destLock, &dRect, D3DLOCK_DISCARD); 467 468 for(int y = 0; y < rHeight; y++) 469 { 470 switch(sourceDescription.Format) 471 { 472 case D3DFMT_DXT1: 473 case D3DFMT_DXT2: 474 case D3DFMT_DXT3: 475 case D3DFMT_DXT4: 476 case D3DFMT_DXT5: 477 memcpy(destLock.pBits, sourceLock.pBits, rWidth * bpp / 8); 478 y += 3; // Advance four lines at once 479 break; 480 default: 481 memcpy(destLock.pBits, sourceLock.pBits, rWidth * bpp / 8); 482 } 483 484 (char*&)sourceLock.pBits += sourceLock.Pitch; 485 (char*&)destLock.pBits += destLock.Pitch; 486 } 487 488 sourceSurface->UnlockRect(); 489 destinationSurface->UnlockRect(); 490 } 491 492 return D3D_OK; 493 } 494 CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS * presentParameters,IDirect3DSwapChain8 ** swapChain)495 long Direct3DDevice8::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *presentParameters, IDirect3DSwapChain8 **swapChain) 496 { 497 TRACE(""); 498 499 *swapChain = 0; 500 501 if(!presentParameters || !swapChain) 502 { 503 return INVALIDCALL(); 504 } 505 506 if(presentParameters->BackBufferCount > 3) 507 { 508 return INVALIDCALL(); // Maximum of three back buffers 509 } 510 511 if(presentParameters->BackBufferCount == 0) 512 { 513 presentParameters->BackBufferCount = 1; 514 } 515 516 D3DPRESENT_PARAMETERS present = *presentParameters; 517 518 *swapChain = new Direct3DSwapChain8(this, &present); 519 520 if(!*swapChain) 521 { 522 return OUTOFMEMORY(); 523 } 524 525 if(GetAvailableTextureMem() == 0) 526 { 527 delete *swapChain; 528 529 return OUTOFVIDEOMEMORY(); 530 } 531 532 this->swapChain.push_back(static_cast<Direct3DSwapChain8*>(*swapChain)); 533 534 (*swapChain)->AddRef(); 535 536 return D3D_OK; 537 } 538 CreateCubeTexture(unsigned int edgeLength,unsigned int levels,unsigned long usage,D3DFORMAT format,D3DPOOL pool,IDirect3DCubeTexture8 ** cubeTexture)539 long Direct3DDevice8::CreateCubeTexture(unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture8 **cubeTexture) 540 { 541 TRACE(""); 542 543 *cubeTexture = 0; 544 545 if(edgeLength == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_CUBETEXTURE, format) != D3D_OK) 546 { 547 return INVALIDCALL(); 548 } 549 550 *cubeTexture = new Direct3DCubeTexture8(this, edgeLength, levels, usage, format, pool); 551 552 if(!*cubeTexture) 553 { 554 return OUTOFMEMORY(); 555 } 556 557 if(GetAvailableTextureMem() == 0) 558 { 559 delete *cubeTexture; 560 561 return OUTOFVIDEOMEMORY(); 562 } 563 564 (*cubeTexture)->AddRef(); 565 566 return D3D_OK; 567 } 568 CreateDepthStencilSurface(unsigned int width,unsigned int height,D3DFORMAT format,D3DMULTISAMPLE_TYPE multiSample,IDirect3DSurface8 ** surface)569 long Direct3DDevice8::CreateDepthStencilSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, IDirect3DSurface8 **surface) 570 { 571 TRACE(""); 572 573 *surface = 0; 574 575 if(width == 0 || height == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION) 576 { 577 return INVALIDCALL(); 578 } 579 580 *surface = new Direct3DSurface8(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, format == D3DFMT_D16_LOCKABLE, D3DUSAGE_DEPTHSTENCIL); 581 582 if(!*surface) 583 { 584 return OUTOFMEMORY(); 585 } 586 587 if(GetAvailableTextureMem() == 0) 588 { 589 delete *surface; 590 591 return OUTOFVIDEOMEMORY(); 592 } 593 594 (*surface)->AddRef(); 595 596 return D3D_OK; 597 } 598 CreateImageSurface(unsigned int width,unsigned int height,D3DFORMAT format,IDirect3DSurface8 ** surface)599 long Direct3DDevice8::CreateImageSurface(unsigned int width, unsigned int height, D3DFORMAT format, IDirect3DSurface8 **surface) 600 { 601 TRACE(""); 602 603 *surface = 0; 604 605 if(width == 0 || height == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, format) != D3D_OK) 606 { 607 return INVALIDCALL(); 608 } 609 610 *surface = new Direct3DSurface8(this, this, width, height, format, D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, true, 0); 611 612 if(!*surface) 613 { 614 return OUTOFMEMORY(); 615 } 616 617 if(GetAvailableTextureMem() == 0) 618 { 619 delete *surface; 620 621 return OUTOFVIDEOMEMORY(); 622 } 623 624 (*surface)->AddRef(); 625 626 return D3D_OK; 627 } 628 CreateIndexBuffer(unsigned int length,unsigned long usage,D3DFORMAT format,D3DPOOL pool,IDirect3DIndexBuffer8 ** indexBuffer)629 long Direct3DDevice8::CreateIndexBuffer(unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer8 **indexBuffer) 630 { 631 TRACE(""); 632 633 *indexBuffer = new Direct3DIndexBuffer8(this, length, usage, format, pool); 634 635 if(!*indexBuffer) 636 { 637 return OUTOFMEMORY(); 638 } 639 640 if(GetAvailableTextureMem() == 0) 641 { 642 delete *indexBuffer; 643 644 return OUTOFVIDEOMEMORY(); 645 } 646 647 (*indexBuffer)->AddRef(); 648 649 return D3D_OK; 650 } 651 CreatePixelShader(const unsigned long * function,unsigned long * handle)652 long Direct3DDevice8::CreatePixelShader(const unsigned long *function, unsigned long *handle) 653 { 654 TRACE(""); 655 656 if(!function || !handle || function[0] > pixelShaderVersion) 657 { 658 return INVALIDCALL(); 659 } 660 661 unsigned int index; 662 663 for(index = 1; index < pixelShader.size(); index++) // Skip NULL handle 664 { 665 if(pixelShader[index] == 0) 666 { 667 pixelShader[index] = new Direct3DPixelShader8(this, function); // FIXME: Check for null 668 669 break; 670 } 671 } 672 673 if(index == pixelShader.size()) 674 { 675 pixelShader.push_back(new Direct3DPixelShader8(this, function)); 676 } 677 678 pixelShader[index]->AddRef(); 679 680 *handle = index; 681 682 return D3D_OK; 683 } 684 CreateRenderTarget(unsigned int width,unsigned int height,D3DFORMAT format,D3DMULTISAMPLE_TYPE multiSample,int lockable,IDirect3DSurface8 ** surface)685 long Direct3DDevice8::CreateRenderTarget(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, int lockable, IDirect3DSurface8 **surface) 686 { 687 TRACE(""); 688 689 *surface = 0; 690 691 if(width == 0 || height == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, format) != D3D_OK || height > sw::OUTLINE_RESOLUTION) 692 { 693 return INVALIDCALL(); 694 } 695 696 *surface = new Direct3DSurface8(this, this, width, height, format, D3DPOOL_DEFAULT, multiSample, lockable != FALSE, D3DUSAGE_RENDERTARGET); 697 698 if(!*surface) 699 { 700 return OUTOFMEMORY(); 701 } 702 703 if(GetAvailableTextureMem() == 0) 704 { 705 delete *surface; 706 707 return OUTOFVIDEOMEMORY(); 708 } 709 710 (*surface)->AddRef(); 711 712 return D3D_OK; 713 } 714 CreateStateBlock(D3DSTATEBLOCKTYPE type,unsigned long * token)715 long Direct3DDevice8::CreateStateBlock(D3DSTATEBLOCKTYPE type, unsigned long *token) 716 { 717 TRACE(""); 718 719 if(!token) 720 { 721 return INVALIDCALL(); 722 } 723 724 Direct3DStateBlock8 *stateBlock = new Direct3DStateBlock8(this, type); 725 stateBlock->bind(); 726 stateRecorder.push_back(stateBlock); 727 *token = (unsigned long)(stateRecorder.size() - 1); 728 729 return D3D_OK; 730 } 731 CreateTexture(unsigned int width,unsigned int height,unsigned int levels,unsigned long usage,D3DFORMAT format,D3DPOOL pool,IDirect3DTexture8 ** texture)732 long Direct3DDevice8::CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture8 **texture) 733 { 734 TRACE(""); 735 736 *texture = 0; 737 738 if(width == 0 || height == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_TEXTURE, format) != D3D_OK) 739 { 740 return INVALIDCALL(); 741 } 742 743 *texture = new Direct3DTexture8(this, width, height, levels, usage, format, pool); 744 745 if(!*texture) 746 { 747 return OUTOFMEMORY(); 748 } 749 750 if(GetAvailableTextureMem() == 0) 751 { 752 delete *texture; 753 754 return OUTOFVIDEOMEMORY(); 755 } 756 757 (*texture)->AddRef(); 758 759 return D3D_OK; 760 } 761 CreateVertexBuffer(unsigned int length,unsigned long usage,unsigned long FVF,D3DPOOL pool,IDirect3DVertexBuffer8 ** vertexBuffer)762 long Direct3DDevice8::CreateVertexBuffer(unsigned int length, unsigned long usage, unsigned long FVF, D3DPOOL pool, IDirect3DVertexBuffer8 **vertexBuffer) 763 { 764 TRACE(""); 765 766 *vertexBuffer = new Direct3DVertexBuffer8(this, length, usage, FVF, pool); 767 768 if(!*vertexBuffer) 769 { 770 return OUTOFMEMORY(); 771 } 772 773 if(GetAvailableTextureMem() == 0) 774 { 775 delete *vertexBuffer; 776 777 return OUTOFVIDEOMEMORY(); 778 } 779 780 (*vertexBuffer)->AddRef(); 781 782 return D3D_OK; 783 } 784 CreateVertexShader(const unsigned long * declaration,const unsigned long * function,unsigned long * handle,unsigned long usage)785 long Direct3DDevice8::CreateVertexShader(const unsigned long *declaration, const unsigned long *function, unsigned long *handle, unsigned long usage) 786 { 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); 788 789 if(!declaration || !handle || (function && function[0] > vertexShaderVersion)) 790 { 791 return INVALIDCALL(); 792 } 793 794 unsigned int index; 795 796 for(index = 1; index < vertexShader.size(); index++) // NOTE: skip NULL handle 797 { 798 if(vertexShader[index] == 0) 799 { 800 vertexShader[index] = new Direct3DVertexShader8(this, declaration, function); // FIXME: Check for null 801 802 break; 803 } 804 } 805 806 if(index == vertexShader.size()) 807 { 808 vertexShader.push_back(new Direct3DVertexShader8(this, declaration, function)); 809 } 810 811 vertexShader[index]->AddRef(); 812 813 *handle = (index << 16) + 1; 814 815 return D3D_OK; 816 } 817 CreateVolumeTexture(unsigned int width,unsigned int height,unsigned int depth,unsigned int levels,unsigned long usage,D3DFORMAT format,D3DPOOL pool,IDirect3DVolumeTexture8 ** volumeTexture)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) 819 { 820 TRACE(""); 821 822 *volumeTexture = 0; 823 824 if(width == 0 || height == 0 || depth == 0 || d3d8->CheckDeviceFormat(adapter, deviceType, D3DFMT_X8R8G8B8, usage, D3DRTYPE_VOLUMETEXTURE, format) != D3D_OK) 825 { 826 return INVALIDCALL(); 827 } 828 829 *volumeTexture = new Direct3DVolumeTexture8(this, width, height, depth, levels, usage, format, pool); 830 831 if(!*volumeTexture) 832 { 833 return OUTOFMEMORY(); 834 } 835 836 if(GetAvailableTextureMem() == 0) 837 { 838 delete *volumeTexture; 839 840 return OUTOFVIDEOMEMORY(); 841 } 842 843 (*volumeTexture)->AddRef(); 844 845 return D3D_OK; 846 } 847 DeletePatch(unsigned int handle)848 long Direct3DDevice8::DeletePatch(unsigned int handle) 849 { 850 TRACE(""); 851 852 UNIMPLEMENTED(); 853 854 return D3D_OK; 855 } 856 DeleteStateBlock(unsigned long token)857 long Direct3DDevice8::DeleteStateBlock(unsigned long token) 858 { 859 TRACE(""); 860 861 if(token >= stateRecorder.size() || !stateRecorder[token]) 862 { 863 return INVALIDCALL(); 864 } 865 866 stateRecorder[token]->unbind(); 867 stateRecorder[token] = 0; 868 869 return D3D_OK; 870 } 871 DeleteVertexShader(unsigned long handle)872 long Direct3DDevice8::DeleteVertexShader(unsigned long handle) 873 { 874 TRACE(""); 875 876 unsigned int index = handle >> 16; 877 878 if(index >= vertexShader.size() || !vertexShader[index]) 879 { 880 return INVALIDCALL(); 881 } 882 883 vertexShader[index]->Release(); 884 vertexShader[index] = 0; 885 886 return D3D_OK; 887 } 888 DrawIndexedPrimitive(D3DPRIMITIVETYPE type,unsigned int minIndex,unsigned int numVertices,unsigned int startIndex,unsigned int primitiveCount)889 long Direct3DDevice8::DrawIndexedPrimitive(D3DPRIMITIVETYPE type, unsigned int minIndex, unsigned int numVertices, unsigned int startIndex, unsigned int primitiveCount) 890 { 891 TRACE(""); 892 893 if(!indexData) 894 { 895 return INVALIDCALL(); 896 } 897 898 if(!bindData(indexData, baseVertexIndex) || !primitiveCount) 899 { 900 return D3D_OK; 901 } 902 903 unsigned int indexOffset = startIndex * (indexData->is32Bit() ? 4 : 2); // FIXME: Doesn't take stream frequencies into account 904 905 sw::DrawType drawType; 906 907 if(indexData->is32Bit()) 908 { 909 switch(type) 910 { 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; 917 default: 918 ASSERT(false); 919 } 920 } 921 else 922 { 923 switch(type) 924 { 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; 931 default: 932 ASSERT(false); 933 } 934 } 935 936 bindData(indexData, baseVertexIndex); 937 938 renderer->draw(drawType, indexOffset, primitiveCount); 939 940 return D3D_OK; 941 } 942 DeletePixelShader(unsigned long handle)943 long Direct3DDevice8::DeletePixelShader(unsigned long handle) 944 { 945 TRACE(""); 946 947 if(handle >= pixelShader.size() || !pixelShader[handle]) 948 { 949 return INVALIDCALL(); 950 } 951 952 pixelShader[handle]->Release(); 953 pixelShader[handle] = 0; 954 955 return D3D_OK; 956 } 957 DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE type,unsigned int minIndex,unsigned int numVertices,unsigned int primitiveCount,const void * indexData,D3DFORMAT indexDataFormat,const void * vertexStreamZeroData,unsigned int vertexStreamZeroStride)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) 959 { 960 TRACE(""); 961 962 if(!vertexStreamZeroData || !indexData) 963 { 964 return INVALIDCALL(); 965 } 966 967 int length = (minIndex + numVertices) * vertexStreamZeroStride; 968 969 Direct3DVertexBuffer8 *vertexBuffer = new Direct3DVertexBuffer8(this, length, 0, 0, D3DPOOL_DEFAULT); 970 971 unsigned char *data; 972 vertexBuffer->Lock(0, 0, &data, 0); 973 memcpy(data, vertexStreamZeroData, length); 974 vertexBuffer->Unlock(); 975 976 SetStreamSource(0, vertexBuffer, vertexStreamZeroStride); 977 978 switch(type) 979 { 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; 986 default: 987 ASSERT(false); 988 } 989 990 length *= indexDataFormat == D3DFMT_INDEX32 ? 4 : 2; 991 992 Direct3DIndexBuffer8 *indexBuffer = new Direct3DIndexBuffer8(this, length, 0, indexDataFormat, D3DPOOL_DEFAULT); 993 994 indexBuffer->Lock(0, 0, &data, 0); 995 memcpy(data, indexData, length); 996 indexBuffer->Unlock(); 997 998 SetIndices(indexBuffer, 0); 999 1000 if(!bindData(indexBuffer, 0) || !primitiveCount) 1001 { 1002 vertexBuffer->Release(); 1003 1004 return D3D_OK; 1005 } 1006 1007 sw::DrawType drawType; 1008 1009 if(indexDataFormat == D3DFMT_INDEX32) 1010 { 1011 switch(type) 1012 { 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; 1019 default: 1020 ASSERT(false); 1021 } 1022 } 1023 else 1024 { 1025 switch(type) 1026 { 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; 1033 default: 1034 ASSERT(false); 1035 } 1036 } 1037 1038 renderer->draw(drawType, 0, primitiveCount); 1039 1040 SetStreamSource(0, 0, 0); 1041 SetIndices(0, 0); 1042 1043 return D3D_OK; 1044 } 1045 DrawPrimitive(D3DPRIMITIVETYPE primitiveType,unsigned int startVertex,unsigned int primitiveCount)1046 long Direct3DDevice8::DrawPrimitive(D3DPRIMITIVETYPE primitiveType, unsigned int startVertex, unsigned int primitiveCount) 1047 { 1048 TRACE(""); 1049 1050 if(!bindData(0, startVertex) || !primitiveCount) 1051 { 1052 return D3D_OK; 1053 } 1054 1055 sw::DrawType drawType; 1056 1057 switch(primitiveType) 1058 { 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; 1065 default: 1066 ASSERT(false); 1067 } 1068 1069 renderer->draw(drawType, 0, primitiveCount); 1070 1071 return D3D_OK; 1072 } 1073 DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType,unsigned int primitiveCount,const void * vertexStreamZeroData,unsigned int vertexStreamZeroStride)1074 long Direct3DDevice8::DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType, unsigned int primitiveCount, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride) 1075 { 1076 TRACE(""); 1077 1078 if(!vertexStreamZeroData) 1079 { 1080 return INVALIDCALL(); 1081 } 1082 1083 IDirect3DVertexBuffer8 *vertexBuffer = 0; 1084 int length = 0; 1085 1086 switch(primitiveType) 1087 { 1088 case D3DPT_POINTLIST: length = primitiveCount; break; 1089 case D3DPT_LINELIST: length = primitiveCount * 2; break; 1090 case D3DPT_LINESTRIP: length = primitiveCount + 1; break; 1091 case D3DPT_TRIANGLELIST: length = primitiveCount * 3; break; 1092 case D3DPT_TRIANGLESTRIP: length = primitiveCount + 2; break; 1093 case D3DPT_TRIANGLEFAN: length = primitiveCount + 2; break; 1094 default: 1095 ASSERT(false); 1096 } 1097 1098 length *= vertexStreamZeroStride; 1099 1100 CreateVertexBuffer(length, 0, 0, D3DPOOL_DEFAULT, &vertexBuffer); 1101 1102 unsigned char *data; 1103 vertexBuffer->Lock(0, 0, &data, 0); 1104 memcpy(data, vertexStreamZeroData, length); 1105 vertexBuffer->Unlock(); 1106 1107 SetStreamSource(0, vertexBuffer, vertexStreamZeroStride); 1108 1109 if(!bindData(0, 0) || !primitiveCount) 1110 { 1111 vertexBuffer->Release(); 1112 1113 return D3D_OK; 1114 } 1115 1116 sw::DrawType drawType; 1117 1118 switch(primitiveType) 1119 { 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; 1126 default: 1127 ASSERT(false); 1128 } 1129 1130 renderer->draw(drawType, 0, primitiveCount); 1131 1132 SetStreamSource(0, 0, 0); 1133 vertexBuffer->Release(); 1134 1135 return D3D_OK; 1136 } 1137 DrawRectPatch(unsigned int handle,const float * numSegs,const D3DRECTPATCH_INFO * rectPatchInfo)1138 long Direct3DDevice8::DrawRectPatch(unsigned int handle, const float *numSegs, const D3DRECTPATCH_INFO *rectPatchInfo) 1139 { 1140 TRACE(""); 1141 1142 if(!numSegs || !rectPatchInfo) 1143 { 1144 return INVALIDCALL(); 1145 } 1146 1147 UNIMPLEMENTED(); 1148 1149 return D3D_OK; 1150 } 1151 DrawTriPatch(unsigned int handle,const float * numSegs,const D3DTRIPATCH_INFO * triPatchInfo)1152 long Direct3DDevice8::DrawTriPatch(unsigned int handle, const float *numSegs, const D3DTRIPATCH_INFO *triPatchInfo) 1153 { 1154 TRACE(""); 1155 1156 if(!numSegs || !triPatchInfo) 1157 { 1158 return INVALIDCALL(); 1159 } 1160 1161 UNIMPLEMENTED(); 1162 1163 return D3D_OK; 1164 } 1165 EndScene()1166 long Direct3DDevice8::EndScene() 1167 { 1168 TRACE(""); 1169 1170 return D3D_OK; 1171 } 1172 EndStateBlock(unsigned long * token)1173 long Direct3DDevice8::EndStateBlock(unsigned long *token) 1174 { 1175 TRACE(""); 1176 1177 if(!token) 1178 { 1179 return INVALIDCALL(); 1180 } 1181 1182 recordState = false; 1183 *token = (unsigned long)(stateRecorder.size() - 1); 1184 1185 return D3D_OK; 1186 } 1187 GetAvailableTextureMem()1188 unsigned int Direct3DDevice8::GetAvailableTextureMem() 1189 { 1190 TRACE(""); 1191 1192 int availableMemory = textureMemory - Direct3DResource8::getMemoryUsage(); 1193 if(availableMemory < 0) availableMemory = 0; 1194 1195 // Round to nearest MB 1196 return (availableMemory + 0x80000) & 0xFFF00000; 1197 } 1198 GetBackBuffer(unsigned int index,D3DBACKBUFFER_TYPE type,IDirect3DSurface8 ** backBuffer)1199 long Direct3DDevice8::GetBackBuffer(unsigned int index, D3DBACKBUFFER_TYPE type, IDirect3DSurface8 **backBuffer) 1200 { 1201 TRACE(""); 1202 1203 if(!backBuffer/* || type != D3DBACKBUFFER_TYPE_MONO*/) 1204 { 1205 return INVALIDCALL(); 1206 } 1207 1208 swapChain[index]->GetBackBuffer(index, type, backBuffer); 1209 1210 return D3D_OK; 1211 } 1212 GetClipPlane(unsigned long index,float * plane)1213 long Direct3DDevice8::GetClipPlane(unsigned long index, float *plane) 1214 { 1215 TRACE(""); 1216 1217 if(!plane || index >= 6) 1218 { 1219 return INVALIDCALL(); 1220 } 1221 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]; 1226 1227 return D3D_OK; 1228 } 1229 GetClipStatus(D3DCLIPSTATUS8 * clipStatus)1230 long Direct3DDevice8::GetClipStatus(D3DCLIPSTATUS8 *clipStatus) 1231 { 1232 TRACE(""); 1233 1234 if(!clipStatus) 1235 { 1236 return INVALIDCALL(); 1237 } 1238 1239 *clipStatus = this->clipStatus; 1240 1241 return D3D_OK; 1242 } 1243 GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS * parameters)1244 long Direct3DDevice8::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *parameters) 1245 { 1246 TRACE(""); 1247 1248 if(!parameters) 1249 { 1250 return INVALIDCALL(); 1251 } 1252 1253 parameters->AdapterOrdinal = adapter; 1254 parameters->BehaviorFlags = behaviourFlags; 1255 parameters->DeviceType = deviceType; 1256 parameters->hFocusWindow = focusWindow; 1257 1258 return D3D_OK; 1259 } 1260 GetCurrentTexturePalette(unsigned int * paletteNumber)1261 long Direct3DDevice8::GetCurrentTexturePalette(unsigned int *paletteNumber) 1262 { 1263 TRACE(""); 1264 1265 if(!paletteNumber) 1266 { 1267 return INVALIDCALL(); 1268 } 1269 1270 *paletteNumber = currentPalette; 1271 1272 return D3D_OK; 1273 } 1274 GetDepthStencilSurface(IDirect3DSurface8 ** depthStencilSurface)1275 long Direct3DDevice8::GetDepthStencilSurface(IDirect3DSurface8 **depthStencilSurface) 1276 { 1277 TRACE(""); 1278 1279 if(!depthStencilSurface) 1280 { 1281 return INVALIDCALL(); 1282 } 1283 1284 *depthStencilSurface = depthStencil; 1285 1286 if(depthStencil) 1287 { 1288 depthStencil->AddRef(); 1289 } 1290 1291 return D3D_OK; // FIXME: Return NOTFOUND() when no depthStencil? 1292 } 1293 GetDeviceCaps(D3DCAPS8 * caps)1294 long Direct3DDevice8::GetDeviceCaps(D3DCAPS8 *caps) 1295 { 1296 TRACE(""); 1297 1298 return d3d8->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, caps); 1299 } 1300 GetDirect3D(IDirect3D8 ** d3d8)1301 long Direct3DDevice8::GetDirect3D(IDirect3D8 **d3d8) 1302 { 1303 TRACE(""); 1304 1305 if(!d3d8) 1306 { 1307 return INVALIDCALL(); 1308 } 1309 1310 ASSERT(this->d3d8); 1311 1312 *d3d8 = this->d3d8; 1313 this->d3d8->AddRef(); 1314 1315 return D3D_OK; 1316 } 1317 GetDisplayMode(D3DDISPLAYMODE * mode)1318 long Direct3DDevice8::GetDisplayMode(D3DDISPLAYMODE *mode) 1319 { 1320 TRACE(""); 1321 1322 if(!mode) 1323 { 1324 return INVALIDCALL(); 1325 } 1326 1327 d3d8->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, mode); 1328 1329 return D3D_OK; 1330 } 1331 GetFrontBuffer(IDirect3DSurface8 * destSurface)1332 long Direct3DDevice8::GetFrontBuffer(IDirect3DSurface8 *destSurface) 1333 { 1334 TRACE(""); 1335 1336 if(!destSurface) 1337 { 1338 return INVALIDCALL(); 1339 } 1340 1341 D3DLOCKED_RECT description; 1342 destSurface->LockRect(&description, 0, 0); 1343 1344 swapChain[0]->screenshot(description.pBits); 1345 1346 destSurface->UnlockRect(); 1347 1348 return D3D_OK; 1349 } 1350 GetGammaRamp(D3DGAMMARAMP * ramp)1351 void Direct3DDevice8::GetGammaRamp(D3DGAMMARAMP *ramp) 1352 { 1353 TRACE(""); 1354 1355 if(!ramp) 1356 { 1357 return; 1358 } 1359 1360 swapChain[0]->getGammaRamp((sw::GammaRamp*)ramp); 1361 } 1362 GetIndices(IDirect3DIndexBuffer8 ** indexData,unsigned int * baseVertexIndex)1363 long Direct3DDevice8::GetIndices(IDirect3DIndexBuffer8 **indexData, unsigned int *baseVertexIndex) 1364 { 1365 TRACE(""); 1366 1367 if(!indexData || !baseVertexIndex) 1368 { 1369 return INVALIDCALL(); 1370 } 1371 1372 *indexData = this->indexData; 1373 1374 if(this->indexData) 1375 { 1376 this->indexData->AddRef(); 1377 } 1378 1379 *baseVertexIndex = this->baseVertexIndex; 1380 1381 return D3D_OK; 1382 } 1383 GetInfo(unsigned long devInfoID,void * devInfoStruct,unsigned long devInfoStructSize)1384 long Direct3DDevice8::GetInfo(unsigned long devInfoID, void *devInfoStruct, unsigned long devInfoStructSize) 1385 { 1386 TRACE(""); 1387 1388 if(!devInfoStruct || devInfoStructSize == 0) 1389 { 1390 return INVALIDCALL(); 1391 } 1392 1393 switch(devInfoID) 1394 { 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; 1403 } 1404 1405 return D3D_OK; 1406 } 1407 GetLight(unsigned long index,D3DLIGHT8 * light)1408 long Direct3DDevice8::GetLight(unsigned long index, D3DLIGHT8 *light) 1409 { 1410 TRACE(""); 1411 1412 if(!light) 1413 { 1414 return INVALIDCALL(); 1415 } 1416 1417 if(!this->light.exists(index)) 1418 { 1419 return INVALIDCALL(); 1420 } 1421 1422 *light = this->light[index]; 1423 1424 return D3D_OK; 1425 } 1426 GetLightEnable(unsigned long index,int * enable)1427 long Direct3DDevice8::GetLightEnable(unsigned long index , int *enable) 1428 { 1429 TRACE(""); 1430 1431 if(!enable) 1432 { 1433 return INVALIDCALL(); 1434 } 1435 1436 if(!light.exists(index)) 1437 { 1438 return INVALIDCALL(); 1439 } 1440 1441 *enable = light[index].enable; 1442 1443 return D3D_OK; 1444 } 1445 GetMaterial(D3DMATERIAL8 * material)1446 long Direct3DDevice8::GetMaterial(D3DMATERIAL8 *material) 1447 { 1448 TRACE(""); 1449 1450 if(!material) 1451 { 1452 return INVALIDCALL(); 1453 } 1454 1455 *material = this->material; 1456 1457 return D3D_OK; 1458 } 1459 GetPaletteEntries(unsigned int paletteNumber,PALETTEENTRY * entries)1460 long Direct3DDevice8::GetPaletteEntries(unsigned int paletteNumber, PALETTEENTRY *entries) 1461 { 1462 TRACE(""); 1463 1464 if(paletteNumber > 0xFFFF || !entries) 1465 { 1466 return INVALIDCALL(); 1467 } 1468 1469 for(int i = 0; i < 256; i++) 1470 { 1471 entries[i] = palette[paletteNumber].entry[i]; 1472 } 1473 1474 return D3D_OK; 1475 } 1476 GetPixelShader(unsigned long * handle)1477 long Direct3DDevice8::GetPixelShader(unsigned long *handle) 1478 { 1479 TRACE(""); 1480 1481 if(!handle) 1482 { 1483 return INVALIDCALL(); 1484 } 1485 1486 *handle = pixelShaderHandle; 1487 1488 return D3D_OK; 1489 } 1490 GetPixelShaderFunction(unsigned long handle,void * data,unsigned long * size)1491 long Direct3DDevice8::GetPixelShaderFunction(unsigned long handle, void *data, unsigned long *size) 1492 { 1493 TRACE(""); 1494 1495 if(!data) 1496 { 1497 return INVALIDCALL(); 1498 } 1499 1500 UNIMPLEMENTED(); 1501 1502 return D3D_OK; 1503 } 1504 GetPixelShaderConstant(unsigned long startRegister,void * constantData,unsigned long count)1505 long Direct3DDevice8::GetPixelShaderConstant(unsigned long startRegister, void *constantData, unsigned long count) 1506 { 1507 TRACE(""); 1508 1509 if(!constantData) 1510 { 1511 return INVALIDCALL(); 1512 } 1513 1514 for(unsigned int i = 0; i < count; i++) 1515 { 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]; 1520 } 1521 1522 return D3D_OK; 1523 } 1524 GetRasterStatus(D3DRASTER_STATUS * rasterStatus)1525 long Direct3DDevice8::GetRasterStatus(D3DRASTER_STATUS *rasterStatus) 1526 { 1527 TRACE(""); 1528 1529 if(!rasterStatus) 1530 { 1531 return INVALIDCALL(); 1532 } 1533 1534 UNIMPLEMENTED(); 1535 1536 return D3D_OK; 1537 } 1538 GetRenderState(D3DRENDERSTATETYPE state,unsigned long * value)1539 long Direct3DDevice8::GetRenderState(D3DRENDERSTATETYPE state, unsigned long *value) 1540 { 1541 TRACE(""); 1542 1543 if(!value) 1544 { 1545 return INVALIDCALL(); 1546 } 1547 1548 *value = renderState[state]; 1549 1550 return D3D_OK; 1551 } 1552 GetRenderTarget(IDirect3DSurface8 ** renderTarget)1553 long Direct3DDevice8::GetRenderTarget(IDirect3DSurface8 **renderTarget) 1554 { 1555 TRACE(""); 1556 1557 if(!renderTarget) 1558 { 1559 return INVALIDCALL(); 1560 } 1561 1562 *renderTarget = this->renderTarget; 1563 this->renderTarget->AddRef(); 1564 1565 return D3D_OK; 1566 } 1567 GetStreamSource(unsigned int streamNumber,IDirect3DVertexBuffer8 ** streamData,unsigned int * stride)1568 long Direct3DDevice8::GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer8 **streamData, unsigned int *stride) 1569 { 1570 TRACE(""); 1571 1572 if(streamNumber >= 16 || !streamData || !stride) 1573 { 1574 return INVALIDCALL(); 1575 } 1576 1577 *streamData = dataStream[streamNumber]; 1578 1579 if(dataStream[streamNumber]) 1580 { 1581 dataStream[streamNumber]->AddRef(); 1582 } 1583 1584 *stride = 0; // NOTE: Unimplemented 1585 1586 return D3D_OK; 1587 } 1588 GetTexture(unsigned long stage,IDirect3DBaseTexture8 ** texture)1589 long Direct3DDevice8::GetTexture(unsigned long stage, IDirect3DBaseTexture8 **texture) 1590 { 1591 TRACE(""); 1592 1593 if(!texture || stage >= 8) 1594 { 1595 return INVALIDCALL(); 1596 } 1597 1598 *texture = this->texture[stage]; 1599 1600 if(this->texture[stage]) 1601 { 1602 this->texture[stage]->AddRef(); 1603 } 1604 1605 return D3D_OK; 1606 } 1607 GetTextureStageState(unsigned long stage,D3DTEXTURESTAGESTATETYPE state,unsigned long * value)1608 long Direct3DDevice8::GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE state, unsigned long *value) 1609 { 1610 TRACE(""); 1611 1612 if(!value || stage < 0 || stage >= 8 || state < 0 || state > D3DTSS_RESULTARG) // FIXME: Set *value to 0? 1613 { 1614 return INVALIDCALL(); 1615 } 1616 1617 *value = textureStageState[stage][state]; 1618 1619 return D3D_OK; 1620 } 1621 GetTransform(D3DTRANSFORMSTATETYPE state,D3DMATRIX * matrix)1622 long Direct3DDevice8::GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix) 1623 { 1624 TRACE(""); 1625 1626 if(!matrix || state < 0 || state > 511) 1627 { 1628 return INVALIDCALL(); 1629 } 1630 1631 *matrix = this->matrix[state]; 1632 1633 return D3D_OK; 1634 } 1635 GetVertexShader(unsigned long * handle)1636 long Direct3DDevice8::GetVertexShader(unsigned long *handle) 1637 { 1638 TRACE(""); 1639 1640 if(!handle) 1641 { 1642 return INVALIDCALL(); 1643 } 1644 1645 *handle = vertexShaderHandle; 1646 1647 return D3D_OK; 1648 } 1649 GetVertexShaderConstant(unsigned long startRegister,void * constantData,unsigned long count)1650 long Direct3DDevice8::GetVertexShaderConstant(unsigned long startRegister, void *constantData, unsigned long count) 1651 { 1652 TRACE(""); 1653 1654 if(!constantData) 1655 { 1656 return INVALIDCALL(); 1657 } 1658 1659 for(unsigned int i = 0; i < count; i++) 1660 { 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]; 1665 } 1666 1667 return D3D_OK; 1668 } 1669 GetVertexShaderDeclaration(unsigned long handle,void * data,unsigned long * size)1670 long Direct3DDevice8::GetVertexShaderDeclaration(unsigned long handle, void *data, unsigned long *size) 1671 { 1672 TRACE(""); 1673 1674 if(!data || !size) 1675 { 1676 return INVALIDCALL(); 1677 } 1678 1679 UNIMPLEMENTED(); 1680 1681 return D3D_OK; 1682 } 1683 GetVertexShaderFunction(unsigned long handle,void * data,unsigned long * size)1684 long Direct3DDevice8::GetVertexShaderFunction(unsigned long handle, void *data, unsigned long *size) 1685 { 1686 TRACE(""); 1687 1688 if(!data || !size) 1689 { 1690 return INVALIDCALL(); 1691 } 1692 1693 UNIMPLEMENTED(); 1694 1695 return D3D_OK; 1696 } 1697 GetViewport(D3DVIEWPORT8 * viewport)1698 long Direct3DDevice8::GetViewport(D3DVIEWPORT8 *viewport) 1699 { 1700 TRACE(""); 1701 1702 if(!viewport) 1703 { 1704 return INVALIDCALL(); 1705 } 1706 1707 *viewport = this->viewport; 1708 1709 return D3D_OK; 1710 } 1711 LightEnable(unsigned long index,int enable)1712 long Direct3DDevice8::LightEnable(unsigned long index, int enable) 1713 { 1714 TRACE(""); 1715 1716 if(!recordState) 1717 { 1718 if(!light.exists(index)) // Insert default light 1719 { 1720 D3DLIGHT8 light; 1721 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; 1741 light.Range = 0; 1742 light.Falloff = 0; 1743 light.Attenuation0 = 0; 1744 light.Attenuation1 = 0; 1745 light.Attenuation2 = 0; 1746 light.Theta = 0; 1747 light.Phi = 0; 1748 1749 SetLight(index, &light); 1750 } 1751 1752 light[index].enable = (enable != FALSE); 1753 1754 lightsDirty = true; 1755 } 1756 else 1757 { 1758 stateRecorder.back()->lightEnable(index, enable); 1759 } 1760 1761 return D3D_OK; 1762 } 1763 MultiplyTransform(D3DTRANSFORMSTATETYPE state,const D3DMATRIX * matrix)1764 long Direct3DDevice8::MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix) 1765 { 1766 TRACE(""); 1767 1768 if(!matrix) 1769 { 1770 return INVALIDCALL(); 1771 } 1772 1773 D3DMATRIX *current = &this->matrix[state]; 1774 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); 1779 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); 1784 1785 switch(state) 1786 { 1787 case D3DTS_WORLD: 1788 renderer->setModelMatrix(C * M); 1789 break; 1790 case D3DTS_VIEW: 1791 renderer->setViewMatrix(C * M); 1792 break; 1793 case D3DTS_PROJECTION: 1794 renderer->setProjectionMatrix(C * M); 1795 break; 1796 case D3DTS_TEXTURE0: 1797 renderer->setTextureMatrix(0, C * M); 1798 break; 1799 case D3DTS_TEXTURE1: 1800 renderer->setTextureMatrix(1, C * M); 1801 break; 1802 case D3DTS_TEXTURE2: 1803 renderer->setTextureMatrix(2, C * M); 1804 break; 1805 case D3DTS_TEXTURE3: 1806 renderer->setTextureMatrix(3, C * M); 1807 break; 1808 case D3DTS_TEXTURE4: 1809 renderer->setTextureMatrix(4, C * M); 1810 break; 1811 case D3DTS_TEXTURE5: 1812 renderer->setTextureMatrix(5, C * M); 1813 break; 1814 case D3DTS_TEXTURE6: 1815 renderer->setTextureMatrix(6, C * M); 1816 break; 1817 case D3DTS_TEXTURE7: 1818 renderer->setTextureMatrix(7, C * M); 1819 break; 1820 default: 1821 if(state > 256 && state < 512) 1822 { 1823 renderer->setModelMatrix(C * M, state - 256); 1824 } 1825 else ASSERT(false); 1826 } 1827 1828 return D3D_OK; 1829 } 1830 Present(const RECT * sourceRect,const RECT * destRect,HWND destWindowOverride,const RGNDATA * dirtyRegion)1831 long Direct3DDevice8::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion) 1832 { 1833 TRACE(""); 1834 1835 // NOTE: sourceRect and destRect can be null, dirtyRegion has to be null 1836 1837 HWND windowHandle = presentParameters.hDeviceWindow ? presentParameters.hDeviceWindow : focusWindow; 1838 1839 if(destWindowOverride && destWindowOverride != windowHandle) 1840 { 1841 UNIMPLEMENTED(); 1842 } 1843 1844 if(dirtyRegion) 1845 { 1846 return INVALIDCALL(); 1847 } 1848 1849 swapChain[0]->Present(sourceRect, destRect, destWindowOverride, dirtyRegion); 1850 1851 return D3D_OK; 1852 } 1853 ProcessVertices(unsigned int srcStartIndex,unsigned int destIndex,unsigned int vertexCount,IDirect3DVertexBuffer8 * destBuffer,unsigned long flags)1854 long Direct3DDevice8::ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer8 *destBuffer, unsigned long flags) 1855 { 1856 TRACE(""); 1857 1858 if(!destBuffer) 1859 { 1860 return INVALIDCALL(); 1861 } 1862 1863 UNIMPLEMENTED(); 1864 1865 return D3D_OK; 1866 } 1867 Reset(D3DPRESENT_PARAMETERS * presentParameters)1868 long Direct3DDevice8::Reset(D3DPRESENT_PARAMETERS *presentParameters) 1869 { 1870 TRACE(""); 1871 1872 if(!presentParameters) 1873 { 1874 return INVALIDCALL(); 1875 } 1876 1877 if(swapChain[0]) 1878 { 1879 swapChain[0]->unbind(); 1880 swapChain[0] = 0; 1881 } 1882 1883 if(depthStencil) 1884 { 1885 depthStencil->unbind(); 1886 depthStencil = 0; 1887 } 1888 1889 if(renderTarget) 1890 { 1891 renderTarget->unbind(); 1892 renderTarget = 0; 1893 } 1894 1895 D3DPRESENT_PARAMETERS present = *presentParameters; 1896 1897 if(!swapChain[0]) 1898 { 1899 swapChain[0] = new Direct3DSwapChain8(this, &present); 1900 swapChain[0]->bind(); 1901 } 1902 else 1903 { 1904 swapChain[0]->reset(&present); 1905 } 1906 1907 HWND windowHandle = presentParameters->hDeviceWindow ? presentParameters->hDeviceWindow : focusWindow; 1908 1909 int width = 0; 1910 int height = 0; 1911 1912 if(presentParameters->Windowed && (presentParameters->BackBufferHeight == 0 || presentParameters->BackBufferWidth == 0)) 1913 { 1914 RECT rectangle; 1915 GetClientRect(windowHandle, &rectangle); 1916 1917 width = rectangle.right - rectangle.left; 1918 height = rectangle.bottom - rectangle.top; 1919 } 1920 else 1921 { 1922 width = presentParameters->BackBufferWidth; 1923 height = presentParameters->BackBufferHeight; 1924 } 1925 1926 if(presentParameters->EnableAutoDepthStencil != FALSE) 1927 { 1928 depthStencil = new Direct3DSurface8(this, this, width, height, presentParameters->AutoDepthStencilFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, presentParameters->AutoDepthStencilFormat == D3DFMT_D16_LOCKABLE, D3DUSAGE_DEPTHSTENCIL); 1929 depthStencil->bind(); 1930 } 1931 1932 IDirect3DSurface8 *renderTarget; 1933 swapChain[0]->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &renderTarget); 1934 SetRenderTarget(renderTarget, depthStencil); 1935 renderTarget->Release(); 1936 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); 2011 2012 for(int i = 0; i < 8; i++) 2013 { 2014 SetTexture(i, 0); 2015 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); 2043 } 2044 2045 currentPalette = 0xFFFF; 2046 2047 delete cursor; 2048 showCursor = false; 2049 2050 return D3D_OK; 2051 } 2052 ResourceManagerDiscardBytes(unsigned long bytes)2053 long Direct3DDevice8::ResourceManagerDiscardBytes(unsigned long bytes) 2054 { 2055 TRACE(""); 2056 2057 return D3D_OK; 2058 } 2059 SetClipPlane(unsigned long index,const float * plane)2060 long Direct3DDevice8::SetClipPlane(unsigned long index, const float *plane) 2061 { 2062 TRACE(""); 2063 2064 if(!plane || index > 6) 2065 { 2066 return INVALIDCALL(); 2067 } 2068 2069 if(!recordState) 2070 { 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]; 2075 2076 renderer->setClipPlane(index, plane); 2077 } 2078 else 2079 { 2080 stateRecorder.back()->setClipPlane(index, plane); 2081 } 2082 2083 return D3D_OK; 2084 } 2085 SetClipStatus(const D3DCLIPSTATUS8 * clipStatus)2086 long Direct3DDevice8::SetClipStatus(const D3DCLIPSTATUS8 *clipStatus) 2087 { 2088 TRACE(""); 2089 2090 if(!clipStatus) 2091 { 2092 return INVALIDCALL(); 2093 } 2094 2095 this->clipStatus = *clipStatus; 2096 2097 UNIMPLEMENTED(); 2098 2099 return D3D_OK; 2100 } 2101 SetCurrentTexturePalette(unsigned int paletteNumber)2102 long Direct3DDevice8::SetCurrentTexturePalette(unsigned int paletteNumber) 2103 { 2104 TRACE(""); 2105 2106 if(paletteNumber > 0xFFFF || palette.find(paletteNumber) == palette.end()) 2107 { 2108 return INVALIDCALL(); 2109 } 2110 2111 if(!recordState) 2112 { 2113 currentPalette = paletteNumber; 2114 2115 sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]); 2116 } 2117 else 2118 { 2119 stateRecorder.back()->setCurrentTexturePalette(paletteNumber); 2120 } 2121 2122 return D3D_OK; 2123 } 2124 SetCursorPosition(int x,int y,unsigned long flags)2125 void Direct3DDevice8::SetCursorPosition(int x, int y, unsigned long flags) 2126 { 2127 TRACE(""); 2128 2129 POINT point = {x, y}; 2130 HWND window = focusWindow ? focusWindow : presentParameters.hDeviceWindow; 2131 ScreenToClient(window, &point); 2132 2133 sw::FrameBuffer::setCursorPosition(point.x, point.y); 2134 } 2135 SetCursorProperties(unsigned int x0,unsigned int y0,IDirect3DSurface8 * cursorBitmap)2136 long Direct3DDevice8::SetCursorProperties(unsigned int x0, unsigned int y0, IDirect3DSurface8 *cursorBitmap) 2137 { 2138 TRACE(""); 2139 2140 if(!cursorBitmap) 2141 { 2142 return INVALIDCALL(); 2143 } 2144 2145 D3DSURFACE_DESC desc; 2146 D3DLOCKED_RECT lock; 2147 2148 cursorBitmap->GetDesc(&desc); 2149 cursorBitmap->LockRect(&lock, 0, 0); 2150 2151 delete cursor; 2152 cursor = sw::Surface::create(0, desc.Width, desc.Height, 1, 0, 1, sw::FORMAT_A8R8G8B8, false, false); 2153 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(); 2157 2158 cursorBitmap->UnlockRect(); 2159 2160 sw::FrameBuffer::setCursorOrigin(x0, y0); 2161 2162 bindCursor(); 2163 2164 return D3D_OK; 2165 } 2166 SetGammaRamp(unsigned long flags,const D3DGAMMARAMP * ramp)2167 void Direct3DDevice8::SetGammaRamp(unsigned long flags, const D3DGAMMARAMP *ramp) 2168 { 2169 TRACE(""); 2170 2171 if(!ramp) 2172 { 2173 return; 2174 } 2175 2176 swapChain[0]->setGammaRamp((sw::GammaRamp*)ramp, flags & D3DSGR_CALIBRATE); 2177 2178 return; 2179 } 2180 SetLight(unsigned long index,const D3DLIGHT8 * light)2181 long Direct3DDevice8::SetLight(unsigned long index, const D3DLIGHT8 *light) 2182 { 2183 TRACE(""); 2184 2185 if(!light) 2186 { 2187 return INVALIDCALL(); 2188 } 2189 2190 if(!recordState) 2191 { 2192 this->light[index] = *light; 2193 2194 lightsDirty = true; 2195 } 2196 else 2197 { 2198 stateRecorder.back()->setLight(index, light); 2199 } 2200 2201 return D3D_OK; 2202 } 2203 SetMaterial(const D3DMATERIAL8 * material)2204 long Direct3DDevice8::SetMaterial(const D3DMATERIAL8 *material) 2205 { 2206 TRACE(""); 2207 2208 if(!material) 2209 { 2210 return INVALIDCALL(); // FIXME: Correct behaviour? 2211 } 2212 2213 if(!recordState) 2214 { 2215 this->material = *material; 2216 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)); 2222 } 2223 else 2224 { 2225 stateRecorder.back()->setMaterial(material); 2226 } 2227 2228 return D3D_OK; 2229 } 2230 SetPaletteEntries(unsigned int paletteNumber,const PALETTEENTRY * entries)2231 long Direct3DDevice8::SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries) 2232 { 2233 TRACE(""); 2234 2235 if(paletteNumber > 0xFFFF || !entries) 2236 { 2237 return INVALIDCALL(); 2238 } 2239 2240 for(int i = 0; i < 256; i++) 2241 { 2242 palette[paletteNumber].entry[i] = entries[i]; 2243 } 2244 2245 if(paletteNumber == currentPalette) 2246 { 2247 sw::Surface::setTexturePalette((unsigned int*)&palette[currentPalette]); 2248 } 2249 2250 return D3D_OK; 2251 } 2252 SetPixelShader(unsigned long handle)2253 long Direct3DDevice8::SetPixelShader(unsigned long handle) 2254 { 2255 TRACE(""); 2256 2257 if(!recordState) 2258 { 2259 if(pixelShader[handle]) 2260 { 2261 pixelShader[handle]->bind(); 2262 } 2263 2264 if(pixelShader[pixelShaderHandle]) 2265 { 2266 pixelShader[pixelShaderHandle]->unbind(); 2267 } 2268 2269 pixelShaderHandle = handle; 2270 2271 if(handle != 0) 2272 { 2273 renderer->setPixelShader(pixelShader[handle]->getPixelShader()); 2274 } 2275 else 2276 { 2277 renderer->setPixelShader(0); 2278 } 2279 } 2280 else 2281 { 2282 stateRecorder.back()->setPixelShader(handle); 2283 } 2284 2285 return D3D_OK; 2286 } 2287 SetPixelShaderConstant(unsigned long startRegister,const void * constantData,unsigned long count)2288 long Direct3DDevice8::SetPixelShaderConstant(unsigned long startRegister, const void *constantData, unsigned long count) 2289 { 2290 TRACE(""); 2291 2292 if(!recordState) 2293 { 2294 for(unsigned int i = 0; i < count; i++) 2295 { 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]; 2300 } 2301 2302 renderer->setPixelShaderConstantF(startRegister, (const float*)constantData, count); 2303 } 2304 else 2305 { 2306 stateRecorder.back()->setPixelShaderConstant(startRegister, constantData, count); 2307 } 2308 2309 return D3D_OK; 2310 } 2311 SetRenderState(D3DRENDERSTATETYPE state,unsigned long value)2312 long Direct3DDevice8::SetRenderState(D3DRENDERSTATETYPE state, unsigned long value) 2313 { 2314 TRACE("D3DRENDERSTATETYPE state = %d, unsigned long value = %d", state, value); 2315 2316 if(state < D3DRS_ZENABLE || state > D3DRS_NORMALORDER) 2317 { 2318 return D3D_OK; // FIXME: Warning 2319 } 2320 2321 if(!recordState) 2322 { 2323 if(!init && renderState[state] == value) 2324 { 2325 return D3D_OK; 2326 } 2327 2328 renderState[state] = value; 2329 2330 switch(state) 2331 { 2332 case D3DRS_ZENABLE: 2333 switch(value) 2334 { 2335 case D3DZB_TRUE: 2336 case D3DZB_USEW: 2337 renderer->setDepthBufferEnable(true); 2338 break; 2339 case D3DZB_FALSE: 2340 renderer->setDepthBufferEnable(false); 2341 break; 2342 default: 2343 ASSERT(false); 2344 } 2345 break; 2346 case D3DRS_FILLMODE: 2347 switch(value) 2348 { 2349 case D3DFILL_POINT: 2350 renderer->setFillMode(sw::FILL_VERTEX); 2351 break; 2352 case D3DFILL_WIREFRAME: 2353 renderer->setFillMode(sw::FILL_WIREFRAME); 2354 break; 2355 case D3DFILL_SOLID: 2356 renderer->setFillMode(sw::FILL_SOLID); 2357 break; 2358 default: 2359 ASSERT(false); 2360 } 2361 break; 2362 case D3DRS_SHADEMODE: 2363 switch(value) 2364 { 2365 case D3DSHADE_FLAT: 2366 renderer->setShadingMode(sw::SHADING_FLAT); 2367 break; 2368 case D3DSHADE_GOURAUD: 2369 renderer->setShadingMode(sw::SHADING_GOURAUD); 2370 break; 2371 case D3DSHADE_PHONG: 2372 // FIXME: Unimplemented (should set gouraud)? 2373 break; 2374 default: 2375 ASSERT(false); 2376 } 2377 break; 2378 case D3DRS_LINEPATTERN: 2379 if(!init) UNIMPLEMENTED(); 2380 break; 2381 case D3DRS_ZWRITEENABLE: 2382 renderer->setDepthWriteEnable(value != FALSE); 2383 break; 2384 case D3DRS_ALPHATESTENABLE: 2385 renderer->setAlphaTestEnable(value != FALSE); 2386 break; 2387 case D3DRS_LASTPIXEL: 2388 if(!init) UNIMPLEMENTED(); 2389 break; 2390 case D3DRS_SRCBLEND: 2391 switch(value) 2392 { 2393 case D3DBLEND_ZERO: 2394 renderer->setSourceBlendFactor(sw::BLEND_ZERO); 2395 break; 2396 case D3DBLEND_ONE: 2397 renderer->setSourceBlendFactor(sw::BLEND_ONE); 2398 break; 2399 case D3DBLEND_SRCCOLOR: 2400 renderer->setSourceBlendFactor(sw::BLEND_SOURCE); 2401 break; 2402 case D3DBLEND_INVSRCCOLOR: 2403 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCE); 2404 break; 2405 case D3DBLEND_SRCALPHA: 2406 renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA); 2407 break; 2408 case D3DBLEND_INVSRCALPHA: 2409 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA); 2410 break; 2411 case D3DBLEND_DESTALPHA: 2412 renderer->setSourceBlendFactor(sw::BLEND_DESTALPHA); 2413 break; 2414 case D3DBLEND_INVDESTALPHA: 2415 renderer->setSourceBlendFactor(sw::BLEND_INVDESTALPHA); 2416 break; 2417 case D3DBLEND_DESTCOLOR: 2418 renderer->setSourceBlendFactor(sw::BLEND_DEST); 2419 break; 2420 case D3DBLEND_INVDESTCOLOR: 2421 renderer->setSourceBlendFactor(sw::BLEND_INVDEST); 2422 break; 2423 case D3DBLEND_SRCALPHASAT: 2424 renderer->setSourceBlendFactor(sw::BLEND_SRCALPHASAT); 2425 break; 2426 case D3DBLEND_BOTHSRCALPHA: 2427 renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA); 2428 renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA); 2429 break; 2430 case D3DBLEND_BOTHINVSRCALPHA: 2431 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA); 2432 renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA); 2433 break; 2434 default: 2435 ASSERT(false); 2436 } 2437 break; 2438 case D3DRS_DESTBLEND: 2439 switch(value) 2440 { 2441 case D3DBLEND_ZERO: 2442 renderer->setDestBlendFactor(sw::BLEND_ZERO); 2443 break; 2444 case D3DBLEND_ONE: 2445 renderer->setDestBlendFactor(sw::BLEND_ONE); 2446 break; 2447 case D3DBLEND_SRCCOLOR: 2448 renderer->setDestBlendFactor(sw::BLEND_SOURCE); 2449 break; 2450 case D3DBLEND_INVSRCCOLOR: 2451 renderer->setDestBlendFactor(sw::BLEND_INVSOURCE); 2452 break; 2453 case D3DBLEND_SRCALPHA: 2454 renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA); 2455 break; 2456 case D3DBLEND_INVSRCALPHA: 2457 renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA); 2458 break; 2459 case D3DBLEND_DESTALPHA: 2460 renderer->setDestBlendFactor(sw::BLEND_DESTALPHA); 2461 break; 2462 case D3DBLEND_INVDESTALPHA: 2463 renderer->setDestBlendFactor(sw::BLEND_INVDESTALPHA); 2464 break; 2465 case D3DBLEND_DESTCOLOR: 2466 renderer->setDestBlendFactor(sw::BLEND_DEST); 2467 break; 2468 case D3DBLEND_INVDESTCOLOR: 2469 renderer->setDestBlendFactor(sw::BLEND_INVDEST); 2470 break; 2471 case D3DBLEND_SRCALPHASAT: 2472 renderer->setDestBlendFactor(sw::BLEND_SRCALPHASAT); 2473 break; 2474 case D3DBLEND_BOTHSRCALPHA: 2475 renderer->setSourceBlendFactor(sw::BLEND_SOURCEALPHA); 2476 renderer->setDestBlendFactor(sw::BLEND_INVSOURCEALPHA); 2477 break; 2478 case D3DBLEND_BOTHINVSRCALPHA: 2479 renderer->setSourceBlendFactor(sw::BLEND_INVSOURCEALPHA); 2480 renderer->setDestBlendFactor(sw::BLEND_SOURCEALPHA); 2481 break; 2482 default: 2483 ASSERT(false); 2484 } 2485 break; 2486 case D3DRS_CULLMODE: 2487 switch(value) 2488 { 2489 case D3DCULL_NONE: 2490 renderer->setCullMode(sw::CULL_NONE, true); 2491 break; 2492 case D3DCULL_CCW: 2493 renderer->setCullMode(sw::CULL_COUNTERCLOCKWISE, true); 2494 break; 2495 case D3DCULL_CW: 2496 renderer->setCullMode(sw::CULL_CLOCKWISE, true); 2497 break; 2498 default: 2499 ASSERT(false); 2500 } 2501 break; 2502 case D3DRS_ZFUNC: 2503 switch(value) 2504 { 2505 case D3DCMP_NEVER: 2506 renderer->setDepthCompare(sw::DEPTH_NEVER); 2507 break; 2508 case D3DCMP_LESS: 2509 renderer->setDepthCompare(sw::DEPTH_LESS); 2510 break; 2511 case D3DCMP_EQUAL: 2512 renderer->setDepthCompare(sw::DEPTH_EQUAL); 2513 break; 2514 case D3DCMP_LESSEQUAL: 2515 renderer->setDepthCompare(sw::DEPTH_LESSEQUAL); 2516 break; 2517 case D3DCMP_GREATER: 2518 renderer->setDepthCompare(sw::DEPTH_GREATER); 2519 break; 2520 case D3DCMP_NOTEQUAL: 2521 renderer->setDepthCompare(sw::DEPTH_NOTEQUAL); 2522 break; 2523 case D3DCMP_GREATEREQUAL: 2524 renderer->setDepthCompare(sw::DEPTH_GREATEREQUAL); 2525 break; 2526 case D3DCMP_ALWAYS: 2527 renderer->setDepthCompare(sw::DEPTH_ALWAYS); 2528 break; 2529 default: 2530 ASSERT(false); 2531 } 2532 break; 2533 case D3DRS_ALPHAREF: 2534 renderer->setAlphaReference(value & 0x000000FF); 2535 break; 2536 case D3DRS_ALPHAFUNC: 2537 switch(value) 2538 { 2539 case D3DCMP_NEVER: 2540 renderer->setAlphaCompare(sw::ALPHA_NEVER); 2541 break; 2542 case D3DCMP_LESS: 2543 renderer->setAlphaCompare(sw::ALPHA_LESS); 2544 break; 2545 case D3DCMP_EQUAL: 2546 renderer->setAlphaCompare(sw::ALPHA_EQUAL); 2547 break; 2548 case D3DCMP_LESSEQUAL: 2549 renderer->setAlphaCompare(sw::ALPHA_LESSEQUAL); 2550 break; 2551 case D3DCMP_GREATER: 2552 renderer->setAlphaCompare(sw::ALPHA_GREATER); 2553 break; 2554 case D3DCMP_NOTEQUAL: 2555 renderer->setAlphaCompare(sw::ALPHA_NOTEQUAL); 2556 break; 2557 case D3DCMP_GREATEREQUAL: 2558 renderer->setAlphaCompare(sw::ALPHA_GREATEREQUAL); 2559 break; 2560 case D3DCMP_ALWAYS: 2561 renderer->setAlphaCompare(sw::ALPHA_ALWAYS); 2562 break; 2563 default: 2564 ASSERT(false); 2565 } 2566 break; 2567 case D3DRS_DITHERENABLE: 2568 // if(!init && value == 1) UNIMPLEMENTED(); // FIXME: Unimplemented 2569 break; 2570 case D3DRS_ALPHABLENDENABLE: 2571 renderer->setAlphaBlendEnable(value != FALSE); 2572 break; 2573 case D3DRS_FOGENABLE: 2574 renderer->setFogEnable(value != FALSE); 2575 break; 2576 case D3DRS_ZVISIBLE: 2577 break; // Not supported 2578 case D3DRS_FOGCOLOR: 2579 renderer->setFogColor(value); 2580 break; 2581 case D3DRS_FOGTABLEMODE: 2582 switch(value) 2583 { 2584 case D3DFOG_NONE: 2585 renderer->setPixelFogMode(sw::FOG_NONE); 2586 break; 2587 case D3DFOG_LINEAR: 2588 renderer->setPixelFogMode(sw::FOG_LINEAR); 2589 break; 2590 case D3DFOG_EXP: 2591 renderer->setPixelFogMode(sw::FOG_EXP); 2592 break; 2593 case D3DFOG_EXP2: 2594 renderer->setPixelFogMode(sw::FOG_EXP2); 2595 break; 2596 default: 2597 ASSERT(false); 2598 } 2599 break; 2600 case D3DRS_FOGSTART: 2601 renderer->setFogStart((float&)value); 2602 break; 2603 case D3DRS_FOGEND: 2604 renderer->setFogEnd((float&)value); 2605 break; 2606 case D3DRS_FOGDENSITY: 2607 renderer->setFogDensity((float&)value); 2608 break; 2609 case D3DRS_EDGEANTIALIAS: 2610 if(!init) if(value != FALSE) UNIMPLEMENTED(); 2611 break; 2612 case D3DRS_ZBIAS: 2613 renderer->setDepthBias(-2.0e-6f * value); 2614 renderer->setSlopeDepthBias(0.0f); 2615 break; 2616 case D3DRS_RANGEFOGENABLE: 2617 renderer->setRangeFogEnable(value != FALSE); 2618 break; 2619 case D3DRS_SPECULARENABLE: 2620 renderer->setSpecularEnable(value != FALSE); 2621 break; 2622 case D3DRS_STENCILENABLE: 2623 renderer->setStencilEnable(value != FALSE); 2624 break; 2625 case D3DRS_STENCILFAIL: 2626 switch(value) 2627 { 2628 case D3DSTENCILOP_KEEP: 2629 renderer->setStencilFailOperation(sw::OPERATION_KEEP); 2630 break; 2631 case D3DSTENCILOP_ZERO: 2632 renderer->setStencilFailOperation(sw::OPERATION_ZERO); 2633 break; 2634 case D3DSTENCILOP_REPLACE: 2635 renderer->setStencilFailOperation(sw::OPERATION_REPLACE); 2636 break; 2637 case D3DSTENCILOP_INCRSAT: 2638 renderer->setStencilFailOperation(sw::OPERATION_INCRSAT); 2639 break; 2640 case D3DSTENCILOP_DECRSAT: 2641 renderer->setStencilFailOperation(sw::OPERATION_DECRSAT); 2642 break; 2643 case D3DSTENCILOP_INVERT: 2644 renderer->setStencilFailOperation(sw::OPERATION_INVERT); 2645 break; 2646 case D3DSTENCILOP_INCR: 2647 renderer->setStencilFailOperation(sw::OPERATION_INCR); 2648 break; 2649 case D3DSTENCILOP_DECR: 2650 renderer->setStencilFailOperation(sw::OPERATION_DECR); 2651 break; 2652 default: 2653 ASSERT(false); 2654 } 2655 break; 2656 case D3DRS_STENCILZFAIL: 2657 switch(value) 2658 { 2659 case D3DSTENCILOP_KEEP: 2660 renderer->setStencilZFailOperation(sw::OPERATION_KEEP); 2661 break; 2662 case D3DSTENCILOP_ZERO: 2663 renderer->setStencilZFailOperation(sw::OPERATION_ZERO); 2664 break; 2665 case D3DSTENCILOP_REPLACE: 2666 renderer->setStencilZFailOperation(sw::OPERATION_REPLACE); 2667 break; 2668 case D3DSTENCILOP_INCRSAT: 2669 renderer->setStencilZFailOperation(sw::OPERATION_INCRSAT); 2670 break; 2671 case D3DSTENCILOP_DECRSAT: 2672 renderer->setStencilZFailOperation(sw::OPERATION_DECRSAT); 2673 break; 2674 case D3DSTENCILOP_INVERT: 2675 renderer->setStencilZFailOperation(sw::OPERATION_INVERT); 2676 break; 2677 case D3DSTENCILOP_INCR: 2678 renderer->setStencilZFailOperation(sw::OPERATION_INCR); 2679 break; 2680 case D3DSTENCILOP_DECR: 2681 renderer->setStencilZFailOperation(sw::OPERATION_DECR); 2682 break; 2683 default: 2684 ASSERT(false); 2685 } 2686 break; 2687 case D3DRS_STENCILPASS: 2688 switch(value) 2689 { 2690 case D3DSTENCILOP_KEEP: 2691 renderer->setStencilPassOperation(sw::OPERATION_KEEP); 2692 break; 2693 case D3DSTENCILOP_ZERO: 2694 renderer->setStencilPassOperation(sw::OPERATION_ZERO); 2695 break; 2696 case D3DSTENCILOP_REPLACE: 2697 renderer->setStencilPassOperation(sw::OPERATION_REPLACE); 2698 break; 2699 case D3DSTENCILOP_INCRSAT: 2700 renderer->setStencilPassOperation(sw::OPERATION_INCRSAT); 2701 break; 2702 case D3DSTENCILOP_DECRSAT: 2703 renderer->setStencilPassOperation(sw::OPERATION_DECRSAT); 2704 break; 2705 case D3DSTENCILOP_INVERT: 2706 renderer->setStencilPassOperation(sw::OPERATION_INVERT); 2707 break; 2708 case D3DSTENCILOP_INCR: 2709 renderer->setStencilPassOperation(sw::OPERATION_INCR); 2710 break; 2711 case D3DSTENCILOP_DECR: 2712 renderer->setStencilPassOperation(sw::OPERATION_DECR); 2713 break; 2714 default: 2715 ASSERT(false); 2716 } 2717 break; 2718 case D3DRS_STENCILFUNC: 2719 switch(value) 2720 { 2721 case D3DCMP_NEVER: 2722 renderer->setStencilCompare(sw::STENCIL_NEVER); 2723 break; 2724 case D3DCMP_LESS: 2725 renderer->setStencilCompare(sw::STENCIL_LESS); 2726 break; 2727 case D3DCMP_EQUAL: 2728 renderer->setStencilCompare(sw::STENCIL_EQUAL); 2729 break; 2730 case D3DCMP_LESSEQUAL: 2731 renderer->setStencilCompare(sw::STENCIL_LESSEQUAL); 2732 break; 2733 case D3DCMP_GREATER: 2734 renderer->setStencilCompare(sw::STENCIL_GREATER); 2735 break; 2736 case D3DCMP_NOTEQUAL: 2737 renderer->setStencilCompare(sw::STENCIL_NOTEQUAL); 2738 break; 2739 case D3DCMP_GREATEREQUAL: 2740 renderer->setStencilCompare(sw::STENCIL_GREATEREQUAL); 2741 break; 2742 case D3DCMP_ALWAYS: 2743 renderer->setStencilCompare(sw::STENCIL_ALWAYS); 2744 break; 2745 default: 2746 ASSERT(false); 2747 } 2748 break; 2749 case D3DRS_STENCILREF: 2750 renderer->setStencilReference(value); 2751 renderer->setStencilReferenceCCW(value); 2752 break; 2753 case D3DRS_STENCILMASK: 2754 renderer->setStencilMask(value); 2755 renderer->setStencilMaskCCW(value); 2756 break; 2757 case D3DRS_STENCILWRITEMASK: 2758 renderer->setStencilWriteMask(value); 2759 renderer->setStencilWriteMaskCCW(value); 2760 break; 2761 case D3DRS_TEXTUREFACTOR: 2762 renderer->setTextureFactor(value); 2763 break; 2764 case D3DRS_WRAP0: 2765 renderer->setTextureWrap(0, value); 2766 break; 2767 case D3DRS_WRAP1: 2768 renderer->setTextureWrap(1, value); 2769 break; 2770 case D3DRS_WRAP2: 2771 renderer->setTextureWrap(2, value); 2772 break; 2773 case D3DRS_WRAP3: 2774 renderer->setTextureWrap(3, value); 2775 break; 2776 case D3DRS_WRAP4: 2777 renderer->setTextureWrap(4, value); 2778 break; 2779 case D3DRS_WRAP5: 2780 renderer->setTextureWrap(5, value); 2781 break; 2782 case D3DRS_WRAP6: 2783 renderer->setTextureWrap(6, value); 2784 break; 2785 case D3DRS_WRAP7: 2786 renderer->setTextureWrap(7, value); 2787 break; 2788 case D3DRS_CLIPPING: 2789 // Ignored, clipping is always performed 2790 break; 2791 case D3DRS_LIGHTING: 2792 renderer->setLightingEnable(value != FALSE); 2793 break; 2794 case D3DRS_AMBIENT: 2795 renderer->setGlobalAmbient(value); 2796 break; 2797 case D3DRS_FOGVERTEXMODE: 2798 switch(value) 2799 { 2800 case D3DFOG_NONE: 2801 renderer->setVertexFogMode(sw::FOG_NONE); 2802 break; 2803 case D3DFOG_LINEAR: 2804 renderer->setVertexFogMode(sw::FOG_LINEAR); 2805 break; 2806 case D3DFOG_EXP: 2807 renderer->setVertexFogMode(sw::FOG_EXP); 2808 break; 2809 case D3DFOG_EXP2: 2810 renderer->setVertexFogMode(sw::FOG_EXP2); 2811 break; 2812 default: 2813 ASSERT(false); 2814 } 2815 break; 2816 case D3DRS_COLORVERTEX: 2817 renderer->setColorVertexEnable(value != FALSE); 2818 break; 2819 case D3DRS_LOCALVIEWER: 2820 renderer->setLocalViewer(value != FALSE); 2821 break; 2822 case D3DRS_NORMALIZENORMALS: 2823 renderer->setNormalizeNormals(value != FALSE); 2824 break; 2825 case D3DRS_DIFFUSEMATERIALSOURCE: 2826 switch(value) 2827 { 2828 case D3DMCS_MATERIAL: 2829 renderer->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL); 2830 break; 2831 case D3DMCS_COLOR1: 2832 renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR1); 2833 break; 2834 case D3DMCS_COLOR2: 2835 renderer->setDiffuseMaterialSource(sw::MATERIAL_COLOR2); 2836 break; 2837 default: 2838 ASSERT(false); 2839 } 2840 break; 2841 case D3DRS_SPECULARMATERIALSOURCE: 2842 switch(value) 2843 { 2844 case D3DMCS_MATERIAL: 2845 renderer->setSpecularMaterialSource(sw::MATERIAL_MATERIAL); 2846 break; 2847 case D3DMCS_COLOR1: 2848 renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR1); 2849 break; 2850 case D3DMCS_COLOR2: 2851 renderer->setSpecularMaterialSource(sw::MATERIAL_COLOR2); 2852 break; 2853 default: 2854 ASSERT(false); 2855 } 2856 break; 2857 case D3DRS_AMBIENTMATERIALSOURCE: 2858 switch(value) 2859 { 2860 case D3DMCS_MATERIAL: 2861 renderer->setAmbientMaterialSource(sw::MATERIAL_MATERIAL); 2862 break; 2863 case D3DMCS_COLOR1: 2864 renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR1); 2865 break; 2866 case D3DMCS_COLOR2: 2867 renderer->setAmbientMaterialSource(sw::MATERIAL_COLOR2); 2868 break; 2869 default: 2870 ASSERT(false); 2871 } 2872 break; 2873 case D3DRS_EMISSIVEMATERIALSOURCE: 2874 switch(value) 2875 { 2876 case D3DMCS_MATERIAL: 2877 renderer->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL); 2878 break; 2879 case D3DMCS_COLOR1: 2880 renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR1); 2881 break; 2882 case D3DMCS_COLOR2: 2883 renderer->setEmissiveMaterialSource(sw::MATERIAL_COLOR2); 2884 break; 2885 default: 2886 ASSERT(false); 2887 } 2888 break; 2889 case D3DRS_VERTEXBLEND: 2890 switch(value) 2891 { 2892 case D3DVBF_DISABLE: 2893 renderer->setVertexBlendMatrixCount(0); 2894 break; 2895 case D3DVBF_1WEIGHTS: 2896 renderer->setVertexBlendMatrixCount(2); 2897 break; 2898 case D3DVBF_2WEIGHTS: 2899 renderer->setVertexBlendMatrixCount(3); 2900 break; 2901 case D3DVBF_3WEIGHTS: 2902 renderer->setVertexBlendMatrixCount(4); 2903 break; 2904 case D3DVBF_TWEENING: 2905 UNIMPLEMENTED(); 2906 break; 2907 case D3DVBF_0WEIGHTS: 2908 renderer->setVertexBlendMatrixCount(1); 2909 break; 2910 default: 2911 ASSERT(false); 2912 } 2913 break; 2914 case D3DRS_CLIPPLANEENABLE: 2915 renderer->setClipFlags(value); 2916 break; 2917 case D3DRS_SOFTWAREVERTEXPROCESSING: 2918 break; 2919 case D3DRS_POINTSIZE: 2920 renderer->setPointSize((float&)value); 2921 break; 2922 case D3DRS_POINTSIZE_MIN: 2923 renderer->setPointSizeMin((float&)value); 2924 break; 2925 case D3DRS_POINTSPRITEENABLE: 2926 renderer->setPointSpriteEnable(value != FALSE); 2927 break; 2928 case D3DRS_POINTSCALEENABLE: 2929 renderer->setPointScaleEnable(value != FALSE); 2930 break; 2931 case D3DRS_POINTSCALE_A: 2932 renderer->setPointScaleA((float&)value); 2933 break; 2934 case D3DRS_POINTSCALE_B: 2935 renderer->setPointScaleB((float&)value); 2936 break; 2937 case D3DRS_POINTSCALE_C: 2938 renderer->setPointScaleC((float&)value); 2939 break; 2940 case D3DRS_MULTISAMPLEANTIALIAS: 2941 // if(!init) UNIMPLEMENTED(); 2942 break; 2943 case D3DRS_MULTISAMPLEMASK: 2944 SetRenderTarget(renderTarget, depthStencil); // Sets the multi-sample mask, if maskable 2945 break; 2946 case D3DRS_PATCHEDGESTYLE: 2947 // if(!init) UNIMPLEMENTED(); 2948 break; 2949 case D3DRS_PATCHSEGMENTS: 2950 // UNIMPLEMENTED(); // FIXME 2951 break; 2952 case D3DRS_DEBUGMONITORTOKEN: 2953 if(!init) UNIMPLEMENTED(); 2954 break; 2955 case D3DRS_POINTSIZE_MAX: 2956 renderer->setPointSizeMax((float&)value); 2957 break; 2958 case D3DRS_INDEXEDVERTEXBLENDENABLE: 2959 renderer->setIndexedVertexBlendEnable(value != FALSE); 2960 break; 2961 case D3DRS_COLORWRITEENABLE: 2962 renderer->setColorWriteMask(0, value); 2963 break; 2964 case D3DRS_TWEENFACTOR: 2965 if(!init) UNIMPLEMENTED(); 2966 break; 2967 case D3DRS_BLENDOP: 2968 switch(value) 2969 { 2970 case D3DBLENDOP_ADD: 2971 renderer->setBlendOperation(sw::BLENDOP_ADD); 2972 break; 2973 case D3DBLENDOP_SUBTRACT: 2974 renderer->setBlendOperation(sw::BLENDOP_SUB); 2975 break; 2976 case D3DBLENDOP_REVSUBTRACT: 2977 renderer->setBlendOperation(sw::BLENDOP_INVSUB); 2978 break; 2979 case D3DBLENDOP_MIN: 2980 renderer->setBlendOperation(sw::BLENDOP_MIN); 2981 break; 2982 case D3DBLENDOP_MAX: 2983 renderer->setBlendOperation(sw::BLENDOP_MAX); 2984 break; 2985 default: 2986 ASSERT(false); 2987 } 2988 break; 2989 case D3DRS_POSITIONORDER: 2990 if(!init) UNIMPLEMENTED(); 2991 break; 2992 case D3DRS_NORMALORDER: 2993 if(!init) UNIMPLEMENTED(); 2994 break; 2995 default: 2996 ASSERT(false); 2997 } 2998 } 2999 else // stateRecorder 3000 { 3001 stateRecorder.back()->setRenderState(state, value); 3002 } 3003 3004 return D3D_OK; 3005 } 3006 SetRenderTarget(IDirect3DSurface8 * newRenderTarget,IDirect3DSurface8 * newDepthStencil)3007 long Direct3DDevice8::SetRenderTarget(IDirect3DSurface8 *newRenderTarget, IDirect3DSurface8 *newDepthStencil) 3008 { 3009 TRACE(""); 3010 3011 Direct3DSurface8 *renderTarget = static_cast<Direct3DSurface8*>(newRenderTarget); 3012 3013 if(renderTarget) // FIXME: Check for D3DUSAGE_RENDERTARGET 3014 { 3015 renderTarget->bind(); 3016 } 3017 3018 if(this->renderTarget) 3019 { 3020 this->renderTarget->unbind(); 3021 } 3022 3023 this->renderTarget = renderTarget; 3024 3025 Direct3DSurface8 *depthStencil = static_cast<Direct3DSurface8*>(newDepthStencil); 3026 3027 if(depthStencil) // FIXME: Check for D3DUSAGE_DEPTHSTENCIL and D3DPOOL_DEFAULT 3028 { 3029 depthStencil->bind(); 3030 } 3031 3032 if(this->depthStencil) 3033 { 3034 this->depthStencil->unbind(); 3035 } 3036 3037 this->depthStencil = depthStencil; 3038 3039 // Reset viewport to size of current render target 3040 D3DSURFACE_DESC renderTargetDesc; 3041 renderTarget->GetDesc(&renderTargetDesc); 3042 3043 D3DVIEWPORT8 viewport; 3044 viewport.X = 0; 3045 viewport.Y = 0; 3046 viewport.Width = renderTargetDesc.Width; 3047 viewport.Height = renderTargetDesc.Height; 3048 viewport.MinZ = 0; 3049 viewport.MaxZ = 1; 3050 3051 SetViewport(&viewport); 3052 3053 // Set the multi-sample mask, if maskable 3054 if(renderTargetDesc.MultiSampleType != D3DMULTISAMPLE_NONE) 3055 { 3056 renderer->setMultiSampleMask(renderState[D3DRS_MULTISAMPLEMASK]); 3057 } 3058 else 3059 { 3060 renderer->setMultiSampleMask(0xFFFFFFFF); 3061 } 3062 3063 renderer->setRenderTarget(0, renderTarget); 3064 renderer->setDepthBuffer(depthStencil); 3065 renderer->setStencilBuffer(depthStencil); 3066 3067 return D3D_OK; 3068 } 3069 SetStreamSource(unsigned int stream,IDirect3DVertexBuffer8 * iVertexBuffer,unsigned int stride)3070 long Direct3DDevice8::SetStreamSource(unsigned int stream, IDirect3DVertexBuffer8 *iVertexBuffer, unsigned int stride) 3071 { 3072 TRACE(""); 3073 3074 Direct3DVertexBuffer8 *vertexBuffer = static_cast<Direct3DVertexBuffer8*>(iVertexBuffer); 3075 3076 if(!recordState) 3077 { 3078 if(vertexBuffer) 3079 { 3080 vertexBuffer->bind(); 3081 } 3082 3083 if(dataStream[stream]) 3084 { 3085 dataStream[stream]->unbind(); 3086 streamStride[stream] = 0; 3087 } 3088 3089 dataStream[stream] = vertexBuffer; 3090 streamStride[stream] = stride; 3091 } 3092 else 3093 { 3094 stateRecorder.back()->setStreamSource(stream, vertexBuffer, stride); 3095 } 3096 3097 return D3D_OK; 3098 } 3099 SetTexture(unsigned long stage,IDirect3DBaseTexture8 * iBaseTexture)3100 long Direct3DDevice8::SetTexture(unsigned long stage, IDirect3DBaseTexture8 *iBaseTexture) 3101 { 3102 TRACE(""); 3103 3104 if(stage >= 8) 3105 { 3106 return INVALIDCALL(); 3107 } 3108 3109 Direct3DBaseTexture8 *baseTexture = dynamic_cast<Direct3DBaseTexture8*>(iBaseTexture); 3110 3111 if(!recordState) 3112 { 3113 if(texture[stage] == baseTexture) 3114 { 3115 return D3D_OK; 3116 } 3117 3118 if(baseTexture) 3119 { 3120 baseTexture->bind(); 3121 } 3122 3123 if(texture[stage]) 3124 { 3125 texture[stage]->unbind(); 3126 } 3127 3128 texture[stage] = baseTexture; 3129 } 3130 else 3131 { 3132 stateRecorder.back()->setTexture(stage, baseTexture); 3133 } 3134 3135 return D3D_OK; 3136 } 3137 SetTextureStageState(unsigned long stage,D3DTEXTURESTAGESTATETYPE type,unsigned long value)3138 long Direct3DDevice8::SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value) 3139 { 3140 TRACE("unsigned long stage = %d, D3DTEXTURESTAGESTATETYPE type = %d, unsigned long value = %d", stage, type, value); 3141 3142 if(stage >= 8 || type < 0 || type > D3DTSS_RESULTARG) 3143 { 3144 return INVALIDCALL(); 3145 } 3146 3147 if(!recordState) 3148 { 3149 if(!init && textureStageState[stage][type] == value) 3150 { 3151 return D3D_OK; 3152 } 3153 3154 textureStageState[stage][type] = value; 3155 3156 switch(type) 3157 { 3158 case D3DTSS_COLOROP: 3159 switch(value) 3160 { 3161 case D3DTOP_DISABLE: 3162 renderer->setStageOperation(stage, sw::TextureStage::STAGE_DISABLE); 3163 break; 3164 case D3DTOP_SELECTARG1: 3165 renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG1); 3166 break; 3167 case D3DTOP_SELECTARG2: 3168 renderer->setStageOperation(stage, sw::TextureStage::STAGE_SELECTARG2); 3169 break; 3170 case D3DTOP_MODULATE: 3171 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE); 3172 break; 3173 case D3DTOP_MODULATE2X: 3174 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE2X); 3175 break; 3176 case D3DTOP_MODULATE4X: 3177 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATE4X); 3178 break; 3179 case D3DTOP_ADD: 3180 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADD); 3181 break; 3182 case D3DTOP_ADDSIGNED: 3183 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED); 3184 break; 3185 case D3DTOP_ADDSIGNED2X: 3186 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSIGNED2X); 3187 break; 3188 case D3DTOP_SUBTRACT: 3189 renderer->setStageOperation(stage, sw::TextureStage::STAGE_SUBTRACT); 3190 break; 3191 case D3DTOP_ADDSMOOTH: 3192 renderer->setStageOperation(stage, sw::TextureStage::STAGE_ADDSMOOTH); 3193 break; 3194 case D3DTOP_BLENDDIFFUSEALPHA: 3195 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA); 3196 break; 3197 case D3DTOP_BLENDTEXTUREALPHA: 3198 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA); 3199 break; 3200 case D3DTOP_BLENDFACTORALPHA: 3201 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA); 3202 break; 3203 case D3DTOP_BLENDTEXTUREALPHAPM: 3204 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM); 3205 break; 3206 case D3DTOP_BLENDCURRENTALPHA: 3207 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA); 3208 break; 3209 case D3DTOP_PREMODULATE: 3210 renderer->setStageOperation(stage, sw::TextureStage::STAGE_PREMODULATE); 3211 break; 3212 case D3DTOP_MODULATEALPHA_ADDCOLOR: 3213 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR); 3214 break; 3215 case D3DTOP_MODULATECOLOR_ADDALPHA: 3216 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA); 3217 break; 3218 case D3DTOP_MODULATEINVALPHA_ADDCOLOR: 3219 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR); 3220 break; 3221 case D3DTOP_MODULATEINVCOLOR_ADDALPHA: 3222 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA); 3223 break; 3224 case D3DTOP_BUMPENVMAP: 3225 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAP); 3226 break; 3227 case D3DTOP_BUMPENVMAPLUMINANCE: 3228 renderer->setStageOperation(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE); 3229 break; 3230 case D3DTOP_DOTPRODUCT3: 3231 renderer->setStageOperation(stage, sw::TextureStage::STAGE_DOT3); 3232 break; 3233 case D3DTOP_MULTIPLYADD: 3234 renderer->setStageOperation(stage, sw::TextureStage::STAGE_MULTIPLYADD); 3235 break; 3236 case D3DTOP_LERP: 3237 renderer->setStageOperation(stage, sw::TextureStage::STAGE_LERP); 3238 break; 3239 default: 3240 ASSERT(false); 3241 } 3242 break; 3243 case D3DTSS_COLORARG1: 3244 switch(value & D3DTA_SELECTMASK) 3245 { 3246 case D3DTA_DIFFUSE: 3247 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_DIFFUSE); 3248 break; 3249 case D3DTA_CURRENT: 3250 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_CURRENT); 3251 break; 3252 case D3DTA_TEXTURE: 3253 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEXTURE); 3254 break; 3255 case D3DTA_TFACTOR: 3256 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TFACTOR); 3257 break; 3258 case D3DTA_SPECULAR: 3259 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_SPECULAR); 3260 break; 3261 case D3DTA_TEMP: 3262 renderer->setFirstArgument(stage, sw::TextureStage::SOURCE_TEMP); 3263 break; 3264 default: 3265 ASSERT(false); 3266 } 3267 3268 switch(value & ~D3DTA_SELECTMASK) 3269 { 3270 case 0: 3271 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_COLOR); 3272 break; 3273 case D3DTA_COMPLEMENT: 3274 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR); 3275 break; 3276 case D3DTA_ALPHAREPLICATE: 3277 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_ALPHA); 3278 break; 3279 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE: 3280 renderer->setFirstModifier(stage, sw::TextureStage::MODIFIER_INVALPHA); 3281 break; 3282 default: 3283 ASSERT(false); 3284 } 3285 break; 3286 case D3DTSS_COLORARG2: 3287 switch(value & D3DTA_SELECTMASK) 3288 { 3289 case D3DTA_DIFFUSE: 3290 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_DIFFUSE); 3291 break; 3292 case D3DTA_CURRENT: 3293 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_CURRENT); 3294 break; 3295 case D3DTA_TEXTURE: 3296 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEXTURE); 3297 break; 3298 case D3DTA_TFACTOR: 3299 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TFACTOR); 3300 break; 3301 case D3DTA_SPECULAR: 3302 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_SPECULAR); 3303 break; 3304 case D3DTA_TEMP: 3305 renderer->setSecondArgument(stage, sw::TextureStage::SOURCE_TEMP); 3306 break; 3307 default: 3308 ASSERT(false); 3309 } 3310 3311 switch(value & ~D3DTA_SELECTMASK) 3312 { 3313 case 0: 3314 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_COLOR); 3315 break; 3316 case D3DTA_COMPLEMENT: 3317 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR); 3318 break; 3319 case D3DTA_ALPHAREPLICATE: 3320 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_ALPHA); 3321 break; 3322 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE: 3323 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA); 3324 break; 3325 default: 3326 ASSERT(false); 3327 } 3328 break; 3329 case D3DTSS_ALPHAOP: 3330 switch(value) 3331 { 3332 case D3DTOP_DISABLE: 3333 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DISABLE); 3334 break; 3335 case D3DTOP_SELECTARG1: 3336 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG1); 3337 break; 3338 case D3DTOP_SELECTARG2: 3339 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SELECTARG2); 3340 break; 3341 case D3DTOP_MODULATE: 3342 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE); 3343 break; 3344 case D3DTOP_MODULATE2X: 3345 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE2X); 3346 break; 3347 case D3DTOP_MODULATE4X: 3348 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATE4X); 3349 break; 3350 case D3DTOP_ADD: 3351 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADD); 3352 break; 3353 case D3DTOP_ADDSIGNED: 3354 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED); 3355 break; 3356 case D3DTOP_ADDSIGNED2X: 3357 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSIGNED2X); 3358 break; 3359 case D3DTOP_SUBTRACT: 3360 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_SUBTRACT); 3361 break; 3362 case D3DTOP_ADDSMOOTH: 3363 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_ADDSMOOTH); 3364 break; 3365 case D3DTOP_BLENDDIFFUSEALPHA: 3366 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDDIFFUSEALPHA); 3367 break; 3368 case D3DTOP_BLENDTEXTUREALPHA: 3369 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHA); 3370 break; 3371 case D3DTOP_BLENDFACTORALPHA: 3372 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDFACTORALPHA); 3373 break; 3374 case D3DTOP_BLENDTEXTUREALPHAPM: 3375 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDTEXTUREALPHAPM); 3376 break; 3377 case D3DTOP_BLENDCURRENTALPHA: 3378 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BLENDCURRENTALPHA); 3379 break; 3380 case D3DTOP_PREMODULATE: 3381 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_PREMODULATE); 3382 break; 3383 case D3DTOP_MODULATEALPHA_ADDCOLOR: 3384 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEALPHA_ADDCOLOR); 3385 break; 3386 case D3DTOP_MODULATECOLOR_ADDALPHA: 3387 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATECOLOR_ADDALPHA); 3388 break; 3389 case D3DTOP_MODULATEINVALPHA_ADDCOLOR: 3390 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVALPHA_ADDCOLOR); 3391 break; 3392 case D3DTOP_MODULATEINVCOLOR_ADDALPHA: 3393 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MODULATEINVCOLOR_ADDALPHA); 3394 break; 3395 case D3DTOP_BUMPENVMAP: 3396 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAP); 3397 break; 3398 case D3DTOP_BUMPENVMAPLUMINANCE: 3399 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_BUMPENVMAPLUMINANCE); 3400 break; 3401 case D3DTOP_DOTPRODUCT3: 3402 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_DOT3); 3403 break; 3404 case D3DTOP_MULTIPLYADD: 3405 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_MULTIPLYADD); 3406 break; 3407 case D3DTOP_LERP: 3408 renderer->setStageOperationAlpha(stage, sw::TextureStage::STAGE_LERP); 3409 break; 3410 default: 3411 ASSERT(false); 3412 } 3413 break; 3414 case D3DTSS_ALPHAARG1: 3415 switch(value & D3DTA_SELECTMASK) 3416 { 3417 case D3DTA_DIFFUSE: 3418 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE); 3419 break; 3420 case D3DTA_CURRENT: 3421 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT); 3422 break; 3423 case D3DTA_TEXTURE: 3424 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE); 3425 break; 3426 case D3DTA_TFACTOR: 3427 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR); 3428 break; 3429 case D3DTA_SPECULAR: 3430 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR); 3431 break; 3432 case D3DTA_TEMP: 3433 renderer->setFirstArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP); 3434 break; 3435 default: 3436 ASSERT(false); 3437 } 3438 3439 switch(value & ~D3DTA_SELECTMASK) 3440 { 3441 case 0: 3442 renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR); 3443 break; 3444 case D3DTA_COMPLEMENT: 3445 renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR); 3446 break; 3447 case D3DTA_ALPHAREPLICATE: 3448 renderer->setFirstModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA); 3449 break; 3450 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE: 3451 renderer->setSecondModifier(stage, sw::TextureStage::MODIFIER_INVALPHA); 3452 break; 3453 default: 3454 ASSERT(false); 3455 } 3456 break; 3457 case D3DTSS_ALPHAARG2: 3458 switch(value & D3DTA_SELECTMASK) 3459 { 3460 case D3DTA_DIFFUSE: 3461 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE); 3462 break; 3463 case D3DTA_CURRENT: 3464 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT); 3465 break; 3466 case D3DTA_TEXTURE: 3467 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE); 3468 break; 3469 case D3DTA_TFACTOR: 3470 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR); 3471 break; 3472 case D3DTA_SPECULAR: 3473 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR); 3474 break; 3475 case D3DTA_TEMP: 3476 renderer->setSecondArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP); 3477 break; 3478 default: 3479 ASSERT(false); 3480 } 3481 3482 switch(value & ~D3DTA_SELECTMASK) 3483 { 3484 case 0: 3485 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR); 3486 break; 3487 case D3DTA_COMPLEMENT: 3488 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR); 3489 break; 3490 case D3DTA_ALPHAREPLICATE: 3491 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA); 3492 break; 3493 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE: 3494 renderer->setSecondModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA); 3495 break; 3496 default: 3497 ASSERT(false); 3498 } 3499 break; 3500 case D3DTSS_BUMPENVMAT00: 3501 renderer->setBumpmapMatrix(stage, 0, (float&)value); 3502 break; 3503 case D3DTSS_BUMPENVMAT01: 3504 renderer->setBumpmapMatrix(stage, 1, (float&)value); 3505 break; 3506 case D3DTSS_BUMPENVMAT10: 3507 renderer->setBumpmapMatrix(stage, 2, (float&)value); 3508 break; 3509 case D3DTSS_BUMPENVMAT11: 3510 renderer->setBumpmapMatrix(stage, 3, (float&)value); 3511 break; 3512 case D3DTSS_TEXCOORDINDEX: 3513 renderer->setTexCoordIndex(stage, value & 0xFFFF); 3514 3515 switch(value & 0xFFFF0000) 3516 { 3517 case D3DTSS_TCI_PASSTHRU: 3518 renderer->setTexGen(stage, sw::TEXGEN_PASSTHRU); 3519 break; 3520 case D3DTSS_TCI_CAMERASPACENORMAL: 3521 renderer->setTexCoordIndex(stage, stage); 3522 renderer->setTexGen(stage, sw::TEXGEN_NORMAL); 3523 break; 3524 case D3DTSS_TCI_CAMERASPACEPOSITION: 3525 renderer->setTexCoordIndex(stage, stage); 3526 renderer->setTexGen(stage, sw::TEXGEN_POSITION); 3527 break; 3528 case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR: 3529 renderer->setTexCoordIndex(stage, stage); 3530 renderer->setTexGen(stage, sw::TEXGEN_REFLECTION); 3531 break; 3532 default: 3533 ASSERT(false); 3534 } 3535 break; 3536 case D3DTSS_ADDRESSU: 3537 switch(value) 3538 { 3539 case D3DTADDRESS_WRAP: 3540 renderer->setAddressingModeU(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_WRAP); 3541 break; 3542 case D3DTADDRESS_MIRROR: 3543 renderer->setAddressingModeU(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRROR); 3544 break; 3545 case D3DTADDRESS_CLAMP: 3546 renderer->setAddressingModeU(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_CLAMP); 3547 break; 3548 case D3DTADDRESS_BORDER: 3549 renderer->setAddressingModeU(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_BORDER); 3550 break; 3551 case D3DTADDRESS_MIRRORONCE: 3552 renderer->setAddressingModeU(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRRORONCE); 3553 break; 3554 default: 3555 ASSERT(false); 3556 } 3557 break; 3558 case D3DTSS_ADDRESSV: 3559 switch(value) 3560 { 3561 case D3DTADDRESS_WRAP: 3562 renderer->setAddressingModeV(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_WRAP); 3563 break; 3564 case D3DTADDRESS_MIRROR: 3565 renderer->setAddressingModeV(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRROR); 3566 break; 3567 case D3DTADDRESS_CLAMP: 3568 renderer->setAddressingModeV(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_CLAMP); 3569 break; 3570 case D3DTADDRESS_BORDER: 3571 renderer->setAddressingModeV(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_BORDER); 3572 break; 3573 case D3DTADDRESS_MIRRORONCE: 3574 renderer->setAddressingModeV(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRRORONCE); 3575 break; 3576 default: 3577 ASSERT(false); 3578 } 3579 break; 3580 case D3DTSS_BORDERCOLOR: 3581 renderer->setBorderColor(sw::SAMPLER_PIXEL, stage, value); 3582 break; 3583 case D3DTSS_MAGFILTER: 3584 // NOTE: SwiftShader does not differentiate between minification and magnification filter 3585 switch(value) 3586 { 3587 case D3DTEXF_NONE: 3588 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_POINT); 3589 break; 3590 case D3DTEXF_POINT: 3591 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_POINT); 3592 break; 3593 case D3DTEXF_LINEAR: 3594 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR); 3595 break; 3596 case D3DTEXF_ANISOTROPIC: 3597 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_ANISOTROPIC); 3598 break; 3599 case D3DTEXF_FLATCUBIC: 3600 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR); // NOTE: Unimplemented, fail silently 3601 break; 3602 case D3DTEXF_GAUSSIANCUBIC: 3603 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR); // NOTE: Unimplemented, fail silently 3604 break; 3605 default: 3606 return INVALIDCALL(); 3607 }; 3608 break; 3609 case D3DTSS_MINFILTER: 3610 // NOTE: SwiftShader does not differentiate between minification and magnification filter 3611 switch(value) 3612 { 3613 case D3DTEXF_NONE: 3614 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_POINT); 3615 break; 3616 case D3DTEXF_POINT: 3617 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_POINT); 3618 break; 3619 case D3DTEXF_LINEAR: 3620 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR); 3621 break; 3622 case D3DTEXF_ANISOTROPIC: 3623 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_ANISOTROPIC); 3624 break; 3625 case D3DTEXF_FLATCUBIC: 3626 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR); // NOTE: Unimplemented, fail silently 3627 break; 3628 case D3DTEXF_GAUSSIANCUBIC: 3629 renderer->setTextureFilter(sw::SAMPLER_PIXEL, stage, sw::FILTER_LINEAR); // NOTE: Unimplemented, fail silently 3630 break; 3631 default: 3632 return INVALIDCALL(); 3633 }; 3634 break; 3635 case D3DTSS_MIPFILTER: 3636 switch(value) 3637 { 3638 case D3DTEXF_NONE: 3639 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_NONE); 3640 break; 3641 case D3DTEXF_POINT: 3642 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_POINT); 3643 break; 3644 case D3DTEXF_LINEAR: 3645 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_LINEAR); 3646 break; 3647 case D3DTEXF_ANISOTROPIC: 3648 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_LINEAR); // NOTE: Unimplemented, fail silently 3649 break; 3650 case D3DTEXF_FLATCUBIC: 3651 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_LINEAR); // NOTE: Unimplemented, fail silently 3652 break; 3653 case D3DTEXF_GAUSSIANCUBIC: 3654 renderer->setMipmapFilter(sw::SAMPLER_PIXEL, stage, sw::MIPMAP_LINEAR); // NOTE: Unimplemented, fail silently 3655 break; 3656 default: 3657 return INVALIDCALL(); 3658 }; 3659 break; 3660 case D3DTSS_MIPMAPLODBIAS: 3661 { 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); 3664 } 3665 break; 3666 case D3DTSS_MAXMIPLEVEL: 3667 break; 3668 case D3DTSS_MAXANISOTROPY: 3669 renderer->setMaxAnisotropy(sw::SAMPLER_PIXEL, stage, sw::clamp((unsigned int)value, (unsigned int)1, maxAnisotropy)); 3670 break; 3671 case D3DTSS_BUMPENVLSCALE: 3672 renderer->setLuminanceScale(stage, (float&)value); 3673 break; 3674 case D3DTSS_BUMPENVLOFFSET: 3675 renderer->setLuminanceOffset(stage, (float&)value); 3676 break; 3677 case D3DTSS_TEXTURETRANSFORMFLAGS: 3678 switch(value & ~D3DTTFF_PROJECTED) 3679 { 3680 case D3DTTFF_DISABLE: 3681 renderer->setTextureTransform(stage, 0, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED); 3682 break; 3683 case D3DTTFF_COUNT1: 3684 renderer->setTextureTransform(stage, 1, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED); 3685 break; 3686 case D3DTTFF_COUNT2: 3687 renderer->setTextureTransform(stage, 2, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED); 3688 break; 3689 case D3DTTFF_COUNT3: 3690 renderer->setTextureTransform(stage, 3, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED); 3691 break; 3692 case D3DTTFF_COUNT4: 3693 renderer->setTextureTransform(stage, 4, (value & D3DTTFF_PROJECTED) == D3DTTFF_PROJECTED); 3694 break; 3695 default: 3696 ASSERT(false); 3697 } 3698 break; 3699 case D3DTSS_ADDRESSW: 3700 switch(value) 3701 { 3702 case D3DTADDRESS_WRAP: 3703 renderer->setAddressingModeW(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_WRAP); 3704 break; 3705 case D3DTADDRESS_MIRROR: 3706 renderer->setAddressingModeW(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRROR); 3707 break; 3708 case D3DTADDRESS_CLAMP: 3709 renderer->setAddressingModeW(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_CLAMP); 3710 break; 3711 case D3DTADDRESS_BORDER: 3712 renderer->setAddressingModeW(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_BORDER); 3713 break; 3714 case D3DTADDRESS_MIRRORONCE: 3715 renderer->setAddressingModeW(sw::SAMPLER_PIXEL, stage, sw::ADDRESSING_MIRRORONCE); 3716 break; 3717 default: 3718 ASSERT(false); 3719 } 3720 break; 3721 case D3DTSS_COLORARG0: 3722 switch(value & D3DTA_SELECTMASK) 3723 { 3724 case D3DTA_CURRENT: 3725 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_CURRENT); 3726 break; 3727 case D3DTA_DIFFUSE: 3728 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_DIFFUSE); 3729 break; 3730 case D3DTA_SPECULAR: 3731 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_SPECULAR); 3732 break; 3733 case D3DTA_TEMP: 3734 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEMP); 3735 break; 3736 case D3DTA_TEXTURE: 3737 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TEXTURE); 3738 break; 3739 case D3DTA_TFACTOR: 3740 renderer->setThirdArgument(stage, sw::TextureStage::SOURCE_TFACTOR); 3741 break; 3742 default: 3743 ASSERT(false); 3744 } 3745 3746 switch(value & ~D3DTA_SELECTMASK) 3747 { 3748 case 0: 3749 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_COLOR); 3750 break; 3751 case D3DTA_COMPLEMENT: 3752 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVCOLOR); 3753 break; 3754 case D3DTA_ALPHAREPLICATE: 3755 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_ALPHA); 3756 break; 3757 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE: 3758 renderer->setThirdModifier(stage, sw::TextureStage::MODIFIER_INVALPHA); 3759 break; 3760 default: 3761 ASSERT(false); 3762 } 3763 break; 3764 case D3DTSS_ALPHAARG0: 3765 switch(value & D3DTA_SELECTMASK) 3766 { 3767 case D3DTA_DIFFUSE: 3768 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_DIFFUSE); 3769 break; 3770 case D3DTA_CURRENT: 3771 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_CURRENT); 3772 break; 3773 case D3DTA_TEXTURE: 3774 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEXTURE); 3775 break; 3776 case D3DTA_TFACTOR: 3777 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TFACTOR); 3778 break; 3779 case D3DTA_SPECULAR: 3780 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_SPECULAR); 3781 break; 3782 case D3DTA_TEMP: 3783 renderer->setThirdArgumentAlpha(stage, sw::TextureStage::SOURCE_TEMP); 3784 break; 3785 default: 3786 ASSERT(false); 3787 } 3788 3789 switch(value & ~D3DTA_SELECTMASK) 3790 { 3791 case 0: 3792 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_COLOR); 3793 break; 3794 case D3DTA_COMPLEMENT: 3795 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVCOLOR); 3796 break; 3797 case D3DTA_ALPHAREPLICATE: 3798 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_ALPHA); 3799 break; 3800 case D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE: 3801 renderer->setThirdModifierAlpha(stage, sw::TextureStage::MODIFIER_INVALPHA); 3802 break; 3803 default: 3804 ASSERT(false); 3805 } 3806 break; 3807 case D3DTSS_RESULTARG: 3808 switch(value & D3DTA_SELECTMASK) 3809 { 3810 case D3DTA_CURRENT: 3811 renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_CURRENT); 3812 break; 3813 case D3DTA_TEMP: 3814 renderer->setDestinationArgument(stage, sw::TextureStage::DESTINATION_TEMP); 3815 break; 3816 default: 3817 ASSERT(false); 3818 } 3819 break; 3820 default: 3821 ASSERT(false); 3822 } 3823 } 3824 else // stateRecorder 3825 { 3826 stateRecorder.back()->setTextureStageState(stage, type, value); 3827 } 3828 3829 return D3D_OK; 3830 } 3831 SetTransform(D3DTRANSFORMSTATETYPE state,const D3DMATRIX * matrix)3832 long Direct3DDevice8::SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix) 3833 { 3834 TRACE(""); 3835 3836 if(!matrix || state < 0 || state > 511) 3837 { 3838 return INVALIDCALL(); 3839 } 3840 3841 if(!recordState) 3842 { 3843 this->matrix[state] = *matrix; 3844 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); 3849 3850 switch(state) 3851 { 3852 case D3DTS_WORLD: 3853 renderer->setModelMatrix(M); 3854 break; 3855 case D3DTS_VIEW: 3856 renderer->setViewMatrix(M); 3857 break; 3858 case D3DTS_PROJECTION: 3859 renderer->setProjectionMatrix(M); 3860 break; 3861 case D3DTS_TEXTURE0: 3862 renderer->setTextureMatrix(0, M); 3863 break; 3864 case D3DTS_TEXTURE1: 3865 renderer->setTextureMatrix(1, M); 3866 break; 3867 case D3DTS_TEXTURE2: 3868 renderer->setTextureMatrix(2, M); 3869 break; 3870 case D3DTS_TEXTURE3: 3871 renderer->setTextureMatrix(3, M); 3872 break; 3873 case D3DTS_TEXTURE4: 3874 renderer->setTextureMatrix(4, M); 3875 break; 3876 case D3DTS_TEXTURE5: 3877 renderer->setTextureMatrix(5, M); 3878 break; 3879 case D3DTS_TEXTURE6: 3880 renderer->setTextureMatrix(6, M); 3881 break; 3882 case D3DTS_TEXTURE7: 3883 renderer->setTextureMatrix(7, M); 3884 break; 3885 default: 3886 if(state > 256 && state < 512) 3887 { 3888 renderer->setModelMatrix(M, state - 256); 3889 } 3890 else ASSERT(false); 3891 } 3892 } 3893 else // stateRecorder 3894 { 3895 stateRecorder.back()->setTransform(state, matrix); 3896 } 3897 3898 return D3D_OK; 3899 } 3900 SetVertexShader(unsigned long handle)3901 long Direct3DDevice8::SetVertexShader(unsigned long handle) 3902 { 3903 TRACE(""); 3904 3905 if(!recordState) 3906 { 3907 if(handle & 0x00000001) 3908 { 3909 unsigned int index = handle >> 16; 3910 3911 if(vertexShader[index]) 3912 { 3913 vertexShader[index]->bind(); 3914 } 3915 3916 if(vertexShader[vertexShaderHandle >> 16]) 3917 { 3918 vertexShader[vertexShaderHandle >> 16]->unbind(); 3919 } 3920 3921 vertexShaderHandle = handle; 3922 3923 Direct3DVertexShader8 *shader = vertexShader[index]; 3924 renderer->setVertexShader(shader->getVertexShader()); 3925 declaration = shader->getDeclaration(); 3926 3927 FVF = 0; 3928 } 3929 else 3930 { 3931 renderer->setVertexShader(0); 3932 declaration = 0; 3933 3934 FVF = handle; 3935 } 3936 } 3937 else 3938 { 3939 stateRecorder.back()->setVertexShader(handle); 3940 } 3941 3942 return D3D_OK; 3943 } 3944 SetVertexShaderConstant(unsigned long startRegister,const void * constantData,unsigned long count)3945 long Direct3DDevice8::SetVertexShaderConstant(unsigned long startRegister, const void *constantData, unsigned long count) 3946 { 3947 TRACE(""); 3948 3949 if(!constantData) 3950 { 3951 return INVALIDCALL(); 3952 } 3953 3954 if(!recordState) 3955 { 3956 for(unsigned int i = 0; i < count; i++) 3957 { 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]; 3962 } 3963 3964 renderer->setVertexShaderConstantF(startRegister, (const float*)constantData, count); 3965 } 3966 else 3967 { 3968 stateRecorder.back()->setVertexShaderConstant(startRegister, constantData, count); 3969 } 3970 3971 return D3D_OK; 3972 } 3973 SetViewport(const D3DVIEWPORT8 * viewport)3974 long Direct3DDevice8::SetViewport(const D3DVIEWPORT8 *viewport) 3975 { 3976 TRACE(""); 3977 3978 if(!viewport) 3979 { 3980 return INVALIDCALL(); 3981 } 3982 3983 if(!recordState) 3984 { 3985 this->viewport = *viewport; 3986 } 3987 else 3988 { 3989 stateRecorder.back()->setViewport(viewport); 3990 } 3991 3992 return D3D_OK; 3993 } 3994 ShowCursor(int show)3995 int Direct3DDevice8::ShowCursor(int show) 3996 { 3997 TRACE(""); 3998 3999 int oldValue = showCursor ? TRUE : FALSE; 4000 4001 showCursor = show != FALSE && cursor; 4002 4003 bindCursor(); 4004 4005 return oldValue; 4006 } 4007 TestCooperativeLevel()4008 long Direct3DDevice8::TestCooperativeLevel() 4009 { 4010 TRACE(""); 4011 4012 return D3D_OK; 4013 } 4014 UpdateTexture(IDirect3DBaseTexture8 * sourceTexture,IDirect3DBaseTexture8 * destinationTexture)4015 long Direct3DDevice8::UpdateTexture(IDirect3DBaseTexture8 *sourceTexture, IDirect3DBaseTexture8 *destinationTexture) 4016 { 4017 TRACE(""); 4018 4019 if(!sourceTexture || !destinationTexture) 4020 { 4021 return INVALIDCALL(); 4022 } 4023 4024 D3DRESOURCETYPE type = sourceTexture->GetType(); 4025 4026 if(type != destinationTexture->GetType()) 4027 { 4028 return INVALIDCALL(); 4029 } 4030 4031 switch(type) 4032 { 4033 case D3DRTYPE_TEXTURE: 4034 { 4035 IDirect3DTexture8 *source; 4036 IDirect3DTexture8 *dest; 4037 4038 sourceTexture->QueryInterface(IID_IDirect3DTexture8, (void**)&source); 4039 destinationTexture->QueryInterface(IID_IDirect3DTexture8, (void**)&dest); 4040 4041 ASSERT(source && dest); 4042 4043 for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++) 4044 { 4045 IDirect3DSurface8 *sourceSurface; 4046 IDirect3DSurface8 *destinationSurface; 4047 4048 source->GetSurfaceLevel(level, &sourceSurface); 4049 dest->GetSurfaceLevel(level, &destinationSurface); 4050 4051 updateSurface(sourceSurface, 0, destinationSurface, 0); 4052 4053 sourceSurface->Release(); 4054 destinationSurface->Release(); 4055 } 4056 4057 source->Release(); 4058 dest->Release(); 4059 } 4060 break; 4061 case D3DRTYPE_VOLUMETEXTURE: 4062 { 4063 IDirect3DVolumeTexture8 *source; 4064 IDirect3DVolumeTexture8 *dest; 4065 4066 sourceTexture->QueryInterface(IID_IDirect3DVolumeTexture8, (void**)&source); 4067 destinationTexture->QueryInterface(IID_IDirect3DVolumeTexture8, (void**)&dest); 4068 4069 ASSERT(source && dest); 4070 4071 for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++) // FIXME: Fail when source texture has fewer levels than the destination 4072 { 4073 IDirect3DVolume8 *sourceVolume; 4074 IDirect3DVolume8 *destinationVolume; 4075 4076 source->GetVolumeLevel(level, &sourceVolume); 4077 dest->GetVolumeLevel(level, &destinationVolume); 4078 4079 updateVolume(sourceVolume, destinationVolume); 4080 4081 sourceVolume->Release(); 4082 destinationVolume->Release(); 4083 } 4084 4085 source->Release(); 4086 dest->Release(); 4087 } 4088 break; 4089 case D3DRTYPE_CUBETEXTURE: 4090 { 4091 IDirect3DCubeTexture8 *source; 4092 IDirect3DCubeTexture8 *dest; 4093 4094 sourceTexture->QueryInterface(IID_IDirect3DCubeTexture8, (void**)&source); 4095 destinationTexture->QueryInterface(IID_IDirect3DCubeTexture8, (void**)&dest); 4096 4097 ASSERT(source && dest); 4098 4099 for(int face = 0; face < 6; face++) 4100 { 4101 for(unsigned int level = 0; level < source->GetLevelCount() && level < dest->GetLevelCount(); level++) 4102 { 4103 IDirect3DSurface8 *sourceSurface; 4104 IDirect3DSurface8 *destinationSurface; 4105 4106 source->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &sourceSurface); 4107 dest->GetCubeMapSurface((D3DCUBEMAP_FACES)face, level, &destinationSurface); 4108 4109 updateSurface(sourceSurface, 0, destinationSurface, 0); 4110 4111 sourceSurface->Release(); 4112 destinationSurface->Release(); 4113 } 4114 } 4115 4116 source->Release(); 4117 dest->Release(); 4118 } 4119 break; 4120 default: 4121 ASSERT(false); 4122 } 4123 4124 return D3D_OK; 4125 } 4126 ValidateDevice(unsigned long * numPasses)4127 long Direct3DDevice8::ValidateDevice(unsigned long *numPasses) 4128 { 4129 TRACE(""); 4130 4131 if(!numPasses) 4132 { 4133 return INVALIDCALL(); 4134 } 4135 4136 *numPasses = 1; 4137 4138 return D3D_OK; 4139 } 4140 updateSurface(IDirect3DSurface8 * sourceSurface,const RECT * sourceRect,IDirect3DSurface8 * destinationSurface,const POINT * destPoint)4141 long Direct3DDevice8::updateSurface(IDirect3DSurface8 *sourceSurface, const RECT *sourceRect, IDirect3DSurface8 *destinationSurface, const POINT *destPoint) 4142 { 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); 4144 4145 if(!sourceSurface || !destinationSurface) 4146 { 4147 return INVALIDCALL(); 4148 } 4149 4150 D3DSURFACE_DESC sourceDescription; 4151 D3DSURFACE_DESC destinationDescription; 4152 4153 sourceSurface->GetDesc(&sourceDescription); 4154 destinationSurface->GetDesc(&destinationDescription); 4155 4156 RECT sRect; 4157 RECT dRect; 4158 4159 if(sourceRect && destPoint) 4160 { 4161 sRect.left = sourceRect->left; 4162 sRect.top = sourceRect->top; 4163 sRect.right = sourceRect->right; 4164 sRect.bottom = sourceRect->bottom; 4165 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; 4170 } 4171 else 4172 { 4173 sRect.left = 0; 4174 sRect.top = 0; 4175 sRect.right = sourceDescription.Width; 4176 sRect.bottom = sourceDescription.Height; 4177 4178 dRect.left = 0; 4179 dRect.top = 0; 4180 dRect.right = destinationDescription.Width; 4181 dRect.bottom = destinationDescription.Height; 4182 } 4183 4184 int sWidth = sRect.right - sRect.left; 4185 int sHeight = sRect.bottom - sRect.top; 4186 4187 int dWidth = dRect.right - dRect.left; 4188 int dHeight = dRect.bottom - dRect.top; 4189 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 || 4195 sWidth != dWidth || 4196 sHeight != dHeight) 4197 { 4198 return INVALIDCALL(); 4199 } 4200 4201 D3DLOCKED_RECT sourceLock; 4202 D3DLOCKED_RECT destinationLock; 4203 4204 sourceSurface->LockRect(&sourceLock, &sRect, D3DLOCK_READONLY); 4205 destinationSurface->LockRect(&destinationLock, &dRect, 0); 4206 4207 unsigned int width; 4208 unsigned int height; 4209 unsigned int bytes; 4210 4211 switch(sourceDescription.Format) 4212 { 4213 case D3DFMT_DXT1: 4214 width = (dWidth + 3) / 4; 4215 height = (dHeight + 3) / 4; 4216 bytes = width * 8; // 64 bit per 4x4 block 4217 break; 4218 case D3DFMT_DXT2: 4219 case D3DFMT_DXT3: 4220 case D3DFMT_DXT4: 4221 case D3DFMT_DXT5: 4222 width = (dWidth + 3) / 4; 4223 height = (dHeight + 3) / 4; 4224 bytes = width * 16; // 128 bit per 4x4 block 4225 break; 4226 default: 4227 width = dWidth; 4228 height = dHeight; 4229 bytes = width * Direct3DSurface8::bytes(sourceDescription.Format); 4230 } 4231 4232 for(unsigned int y = 0; y < height; y++) 4233 { 4234 memcpy(destinationLock.pBits, sourceLock.pBits, bytes); 4235 4236 (byte*&)sourceLock.pBits += sourceLock.Pitch; 4237 (byte*&)destinationLock.pBits += destinationLock.Pitch; 4238 } 4239 4240 sourceSurface->UnlockRect(); 4241 destinationSurface->UnlockRect(); 4242 4243 return D3D_OK; 4244 } 4245 SetIndices(IDirect3DIndexBuffer8 * iIndexBuffer,unsigned int baseVertexIndex)4246 long Direct3DDevice8::SetIndices(IDirect3DIndexBuffer8 *iIndexBuffer, unsigned int baseVertexIndex) 4247 { 4248 TRACE(""); 4249 4250 Direct3DIndexBuffer8 *indexBuffer = static_cast<Direct3DIndexBuffer8*>(iIndexBuffer); 4251 4252 if(!recordState) 4253 { 4254 if(indexBuffer) 4255 { 4256 indexBuffer->bind(); 4257 } 4258 4259 if(this->indexData) 4260 { 4261 this->indexData->unbind(); 4262 } 4263 4264 this->indexData = indexBuffer; 4265 this->baseVertexIndex = baseVertexIndex; 4266 } 4267 else 4268 { 4269 stateRecorder.back()->setIndices(indexBuffer, baseVertexIndex); 4270 } 4271 4272 return D3D_OK; 4273 } 4274 FVFStride(unsigned long FVF)4275 int Direct3DDevice8::FVFStride(unsigned long FVF) 4276 { 4277 int stride = 0; 4278 4279 switch(FVF & D3DFVF_POSITION_MASK) 4280 { 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; 4288 } 4289 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; 4294 4295 switch((FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) 4296 { 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); 4305 case 0: break; 4306 default: 4307 ASSERT(false); 4308 } 4309 4310 return stride; 4311 } 4312 typeStride(unsigned char type)4313 int Direct3DDevice8::typeStride(unsigned char type) 4314 { 4315 static const int LUT[] = 4316 { 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 4325 }; 4326 4327 if(type <= 7) 4328 { 4329 return LUT[type]; 4330 } 4331 else ASSERT(false); 4332 4333 return 0; 4334 } 4335 bindData(Direct3DIndexBuffer8 * indexBuffer,int base)4336 bool Direct3DDevice8::bindData(Direct3DIndexBuffer8 *indexBuffer, int base) 4337 { 4338 if(!bindViewport()) 4339 { 4340 return false; // Zero-area target region 4341 } 4342 4343 bindTextures(); 4344 bindStreams(base); 4345 bindIndexBuffer(indexBuffer); 4346 bindLights(); 4347 4348 return true; 4349 } 4350 bindStreams(int base)4351 void Direct3DDevice8::bindStreams(int base) 4352 { 4353 renderer->resetInputStreams((FVF & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW); 4354 4355 int stride; 4356 4357 if(!declaration) // Fixed-function vertex pipeline 4358 { 4359 const void *buffer = 0; 4360 4361 ASSERT(dataStream[0]); 4362 4363 Direct3DVertexBuffer8 *stream = dataStream[0]; 4364 sw::Resource *resource = stream->getResource(); 4365 buffer = (char*)resource->data(); 4366 stride = FVFStride(FVF); 4367 4368 ASSERT(stride == streamStride[0]); // FIXME 4369 ASSERT(buffer && stride); 4370 4371 (char*&)buffer += stride * base; 4372 4373 sw::Stream attribute(resource, buffer, stride); 4374 4375 switch(FVF & D3DFVF_POSITION_MASK) 4376 { 4377 case D3DFVF_XYZ: 4378 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3)); 4379 (char*&)buffer += 12; 4380 break; 4381 case D3DFVF_XYZRHW: 4382 renderer->setInputStream(sw::PositionT, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 4)); 4383 (char*&)buffer += 16; 4384 break; 4385 case D3DFVF_XYZB1: 4386 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3)); 4387 (char*&)buffer += 12; 4388 4389 renderer->setInputStream(sw::BlendWeight, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 1)); // FIXME: Stream type depends on indexed blending active? 4390 (char*&)buffer += 4; 4391 break; 4392 case D3DFVF_XYZB2: 4393 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3)); 4394 (char*&)buffer += 12; 4395 4396 renderer->setInputStream(sw::BlendWeight, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 1)); // FIXME: Stream type depends on indexed blending active? 4397 (char*&)buffer += 8; 4398 break; 4399 case D3DFVF_XYZB3: 4400 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3)); 4401 (char*&)buffer += 12; 4402 4403 renderer->setInputStream(sw::BlendWeight, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 2)); // FIXME: Stream type depends on indexed blending active? 4404 (char*&)buffer += 12; 4405 break; 4406 case D3DFVF_XYZB4: 4407 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3)); 4408 (char*&)buffer += 12; 4409 4410 renderer->setInputStream(sw::BlendWeight, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3)); // FIXME: Stream type depends on indexed blending active? 4411 (char*&)buffer += 16; 4412 break; 4413 case D3DFVF_XYZB5: 4414 renderer->setInputStream(sw::Position, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3)); 4415 (char*&)buffer += 12; 4416 4417 renderer->setInputStream(sw::BlendWeight, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 4)); // FIXME: Stream type depends on indexed blending active? 4418 (char*&)buffer += 20; 4419 break; 4420 } 4421 4422 if(FVF & D3DFVF_LASTBETA_UBYTE4) 4423 { 4424 renderer->setInputStream(sw::BlendIndices, attribute.define((char*&)buffer - 4, sw::STREAMTYPE_INDICES, 1)); 4425 } 4426 4427 if(FVF & D3DFVF_NORMAL) 4428 { 4429 renderer->setInputStream(sw::Normal, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 3)); 4430 (char*&)buffer += 12; 4431 } 4432 4433 if(FVF & D3DFVF_PSIZE) 4434 { 4435 renderer->setInputStream(sw::PointSize, attribute.define(buffer, sw::STREAMTYPE_FLOAT, 1)); 4436 (char*&)buffer += 4; 4437 } 4438 4439 if(FVF & D3DFVF_DIFFUSE) 4440 { 4441 renderer->setInputStream(sw::Color0, attribute.define(buffer, sw::STREAMTYPE_COLOR, 4)); 4442 (char*&)buffer += 4; 4443 } 4444 4445 if(FVF & D3DFVF_SPECULAR) 4446 { 4447 renderer->setInputStream(sw::Color1, attribute.define(buffer, sw::STREAMTYPE_COLOR, 4)); 4448 (char*&)buffer += 4; 4449 } 4450 4451 for(unsigned int i = 0; i < 8; i++) 4452 { 4453 if((FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT >= i + 1) 4454 { 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); 4457 } 4458 } 4459 } 4460 else 4461 { 4462 const unsigned long *element = declaration; 4463 int stream = 0; 4464 sw::Resource *resource; 4465 const void *buffer = 0; 4466 4467 while(*element != 0xFFFFFFFF) 4468 { 4469 switch((*element & 0xE0000000) >> 29) 4470 { 4471 case 0: // NOP 4472 if(*element != 0x00000000) 4473 { 4474 ASSERT(false); 4475 } 4476 break; 4477 case 1: // Stream selector 4478 stream = *element & 0x0000000F; 4479 { 4480 ASSERT(dataStream[stream]); // Expected a stream 4481 4482 Direct3DVertexBuffer8 *streamBuffer = (Direct3DVertexBuffer8*)dataStream[stream]; 4483 resource = streamBuffer->getResource(); 4484 buffer = (char*)resource->data(); 4485 4486 const unsigned long *streamElement = element + 1; 4487 stride = 0; 4488 4489 while((*streamElement & 0xE0000000) >> 29 == 2) // Data definition 4490 { 4491 if(*streamElement & 0x10000000) // Data skip 4492 { 4493 int skip = (*streamElement & 0x000F0000) >> 16; 4494 4495 stride += 4 * skip; 4496 } 4497 else 4498 { 4499 stride += typeStride((unsigned char)((*streamElement & 0x000F0000) >> 16)); 4500 } 4501 4502 streamElement++; 4503 } 4504 4505 // ASSERT(stride == streamStride[stream]); // FIXME: Probably just ignore 4506 4507 (char*&)buffer += stride * base; 4508 } 4509 break; 4510 case 2: // Data definition 4511 if(*element & 0x10000000) // Data skip 4512 { 4513 int skip = (*element & 0x000F0000) >> 16; 4514 4515 (char*&)buffer += 4 * skip; 4516 } 4517 else 4518 { 4519 int type = (*element & 0x000F0000) >> 16; 4520 int index = (*element & 0x0000000F) >> 0; 4521 4522 sw::Stream attribute(resource, buffer, stride); 4523 4524 switch(type) 4525 { 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); 4535 } 4536 4537 switch(index) 4538 { 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; 4556 default: 4557 ASSERT(false); 4558 } 4559 4560 (char*&)buffer += typeStride(type); 4561 } 4562 break; 4563 case 3: // Tesselator data 4564 UNIMPLEMENTED(); 4565 break; 4566 case 4: // Constant data 4567 { 4568 int count = (*element & 0x1E000000) >> 25; 4569 int index = (*element & 0x0000007F) >> 0; 4570 4571 SetVertexShaderConstant(index, element + 1, count); 4572 4573 element += 4 * count; 4574 } 4575 break; 4576 case 5: // Extension 4577 UNIMPLEMENTED(); 4578 break; 4579 default: 4580 ASSERT(false); 4581 } 4582 4583 element++; 4584 } 4585 } 4586 } 4587 bindIndexBuffer(Direct3DIndexBuffer8 * indexBuffer)4588 void Direct3DDevice8::bindIndexBuffer(Direct3DIndexBuffer8 *indexBuffer) 4589 { 4590 sw::Resource *resource = 0; 4591 4592 if(indexBuffer) 4593 { 4594 resource = indexBuffer->getResource(); 4595 } 4596 4597 renderer->setIndexBuffer(resource); 4598 } 4599 bindLights()4600 void Direct3DDevice8::bindLights() 4601 { 4602 if(!lightsDirty) return; 4603 4604 Lights::iterator i = light.begin(); 4605 int active = 0; 4606 4607 // Set and enable renderer lights 4608 while(active < 8) 4609 { 4610 while(i != light.end() && !i->second.enable) 4611 { 4612 i++; 4613 } 4614 4615 if(i == light.end()) 4616 { 4617 break; 4618 } 4619 4620 const Light &l = i->second; 4621 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); 4627 4628 renderer->setLightDiffuse(active, diffuse); 4629 renderer->setLightSpecular(active, specular); 4630 renderer->setLightAmbient(active, ambient); 4631 4632 if(l.Type == D3DLIGHT_DIRECTIONAL) 4633 { 4634 // goto next; // FIXME 4635 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); 4640 } 4641 else if(l.Type == D3DLIGHT_SPOT) 4642 { 4643 // goto next; // FIXME 4644 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); 4649 } 4650 else 4651 { 4652 renderer->setLightPosition(active, position); 4653 renderer->setLightRange(active, l.Range); 4654 renderer->setLightAttenuation(active, l.Attenuation0, l.Attenuation1, l.Attenuation2); 4655 } 4656 4657 renderer->setLightEnable(active, true); 4658 4659 active++; 4660 4661 // next: // FIXME 4662 i++; 4663 } 4664 4665 // Remaining lights are disabled 4666 while(active < 8) 4667 { 4668 renderer->setLightEnable(active, false); 4669 4670 active++; 4671 } 4672 4673 lightsDirty= false; 4674 } 4675 bindViewport()4676 bool Direct3DDevice8::bindViewport() 4677 { 4678 if(viewport.Width == 0 || viewport.Height == 0) 4679 { 4680 return false; 4681 } 4682 4683 sw::Viewport view; 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; 4690 4691 renderer->setViewport(view); 4692 4693 sw::Rect scissor; 4694 scissor.x0 = viewport.X; 4695 scissor.x1 = viewport.X + viewport.Width; 4696 scissor.y0 = viewport.Y; 4697 scissor.y1 = viewport.Y + viewport.Height; 4698 4699 renderer->setScissor(scissor); 4700 4701 return true; 4702 } 4703 bindTextures()4704 void Direct3DDevice8::bindTextures() 4705 { 4706 for(int stage = 0; stage < 8; stage++) 4707 { 4708 Direct3DBaseTexture8 *baseTexture = texture[stage]; 4709 sw::Resource *resource = 0; 4710 4711 bool textureUsed = false; 4712 4713 if(pixelShader[pixelShaderHandle]) 4714 { 4715 textureUsed = pixelShader[pixelShaderHandle]->getPixelShader()->usesSampler(stage); 4716 } 4717 else 4718 { 4719 textureUsed = true; // FIXME: Check fixed-function use? 4720 } 4721 4722 if(baseTexture && textureUsed) 4723 { 4724 resource = baseTexture->getResource(); 4725 } 4726 4727 renderer->setTextureResource(stage, resource); 4728 4729 if(baseTexture && textureUsed) 4730 { 4731 int levelCount = baseTexture->getInternalLevelCount(); 4732 4733 int textureLOD = baseTexture->GetLOD(); 4734 int stageLOD = textureStageState[stage][D3DTSS_MAXMIPLEVEL]; 4735 int LOD = textureLOD > stageLOD ? textureLOD : stageLOD; 4736 4737 if(textureStageState[stage][D3DTSS_MIPFILTER] == D3DTEXF_NONE) 4738 { 4739 LOD = 0; 4740 } 4741 4742 switch(baseTexture->GetType()) 4743 { 4744 case D3DRTYPE_TEXTURE: 4745 { 4746 Direct3DTexture8 *texture = dynamic_cast<Direct3DTexture8*>(baseTexture); 4747 Direct3DSurface8 *surface; 4748 4749 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++) 4750 { 4751 int surfaceLevel = mipmapLevel; 4752 4753 if(surfaceLevel < LOD) 4754 { 4755 surfaceLevel = LOD; 4756 } 4757 4758 if(surfaceLevel < 0) 4759 { 4760 surfaceLevel = 0; 4761 } 4762 else if(surfaceLevel >= levelCount) 4763 { 4764 surfaceLevel = levelCount - 1; 4765 } 4766 4767 surface = texture->getInternalSurfaceLevel(surfaceLevel); 4768 renderer->setTextureLevel(stage, 0, mipmapLevel, surface, sw::TEXTURE_2D); 4769 } 4770 } 4771 break; 4772 case D3DRTYPE_CUBETEXTURE: 4773 for(int face = 0; face < 6; face++) 4774 { 4775 Direct3DCubeTexture8 *cubeTexture = dynamic_cast<Direct3DCubeTexture8*>(baseTexture); 4776 Direct3DSurface8 *surface; 4777 4778 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++) 4779 { 4780 int surfaceLevel = mipmapLevel; 4781 4782 if(surfaceLevel < LOD) 4783 { 4784 surfaceLevel = LOD; 4785 } 4786 4787 if(surfaceLevel < 0) 4788 { 4789 surfaceLevel = 0; 4790 } 4791 else if(surfaceLevel >= levelCount) 4792 { 4793 surfaceLevel = levelCount - 1; 4794 } 4795 4796 surface = cubeTexture->getInternalCubeMapSurface((D3DCUBEMAP_FACES)face, surfaceLevel); 4797 renderer->setTextureLevel(stage, face, mipmapLevel, surface, sw::TEXTURE_CUBE); 4798 } 4799 } 4800 break; 4801 case D3DRTYPE_VOLUMETEXTURE: 4802 { 4803 Direct3DVolumeTexture8 *volumeTexture = dynamic_cast<Direct3DVolumeTexture8*>(baseTexture); 4804 Direct3DVolume8 *volume; 4805 4806 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++) 4807 { 4808 int surfaceLevel = mipmapLevel; 4809 4810 if(surfaceLevel < LOD) 4811 { 4812 surfaceLevel = LOD; 4813 } 4814 4815 if(surfaceLevel < 0) 4816 { 4817 surfaceLevel = 0; 4818 } 4819 else if(surfaceLevel >= levelCount) 4820 { 4821 surfaceLevel = levelCount - 1; 4822 } 4823 4824 volume = volumeTexture->getInternalVolumeLevel(surfaceLevel); 4825 renderer->setTextureLevel(stage, 0, mipmapLevel, volume, sw::TEXTURE_3D); 4826 } 4827 } 4828 break; 4829 default: 4830 UNIMPLEMENTED(); 4831 } 4832 } 4833 else 4834 { 4835 renderer->setTextureLevel(stage, 0, 0, 0, sw::TEXTURE_NULL); 4836 } 4837 } 4838 } 4839 bindCursor()4840 void Direct3DDevice8::bindCursor() 4841 { 4842 if(showCursor) 4843 { 4844 sw::FrameBuffer::setCursorImage(cursor); 4845 4846 HCURSOR oldCursor = SetCursor(nullCursor); 4847 4848 if(oldCursor != nullCursor) 4849 { 4850 win32Cursor = oldCursor; 4851 } 4852 } 4853 else 4854 { 4855 sw::FrameBuffer::setCursorImage(0); 4856 4857 if(GetCursor() == nullCursor) 4858 { 4859 SetCursor(win32Cursor); 4860 } 4861 } 4862 } 4863 updateVolume(IDirect3DVolume8 * sourceVolume,IDirect3DVolume8 * destinationVolume)4864 long Direct3DDevice8::updateVolume(IDirect3DVolume8 *sourceVolume, IDirect3DVolume8 *destinationVolume) 4865 { 4866 TRACE("IDirect3DVolume8 *sourceVolume = 0x%0.8p, IDirect3DVolume8 *destinationVolume = 0x%0.8p", sourceVolume, destinationVolume); 4867 4868 if(!sourceVolume || !destinationVolume) 4869 { 4870 return INVALIDCALL(); 4871 } 4872 4873 D3DVOLUME_DESC sourceDescription; 4874 D3DVOLUME_DESC destinationDescription; 4875 4876 sourceVolume->GetDesc(&sourceDescription); 4877 destinationVolume->GetDesc(&destinationDescription); 4878 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) 4884 { 4885 return INVALIDCALL(); 4886 } 4887 4888 D3DLOCKED_BOX sourceLock; 4889 D3DLOCKED_BOX destinationLock; 4890 4891 sourceVolume->LockBox(&sourceLock, 0, 0); 4892 destinationVolume->LockBox(&destinationLock, 0, 0); 4893 4894 if(sourceLock.RowPitch != destinationLock.RowPitch || 4895 sourceLock.SlicePitch != destinationLock.SlicePitch) 4896 { 4897 UNIMPLEMENTED(); 4898 } 4899 4900 memcpy(destinationLock.pBits, sourceLock.pBits, sourceLock.SlicePitch * sourceDescription.Depth); 4901 4902 sourceVolume->UnlockBox(); 4903 destinationVolume->UnlockBox(); 4904 4905 return D3D_OK; 4906 } 4907 configureFPU()4908 void Direct3DDevice8::configureFPU() 4909 { 4910 unsigned short cw; 4911 4912 __asm 4913 { 4914 fstcw cw 4915 and cw, 0xFCFC // Single-precision 4916 or cw, 0x003F // Mask all exceptions 4917 and cw, 0xF3FF // Round to nearest 4918 fldcw cw 4919 } 4920 } 4921 } 4922