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