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
28namespace 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