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