| // Copyright 2016 The SwiftShader Authors. All Rights Reserved. | 
 | // | 
 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | // you may not use this file except in compliance with the License. | 
 | // You may obtain a copy of the License at | 
 | // | 
 | //    http://www.apache.org/licenses/LICENSE-2.0 | 
 | // | 
 | // Unless required by applicable law or agreed to in writing, software | 
 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | // See the License for the specific language governing permissions and | 
 | // limitations under the License. | 
 |  | 
 | #include "Direct3DStateBlock8.hpp" | 
 |  | 
 | #include "Direct3DDevice8.hpp" | 
 | #include "Direct3DBaseTexture8.hpp" | 
 | #include "Direct3DVertexBuffer8.hpp" | 
 | #include "Direct3DIndexBuffer8.hpp" | 
 | #include "Debug.hpp" | 
 |  | 
 | #include <assert.h> | 
 |  | 
 | namespace D3D8 | 
 | { | 
 | 	Direct3DStateBlock8::Direct3DStateBlock8(Direct3DDevice8 *device, D3DSTATEBLOCKTYPE type) : device(device), type(type) | 
 | 	{ | 
 | 		vertexShaderHandle = 0; | 
 | 		pixelShaderHandle = 0; | 
 | 		indexBuffer = 0; | 
 |  | 
 | 		for(int stream = 0; stream < 16; stream++) | 
 | 		{ | 
 | 			streamSource[stream].vertexBuffer = 0; | 
 | 		} | 
 |  | 
 | 		for(int stage = 0; stage < 8; stage++) | 
 | 		{ | 
 | 			texture[stage] = 0; | 
 | 		} | 
 |  | 
 | 		clear(); | 
 |  | 
 | 		if(type == D3DSBT_PIXELSTATE || type == D3DSBT_ALL) | 
 | 		{ | 
 | 			capturePixelRenderStates(); | 
 | 			capturePixelTextureStates(); | 
 | 			capturePixelShaderStates(); | 
 | 		} | 
 | 		 | 
 | 		if(type == D3DSBT_VERTEXSTATE || type == D3DSBT_ALL) | 
 | 		{ | 
 | 			captureVertexRenderStates(); | 
 | 			captureVertexTextureStates(); | 
 | 			captureLightStates(); | 
 | 			captureVertexShaderStates(); | 
 | 		} | 
 |  | 
 | 		if(type == D3DSBT_ALL)   // Capture remaining states | 
 | 		{ | 
 | 			captureTextures(); | 
 | 			captureVertexTextures(); | 
 | 			captureDisplacementTextures(); | 
 | 			captureTexturePalette(); | 
 | 			captureVertexStreams(); | 
 | 			captureIndexBuffer(); | 
 | 			captureViewport(); | 
 | 			captureTransforms(); | 
 | 			captureTextureTransforms(); | 
 | 			captureClippingPlanes(); | 
 | 			captureMaterial(); | 
 | 		} | 
 | 	} | 
 |  | 
 | 	Direct3DStateBlock8::~Direct3DStateBlock8() | 
 | 	{ | 
 | 		clear(); | 
 | 	} | 
 |  | 
 | 	long Direct3DStateBlock8::QueryInterface(const IID &iid, void **object) | 
 | 	{ | 
 | 		TRACE(""); | 
 |  | 
 | 		ASSERT(false);   // Internal object | 
 |  | 
 | 		return NOINTERFACE(iid); | 
 | 	} | 
 |  | 
 | 	unsigned long Direct3DStateBlock8::AddRef() | 
 | 	{ | 
 | 		TRACE(""); | 
 |  | 
 | 		return Unknown::AddRef(); | 
 | 	} | 
 | 	 | 
 | 	unsigned long Direct3DStateBlock8::Release() | 
 | 	{ | 
 | 		TRACE(""); | 
 |  | 
 | 		return Unknown::Release(); | 
 | 	} | 
 |  | 
 | 	long Direct3DStateBlock8::Apply() | 
 | 	{ | 
 | 		TRACE(""); | 
 |  | 
 | 		if(vertexShaderCaptured) | 
 | 		{ | 
 | 			device->SetVertexShader(vertexShaderHandle); | 
 | 		} | 
 |  | 
 | 		if(pixelShaderCaptured) | 
 | 		{ | 
 | 			device->SetPixelShader(pixelShaderHandle); | 
 | 		} | 
 |  | 
 | 		if(indexBufferCaptured) | 
 | 		{ | 
 | 			device->SetIndices(indexBuffer, baseVertexIndex); | 
 | 		} | 
 |  | 
 | 		for(int state = 0; state < D3DRS_NORMALORDER + 1; state++) | 
 | 		{ | 
 | 			if(renderStateCaptured[state]) | 
 | 			{ | 
 | 				device->SetRenderState((D3DRENDERSTATETYPE)state, renderState[state]); | 
 | 			} | 
 | 		} | 
 |  | 
 | 		for(int stage = 0; stage < 8; stage++) | 
 | 		{ | 
 | 			for(int state = 0; state < D3DTSS_RESULTARG + 1; state++) | 
 | 			{ | 
 | 				if(textureStageStateCaptured[stage][state]) | 
 | 				{ | 
 | 					device->SetTextureStageState(stage, (D3DTEXTURESTAGESTATETYPE)state, textureStageState[stage][state]); | 
 | 				} | 
 | 			} | 
 | 		} | 
 |  | 
 | 		for(int stream = 0; stream < 16; stream++) | 
 | 		{ | 
 | 			if(streamSourceCaptured[stream]) | 
 | 			{ | 
 | 				device->SetStreamSource(stream, streamSource[stream].vertexBuffer, streamSource[stream].stride); | 
 | 			} | 
 | 		} | 
 |  | 
 | 		for(int stage = 0; stage < 8; stage++) | 
 | 		{ | 
 | 			if(textureCaptured[stage]) | 
 | 			{ | 
 | 				device->SetTexture(stage, texture[stage]); | 
 | 			} | 
 | 		} | 
 |  | 
 | 		for(int state = 0; state < 512; state++) | 
 | 		{ | 
 | 			if(transformCaptured[state]) | 
 | 			{ | 
 | 				device->SetTransform((D3DTRANSFORMSTATETYPE)state, &transform[state]); | 
 | 			} | 
 | 		} | 
 |  | 
 | 		if(viewportCaptured) | 
 | 		{ | 
 | 			device->SetViewport(&viewport); | 
 | 		} | 
 |  | 
 | 		for(int index = 0; index < 6; index++) | 
 | 		{ | 
 | 			if(clipPlaneCaptured[index]) | 
 | 			{ | 
 | 				device->SetClipPlane(index, clipPlane[index]); | 
 | 			} | 
 | 		} | 
 |  | 
 | 		return D3D_OK; | 
 | 	} | 
 |  | 
 | 	long Direct3DStateBlock8::Capture() | 
 | 	{ | 
 | 		TRACE(""); | 
 |  | 
 | 		if(vertexShaderCaptured) | 
 | 		{		 | 
 | 			device->GetVertexShader(&vertexShaderHandle); | 
 | 		} | 
 |  | 
 | 		if(pixelShaderCaptured) | 
 | 		{		 | 
 | 			device->GetPixelShader(&pixelShaderHandle); | 
 | 		} | 
 |  | 
 | 		if(indexBufferCaptured) | 
 | 		{ | 
 | 			if(indexBuffer) | 
 | 			{ | 
 | 				indexBuffer->Release(); | 
 | 			} | 
 |  | 
 | 			device->GetIndices(reinterpret_cast<IDirect3DIndexBuffer8**>(&indexBuffer), &baseVertexIndex); | 
 | 		} | 
 |  | 
 | 		for(int state = 0; state < D3DRS_NORMALORDER + 1; state++) | 
 | 		{ | 
 | 			if(renderStateCaptured[state]) | 
 | 			{ | 
 | 				device->GetRenderState((D3DRENDERSTATETYPE)state, &renderState[state]); | 
 | 			} | 
 | 		} | 
 |  | 
 | 		for(int stage = 0; stage < 8; stage++) | 
 | 		{ | 
 | 			for(int state = 0; state < D3DTSS_RESULTARG + 1; state++) | 
 | 			{ | 
 | 				if(textureStageStateCaptured[stage][state]) | 
 | 				{ | 
 | 					device->GetTextureStageState(stage, (D3DTEXTURESTAGESTATETYPE)state, &textureStageState[stage][state]); | 
 | 				} | 
 | 			} | 
 | 		} | 
 |  | 
 | 		for(int stream = 0; stream < 16; stream++) | 
 | 		{ | 
 | 			if(streamSourceCaptured[stream]) | 
 | 			{ | 
 | 				if(streamSource[stream].vertexBuffer) | 
 | 				{ | 
 | 					streamSource[stream].vertexBuffer->Release(); | 
 | 				} | 
 |  | 
 | 				device->GetStreamSource(stream, reinterpret_cast<IDirect3DVertexBuffer8**>(&streamSource[stream].vertexBuffer), &streamSource[stream].stride); | 
 | 			} | 
 | 		} | 
 |  | 
 | 		for(int stage = 0; stage < 8; stage++) | 
 | 		{ | 
 | 			if(textureCaptured[stage]) | 
 | 			{ | 
 | 				if(texture[stage]) | 
 | 				{ | 
 | 					texture[stage]->Release(); | 
 | 				} | 
 |  | 
 | 				device->GetTexture(stage, reinterpret_cast<IDirect3DBaseTexture8**>(&texture[stage])); | 
 | 			} | 
 | 		} | 
 |  | 
 | 		for(int state = 0; state < 512; state++) | 
 | 		{ | 
 | 			if(transformCaptured[state]) | 
 | 			{ | 
 | 				device->GetTransform((D3DTRANSFORMSTATETYPE)state, &transform[state]); | 
 | 			} | 
 | 		} | 
 |  | 
 | 		if(viewportCaptured) | 
 | 		{ | 
 | 			device->GetViewport(&viewport); | 
 | 		} | 
 |  | 
 | 		for(int index = 0; index < 6; index++) | 
 | 		{ | 
 | 			if(clipPlaneCaptured[index]) | 
 | 			{ | 
 | 				device->GetClipPlane(index, clipPlane[index]); | 
 | 			} | 
 | 		} | 
 |  | 
 | 		return D3D_OK; | 
 | 	} | 
 |  | 
 | 	long Direct3DStateBlock8::GetDevice(IDirect3DDevice8 **device) | 
 | 	{ | 
 | 		TRACE(""); | 
 |  | 
 | 		if(!device) | 
 | 		{ | 
 | 			return INVALIDCALL(); | 
 | 		} | 
 |  | 
 | 		this->device->AddRef(); | 
 | 		*device = this->device; | 
 |  | 
 | 		return D3D_OK; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::lightEnable(unsigned long index, int enable) | 
 | 	{ | 
 | 		UNIMPLEMENTED(); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setClipPlane(unsigned long index, const float *plane) | 
 | 	{ | 
 | 		clipPlaneCaptured[index] = true; | 
 | 		clipPlane[index][0] = plane[0]; | 
 | 		clipPlane[index][1] = plane[1]; | 
 | 		clipPlane[index][2] = plane[2]; | 
 | 		clipPlane[index][3] = plane[3]; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setCurrentTexturePalette(unsigned int paletteNumber) | 
 | 	{ | 
 | 		UNIMPLEMENTED(); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setFVF(unsigned long FVF) | 
 | 	{ | 
 | 		UNIMPLEMENTED(); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setIndices(Direct3DIndexBuffer8 *indexData, unsigned int baseVertexIndex) | 
 | 	{ | 
 | 		if(indexData) indexData->AddRef(); | 
 |  | 
 | 		indexBufferCaptured = true; | 
 | 		indexBuffer = indexData; | 
 | 		this->baseVertexIndex = baseVertexIndex; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setLight(unsigned long index, const D3DLIGHT8 *light) | 
 | 	{ | 
 | 		UNIMPLEMENTED(); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setMaterial(const D3DMATERIAL8 *material) | 
 | 	{ | 
 | 		UNIMPLEMENTED(); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setPixelShader(unsigned long shaderHandle)		 | 
 | 	{ | 
 | 		pixelShaderCaptured = true; | 
 | 		pixelShaderHandle = shaderHandle; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setPixelShaderConstant(unsigned int startRegister, const void *constantData, unsigned int count) | 
 | 	{ | 
 | 		UNIMPLEMENTED(); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setRenderState(D3DRENDERSTATETYPE state, unsigned long value) | 
 | 	{ | 
 | 		renderStateCaptured[state] = true; | 
 | 		renderState[state] = value; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setScissorRect(const RECT *rect) | 
 | 	{ | 
 | 		UNIMPLEMENTED(); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setStreamSource(unsigned int stream, Direct3DVertexBuffer8 *data, unsigned int stride) | 
 | 	{ | 
 | 		if(data) data->AddRef(); | 
 |  | 
 | 		streamSourceCaptured[stream] = true; | 
 | 		streamSource[stream].vertexBuffer = data; | 
 | 		streamSource[stream].stride = stride; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setTexture(unsigned long stage, Direct3DBaseTexture8 *texture) | 
 | 	{ | 
 | 		if(texture) texture->AddRef(); | 
 |  | 
 | 		textureCaptured[stage] = true; | 
 | 		this->texture[stage] = texture; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value) | 
 | 	{ | 
 | 		textureStageStateCaptured[stage][type] = true; | 
 | 		textureStageState[stage][type] = value; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix) | 
 | 	{ | 
 | 		transformCaptured[state] = true; | 
 | 		transform[state] = *matrix; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setViewport(const D3DVIEWPORT8 *viewport) | 
 | 	{ | 
 | 		viewportCaptured = true; | 
 | 		this->viewport = *viewport; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setVertexShader(unsigned long shaderHandle) | 
 | 	{ | 
 | 		vertexShaderCaptured = true; | 
 | 		vertexShaderHandle = shaderHandle; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::setVertexShaderConstant(unsigned int startRegister, const void *constantData, unsigned int count) | 
 | 	{ | 
 | 		UNIMPLEMENTED(); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::clear() | 
 | 	{ | 
 | 		// Erase capture flags | 
 | 		vertexShaderCaptured = false; | 
 | 		pixelShaderCaptured = false; | 
 | 		indexBufferCaptured = false; | 
 |  | 
 | 		for(int state = 0; state < D3DRS_NORMALORDER + 1; state++) | 
 | 		{ | 
 | 			renderStateCaptured[state] = false; | 
 | 		} | 
 |  | 
 | 		for(int stage = 0; stage < 8; stage++) | 
 | 		{ | 
 | 			for(int state = 0; state < D3DTSS_RESULTARG + 1; state++) | 
 | 			{ | 
 | 				textureStageStateCaptured[stage][state] = false; | 
 | 			} | 
 | 		} | 
 |  | 
 | 		for(int stream = 0; stream < 16; stream++) | 
 | 		{ | 
 | 			streamSourceCaptured[stream] = false; | 
 | 		} | 
 |  | 
 | 		for(int stage = 0; stage < 8; stage++) | 
 | 		{ | 
 | 			textureCaptured[stage] = false; | 
 | 		} | 
 |  | 
 | 		for(int state = 0; state < 512; state++) | 
 | 		{ | 
 | 			transformCaptured[state] = false; | 
 | 		} | 
 |  | 
 | 		viewportCaptured = false; | 
 |  | 
 | 		for(int index = 0; index < 6; index++) | 
 | 		{ | 
 | 			clipPlaneCaptured[index] = false; | 
 | 		} | 
 |  | 
 | 		// Release resources | 
 | 		vertexShaderHandle = 0; | 
 | 		pixelShaderHandle = 0; | 
 |  | 
 | 		if(indexBuffer) | 
 | 		{ | 
 | 			indexBuffer->Release(); | 
 | 			indexBuffer = 0; | 
 | 		} | 
 |  | 
 | 		for(int stream = 0; stream < 16; stream++) | 
 | 		{ | 
 | 			if(streamSource[stream].vertexBuffer) | 
 | 			{ | 
 | 				streamSource[stream].vertexBuffer->Release(); | 
 | 				streamSource[stream].vertexBuffer = 0; | 
 | 			} | 
 | 		} | 
 |  | 
 | 		for(int stage = 0; stage < 8; stage++) | 
 | 		{ | 
 | 			if(texture[stage]) | 
 | 			{ | 
 | 				texture[stage]->Release(); | 
 | 				texture[stage] = 0; | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureRenderState(D3DRENDERSTATETYPE state) | 
 | 	{ | 
 | 		device->GetRenderState(state, &renderState[state]); | 
 | 		renderStateCaptured[state] = true; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type) | 
 | 	{ | 
 | 		device->GetTextureStageState(stage, type, &textureStageState[stage][type]); | 
 | 		textureStageStateCaptured[stage][type] = true; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureTransform(D3DTRANSFORMSTATETYPE state) | 
 | 	{ | 
 | 		device->GetTransform(state, &transform[state]); | 
 | 		transformCaptured[state] = true; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::capturePixelRenderStates() | 
 | 	{ | 
 | 		captureRenderState(D3DRS_ZENABLE); | 
 | 		captureRenderState(D3DRS_FILLMODE); | 
 | 		captureRenderState(D3DRS_SHADEMODE); | 
 | 		captureRenderState(D3DRS_ZWRITEENABLE); | 
 | 		captureRenderState(D3DRS_ALPHATESTENABLE); | 
 | 		captureRenderState(D3DRS_LASTPIXEL); | 
 | 		captureRenderState(D3DRS_SRCBLEND); | 
 | 		captureRenderState(D3DRS_DESTBLEND); | 
 | 		captureRenderState(D3DRS_ZFUNC); | 
 | 		captureRenderState(D3DRS_ALPHAREF); | 
 | 		captureRenderState(D3DRS_ALPHAFUNC); | 
 | 		captureRenderState(D3DRS_DITHERENABLE); | 
 | 		captureRenderState(D3DRS_FOGSTART); | 
 | 		captureRenderState(D3DRS_FOGEND); | 
 | 		captureRenderState(D3DRS_FOGDENSITY); | 
 | 		captureRenderState(D3DRS_ALPHABLENDENABLE); | 
 | 		captureRenderState(D3DRS_ZBIAS); | 
 | 		captureRenderState(D3DRS_STENCILENABLE); | 
 | 		captureRenderState(D3DRS_STENCILFAIL); | 
 | 		captureRenderState(D3DRS_STENCILZFAIL); | 
 | 		captureRenderState(D3DRS_STENCILPASS); | 
 | 		captureRenderState(D3DRS_STENCILFUNC); | 
 | 		captureRenderState(D3DRS_STENCILREF); | 
 | 		captureRenderState(D3DRS_STENCILMASK); | 
 | 		captureRenderState(D3DRS_STENCILWRITEMASK); | 
 | 		captureRenderState(D3DRS_TEXTUREFACTOR); | 
 | 		captureRenderState(D3DRS_WRAP0); | 
 | 		captureRenderState(D3DRS_WRAP1); | 
 | 		captureRenderState(D3DRS_WRAP2); | 
 | 		captureRenderState(D3DRS_WRAP3); | 
 | 		captureRenderState(D3DRS_WRAP4); | 
 | 		captureRenderState(D3DRS_WRAP5); | 
 | 		captureRenderState(D3DRS_WRAP6); | 
 | 		captureRenderState(D3DRS_WRAP7); | 
 | 		captureRenderState(D3DRS_COLORWRITEENABLE); | 
 | 		captureRenderState(D3DRS_BLENDOP); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::capturePixelTextureStates() | 
 | 	{ | 
 | 		for(int stage = 0; stage < 8; stage++) | 
 | 		{ | 
 | 			captureTextureStageState(stage, D3DTSS_COLOROP); | 
 | 			captureTextureStageState(stage, D3DTSS_COLORARG1); | 
 | 			captureTextureStageState(stage, D3DTSS_COLORARG2); | 
 | 			captureTextureStageState(stage, D3DTSS_ALPHAOP); | 
 | 			captureTextureStageState(stage, D3DTSS_ALPHAARG1); | 
 | 			captureTextureStageState(stage, D3DTSS_ALPHAARG2); | 
 | 			captureTextureStageState(stage, D3DTSS_BUMPENVMAT00); | 
 | 			captureTextureStageState(stage, D3DTSS_BUMPENVMAT01); | 
 | 			captureTextureStageState(stage, D3DTSS_BUMPENVMAT10); | 
 | 			captureTextureStageState(stage, D3DTSS_BUMPENVMAT11); | 
 | 			captureTextureStageState(stage, D3DTSS_TEXCOORDINDEX); | 
 | 			captureTextureStageState(stage, D3DTSS_BUMPENVLSCALE); | 
 | 			captureTextureStageState(stage, D3DTSS_BUMPENVLOFFSET); | 
 | 			captureTextureStageState(stage, D3DTSS_TEXTURETRANSFORMFLAGS); | 
 | 			captureTextureStageState(stage, D3DTSS_COLORARG0); | 
 | 			captureTextureStageState(stage, D3DTSS_ALPHAARG0); | 
 | 			captureTextureStageState(stage, D3DTSS_RESULTARG); | 
 | 		 | 
 | 			captureTextureStageState(stage, D3DTSS_ADDRESSU); | 
 | 			captureTextureStageState(stage, D3DTSS_ADDRESSV); | 
 | 			captureTextureStageState(stage, D3DTSS_ADDRESSW);  | 
 | 			captureTextureStageState(stage, D3DTSS_BORDERCOLOR); | 
 | 			captureTextureStageState(stage, D3DTSS_MAGFILTER); | 
 | 			captureTextureStageState(stage, D3DTSS_MINFILTER); | 
 | 			captureTextureStageState(stage, D3DTSS_MIPFILTER); | 
 | 			captureTextureStageState(stage, D3DTSS_MIPMAPLODBIAS); | 
 | 			captureTextureStageState(stage, D3DTSS_MAXMIPLEVEL); | 
 | 			captureTextureStageState(stage, D3DTSS_MAXANISOTROPY); | 
 | 		} | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::capturePixelShaderStates() | 
 | 	{ | 
 | 		pixelShaderCaptured = true; | 
 | 		device->GetPixelShader(&pixelShaderHandle); | 
 |  | 
 | 		device->GetPixelShaderConstant(0, pixelShaderConstant, 8); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureVertexRenderStates() | 
 | 	{ | 
 | 		captureRenderState(D3DRS_CULLMODE); | 
 | 		captureRenderState(D3DRS_FOGENABLE); | 
 | 		captureRenderState(D3DRS_FOGCOLOR); | 
 | 		captureRenderState(D3DRS_FOGTABLEMODE); | 
 | 		captureRenderState(D3DRS_FOGSTART); | 
 | 		captureRenderState(D3DRS_FOGEND); | 
 | 		captureRenderState(D3DRS_FOGDENSITY); | 
 | 		captureRenderState(D3DRS_RANGEFOGENABLE); | 
 | 		captureRenderState(D3DRS_AMBIENT); | 
 | 		captureRenderState(D3DRS_COLORVERTEX); | 
 | 		captureRenderState(D3DRS_FOGVERTEXMODE); | 
 | 		captureRenderState(D3DRS_CLIPPING); | 
 | 		captureRenderState(D3DRS_LIGHTING); | 
 | 		captureRenderState(D3DRS_LOCALVIEWER); | 
 | 		captureRenderState(D3DRS_EMISSIVEMATERIALSOURCE); | 
 | 		captureRenderState(D3DRS_AMBIENTMATERIALSOURCE); | 
 | 		captureRenderState(D3DRS_DIFFUSEMATERIALSOURCE); | 
 | 		captureRenderState(D3DRS_SPECULARMATERIALSOURCE); | 
 | 		captureRenderState(D3DRS_VERTEXBLEND); | 
 | 		captureRenderState(D3DRS_CLIPPLANEENABLE); | 
 | 		captureRenderState(D3DRS_POINTSIZE); | 
 | 		captureRenderState(D3DRS_POINTSIZE_MIN); | 
 | 		captureRenderState(D3DRS_POINTSPRITEENABLE); | 
 | 		captureRenderState(D3DRS_POINTSCALEENABLE); | 
 | 		captureRenderState(D3DRS_POINTSCALE_A); | 
 | 		captureRenderState(D3DRS_POINTSCALE_B); | 
 | 		captureRenderState(D3DRS_POINTSCALE_C); | 
 | 		captureRenderState(D3DRS_MULTISAMPLEANTIALIAS); | 
 | 		captureRenderState(D3DRS_MULTISAMPLEMASK); | 
 | 		captureRenderState(D3DRS_PATCHEDGESTYLE); | 
 | 		captureRenderState(D3DRS_POINTSIZE_MAX); | 
 | 		captureRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE); | 
 | 		captureRenderState(D3DRS_TWEENFACTOR); | 
 | 		captureRenderState(D3DRS_NORMALIZENORMALS); | 
 | 		captureRenderState(D3DRS_SPECULARENABLE); | 
 | 		captureRenderState(D3DRS_SHADEMODE); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureVertexTextureStates() | 
 | 	{ | 
 | 		for(int stage = 0; stage < 8; stage++) | 
 | 		{ | 
 | 			captureTextureStageState(stage, D3DTSS_TEXCOORDINDEX); | 
 | 			captureTextureStageState(stage, D3DTSS_TEXTURETRANSFORMFLAGS); | 
 | 		} | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureLightStates() | 
 | 	{ | 
 | 		for(int index = 0; index < 8; index++)   // FIXME: Support unlimited index | 
 | 		{ | 
 | 			device->GetLight(index, &light[index]); | 
 | 			lightCaptured[index] = true; | 
 | 		} | 
 |  | 
 | 		for(int index = 0; index < 8; index++)   // FIXME: Support unlimited index | 
 | 		{ | 
 | 			lightEnableState[index] = false; | 
 | 			device->GetLightEnable(index, &lightEnableState[index]); | 
 | 			lightEnableCaptured[index] = true; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureVertexShaderStates() | 
 | 	{ | 
 | 		vertexShaderCaptured = true; | 
 | 		device->GetVertexShader(&vertexShaderHandle); | 
 |  | 
 | 		device->GetVertexShaderConstant(0, vertexShaderConstant[0], 256); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureTextures() | 
 | 	{ | 
 | 		for(int sampler = 0; sampler < 8; sampler++) | 
 | 		{ | 
 | 			textureCaptured[sampler] = true; | 
 | 			device->GetTexture(sampler, reinterpret_cast<IDirect3DBaseTexture8**>(&texture[sampler])); | 
 |  | 
 | 			if(texture[sampler]) | 
 | 			{ | 
 | 				texture[sampler]->bind(); | 
 | 				texture[sampler]->Release(); | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureVertexTextures() | 
 | 	{ | 
 | 		// FIXME | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureDisplacementTextures() | 
 | 	{ | 
 | 		// FIXME	 | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureTexturePalette() | 
 | 	{ | 
 | 		paletteNumberCaptured = true; | 
 | 		device->GetCurrentTexturePalette(&paletteNumber); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureVertexStreams() | 
 | 	{ | 
 | 		for(int stream = 0; stream < 16; stream++) | 
 | 		{ | 
 | 			streamSourceCaptured[stream] = true; | 
 | 			device->GetStreamSource(stream, reinterpret_cast<IDirect3DVertexBuffer8**>(&streamSource[stream].vertexBuffer),  &streamSource[stream].stride); | 
 | 			 | 
 | 			if(streamSource[stream].vertexBuffer) | 
 | 			{ | 
 | 				streamSource[stream].vertexBuffer->bind(); | 
 | 				streamSource[stream].vertexBuffer->Release(); | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureIndexBuffer() | 
 | 	{ | 
 | 		indexBufferCaptured = true; | 
 | 		device->GetIndices(reinterpret_cast<IDirect3DIndexBuffer8**>(&indexBuffer), &baseVertexIndex); | 
 |  | 
 | 		if(indexBuffer) | 
 | 		{ | 
 | 			indexBuffer->bind(); | 
 | 			indexBuffer->Release(); | 
 | 		} | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureViewport() | 
 | 	{ | 
 | 		device->GetViewport(&viewport); | 
 | 		viewportCaptured = true; | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureTransforms() | 
 | 	{ | 
 | 		captureTransform(D3DTS_VIEW); | 
 | 		captureTransform(D3DTS_PROJECTION); | 
 | 		captureTransform(D3DTS_WORLD); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureTextureTransforms() | 
 | 	{ | 
 | 		captureTransform(D3DTS_TEXTURE0); | 
 | 		captureTransform(D3DTS_TEXTURE1); | 
 | 		captureTransform(D3DTS_TEXTURE2); | 
 | 		captureTransform(D3DTS_TEXTURE3); | 
 | 		captureTransform(D3DTS_TEXTURE4); | 
 | 		captureTransform(D3DTS_TEXTURE5); | 
 | 		captureTransform(D3DTS_TEXTURE6); | 
 | 		captureTransform(D3DTS_TEXTURE7); | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureClippingPlanes() | 
 | 	{ | 
 | 		for(int index = 0; index < 6; index++) | 
 | 		{ | 
 | 			device->GetClipPlane(index, (float*)&clipPlane[index]); | 
 | 			clipPlaneCaptured[index] = true; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	void Direct3DStateBlock8::captureMaterial() | 
 | 	{ | 
 | 		device->GetMaterial(&material); | 
 | 		materialCaptured = true; | 
 | 	} | 
 | } |