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