Add back the D3D9 code from before the April 2014 code dump. Bug 22533227 Change-Id: Ib669fcd6a644c79b3a9e8f5dcf7da278d75cefef Reviewed-on: https://swiftshader-review.googlesource.com/3730 Reviewed-by: Nicolas Capens <capn@google.com> Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/D3D9/Direct3DStateBlock9.cpp b/src/D3D9/Direct3DStateBlock9.cpp new file mode 100644 index 0000000..9c5d02a --- /dev/null +++ b/src/D3D9/Direct3DStateBlock9.cpp
@@ -0,0 +1,1342 @@ +// SwiftShader Software Renderer +// +// Copyright(c) 2005-2011 TransGaming Inc. +// +// All rights reserved. No part of this software may be copied, distributed, transmitted, +// transcribed, stored in a retrieval system, translated into any human or computer +// language by any means, or disclosed to third parties without the explicit written +// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express +// or implied, including but not limited to any patent rights, are granted to you. +// + +#include "Direct3DStateBlock9.hpp" + +#include "Direct3DDevice9.hpp" +#include "Direct3DVertexDeclaration9.hpp" +#include "Direct3DIndexBuffer9.hpp" +#include "Direct3DVertexBuffer9.hpp" +#include "Direct3DBaseTexture9.hpp" +#include "Direct3DPixelShader9.hpp" +#include "Direct3DVertexShader9.hpp" +#include "Debug.hpp" + +#include <assert.h> + +namespace D3D9 +{ + Direct3DStateBlock9::Direct3DStateBlock9(Direct3DDevice9 *device, D3DSTATEBLOCKTYPE type) : device(device), type(type) + { + vertexDeclaration = 0; + + indexBuffer = 0; + + for(int stream = 0; stream < 16; stream++) + { + streamSource[stream].vertexBuffer = 0; + } + + for(int sampler = 0; sampler < 16 + 4; sampler++) + { + texture[sampler] = 0; + } + + pixelShader = 0; + vertexShader = 0; + + clear(); + + if(type == D3DSBT_PIXELSTATE || type == D3DSBT_ALL) + { + capturePixelRenderStates(); + capturePixelTextureStates(); + capturePixelSamplerStates(); + capturePixelShaderStates(); + } + + if(type == D3DSBT_VERTEXSTATE || type == D3DSBT_ALL) + { + captureVertexRenderStates(); + captureVertexSamplerStates(); + captureVertexTextureStates(); + captureNPatchMode(); + captureLightStates(); + captureVertexShaderStates(); + captureStreamSourceFrequencies(); + captureFVF(); + captureVertexDeclaration(); + } + + if(type == D3DSBT_ALL) // Capture remaining states + { + captureTextures(); + captureTexturePalette(); + captureVertexStreams(); + captureIndexBuffer(); + captureViewport(); + captureScissorRectangle(); + captureTransforms(); + captureTextureTransforms(); + captureClippingPlanes(); + captureMaterial(); + } + } + + Direct3DStateBlock9::~Direct3DStateBlock9() + { + clear(); + } + + long Direct3DStateBlock9::QueryInterface(const IID &iid, void **object) + { + CriticalSection cs(device); + + TRACE(""); + + if(iid == IID_IDirect3DStateBlock9 || + iid == IID_IUnknown) + { + AddRef(); + *object = this; + + return S_OK; + } + + *object = 0; + + return NOINTERFACE(iid); + } + + unsigned long Direct3DStateBlock9::AddRef() + { + TRACE(""); + + return Unknown::AddRef(); + } + + unsigned long Direct3DStateBlock9::Release() + { + TRACE(""); + + return Unknown::Release(); + } + + long Direct3DStateBlock9::Apply() + { + CriticalSection cs(device); + + TRACE(""); + + if(device->isRecording()) + { + return INVALIDCALL(); + } + + if(fvfCaptured) + { + device->SetFVF(FVF); + } + + if(vertexDeclarationCaptured) + { + device->SetVertexDeclaration(vertexDeclaration); + } + + if(indexBufferCaptured) + { + device->SetIndices(indexBuffer); + } + + for(int state = D3DRS_ZENABLE; state <= D3DRS_BLENDOPALPHA; state++) + { + if(renderStateCaptured[state]) + { + device->SetRenderState((D3DRENDERSTATETYPE)state, renderState[state]); + } + } + + if(nPatchModeCaptured) + { + device->SetNPatchMode(nPatchMode); + } + + for(int stage = 0; stage < 8; stage++) + { + for(int state = D3DTSS_COLOROP; state <= D3DTSS_CONSTANT; state++) + { + if(textureStageStateCaptured[stage][state]) + { + device->SetTextureStageState(stage, (D3DTEXTURESTAGESTATETYPE)state, textureStageState[stage][state]); + } + } + } + + for(int sampler = 0; sampler < 16 + 4; sampler++) + { + for(int state = D3DSAMP_ADDRESSU; state <= D3DSAMP_DMAPOFFSET; state++) + { + if(samplerStateCaptured[sampler][state]) + { + int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16); + device->SetSamplerState(index, (D3DSAMPLERSTATETYPE)state, samplerState[sampler][state]); + } + } + } + + for(int stream = 0; stream < 16; stream++) + { + if(streamSourceCaptured[stream]) + { + device->SetStreamSource(stream, streamSource[stream].vertexBuffer, streamSource[stream].offset, streamSource[stream].stride); + } + + if(streamSourceFrequencyCaptured[stream]) + { + device->SetStreamSourceFreq(stream, streamSourceFrequency[stream]); + } + } + + for(int sampler = 0; sampler < 16 + 4; sampler++) + { + if(textureCaptured[sampler]) + { + int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16); + device->SetTexture(index, texture[sampler]); + } + } + + for(int state = 0; state < 512; state++) + { + if(transformCaptured[state]) + { + device->SetTransform((D3DTRANSFORMSTATETYPE)state, &transform[state]); + } + } + + if(materialCaptured) + { + device->SetMaterial(&material); + } + + for(int index = 0; index < 8; index++) // FIXME: Support unlimited index + { + if(lightCaptured[index]) + { + device->SetLight(index, &light[index]); + } + } + + for(int index = 0; index < 8; index++) // FIXME: Support unlimited index + { + if(lightEnableCaptured[index]) + { + device->LightEnable(index, lightEnableState[index]); + } + } + + if(pixelShaderCaptured) + { + device->SetPixelShader(pixelShader); + } + + if(vertexShaderCaptured) + { + device->SetVertexShader(vertexShader); + } + + if(viewportCaptured) + { + device->SetViewport(&viewport); + } + + for(int i = 0; i < 224; i++) + { + if(*(int*)pixelShaderConstantF[i] != 0x80000000) + { + device->SetPixelShaderConstantF(i, pixelShaderConstantF[i], 1); + } + } + + for(int i = 0; i < 16; i++) + { + if(pixelShaderConstantI[i][0] != 0x80000000) + { + device->SetPixelShaderConstantI(i, pixelShaderConstantI[i], 1); + } + } + + for(int i = 0; i < 16; i++) + { + if(pixelShaderConstantB[i] != 0x80000000) + { + device->SetPixelShaderConstantB(i, &pixelShaderConstantB[i], 1); + } + } + + for(int i = 0; i < 256; i++) + { + if(*(int*)vertexShaderConstantF[i] != 0x80000000) + { + device->SetVertexShaderConstantF(i, vertexShaderConstantF[i], 1); + } + } + + for(int i = 0; i < 16; i++) + { + if(vertexShaderConstantI[i][0] != 0x80000000) + { + device->SetVertexShaderConstantI(i, vertexShaderConstantI[i], 1); + } + } + + for(int i = 0; i < 16; i++) + { + if(vertexShaderConstantB[i] != 0x80000000) + { + device->SetVertexShaderConstantB(i, &vertexShaderConstantB[i], 1); + } + } + + for(int index = 0; index < 6; index++) + { + if(clipPlaneCaptured[index]) + { + device->SetClipPlane(index, clipPlane[index]); + } + } + + if(scissorRectCaptured) + { + device->SetScissorRect(&scissorRect); + } + + if(paletteNumberCaptured) + { + device->SetCurrentTexturePalette(paletteNumber); + } + + return D3D_OK; + } + + long Direct3DStateBlock9::Capture() + { + CriticalSection cs(device); + + TRACE(""); + + if(fvfCaptured) + { + device->GetFVF(&FVF); + } + + if(vertexDeclarationCaptured) + { + Direct3DVertexDeclaration9 *vertexDeclaration; + device->GetVertexDeclaration(reinterpret_cast<IDirect3DVertexDeclaration9**>(&vertexDeclaration)); + + if(vertexDeclaration) + { + vertexDeclaration->bind(); + vertexDeclaration->Release(); + } + + if(this->vertexDeclaration) + { + this->vertexDeclaration->unbind(); + } + + this->vertexDeclaration = vertexDeclaration; + } + + if(indexBufferCaptured) + { + Direct3DIndexBuffer9 *indexBuffer; + device->GetIndices(reinterpret_cast<IDirect3DIndexBuffer9**>(&indexBuffer)); + + if(indexBuffer) + { + indexBuffer->bind(); + indexBuffer->Release(); + } + + if(this->indexBuffer) + { + this->indexBuffer->unbind(); + } + + this->indexBuffer = indexBuffer; + } + + for(int state = 0; state < D3DRS_BLENDOPALPHA + 1; state++) + { + if(renderStateCaptured[state]) + { + device->GetRenderState((D3DRENDERSTATETYPE)state, &renderState[state]); + } + } + + if(nPatchModeCaptured) + { + nPatchMode = device->GetNPatchMode(); + } + + for(int stage = 0; stage < 8; stage++) + { + for(int state = 0; state < D3DTSS_CONSTANT + 1; state++) + { + if(textureStageStateCaptured[stage][state]) + { + device->GetTextureStageState(stage, (D3DTEXTURESTAGESTATETYPE)state, &textureStageState[stage][state]); + } + } + } + + for(int sampler = 0; sampler < 16 + 4; sampler++) + { + for(int state = 0; state < D3DSAMP_DMAPOFFSET + 1; state++) + { + if(samplerStateCaptured[sampler][state]) + { + int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16); + device->GetSamplerState(index, (D3DSAMPLERSTATETYPE)state, &samplerState[sampler][state]); + } + } + } + + for(int stream = 0; stream < 16; stream++) + { + if(streamSourceCaptured[stream]) + { + Direct3DVertexBuffer9 *vertexBuffer; + device->GetStreamSource(stream, reinterpret_cast<IDirect3DVertexBuffer9**>(&vertexBuffer), &streamSource[stream].offset, &streamSource[stream].stride); + + if(vertexBuffer) + { + vertexBuffer->bind(); + vertexBuffer->Release(); + } + + if(streamSource[stream].vertexBuffer) + { + streamSource[stream].vertexBuffer->unbind(); + } + + streamSource[stream].vertexBuffer = vertexBuffer; + } + + if(streamSourceFrequencyCaptured[stream]) + { + device->GetStreamSourceFreq(stream, &streamSourceFrequency[stream]); + } + } + + for(int sampler = 0; sampler < 16 + 4; sampler++) + { + if(textureCaptured[sampler]) + { + Direct3DBaseTexture9 *texture; + int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16); + device->GetTexture(index, reinterpret_cast<IDirect3DBaseTexture9**>(&texture)); + + if(texture) + { + texture->bind(); + texture->Release(); + } + + if(this->texture[sampler]) + { + this->texture[sampler]->unbind(); + } + + this->texture[sampler] = texture; + } + } + + for(int state = 0; state < 512; state++) + { + if(transformCaptured[state]) + { + device->GetTransform((D3DTRANSFORMSTATETYPE)state, &transform[state]); + } + } + + if(materialCaptured) + { + device->GetMaterial(&material); + } + + for(int index = 0; index < 8; index++) // FIXME: Support unlimited index + { + if(lightCaptured[index]) + { + device->GetLight(index, &light[index]); + } + } + + for(int index = 0; index < 8; index++) // FIXME: Support unlimited index + { + if(lightEnableCaptured[index]) + { + lightEnableState[index] = false; + device->GetLightEnable(index, &lightEnableState[index]); + } + } + + if(pixelShaderCaptured) + { + Direct3DPixelShader9 *pixelShader; + device->GetPixelShader(reinterpret_cast<IDirect3DPixelShader9**>(&pixelShader)); + + if(pixelShader) + { + pixelShader->bind(); + pixelShader->Release(); + } + + if(this->pixelShader) + { + this->pixelShader->unbind(); + } + + this->pixelShader = pixelShader; + } + + if(vertexShaderCaptured) + { + Direct3DVertexShader9 *vertexShader; + device->GetVertexShader(reinterpret_cast<IDirect3DVertexShader9**>(&vertexShader)); + + if(vertexShader) + { + vertexShader->bind(); + vertexShader->Release(); + } + + if(this->vertexShader) + { + this->vertexShader->unbind(); + } + + this->vertexShader = vertexShader; + } + + if(viewportCaptured) + { + device->GetViewport(&viewport); + } + + for(int i = 0; i < 224; i++) + { + if(*(int*)pixelShaderConstantF[i] != 0x80000000) + { + device->GetPixelShaderConstantF(i, pixelShaderConstantF[i], 1); + } + } + + for(int i = 0; i < 16; i++) + { + if(pixelShaderConstantI[i][0] != 0x80000000) + { + device->GetPixelShaderConstantI(i, pixelShaderConstantI[i], 1); + } + } + + for(int i = 0; i < 16; i++) + { + if(pixelShaderConstantB[i] != 0x80000000) + { + device->GetPixelShaderConstantB(i, &pixelShaderConstantB[i], 1); + } + } + + for(int i = 0; i < 256; i++) + { + if(*(int*)vertexShaderConstantF[i] != 0x80000000) + { + device->GetVertexShaderConstantF(i, vertexShaderConstantF[i], 1); + } + } + + for(int i = 0; i < 16; i++) + { + if(vertexShaderConstantI[i][0] != 0x80000000) + { + device->GetVertexShaderConstantI(i, vertexShaderConstantI[i], 1); + } + } + + for(int i = 0; i < 16; i++) + { + if(vertexShaderConstantB[i] != 0x80000000) + { + device->GetVertexShaderConstantB(i, &vertexShaderConstantB[i], 1); + } + } + + for(int index = 0; index < 6; index++) + { + if(clipPlaneCaptured[index]) + { + device->GetClipPlane(index, clipPlane[index]); + } + } + + if(scissorRectCaptured) + { + device->GetScissorRect(&scissorRect); + } + + if(paletteNumberCaptured) + { + device->GetCurrentTexturePalette(&paletteNumber); + } + + return D3D_OK; + } + + long Direct3DStateBlock9::GetDevice(IDirect3DDevice9 **device) + { + CriticalSection cs(this->device); + + TRACE(""); + + if(!device) + { + return INVALIDCALL(); + } + + this->device->AddRef(); + *device = this->device; + + return D3D_OK; + } + + void Direct3DStateBlock9::lightEnable(unsigned long index, int enable) + { + if(index < 8) + { + lightEnableCaptured[index] = true; + lightEnableState[index] = enable; + } + else ASSERT(false); // FIXME: Support unlimited index + } + + void Direct3DStateBlock9::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 Direct3DStateBlock9::setCurrentTexturePalette(unsigned int paletteNumber) + { + paletteNumberCaptured = true; + this->paletteNumber = paletteNumber; + } + + void Direct3DStateBlock9::setFVF(unsigned long FVF) + { + fvfCaptured = true; + this->FVF = FVF; + } + + void Direct3DStateBlock9::setIndices(Direct3DIndexBuffer9 *indexBuffer) + { + if(indexBuffer) indexBuffer->bind(); + if(this->indexBuffer) this->indexBuffer->unbind(); + + indexBufferCaptured = true; + this->indexBuffer = indexBuffer; + } + + void Direct3DStateBlock9::setLight(unsigned long index, const D3DLIGHT9 *light) + { + if(index < 8) + { + lightCaptured[index] = true; + this->light[index] = *light; + } + else ASSERT(false); // FIXME: Support unlimited index + } + + void Direct3DStateBlock9::setMaterial(const D3DMATERIAL9 *material) + { + materialCaptured = true; + this->material = *material; + } + + void Direct3DStateBlock9::setNPatchMode(float segments) + { + nPatchModeCaptured = true; + nPatchMode = segments; + } + + void Direct3DStateBlock9::setPixelShader(Direct3DPixelShader9 *pixelShader) + { + if(pixelShader) pixelShader->bind(); + if(this->pixelShader) this->pixelShader->unbind(); + + pixelShaderCaptured = true; + this->pixelShader = pixelShader; + } + + void Direct3DStateBlock9::setPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count) + { + memcpy(&pixelShaderConstantB[startRegister], constantData, count * sizeof(int)); + } + + void Direct3DStateBlock9::setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count) + { + memcpy(pixelShaderConstantF[startRegister], constantData, count * sizeof(float[4])); + } + + void Direct3DStateBlock9::setPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count) + { + memcpy(pixelShaderConstantI[startRegister], constantData, count * sizeof(int[4])); + } + + void Direct3DStateBlock9::setRenderState(D3DRENDERSTATETYPE state, unsigned long value) + { + renderStateCaptured[state] = true; + renderState[state] = value; + } + + void Direct3DStateBlock9::setSamplerState(unsigned long index, D3DSAMPLERSTATETYPE state, unsigned long value) + { + unsigned int sampler = index < 16 ? index : (index - D3DVERTEXTEXTURESAMPLER0) + 16; + + if(sampler >= 16 + 4) + { + return; + } + + samplerStateCaptured[sampler][state] = true; + samplerState[sampler][state] = value; + } + + void Direct3DStateBlock9::setScissorRect(const RECT *rect) + { + scissorRectCaptured = true; + scissorRect = *rect; + } + + void Direct3DStateBlock9::setStreamSource(unsigned int stream, Direct3DVertexBuffer9 *vertexBuffer, unsigned int offset, unsigned int stride) + { + if(vertexBuffer) vertexBuffer->bind(); + if(streamSource[stream].vertexBuffer) streamSource[stream].vertexBuffer->unbind(); + + streamSourceCaptured[stream] = true; + streamSource[stream].vertexBuffer = vertexBuffer; + streamSource[stream].offset = offset; + streamSource[stream].stride = stride; + } + + void Direct3DStateBlock9::setStreamSourceFreq(unsigned int streamNumber, unsigned int divider) + { + streamSourceFrequencyCaptured[streamNumber] = true; + streamSourceFrequency[streamNumber] = divider; + } + + void Direct3DStateBlock9::setTexture(unsigned long index, Direct3DBaseTexture9 *texture) + { + unsigned int sampler = index < 16 ? index : (index - D3DVERTEXTEXTURESAMPLER0) + 16; + + if(sampler >= 16 + 4) + { + return; + } + + if(texture) texture->bind(); + if(this->texture[sampler]) this->texture[sampler]->unbind(); + + textureCaptured[sampler] = true; + this->texture[sampler] = texture; + } + + void Direct3DStateBlock9::setTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value) + { + textureStageStateCaptured[stage][type] = true; + textureStageState[stage][type] = value; + } + + void Direct3DStateBlock9::setTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix) + { + transformCaptured[state] = true; + transform[state] = *matrix; + } + + void Direct3DStateBlock9::setViewport(const D3DVIEWPORT9 *viewport) + { + viewportCaptured = true; + this->viewport = *viewport; + } + + void Direct3DStateBlock9::setVertexDeclaration(Direct3DVertexDeclaration9 *vertexDeclaration) + { + if(vertexDeclaration) vertexDeclaration->bind(); + if(this->vertexDeclaration) this->vertexDeclaration->unbind(); + + vertexDeclarationCaptured = true; + this->vertexDeclaration = vertexDeclaration; + } + + void Direct3DStateBlock9::setVertexShader(Direct3DVertexShader9 *vertexShader) + { + if(vertexShader) vertexShader->bind(); + if(this->vertexShader) this->vertexShader->unbind(); + + vertexShaderCaptured = true; + this->vertexShader = vertexShader; + } + + void Direct3DStateBlock9::setVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count) + { + memcpy(&vertexShaderConstantB[startRegister], constantData, count * sizeof(int)); + } + + void Direct3DStateBlock9::setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count) + { + memcpy(vertexShaderConstantF[startRegister], constantData, count * sizeof(float[4])); + } + + void Direct3DStateBlock9::setVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count) + { + memcpy(vertexShaderConstantI[startRegister], constantData, count * sizeof(int[4])); + } + + void Direct3DStateBlock9::clear() + { + // Erase capture flags + fvfCaptured = false; + vertexDeclarationCaptured = false; + + indexBufferCaptured = false; + + for(int state = 0; state < D3DRS_BLENDOPALPHA + 1; state++) + { + renderStateCaptured[state] = false; + } + + nPatchModeCaptured = false; + + for(int stage = 0; stage < 8; stage++) + { + for(int state = 0; state < D3DTSS_CONSTANT + 1; state++) + { + textureStageStateCaptured[stage][state] = false; + } + } + + for(int sampler = 0; sampler < 16 + 4; sampler++) + { + for(int state = 0; state < D3DSAMP_DMAPOFFSET + 1; state++) + { + samplerStateCaptured[sampler][state] = false; + } + } + + for(int stream = 0; stream < 16; stream++) + { + streamSourceCaptured[stream] = false; + streamSourceFrequencyCaptured[stream] = false; + } + + for(int sampler = 0; sampler < 16 + 4; sampler++) + { + textureCaptured[sampler] = false; + } + + for(int state = 0; state < 512; state++) + { + transformCaptured[state] = false; + } + + materialCaptured = false; + + for(int index = 0; index < 8; index++) // FIXME: Support unlimited index + { + lightCaptured[index] = false; + } + + for(int index = 0; index < 8; index++) // FIXME: Support unlimited index + { + lightEnableCaptured[index] = false; + } + + scissorRectCaptured = false; + + pixelShaderCaptured = false; + vertexShaderCaptured = false; + + viewportCaptured = false; + + for(int i = 0; i < 224; i++) + { + (int&)pixelShaderConstantF[i][0] = 0x80000000; + (int&)pixelShaderConstantF[i][1] = 0x80000000; + (int&)pixelShaderConstantF[i][2] = 0x80000000; + (int&)pixelShaderConstantF[i][3] = 0x80000000; + } + + for(int i = 0; i < 256; i++) + { + (int&)vertexShaderConstantF[i][0] = 0x80000000; + (int&)vertexShaderConstantF[i][1] = 0x80000000; + (int&)vertexShaderConstantF[i][2] = 0x80000000; + (int&)vertexShaderConstantF[i][3] = 0x80000000; + } + + for(int i = 0; i < 16; i++) + { + pixelShaderConstantI[i][0] = 0x80000000; + pixelShaderConstantI[i][1] = 0x80000000; + pixelShaderConstantI[i][2] = 0x80000000; + pixelShaderConstantI[i][3] = 0x80000000; + + pixelShaderConstantB[i] = 0x80000000; + + vertexShaderConstantI[i][0] = 0x80000000; + vertexShaderConstantI[i][1] = 0x80000000; + vertexShaderConstantI[i][2] = 0x80000000; + vertexShaderConstantI[i][3] = 0x80000000; + + vertexShaderConstantB[i] = 0x80000000; + } + + for(int index = 0; index < 6; index++) + { + clipPlaneCaptured[index] = false; + } + + paletteNumberCaptured = false; + + // unbind resources + if(vertexDeclaration) + { + vertexDeclaration->unbind(); + vertexDeclaration = 0; + } + + if(indexBuffer) + { + indexBuffer->unbind(); + indexBuffer = 0; + } + + for(int stream = 0; stream < 16; stream++) + { + if(streamSource[stream].vertexBuffer) + { + streamSource[stream].vertexBuffer->unbind(); + streamSource[stream].vertexBuffer = 0; + } + } + + for(int sampler = 0; sampler < 16 + 4; sampler++) + { + if(texture[sampler]) + { + texture[sampler]->unbind(); + texture[sampler] = 0; + } + } + + if(pixelShader) + { + pixelShader->unbind(); + pixelShader = 0; + } + + if(vertexShader) + { + vertexShader->unbind(); + vertexShader = 0; + } + } + + void Direct3DStateBlock9::captureRenderState(D3DRENDERSTATETYPE state) + { + device->GetRenderState(state, &renderState[state]); + renderStateCaptured[state] = true; + } + + void Direct3DStateBlock9::captureSamplerState(unsigned long index, D3DSAMPLERSTATETYPE state) + { + if(index < 16) + { + device->GetSamplerState(index, state, &samplerState[index][state]); + samplerStateCaptured[index][state] = true; + } + else if(index >= D3DVERTEXTEXTURESAMPLER0) + { + unsigned int sampler = 16 + (index - D3DVERTEXTEXTURESAMPLER0); + + device->GetSamplerState(index, state, &samplerState[sampler][state]); + samplerStateCaptured[sampler][state] = true; + } + } + + void Direct3DStateBlock9::captureTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type) + { + device->GetTextureStageState(stage, type, &textureStageState[stage][type]); + textureStageStateCaptured[stage][type] = true; + } + + void Direct3DStateBlock9::captureTransform(D3DTRANSFORMSTATETYPE state) + { + device->GetTransform(state, &transform[state]); + transformCaptured[state] = true; + } + + void Direct3DStateBlock9::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_DEPTHBIAS); + 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_WRAP8); + captureRenderState(D3DRS_WRAP9); + captureRenderState(D3DRS_WRAP10); + captureRenderState(D3DRS_WRAP11); + captureRenderState(D3DRS_WRAP12); + captureRenderState(D3DRS_WRAP13); + captureRenderState(D3DRS_WRAP14); + captureRenderState(D3DRS_WRAP15); + captureRenderState(D3DRS_COLORWRITEENABLE); + captureRenderState(D3DRS_BLENDOP); + captureRenderState(D3DRS_SCISSORTESTENABLE); + captureRenderState(D3DRS_SLOPESCALEDEPTHBIAS); + captureRenderState(D3DRS_ANTIALIASEDLINEENABLE); + captureRenderState(D3DRS_TWOSIDEDSTENCILMODE); + captureRenderState(D3DRS_CCW_STENCILFAIL); + captureRenderState(D3DRS_CCW_STENCILZFAIL); + captureRenderState(D3DRS_CCW_STENCILPASS); + captureRenderState(D3DRS_CCW_STENCILFUNC); + captureRenderState(D3DRS_COLORWRITEENABLE1); + captureRenderState(D3DRS_COLORWRITEENABLE2); + captureRenderState(D3DRS_COLORWRITEENABLE3); + captureRenderState(D3DRS_BLENDFACTOR); + captureRenderState(D3DRS_SRGBWRITEENABLE); + captureRenderState(D3DRS_SEPARATEALPHABLENDENABLE); + captureRenderState(D3DRS_SRCBLENDALPHA); + captureRenderState(D3DRS_DESTBLENDALPHA); + captureRenderState(D3DRS_BLENDOPALPHA); + } + + void Direct3DStateBlock9::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); + } + } + + void Direct3DStateBlock9::capturePixelSamplerStates() + { + for(int sampler = 0; sampler <= D3DVERTEXTEXTURESAMPLER3; sampler++) + { + captureSamplerState(sampler, D3DSAMP_ADDRESSU); + captureSamplerState(sampler, D3DSAMP_ADDRESSV); + captureSamplerState(sampler, D3DSAMP_ADDRESSW); + captureSamplerState(sampler, D3DSAMP_BORDERCOLOR); + captureSamplerState(sampler, D3DSAMP_MAGFILTER); + captureSamplerState(sampler, D3DSAMP_MINFILTER); + captureSamplerState(sampler, D3DSAMP_MIPFILTER); + captureSamplerState(sampler, D3DSAMP_MIPMAPLODBIAS); + captureSamplerState(sampler, D3DSAMP_MAXMIPLEVEL); + captureSamplerState(sampler, D3DSAMP_MAXANISOTROPY); + captureSamplerState(sampler, D3DSAMP_SRGBTEXTURE); + captureSamplerState(sampler, D3DSAMP_ELEMENTINDEX); + } + } + + void Direct3DStateBlock9::capturePixelShaderStates() + { + pixelShaderCaptured = true; + device->GetPixelShader(reinterpret_cast<IDirect3DPixelShader9**>(&pixelShader)); + + if(pixelShader) + { + pixelShader->bind(); + pixelShader->Release(); + } + + device->GetPixelShaderConstantF(0, pixelShaderConstantF[0], 32); + device->GetPixelShaderConstantI(0, pixelShaderConstantI[0], 16); + device->GetPixelShaderConstantB(0, pixelShaderConstantB, 16); + } + + void Direct3DStateBlock9::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_POSITIONDEGREE); + captureRenderState(D3DRS_NORMALDEGREE); + captureRenderState(D3DRS_MINTESSELLATIONLEVEL); + captureRenderState(D3DRS_MAXTESSELLATIONLEVEL); + captureRenderState(D3DRS_ADAPTIVETESS_X); + captureRenderState(D3DRS_ADAPTIVETESS_Y); + captureRenderState(D3DRS_ADAPTIVETESS_Z); + captureRenderState(D3DRS_ADAPTIVETESS_W); + captureRenderState(D3DRS_ENABLEADAPTIVETESSELLATION); + captureRenderState(D3DRS_NORMALIZENORMALS); + captureRenderState(D3DRS_SPECULARENABLE); + captureRenderState(D3DRS_SHADEMODE); + } + + void Direct3DStateBlock9::captureVertexSamplerStates() + { + for(int sampler = 0; sampler <= D3DVERTEXTEXTURESAMPLER3; sampler++) + { + captureSamplerState(sampler, D3DSAMP_DMAPOFFSET); + } + } + + void Direct3DStateBlock9::captureVertexTextureStates() + { + for(int stage = 0; stage < 8; stage++) + { + captureTextureStageState(stage, D3DTSS_TEXCOORDINDEX); + captureTextureStageState(stage, D3DTSS_TEXTURETRANSFORMFLAGS); + } + } + + void Direct3DStateBlock9::captureNPatchMode() + { + nPatchMode = device->GetNPatchMode(); + nPatchModeCaptured = true; + } + + void Direct3DStateBlock9::captureLightStates() + { + for(int index = 0; index < 8; index++) // FIXME: Support unlimited index + { + long result = device->GetLight(index, &light[index]); + lightCaptured[index] = SUCCEEDED(result); + } + + for(int index = 0; index < 8; index++) // FIXME: Support unlimited index + { + lightEnableState[index] = false; + long result = device->GetLightEnable(index, &lightEnableState[index]); + lightEnableCaptured[index] = SUCCEEDED(result); + } + } + + void Direct3DStateBlock9::captureVertexShaderStates() + { + vertexShaderCaptured = true; + device->GetVertexShader(reinterpret_cast<IDirect3DVertexShader9**>(&vertexShader)); + + if(vertexShader) + { + vertexShader->bind(); + vertexShader->Release(); + } + + device->GetVertexShaderConstantF(0, vertexShaderConstantF[0], 256); + device->GetVertexShaderConstantI(0, vertexShaderConstantI[0], 16); + device->GetVertexShaderConstantB(0, vertexShaderConstantB, 16); + } + + void Direct3DStateBlock9::captureStreamSourceFrequencies() + { + for(int stream = 0; stream < 16; stream++) + { + streamSourceFrequencyCaptured[stream] = true; + device->GetStreamSourceFreq(stream, &streamSourceFrequency[stream]); + } + } + + void Direct3DStateBlock9::captureFVF() + { + device->GetFVF(&FVF); + fvfCaptured = true; + } + + void Direct3DStateBlock9::captureVertexDeclaration() + { + vertexDeclarationCaptured = true; + device->GetVertexDeclaration(reinterpret_cast<IDirect3DVertexDeclaration9**>(&vertexDeclaration)); + + if(vertexDeclaration) + { + vertexDeclaration->bind(); + vertexDeclaration->Release(); + } + } + + void Direct3DStateBlock9::captureTextures() + { + for(int sampler = 0; sampler < 16 + 4; sampler++) + { + textureCaptured[sampler] = true; + int index = sampler < 16 ? sampler : D3DVERTEXTEXTURESAMPLER0 + (sampler - 16); + device->GetTexture(index, reinterpret_cast<IDirect3DBaseTexture9**>(&texture[sampler])); + + if(texture[sampler]) + { + texture[sampler]->bind(); + texture[sampler]->Release(); + } + } + } + + void Direct3DStateBlock9::captureTexturePalette() + { + paletteNumberCaptured = true; + device->GetCurrentTexturePalette(&paletteNumber); + } + + void Direct3DStateBlock9::captureVertexStreams() + { + for(int stream = 0; stream < 16; stream++) + { + streamSourceCaptured[stream] = true; + device->GetStreamSource(stream, reinterpret_cast<IDirect3DVertexBuffer9**>(&streamSource[stream].vertexBuffer), &streamSource[stream].offset, &streamSource[stream].stride); + + if(streamSource[stream].vertexBuffer) + { + streamSource[stream].vertexBuffer->bind(); + streamSource[stream].vertexBuffer->Release(); + } + } + } + + void Direct3DStateBlock9::captureIndexBuffer() + { + indexBufferCaptured = true; + device->GetIndices(reinterpret_cast<IDirect3DIndexBuffer9**>(&indexBuffer)); + + if(indexBuffer) + { + indexBuffer->bind(); + indexBuffer->Release(); + } + } + + void Direct3DStateBlock9::captureViewport() + { + device->GetViewport(&viewport); + viewportCaptured = true; + } + + void Direct3DStateBlock9::captureScissorRectangle() + { + device->GetScissorRect(&scissorRect); + scissorRectCaptured = true; + } + + void Direct3DStateBlock9::captureTransforms() + { + captureTransform(D3DTS_VIEW); + captureTransform(D3DTS_PROJECTION); + captureTransform(D3DTS_WORLD); + } + + void Direct3DStateBlock9::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 Direct3DStateBlock9::captureClippingPlanes() + { + for(int index = 0; index < 6; index++) + { + device->GetClipPlane(index, (float*)&clipPlane[index]); + clipPlaneCaptured[index] = true; + } + } + + void Direct3DStateBlock9::captureMaterial() + { + device->GetMaterial(&material); + materialCaptured = true; + } +}