Home | History | Annotate | Download | only in D3D9
      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 "Direct3DStateBlock9.hpp"
     16 
     17 #include "Direct3DDevice9.hpp"
     18 #include "Direct3DVertexDeclaration9.hpp"
     19 #include "Direct3DIndexBuffer9.hpp"
     20 #include "Direct3DVertexBuffer9.hpp"
     21 #include "Direct3DBaseTexture9.hpp"
     22 #include "Direct3DPixelShader9.hpp"
     23 #include "Direct3DVertexShader9.hpp"
     24 #include "Debug.hpp"
     25 
     26 #include <assert.h>
     27 
     28 namespace D3D9
     29 {
     30 	Direct3DStateBlock9::Direct3DStateBlock9(Direct3DDevice9 *device, D3DSTATEBLOCKTYPE type) : device(device), type(type)
     31 	{
     32 		vertexDeclaration = 0;
     33 
     34 		indexBuffer = 0;
     35 
     36 		for(int stream = 0; stream < MAX_VERTEX_INPUTS; stream++)
     37 		{
     38 			streamSource[stream].vertexBuffer = 0;
     39 		}
     40 
     41 		for(int sampler = 0; sampler < 16 + 4; sampler++)
     42 		{
     43 			texture[sampler] = 0;
     44 		}
     45 
     46 		pixelShader = 0;
     47 		vertexShader = 0;
     48 
     49 		clear();
     50 
     51 		if(type == D3DSBT_PIXELSTATE || type == D3DSBT_ALL)
     52 		{
     53 			capturePixelRenderStates();
     54 			capturePixelTextureStates();
     55 			capturePixelSamplerStates();
     56 			capturePixelShaderStates();
     57 		}
     58 
     59 		if(type == D3DSBT_VERTEXSTATE || type == D3DSBT_ALL)
     60 		{
     61 			captureVertexRenderStates();
     62 			captureVertexSamplerStates();
     63 			captureVertexTextureStates();
     64 			captureNPatchMode();
     65 			captureLightStates();
     66 			captureVertexShaderStates();
     67 			captureStreamSourceFrequencies();
     68 			captureFVF();
     69 			captureVertexDeclaration();
     70 		}
     71 
     72 		if(type == D3DSBT_ALL)   // Capture remaining states
     73 		{
     74 			captureTextures();
     75 			captureTexturePalette();
     76 			captureVertexStreams();
     77 			captureIndexBuffer();
     78 			captureViewport();
     79 			captureScissorRectangle();
     80 			captureTransforms();
     81 			captureTextureTransforms();
     82 			captureClippingPlanes();
     83 			captureMaterial();
     84 		}
     85 	}
     86 
     87 	Direct3DStateBlock9::~Direct3DStateBlock9()
     88 	{
     89 		clear();
     90 	}
     91 
     92 	long Direct3DStateBlock9::QueryInterface(const IID &iid, void **object)
     93 	{
     94 		CriticalSection cs(device);
     95 
     96 		TRACE("");
     97 
     98 		if(iid == IID_IDirect3DStateBlock9 ||
     99 		   iid == IID_IUnknown)
    100 		{
    101 			AddRef();
    102 			*object = this;
    103 
    104 			return S_OK;
    105 		}
    106 
    107 		*object = 0;
    108 
    109 		return NOINTERFACE(iid);
    110 	}
    111 
    112 	unsigned long Direct3DStateBlock9::AddRef()
    113 	{
    114 		TRACE("");
    115 
    116 		return Unknown::AddRef();
    117 	}
    118 
    119 	unsigned long Direct3DStateBlock9::Release()
    120 	{
    121 		TRACE("");
    122 
    123 		return Unknown::Release();
    124 	}
    125 
    126 	long Direct3DStateBlock9::Apply()
    127 	{
    128 		CriticalSection cs(device);
    129 
    130 		TRACE("");
    131 
    132 		if(device->isRecording())
    133 		{
    134 			return INVALIDCALL();
    135 		}
    136 
    137 		if(fvfCaptured)
    138 		{
    139 			device->SetFVF(FVF);
    140 		}
    141 
    142 		if(vertexDeclarationCaptured)
    143 		{
    144 			device->SetVertexDeclaration(vertexDeclaration);
    145 		}
    146 
    147 		if(indexBufferCaptured)
    148 		{
    149 			device->SetIndices(indexBuffer);
    150 		}
    151 
    152 		for(int state = D3DRS_ZENABLE; state <= D3DRS_BLENDOPALPHA; state++)
    153 		{
    154 			if(renderStateCaptured[state])
    155 			{
    156 				device->SetRenderState((D3DRENDERSTATETYPE)state, renderState[state]);
    157 			}
    158 		}
    159 
    160 		if(nPatchModeCaptured)
    161 		{
    162 			device->SetNPatchMode(nPatchMode);
    163 		}
    164 
    165 		for(int stage = 0; stage < 8; stage++)
    166 		{
    167 			for(int state = D3DTSS_COLOROP; state <= D3DTSS_CONSTANT; state++)
    168 			{
    169 				if(textureStageStateCaptured[stage][state])
    170 				{
    171 					device->SetTextureStageState(stage, (D3DTEXTURESTAGESTATETYPE)state, textureStageState[stage][state]);
    172 				}
    173 			}
    174 		}
    175 
    176 		for(int sampler = 0; sampler < 16 + 4; sampler++)
    177 		{
    178 			for(int state = D3DSAMP_ADDRESSU; state <= D3DSAMP_DMAPOFFSET; state++)
    179 			{
    180 				if(samplerStateCaptured[sampler][state])
    181 				{
    182 					int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16);
    183 					device->SetSamplerState(index, (D3DSAMPLERSTATETYPE)state, samplerState[sampler][state]);
    184 				}
    185 			}
    186 		}
    187 
    188 		for(int stream = 0; stream < MAX_VERTEX_INPUTS; stream++)
    189 		{
    190 			if(streamSourceCaptured[stream])
    191 			{
    192 				device->SetStreamSource(stream, streamSource[stream].vertexBuffer, streamSource[stream].offset, streamSource[stream].stride);
    193 			}
    194 
    195 			if(streamSourceFrequencyCaptured[stream])
    196 			{
    197 				device->SetStreamSourceFreq(stream, streamSourceFrequency[stream]);
    198 			}
    199 		}
    200 
    201 		for(int sampler = 0; sampler < 16 + 4; sampler++)
    202 		{
    203 			if(textureCaptured[sampler])
    204 			{
    205 				int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16);
    206 				device->SetTexture(index, texture[sampler]);
    207 			}
    208 		}
    209 
    210 		for(int state = 0; state < 512; state++)
    211 		{
    212 			if(transformCaptured[state])
    213 			{
    214 				device->SetTransform((D3DTRANSFORMSTATETYPE)state, &transform[state]);
    215 			}
    216 		}
    217 
    218 		if(materialCaptured)
    219 		{
    220 			device->SetMaterial(&material);
    221 		}
    222 
    223 		for(int index = 0; index < 8; index++)   // FIXME: Support unlimited index
    224 		{
    225 			if(lightCaptured[index])
    226 			{
    227 				device->SetLight(index, &light[index]);
    228 			}
    229 		}
    230 
    231 		for(int index = 0; index < 8; index++)   // FIXME: Support unlimited index
    232 		{
    233 			if(lightEnableCaptured[index])
    234 			{
    235 				device->LightEnable(index, lightEnableState[index]);
    236 			}
    237 		}
    238 
    239 		if(pixelShaderCaptured)
    240 		{
    241 			device->SetPixelShader(pixelShader);
    242 		}
    243 
    244 		if(vertexShaderCaptured)
    245 		{
    246 			device->SetVertexShader(vertexShader);
    247 		}
    248 
    249 		if(viewportCaptured)
    250 		{
    251 			device->SetViewport(&viewport);
    252 		}
    253 
    254 		for(int i = 0; i < MAX_PIXEL_SHADER_CONST; i++)
    255 		{
    256 			if(*(int*)pixelShaderConstantF[i] != 0x80000000)
    257 			{
    258 				device->SetPixelShaderConstantF(i, pixelShaderConstantF[i], 1);
    259 			}
    260 		}
    261 
    262 		for(int i = 0; i < 16; i++)
    263 		{
    264 			if(pixelShaderConstantI[i][0] != 0x80000000)
    265 			{
    266 				device->SetPixelShaderConstantI(i, pixelShaderConstantI[i], 1);
    267 			}
    268 		}
    269 
    270 		for(int i = 0; i < 16; i++)
    271 		{
    272 			if(pixelShaderConstantB[i] != 0x80000000)
    273 			{
    274 				device->SetPixelShaderConstantB(i, &pixelShaderConstantB[i], 1);
    275 			}
    276 		}
    277 
    278 		for(int i = 0; i < MAX_VERTEX_SHADER_CONST; i++)
    279 		{
    280 			if(*(int*)vertexShaderConstantF[i] != 0x80000000)
    281 			{
    282 				device->SetVertexShaderConstantF(i, vertexShaderConstantF[i], 1);
    283 			}
    284 		}
    285 
    286 		for(int i = 0; i < 16; i++)
    287 		{
    288 			if(vertexShaderConstantI[i][0] != 0x80000000)
    289 			{
    290 				device->SetVertexShaderConstantI(i, vertexShaderConstantI[i], 1);
    291 			}
    292 		}
    293 
    294 		for(int i = 0; i < 16; i++)
    295 		{
    296 			if(vertexShaderConstantB[i] != 0x80000000)
    297 			{
    298 				device->SetVertexShaderConstantB(i, &vertexShaderConstantB[i], 1);
    299 			}
    300 		}
    301 
    302 		for(int index = 0; index < 6; index++)
    303 		{
    304 			if(clipPlaneCaptured[index])
    305 			{
    306 				device->SetClipPlane(index, clipPlane[index]);
    307 			}
    308 		}
    309 
    310 		if(scissorRectCaptured)
    311 		{
    312 			device->SetScissorRect(&scissorRect);
    313 		}
    314 
    315 		if(paletteNumberCaptured)
    316 		{
    317 			device->SetCurrentTexturePalette(paletteNumber);
    318 		}
    319 
    320 		return D3D_OK;
    321 	}
    322 
    323 	long Direct3DStateBlock9::Capture()
    324 	{
    325 		CriticalSection cs(device);
    326 
    327 		TRACE("");
    328 
    329 		if(fvfCaptured)
    330 		{
    331 			device->GetFVF(&FVF);
    332 		}
    333 
    334 		if(vertexDeclarationCaptured)
    335 		{
    336 			Direct3DVertexDeclaration9 *vertexDeclaration;
    337 			device->GetVertexDeclaration(reinterpret_cast<IDirect3DVertexDeclaration9**>(&vertexDeclaration));
    338 
    339 			if(vertexDeclaration)
    340 			{
    341 				vertexDeclaration->bind();
    342 				vertexDeclaration->Release();
    343 			}
    344 
    345 			if(this->vertexDeclaration)
    346 			{
    347 				this->vertexDeclaration->unbind();
    348 			}
    349 
    350 			this->vertexDeclaration = vertexDeclaration;
    351 		}
    352 
    353 		if(indexBufferCaptured)
    354 		{
    355 			Direct3DIndexBuffer9 *indexBuffer;
    356 			device->GetIndices(reinterpret_cast<IDirect3DIndexBuffer9**>(&indexBuffer));
    357 
    358 			if(indexBuffer)
    359 			{
    360 				indexBuffer->bind();
    361 				indexBuffer->Release();
    362 			}
    363 
    364 			if(this->indexBuffer)
    365 			{
    366 				this->indexBuffer->unbind();
    367 			}
    368 
    369 			this->indexBuffer = indexBuffer;
    370 		}
    371 
    372 		for(int state = 0; state < D3DRS_BLENDOPALPHA + 1; state++)
    373 		{
    374 			if(renderStateCaptured[state])
    375 			{
    376 				device->GetRenderState((D3DRENDERSTATETYPE)state, &renderState[state]);
    377 			}
    378 		}
    379 
    380 		if(nPatchModeCaptured)
    381 		{
    382 			nPatchMode = device->GetNPatchMode();
    383 		}
    384 
    385 		for(int stage = 0; stage < 8; stage++)
    386 		{
    387 			for(int state = 0; state < D3DTSS_CONSTANT + 1; state++)
    388 			{
    389 				if(textureStageStateCaptured[stage][state])
    390 				{
    391 					device->GetTextureStageState(stage, (D3DTEXTURESTAGESTATETYPE)state, &textureStageState[stage][state]);
    392 				}
    393 			}
    394 		}
    395 
    396 		for(int sampler = 0; sampler < 16 + 4; sampler++)
    397 		{
    398 			for(int state = 0; state < D3DSAMP_DMAPOFFSET + 1; state++)
    399 			{
    400 				if(samplerStateCaptured[sampler][state])
    401 				{
    402 					int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16);
    403 					device->GetSamplerState(index, (D3DSAMPLERSTATETYPE)state, &samplerState[sampler][state]);
    404 				}
    405 			}
    406 		}
    407 
    408 		for(int stream = 0; stream < MAX_VERTEX_INPUTS; stream++)
    409 		{
    410 			if(streamSourceCaptured[stream])
    411 			{
    412 				Direct3DVertexBuffer9 *vertexBuffer;
    413 				device->GetStreamSource(stream, reinterpret_cast<IDirect3DVertexBuffer9**>(&vertexBuffer), &streamSource[stream].offset, &streamSource[stream].stride);
    414 
    415 				if(vertexBuffer)
    416 				{
    417 					vertexBuffer->bind();
    418 					vertexBuffer->Release();
    419 				}
    420 
    421 				if(streamSource[stream].vertexBuffer)
    422 				{
    423 					streamSource[stream].vertexBuffer->unbind();
    424 				}
    425 
    426 				streamSource[stream].vertexBuffer = vertexBuffer;
    427 			}
    428 
    429 			if(streamSourceFrequencyCaptured[stream])
    430 			{
    431 				device->GetStreamSourceFreq(stream, &streamSourceFrequency[stream]);
    432 			}
    433 		}
    434 
    435 		for(int sampler = 0; sampler < 16 + 4; sampler++)
    436 		{
    437 			if(textureCaptured[sampler])
    438 			{
    439 				Direct3DBaseTexture9 *texture;
    440 				int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16);
    441 				device->GetTexture(index, reinterpret_cast<IDirect3DBaseTexture9**>(&texture));
    442 
    443 				if(texture)
    444 				{
    445 					texture->bind();
    446 					texture->Release();
    447 				}
    448 
    449 				if(this->texture[sampler])
    450 				{
    451 					this->texture[sampler]->unbind();
    452 				}
    453 
    454 				this->texture[sampler] = texture;
    455 			}
    456 		}
    457 
    458 		for(int state = 0; state < 512; state++)
    459 		{
    460 			if(transformCaptured[state])
    461 			{
    462 				device->GetTransform((D3DTRANSFORMSTATETYPE)state, &transform[state]);
    463 			}
    464 		}
    465 
    466 		if(materialCaptured)
    467 		{
    468 			device->GetMaterial(&material);
    469 		}
    470 
    471 		for(int index = 0; index < 8; index++)   // FIXME: Support unlimited index
    472 		{
    473 			if(lightCaptured[index])
    474 			{
    475 				device->GetLight(index, &light[index]);
    476 			}
    477 		}
    478 
    479 		for(int index = 0; index < 8; index++)   // FIXME: Support unlimited index
    480 		{
    481 			if(lightEnableCaptured[index])
    482 			{
    483 				lightEnableState[index] = false;
    484 				device->GetLightEnable(index, &lightEnableState[index]);
    485 			}
    486 		}
    487 
    488 		if(pixelShaderCaptured)
    489 		{
    490 			Direct3DPixelShader9 *pixelShader;
    491 			device->GetPixelShader(reinterpret_cast<IDirect3DPixelShader9**>(&pixelShader));
    492 
    493 			if(pixelShader)
    494 			{
    495 				pixelShader->bind();
    496 				pixelShader->Release();
    497 			}
    498 
    499 			if(this->pixelShader)
    500 			{
    501 				this->pixelShader->unbind();
    502 			}
    503 
    504 			this->pixelShader = pixelShader;
    505 		}
    506 
    507 		if(vertexShaderCaptured)
    508 		{
    509 			Direct3DVertexShader9 *vertexShader;
    510 			device->GetVertexShader(reinterpret_cast<IDirect3DVertexShader9**>(&vertexShader));
    511 
    512 			if(vertexShader)
    513 			{
    514 				vertexShader->bind();
    515 				vertexShader->Release();
    516 			}
    517 
    518 			if(this->vertexShader)
    519 			{
    520 				this->vertexShader->unbind();
    521 			}
    522 
    523 			this->vertexShader = vertexShader;
    524 		}
    525 
    526 		if(viewportCaptured)
    527 		{
    528 			device->GetViewport(&viewport);
    529 		}
    530 
    531 		for(int i = 0; i < MAX_PIXEL_SHADER_CONST; i++)
    532 		{
    533 			if(*(int*)pixelShaderConstantF[i] != 0x80000000)
    534 			{
    535 				device->GetPixelShaderConstantF(i, pixelShaderConstantF[i], 1);
    536 			}
    537 		}
    538 
    539 		for(int i = 0; i < 16; i++)
    540 		{
    541 			if(pixelShaderConstantI[i][0] != 0x80000000)
    542 			{
    543 				device->GetPixelShaderConstantI(i, pixelShaderConstantI[i], 1);
    544 			}
    545 		}
    546 
    547 		for(int i = 0; i < 16; i++)
    548 		{
    549 			if(pixelShaderConstantB[i] != 0x80000000)
    550 			{
    551 				device->GetPixelShaderConstantB(i, &pixelShaderConstantB[i], 1);
    552 			}
    553 		}
    554 
    555 		for(int i = 0; i < MAX_VERTEX_SHADER_CONST; i++)
    556 		{
    557 			if(*(int*)vertexShaderConstantF[i] != 0x80000000)
    558 			{
    559 				device->GetVertexShaderConstantF(i, vertexShaderConstantF[i], 1);
    560 			}
    561 		}
    562 
    563 		for(int i = 0; i < 16; i++)
    564 		{
    565 			if(vertexShaderConstantI[i][0] != 0x80000000)
    566 			{
    567 				device->GetVertexShaderConstantI(i, vertexShaderConstantI[i], 1);
    568 			}
    569 		}
    570 
    571 		for(int i = 0; i < 16; i++)
    572 		{
    573 			if(vertexShaderConstantB[i] != 0x80000000)
    574 			{
    575 				device->GetVertexShaderConstantB(i, &vertexShaderConstantB[i], 1);
    576 			}
    577 		}
    578 
    579 		for(int index = 0; index < 6; index++)
    580 		{
    581 			if(clipPlaneCaptured[index])
    582 			{
    583 				device->GetClipPlane(index, clipPlane[index]);
    584 			}
    585 		}
    586 
    587 		if(scissorRectCaptured)
    588 		{
    589 			device->GetScissorRect(&scissorRect);
    590 		}
    591 
    592 		if(paletteNumberCaptured)
    593 		{
    594 			device->GetCurrentTexturePalette(&paletteNumber);
    595 		}
    596 
    597 		return D3D_OK;
    598 	}
    599 
    600 	long Direct3DStateBlock9::GetDevice(IDirect3DDevice9 **device)
    601 	{
    602 		CriticalSection cs(this->device);
    603 
    604 		TRACE("");
    605 
    606 		if(!device)
    607 		{
    608 			return INVALIDCALL();
    609 		}
    610 
    611 		this->device->AddRef();
    612 		*device = this->device;
    613 
    614 		return D3D_OK;
    615 	}
    616 
    617 	void Direct3DStateBlock9::lightEnable(unsigned long index, int enable)
    618 	{
    619 		if(index < 8)
    620 		{
    621 			lightEnableCaptured[index] = true;
    622 			lightEnableState[index] = enable;
    623 		}
    624 		else ASSERT(false);   // FIXME: Support unlimited index
    625 	}
    626 
    627 	void Direct3DStateBlock9::setClipPlane(unsigned long index, const float *plane)
    628 	{
    629 		clipPlaneCaptured[index] = true;
    630 		clipPlane[index][0] = plane[0];
    631 		clipPlane[index][1] = plane[1];
    632 		clipPlane[index][2] = plane[2];
    633 		clipPlane[index][3] = plane[3];
    634 	}
    635 
    636 	void Direct3DStateBlock9::setCurrentTexturePalette(unsigned int paletteNumber)
    637 	{
    638 		paletteNumberCaptured = true;
    639 		this->paletteNumber = paletteNumber;
    640 	}
    641 
    642 	void Direct3DStateBlock9::setFVF(unsigned long FVF)
    643 	{
    644 		fvfCaptured = true;
    645 		this->FVF = FVF;
    646 	}
    647 
    648 	void Direct3DStateBlock9::setIndices(Direct3DIndexBuffer9 *indexBuffer)
    649 	{
    650 		if(indexBuffer) indexBuffer->bind();
    651 		if(this->indexBuffer) this->indexBuffer->unbind();
    652 
    653 		indexBufferCaptured = true;
    654 		this->indexBuffer = indexBuffer;
    655 	}
    656 
    657 	void Direct3DStateBlock9::setLight(unsigned long index, const D3DLIGHT9 *light)
    658 	{
    659 		if(index < 8)
    660 		{
    661 			lightCaptured[index] = true;
    662 			this->light[index] = *light;
    663 		}
    664 		else ASSERT(false);   // FIXME: Support unlimited index
    665 	}
    666 
    667 	void Direct3DStateBlock9::setMaterial(const D3DMATERIAL9 *material)
    668 	{
    669 		materialCaptured = true;
    670 		this->material = *material;
    671 	}
    672 
    673 	void Direct3DStateBlock9::setNPatchMode(float segments)
    674 	{
    675 		nPatchModeCaptured = true;
    676 		nPatchMode = segments;
    677 	}
    678 
    679 	void Direct3DStateBlock9::setPixelShader(Direct3DPixelShader9 *pixelShader)
    680 	{
    681 		if(pixelShader) pixelShader->bind();
    682 		if(this->pixelShader) this->pixelShader->unbind();
    683 
    684 		pixelShaderCaptured = true;
    685 		this->pixelShader = pixelShader;
    686 	}
    687 
    688 	void Direct3DStateBlock9::setPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
    689 	{
    690 		memcpy(&pixelShaderConstantB[startRegister], constantData, count * sizeof(int));
    691 	}
    692 
    693 	void Direct3DStateBlock9::setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
    694 	{
    695 		memcpy(pixelShaderConstantF[startRegister], constantData, count * sizeof(float[4]));
    696 	}
    697 
    698 	void Direct3DStateBlock9::setPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
    699 	{
    700 		memcpy(pixelShaderConstantI[startRegister], constantData, count * sizeof(int[4]));
    701 	}
    702 
    703 	void Direct3DStateBlock9::setRenderState(D3DRENDERSTATETYPE state, unsigned long value)
    704 	{
    705 		renderStateCaptured[state] = true;
    706 		renderState[state] = value;
    707 	}
    708 
    709 	void Direct3DStateBlock9::setSamplerState(unsigned long index, D3DSAMPLERSTATETYPE state, unsigned long value)
    710 	{
    711 		unsigned int sampler = index < 16 ? index : (index - D3DVERTEXTEXTURESAMPLER0) + 16;
    712 
    713 		if(sampler >= 16 + 4)
    714 		{
    715 			return;
    716 		}
    717 
    718 		samplerStateCaptured[sampler][state] = true;
    719 		samplerState[sampler][state] = value;
    720 	}
    721 
    722 	void Direct3DStateBlock9::setScissorRect(const RECT *rect)
    723 	{
    724 		scissorRectCaptured = true;
    725 		scissorRect = *rect;
    726 	}
    727 
    728 	void Direct3DStateBlock9::setStreamSource(unsigned int stream, Direct3DVertexBuffer9 *vertexBuffer, unsigned int offset, unsigned int stride)
    729 	{
    730 		if(vertexBuffer) vertexBuffer->bind();
    731 		if(streamSource[stream].vertexBuffer) streamSource[stream].vertexBuffer->unbind();
    732 
    733 		streamSourceCaptured[stream] = true;
    734 		streamSource[stream].vertexBuffer = vertexBuffer;
    735 		streamSource[stream].offset = offset;
    736 		streamSource[stream].stride = stride;
    737 	}
    738 
    739 	void Direct3DStateBlock9::setStreamSourceFreq(unsigned int streamNumber, unsigned int divider)
    740 	{
    741 		streamSourceFrequencyCaptured[streamNumber] = true;
    742 		streamSourceFrequency[streamNumber] = divider;
    743 	}
    744 
    745 	void Direct3DStateBlock9::setTexture(unsigned long index, Direct3DBaseTexture9 *texture)
    746 	{
    747 		unsigned int sampler = index < 16 ? index : (index - D3DVERTEXTEXTURESAMPLER0) + 16;
    748 
    749 		if(sampler >= 16 + 4)
    750 		{
    751 			return;
    752 		}
    753 
    754 		if(texture) texture->bind();
    755 		if(this->texture[sampler]) this->texture[sampler]->unbind();
    756 
    757 		textureCaptured[sampler] = true;
    758 		this->texture[sampler] = texture;
    759 	}
    760 
    761 	void Direct3DStateBlock9::setTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value)
    762 	{
    763 		textureStageStateCaptured[stage][type] = true;
    764 		textureStageState[stage][type] = value;
    765 	}
    766 
    767 	void Direct3DStateBlock9::setTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
    768 	{
    769 		transformCaptured[state] = true;
    770 		transform[state] = *matrix;
    771 	}
    772 
    773 	void Direct3DStateBlock9::setViewport(const D3DVIEWPORT9 *viewport)
    774 	{
    775 		viewportCaptured = true;
    776 		this->viewport = *viewport;
    777 	}
    778 
    779 	void Direct3DStateBlock9::setVertexDeclaration(Direct3DVertexDeclaration9 *vertexDeclaration)
    780 	{
    781 		if(vertexDeclaration) vertexDeclaration->bind();
    782 		if(this->vertexDeclaration) this->vertexDeclaration->unbind();
    783 
    784 		vertexDeclarationCaptured = true;
    785 		this->vertexDeclaration = vertexDeclaration;
    786 	}
    787 
    788 	void Direct3DStateBlock9::setVertexShader(Direct3DVertexShader9 *vertexShader)
    789 	{
    790 		if(vertexShader) vertexShader->bind();
    791 		if(this->vertexShader) this->vertexShader->unbind();
    792 
    793 		vertexShaderCaptured = true;
    794 		this->vertexShader = vertexShader;
    795 	}
    796 
    797 	void Direct3DStateBlock9::setVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count)
    798 	{
    799 		memcpy(&vertexShaderConstantB[startRegister], constantData, count * sizeof(int));
    800 	}
    801 
    802 	void Direct3DStateBlock9::setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
    803 	{
    804 		memcpy(vertexShaderConstantF[startRegister], constantData, count * sizeof(float[4]));
    805 	}
    806 
    807 	void Direct3DStateBlock9::setVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count)
    808 	{
    809 		memcpy(vertexShaderConstantI[startRegister], constantData, count * sizeof(int[4]));
    810 	}
    811 
    812 	void Direct3DStateBlock9::clear()
    813 	{
    814 		// Erase capture flags
    815 		fvfCaptured = false;
    816 		vertexDeclarationCaptured = false;
    817 
    818 		indexBufferCaptured = false;
    819 
    820 		for(int state = 0; state < D3DRS_BLENDOPALPHA + 1; state++)
    821 		{
    822 			renderStateCaptured[state] = false;
    823 		}
    824 
    825 		nPatchModeCaptured = false;
    826 
    827 		for(int stage = 0; stage < 8; stage++)
    828 		{
    829 			for(int state = 0; state < D3DTSS_CONSTANT + 1; state++)
    830 			{
    831 				textureStageStateCaptured[stage][state] = false;
    832 			}
    833 		}
    834 
    835 		for(int sampler = 0; sampler < 16 + 4; sampler++)
    836 		{
    837 			for(int state = 0; state < D3DSAMP_DMAPOFFSET + 1; state++)
    838 			{
    839 				samplerStateCaptured[sampler][state] = false;
    840 			}
    841 		}
    842 
    843 		for(int stream = 0; stream < MAX_VERTEX_INPUTS; stream++)
    844 		{
    845 			streamSourceCaptured[stream] = false;
    846 			streamSourceFrequencyCaptured[stream] = false;
    847 		}
    848 
    849 		for(int sampler = 0; sampler < 16 + 4; sampler++)
    850 		{
    851 			textureCaptured[sampler] = false;
    852 		}
    853 
    854 		for(int state = 0; state < 512; state++)
    855 		{
    856 			transformCaptured[state] = false;
    857 		}
    858 
    859 		materialCaptured = false;
    860 
    861 		for(int index = 0; index < 8; index++)   // FIXME: Support unlimited index
    862 		{
    863 			lightCaptured[index] = false;
    864 		}
    865 
    866 		for(int index = 0; index < 8; index++)   // FIXME: Support unlimited index
    867 		{
    868 			lightEnableCaptured[index] = false;
    869 		}
    870 
    871 		scissorRectCaptured = false;
    872 
    873 		pixelShaderCaptured = false;
    874 		vertexShaderCaptured = false;
    875 
    876 		viewportCaptured = false;
    877 
    878 		for(int i = 0; i < MAX_PIXEL_SHADER_CONST; i++)
    879 		{
    880 			(int&)pixelShaderConstantF[i][0] = 0x80000000;
    881 			(int&)pixelShaderConstantF[i][1] = 0x80000000;
    882 			(int&)pixelShaderConstantF[i][2] = 0x80000000;
    883 			(int&)pixelShaderConstantF[i][3] = 0x80000000;
    884 		}
    885 
    886 		for(int i = 0; i < MAX_VERTEX_SHADER_CONST; i++)
    887 		{
    888 			(int&)vertexShaderConstantF[i][0] = 0x80000000;
    889 			(int&)vertexShaderConstantF[i][1] = 0x80000000;
    890 			(int&)vertexShaderConstantF[i][2] = 0x80000000;
    891 			(int&)vertexShaderConstantF[i][3] = 0x80000000;
    892 		}
    893 
    894 		for(int i = 0; i < 16; i++)
    895 		{
    896 			pixelShaderConstantI[i][0] = 0x80000000;
    897 			pixelShaderConstantI[i][1] = 0x80000000;
    898 			pixelShaderConstantI[i][2] = 0x80000000;
    899 			pixelShaderConstantI[i][3] = 0x80000000;
    900 
    901 			pixelShaderConstantB[i] = 0x80000000;
    902 
    903 			vertexShaderConstantI[i][0] = 0x80000000;
    904 			vertexShaderConstantI[i][1] = 0x80000000;
    905 			vertexShaderConstantI[i][2] = 0x80000000;
    906 			vertexShaderConstantI[i][3] = 0x80000000;
    907 
    908 			vertexShaderConstantB[i] = 0x80000000;
    909 		}
    910 
    911 		for(int index = 0; index < 6; index++)
    912 		{
    913 			clipPlaneCaptured[index] = false;
    914 		}
    915 
    916 		paletteNumberCaptured = false;
    917 
    918 		// unbind resources
    919 		if(vertexDeclaration)
    920 		{
    921 			vertexDeclaration->unbind();
    922 			vertexDeclaration = 0;
    923 		}
    924 
    925 		if(indexBuffer)
    926 		{
    927 			indexBuffer->unbind();
    928 			indexBuffer = 0;
    929 		}
    930 
    931 		for(int stream = 0; stream < MAX_VERTEX_INPUTS; stream++)
    932 		{
    933 			if(streamSource[stream].vertexBuffer)
    934 			{
    935 				streamSource[stream].vertexBuffer->unbind();
    936 				streamSource[stream].vertexBuffer = 0;
    937 			}
    938 		}
    939 
    940 		for(int sampler = 0; sampler < 16 + 4; sampler++)
    941 		{
    942 			if(texture[sampler])
    943 			{
    944 				texture[sampler]->unbind();
    945 				texture[sampler] = 0;
    946 			}
    947 		}
    948 
    949 		if(pixelShader)
    950 		{
    951 			pixelShader->unbind();
    952 			pixelShader = 0;
    953 		}
    954 
    955 		if(vertexShader)
    956 		{
    957 			vertexShader->unbind();
    958 			vertexShader = 0;
    959 		}
    960 	}
    961 
    962 	void Direct3DStateBlock9::captureRenderState(D3DRENDERSTATETYPE state)
    963 	{
    964 		device->GetRenderState(state, &renderState[state]);
    965 		renderStateCaptured[state] = true;
    966 	}
    967 
    968 	void Direct3DStateBlock9::captureSamplerState(unsigned long index, D3DSAMPLERSTATETYPE state)
    969 	{
    970 		if(index < 16)
    971 		{
    972 			device->GetSamplerState(index, state, &samplerState[index][state]);
    973 			samplerStateCaptured[index][state] = true;
    974 		}
    975 		else if(index >= D3DVERTEXTEXTURESAMPLER0)
    976 		{
    977 			unsigned int sampler = 16 + (index - D3DVERTEXTEXTURESAMPLER0);
    978 
    979 			device->GetSamplerState(index, state, &samplerState[sampler][state]);
    980 			samplerStateCaptured[sampler][state] = true;
    981 		}
    982 	}
    983 
    984 	void Direct3DStateBlock9::captureTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type)
    985 	{
    986 		device->GetTextureStageState(stage, type, &textureStageState[stage][type]);
    987 		textureStageStateCaptured[stage][type] = true;
    988 	}
    989 
    990 	void Direct3DStateBlock9::captureTransform(D3DTRANSFORMSTATETYPE state)
    991 	{
    992 		device->GetTransform(state, &transform[state]);
    993 		transformCaptured[state] = true;
    994 	}
    995 
    996 	void Direct3DStateBlock9::capturePixelRenderStates()
    997 	{
    998 		captureRenderState(D3DRS_ZENABLE);
    999 		captureRenderState(D3DRS_FILLMODE);
   1000 		captureRenderState(D3DRS_SHADEMODE);
   1001 		captureRenderState(D3DRS_ZWRITEENABLE);
   1002 		captureRenderState(D3DRS_ALPHATESTENABLE);
   1003 		captureRenderState(D3DRS_LASTPIXEL);
   1004 		captureRenderState(D3DRS_SRCBLEND);
   1005 		captureRenderState(D3DRS_DESTBLEND);
   1006 		captureRenderState(D3DRS_ZFUNC);
   1007 		captureRenderState(D3DRS_ALPHAREF);
   1008 		captureRenderState(D3DRS_ALPHAFUNC);
   1009 		captureRenderState(D3DRS_DITHERENABLE);
   1010 		captureRenderState(D3DRS_FOGSTART);
   1011 		captureRenderState(D3DRS_FOGEND);
   1012 		captureRenderState(D3DRS_FOGDENSITY);
   1013 		captureRenderState(D3DRS_ALPHABLENDENABLE);
   1014 		captureRenderState(D3DRS_DEPTHBIAS);
   1015 		captureRenderState(D3DRS_STENCILENABLE);
   1016 		captureRenderState(D3DRS_STENCILFAIL);
   1017 		captureRenderState(D3DRS_STENCILZFAIL);
   1018 		captureRenderState(D3DRS_STENCILPASS);
   1019 		captureRenderState(D3DRS_STENCILFUNC);
   1020 		captureRenderState(D3DRS_STENCILREF);
   1021 		captureRenderState(D3DRS_STENCILMASK);
   1022 		captureRenderState(D3DRS_STENCILWRITEMASK);
   1023 		captureRenderState(D3DRS_TEXTUREFACTOR);
   1024 		captureRenderState(D3DRS_WRAP0);
   1025 		captureRenderState(D3DRS_WRAP1);
   1026 		captureRenderState(D3DRS_WRAP2);
   1027 		captureRenderState(D3DRS_WRAP3);
   1028 		captureRenderState(D3DRS_WRAP4);
   1029 		captureRenderState(D3DRS_WRAP5);
   1030 		captureRenderState(D3DRS_WRAP6);
   1031 		captureRenderState(D3DRS_WRAP7);
   1032 		captureRenderState(D3DRS_WRAP8);
   1033 		captureRenderState(D3DRS_WRAP9);
   1034 		captureRenderState(D3DRS_WRAP10);
   1035 		captureRenderState(D3DRS_WRAP11);
   1036 		captureRenderState(D3DRS_WRAP12);
   1037 		captureRenderState(D3DRS_WRAP13);
   1038 		captureRenderState(D3DRS_WRAP14);
   1039 		captureRenderState(D3DRS_WRAP15);
   1040 		captureRenderState(D3DRS_COLORWRITEENABLE);
   1041 		captureRenderState(D3DRS_BLENDOP);
   1042 		captureRenderState(D3DRS_SCISSORTESTENABLE);
   1043 		captureRenderState(D3DRS_SLOPESCALEDEPTHBIAS);
   1044 		captureRenderState(D3DRS_ANTIALIASEDLINEENABLE);
   1045 		captureRenderState(D3DRS_TWOSIDEDSTENCILMODE);
   1046 		captureRenderState(D3DRS_CCW_STENCILFAIL);
   1047 		captureRenderState(D3DRS_CCW_STENCILZFAIL);
   1048 		captureRenderState(D3DRS_CCW_STENCILPASS);
   1049 		captureRenderState(D3DRS_CCW_STENCILFUNC);
   1050 		captureRenderState(D3DRS_COLORWRITEENABLE1);
   1051 		captureRenderState(D3DRS_COLORWRITEENABLE2);
   1052 		captureRenderState(D3DRS_COLORWRITEENABLE3);
   1053 		captureRenderState(D3DRS_BLENDFACTOR);
   1054 		captureRenderState(D3DRS_SRGBWRITEENABLE);
   1055 		captureRenderState(D3DRS_SEPARATEALPHABLENDENABLE);
   1056 		captureRenderState(D3DRS_SRCBLENDALPHA);
   1057 		captureRenderState(D3DRS_DESTBLENDALPHA);
   1058 		captureRenderState(D3DRS_BLENDOPALPHA);
   1059 	}
   1060 
   1061 	void Direct3DStateBlock9::capturePixelTextureStates()
   1062 	{
   1063 		for(int stage = 0; stage < 8; stage++)
   1064 		{
   1065 			captureTextureStageState(stage, D3DTSS_COLOROP);
   1066 			captureTextureStageState(stage, D3DTSS_COLORARG1);
   1067 			captureTextureStageState(stage, D3DTSS_COLORARG2);
   1068 			captureTextureStageState(stage, D3DTSS_ALPHAOP);
   1069 			captureTextureStageState(stage, D3DTSS_ALPHAARG1);
   1070 			captureTextureStageState(stage, D3DTSS_ALPHAARG2);
   1071 			captureTextureStageState(stage, D3DTSS_BUMPENVMAT00);
   1072 			captureTextureStageState(stage, D3DTSS_BUMPENVMAT01);
   1073 			captureTextureStageState(stage, D3DTSS_BUMPENVMAT10);
   1074 			captureTextureStageState(stage, D3DTSS_BUMPENVMAT11);
   1075 			captureTextureStageState(stage, D3DTSS_TEXCOORDINDEX);
   1076 			captureTextureStageState(stage, D3DTSS_BUMPENVLSCALE);
   1077 			captureTextureStageState(stage, D3DTSS_BUMPENVLOFFSET);
   1078 			captureTextureStageState(stage, D3DTSS_TEXTURETRANSFORMFLAGS);
   1079 			captureTextureStageState(stage, D3DTSS_COLORARG0);
   1080 			captureTextureStageState(stage, D3DTSS_ALPHAARG0);
   1081 			captureTextureStageState(stage, D3DTSS_RESULTARG);
   1082 		}
   1083 	}
   1084 
   1085 	void Direct3DStateBlock9::capturePixelSamplerStates()
   1086 	{
   1087 		for(int sampler = 0; sampler <= D3DVERTEXTEXTURESAMPLER3; sampler++)
   1088 		{
   1089 			captureSamplerState(sampler, D3DSAMP_ADDRESSU);
   1090 			captureSamplerState(sampler, D3DSAMP_ADDRESSV);
   1091 			captureSamplerState(sampler, D3DSAMP_ADDRESSW);
   1092 			captureSamplerState(sampler, D3DSAMP_BORDERCOLOR);
   1093 			captureSamplerState(sampler, D3DSAMP_MAGFILTER);
   1094 			captureSamplerState(sampler, D3DSAMP_MINFILTER);
   1095 			captureSamplerState(sampler, D3DSAMP_MIPFILTER);
   1096 			captureSamplerState(sampler, D3DSAMP_MIPMAPLODBIAS);
   1097 			captureSamplerState(sampler, D3DSAMP_MAXMIPLEVEL);
   1098 			captureSamplerState(sampler, D3DSAMP_MAXANISOTROPY);
   1099 			captureSamplerState(sampler, D3DSAMP_SRGBTEXTURE);
   1100 			captureSamplerState(sampler, D3DSAMP_ELEMENTINDEX);
   1101 		}
   1102 	}
   1103 
   1104 	void Direct3DStateBlock9::capturePixelShaderStates()
   1105 	{
   1106 		pixelShaderCaptured = true;
   1107 		device->GetPixelShader(reinterpret_cast<IDirect3DPixelShader9**>(&pixelShader));
   1108 
   1109 		if(pixelShader)
   1110 		{
   1111 			pixelShader->bind();
   1112 			pixelShader->Release();
   1113 		}
   1114 
   1115 		device->GetPixelShaderConstantF(0, pixelShaderConstantF[0], 32);
   1116 		device->GetPixelShaderConstantI(0, pixelShaderConstantI[0], 16);
   1117 		device->GetPixelShaderConstantB(0, pixelShaderConstantB, 16);
   1118 	}
   1119 
   1120 	void Direct3DStateBlock9::captureVertexRenderStates()
   1121 	{
   1122 		captureRenderState(D3DRS_CULLMODE);
   1123 		captureRenderState(D3DRS_FOGENABLE);
   1124 		captureRenderState(D3DRS_FOGCOLOR);
   1125 		captureRenderState(D3DRS_FOGTABLEMODE);
   1126 		captureRenderState(D3DRS_FOGSTART);
   1127 		captureRenderState(D3DRS_FOGEND);
   1128 		captureRenderState(D3DRS_FOGDENSITY);
   1129 		captureRenderState(D3DRS_RANGEFOGENABLE);
   1130 		captureRenderState(D3DRS_AMBIENT);
   1131 		captureRenderState(D3DRS_COLORVERTEX);
   1132 		captureRenderState(D3DRS_FOGVERTEXMODE);
   1133 		captureRenderState(D3DRS_CLIPPING);
   1134 		captureRenderState(D3DRS_LIGHTING);
   1135 		captureRenderState(D3DRS_LOCALVIEWER);
   1136 		captureRenderState(D3DRS_EMISSIVEMATERIALSOURCE);
   1137 		captureRenderState(D3DRS_AMBIENTMATERIALSOURCE);
   1138 		captureRenderState(D3DRS_DIFFUSEMATERIALSOURCE);
   1139 		captureRenderState(D3DRS_SPECULARMATERIALSOURCE);
   1140 		captureRenderState(D3DRS_VERTEXBLEND);
   1141 		captureRenderState(D3DRS_CLIPPLANEENABLE);
   1142 		captureRenderState(D3DRS_POINTSIZE);
   1143 		captureRenderState(D3DRS_POINTSIZE_MIN);
   1144 		captureRenderState(D3DRS_POINTSPRITEENABLE);
   1145 		captureRenderState(D3DRS_POINTSCALEENABLE);
   1146 		captureRenderState(D3DRS_POINTSCALE_A);
   1147 		captureRenderState(D3DRS_POINTSCALE_B);
   1148 		captureRenderState(D3DRS_POINTSCALE_C);
   1149 		captureRenderState(D3DRS_MULTISAMPLEANTIALIAS);
   1150 		captureRenderState(D3DRS_MULTISAMPLEMASK);
   1151 		captureRenderState(D3DRS_PATCHEDGESTYLE);
   1152 		captureRenderState(D3DRS_POINTSIZE_MAX);
   1153 		captureRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE);
   1154 		captureRenderState(D3DRS_TWEENFACTOR);
   1155 		captureRenderState(D3DRS_POSITIONDEGREE);
   1156 		captureRenderState(D3DRS_NORMALDEGREE);
   1157 		captureRenderState(D3DRS_MINTESSELLATIONLEVEL);
   1158 		captureRenderState(D3DRS_MAXTESSELLATIONLEVEL);
   1159 		captureRenderState(D3DRS_ADAPTIVETESS_X);
   1160 		captureRenderState(D3DRS_ADAPTIVETESS_Y);
   1161 		captureRenderState(D3DRS_ADAPTIVETESS_Z);
   1162 		captureRenderState(D3DRS_ADAPTIVETESS_W);
   1163 		captureRenderState(D3DRS_ENABLEADAPTIVETESSELLATION);
   1164 		captureRenderState(D3DRS_NORMALIZENORMALS);
   1165 		captureRenderState(D3DRS_SPECULARENABLE);
   1166 		captureRenderState(D3DRS_SHADEMODE);
   1167 	}
   1168 
   1169 	void Direct3DStateBlock9::captureVertexSamplerStates()
   1170 	{
   1171 		for(int sampler = 0; sampler <= D3DVERTEXTEXTURESAMPLER3; sampler++)
   1172 		{
   1173 			captureSamplerState(sampler, D3DSAMP_DMAPOFFSET);
   1174 		}
   1175 	}
   1176 
   1177 	void Direct3DStateBlock9::captureVertexTextureStates()
   1178 	{
   1179 		for(int stage = 0; stage < 8; stage++)
   1180 		{
   1181 			captureTextureStageState(stage, D3DTSS_TEXCOORDINDEX);
   1182 			captureTextureStageState(stage, D3DTSS_TEXTURETRANSFORMFLAGS);
   1183 		}
   1184 	}
   1185 
   1186 	void Direct3DStateBlock9::captureNPatchMode()
   1187 	{
   1188 		nPatchMode = device->GetNPatchMode();
   1189 		nPatchModeCaptured = true;
   1190 	}
   1191 
   1192 	void Direct3DStateBlock9::captureLightStates()
   1193 	{
   1194 		for(int index = 0; index < 8; index++)   // FIXME: Support unlimited index
   1195 		{
   1196 			long result = device->GetLight(index, &light[index]);
   1197 			lightCaptured[index] = SUCCEEDED(result);
   1198 		}
   1199 
   1200 		for(int index = 0; index < 8; index++)   // FIXME: Support unlimited index
   1201 		{
   1202 			lightEnableState[index] = false;
   1203 			long result = device->GetLightEnable(index, &lightEnableState[index]);
   1204 			lightEnableCaptured[index] = SUCCEEDED(result);
   1205 		}
   1206 	}
   1207 
   1208 	void Direct3DStateBlock9::captureVertexShaderStates()
   1209 	{
   1210 		vertexShaderCaptured = true;
   1211 		device->GetVertexShader(reinterpret_cast<IDirect3DVertexShader9**>(&vertexShader));
   1212 
   1213 		if(vertexShader)
   1214 		{
   1215 			vertexShader->bind();
   1216 			vertexShader->Release();
   1217 		}
   1218 
   1219 		device->GetVertexShaderConstantF(0, vertexShaderConstantF[0], MAX_VERTEX_SHADER_CONST);
   1220 		device->GetVertexShaderConstantI(0, vertexShaderConstantI[0], 16);
   1221 		device->GetVertexShaderConstantB(0, vertexShaderConstantB, 16);
   1222 	}
   1223 
   1224 	void Direct3DStateBlock9::captureStreamSourceFrequencies()
   1225 	{
   1226 		for(int stream = 0; stream < MAX_VERTEX_INPUTS; stream++)
   1227 		{
   1228 			streamSourceFrequencyCaptured[stream] = true;
   1229 			device->GetStreamSourceFreq(stream, &streamSourceFrequency[stream]);
   1230 		}
   1231 	}
   1232 
   1233 	void Direct3DStateBlock9::captureFVF()
   1234 	{
   1235 		device->GetFVF(&FVF);
   1236 		fvfCaptured = true;
   1237 	}
   1238 
   1239 	void Direct3DStateBlock9::captureVertexDeclaration()
   1240 	{
   1241 		vertexDeclarationCaptured = true;
   1242 		device->GetVertexDeclaration(reinterpret_cast<IDirect3DVertexDeclaration9**>(&vertexDeclaration));
   1243 
   1244 		if(vertexDeclaration)
   1245 		{
   1246 			vertexDeclaration->bind();
   1247 			vertexDeclaration->Release();
   1248 		}
   1249 	}
   1250 
   1251 	void Direct3DStateBlock9::captureTextures()
   1252 	{
   1253 		for(int sampler = 0; sampler < 16 + 4; sampler++)
   1254 		{
   1255 			textureCaptured[sampler] = true;
   1256 			int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16);
   1257 			device->GetTexture(index, reinterpret_cast<IDirect3DBaseTexture9**>(&texture[sampler]));
   1258 
   1259 			if(texture[sampler])
   1260 			{
   1261 				texture[sampler]->bind();
   1262 				texture[sampler]->Release();
   1263 			}
   1264 		}
   1265 	}
   1266 
   1267 	void Direct3DStateBlock9::captureTexturePalette()
   1268 	{
   1269 		paletteNumberCaptured = true;
   1270 		device->GetCurrentTexturePalette(&paletteNumber);
   1271 	}
   1272 
   1273 	void Direct3DStateBlock9::captureVertexStreams()
   1274 	{
   1275 		for(int stream = 0; stream < MAX_VERTEX_INPUTS; stream++)
   1276 		{
   1277 			streamSourceCaptured[stream] = true;
   1278 			device->GetStreamSource(stream, reinterpret_cast<IDirect3DVertexBuffer9**>(&streamSource[stream].vertexBuffer), &streamSource[stream].offset, &streamSource[stream].stride);
   1279 
   1280 			if(streamSource[stream].vertexBuffer)
   1281 			{
   1282 				streamSource[stream].vertexBuffer->bind();
   1283 				streamSource[stream].vertexBuffer->Release();
   1284 			}
   1285 		}
   1286 	}
   1287 
   1288 	void Direct3DStateBlock9::captureIndexBuffer()
   1289 	{
   1290 		indexBufferCaptured = true;
   1291 		device->GetIndices(reinterpret_cast<IDirect3DIndexBuffer9**>(&indexBuffer));
   1292 
   1293 		if(indexBuffer)
   1294 		{
   1295 			indexBuffer->bind();
   1296 			indexBuffer->Release();
   1297 		}
   1298 	}
   1299 
   1300 	void Direct3DStateBlock9::captureViewport()
   1301 	{
   1302 		device->GetViewport(&viewport);
   1303 		viewportCaptured = true;
   1304 	}
   1305 
   1306 	void Direct3DStateBlock9::captureScissorRectangle()
   1307 	{
   1308 		device->GetScissorRect(&scissorRect);
   1309 		scissorRectCaptured = true;
   1310 	}
   1311 
   1312 	void Direct3DStateBlock9::captureTransforms()
   1313 	{
   1314 		captureTransform(D3DTS_VIEW);
   1315 		captureTransform(D3DTS_PROJECTION);
   1316 		captureTransform(D3DTS_WORLD);
   1317 	}
   1318 
   1319 	void Direct3DStateBlock9::captureTextureTransforms()
   1320 	{
   1321 		captureTransform(D3DTS_TEXTURE0);
   1322 		captureTransform(D3DTS_TEXTURE1);
   1323 		captureTransform(D3DTS_TEXTURE2);
   1324 		captureTransform(D3DTS_TEXTURE3);
   1325 		captureTransform(D3DTS_TEXTURE4);
   1326 		captureTransform(D3DTS_TEXTURE5);
   1327 		captureTransform(D3DTS_TEXTURE6);
   1328 		captureTransform(D3DTS_TEXTURE7);
   1329 	}
   1330 
   1331 	void Direct3DStateBlock9::captureClippingPlanes()
   1332 	{
   1333 		for(int index = 0; index < 6; index++)
   1334 		{
   1335 			device->GetClipPlane(index, (float*)&clipPlane[index]);
   1336 			clipPlaneCaptured[index] = true;
   1337 		}
   1338 	}
   1339 
   1340 	void Direct3DStateBlock9::captureMaterial()
   1341 	{
   1342 		device->GetMaterial(&material);
   1343 		materialCaptured = true;
   1344 	}
   1345 }
   1346