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#ifndef D3D9_Direct3DDevice9_hpp
16#define D3D9_Direct3DDevice9_hpp
17
18#include "Unknown.hpp"
19
20#include "Direct3D9.hpp"
21#include "Direct3DSwapChain9.hpp"
22#include "Capabilities.hpp"
23
24#include "Stream.hpp"
25
26#include <d3d9.h>
27#include <map>
28#include <list>
29
30namespace sw
31{
32	class Renderer;
33	class Context;
34	struct Query;
35}
36
37namespace D3D9
38{
39	class Direct3DVertexDeclaration9;
40	class Direct3DStateBlock9;
41	class Direct3DSurface9;
42	class Direct3DPixelShader9;
43	class Direct3DVertexShader9;
44	class irect3DVertexDeclaration9;
45	class Direct3DVertexBuffer9;
46	class Direct3DIndexBuffer9;
47	class CriticalSection;
48
49	class Direct3DDevice9 : public IDirect3DDevice9, public Unknown
50	{
51		friend CriticalSection;
52		friend Direct3DSwapChain9;
53
54	public:
55		Direct3DDevice9(const HINSTANCE instance, Direct3D9 *d3d9, unsigned int adapter, D3DDEVTYPE deviceType, HWND focusWindow, unsigned long behaviourFlags, D3DPRESENT_PARAMETERS *presentParameters);
56
57		virtual ~Direct3DDevice9();
58
59		// IUnknown methods
60		long __stdcall QueryInterface(const IID &iid, void **object);
61		unsigned long __stdcall AddRef();
62		unsigned long __stdcall Release();
63
64		// IDirect3DDevice9 methods
65		long __stdcall BeginScene();
66		long __stdcall BeginStateBlock();
67		long __stdcall Clear(unsigned long count, const D3DRECT *rects, unsigned long flags, unsigned long color, float z, unsigned long stencil);
68		long __stdcall ColorFill(IDirect3DSurface9 *surface, const RECT *rect, D3DCOLOR color);
69		long __stdcall CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *presentParameters, IDirect3DSwapChain9 **swapChain);
70		long __stdcall CreateCubeTexture(unsigned int edgeLength, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture9 **cubeTexture, void **sharedHandle);
71		long __stdcall CreateDepthStencilSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int discard, IDirect3DSurface9 **surface, void **sharedHandle);
72		long __stdcall CreateIndexBuffer(unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **indexBuffer, void **sharedHandle);
73		long __stdcall CreateOffscreenPlainSurface(unsigned int width, unsigned int height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface, void **sharedHandle);
74		long __stdcall CreatePixelShader(const unsigned long *function, IDirect3DPixelShader9 **shader);
75		long __stdcall CreateQuery(D3DQUERYTYPE type, IDirect3DQuery9 **query);
76		long __stdcall CreateRenderTarget(unsigned int width, unsigned int height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multiSample, unsigned long multiSampleQuality, int lockable, IDirect3DSurface9 **surface, void **sharedHandle);
77		long __stdcall CreateStateBlock(D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateBlock);
78		long __stdcall CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture9 **texture, void **sharedHandle);
79		long __stdcall CreateVertexBuffer(unsigned int length, unsigned long usage, unsigned long FVF, D3DPOOL pool, IDirect3DVertexBuffer9 **vertexBuffer, void **sharedHandle);
80		long __stdcall CreateVertexDeclaration(const D3DVERTEXELEMENT9 *vertexElements, IDirect3DVertexDeclaration9 **declaration);
81		long __stdcall CreateVertexShader(const unsigned long *function, IDirect3DVertexShader9 **shader);
82		long __stdcall CreateVolumeTexture(unsigned int width, unsigned int height, unsigned int depth, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool, IDirect3DVolumeTexture9 **volumeTexture, void **sharedHandle);
83		long __stdcall DeletePatch(unsigned int handle);
84		long __stdcall DrawIndexedPrimitive(D3DPRIMITIVETYPE type, int baseVertexIndex, unsigned int minIndex, unsigned int numVertices, unsigned int startIndex, unsigned int primitiveCount);
85		long __stdcall DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE type, unsigned int minVertexIndex, unsigned int numVertexIndices, unsigned int PrimitiveCount, const void *indexData, D3DFORMAT indexDataFormat, const void *vertexStreamZeroData, unsigned int VertexStreamZeroStride);
86		long __stdcall DrawPrimitive(D3DPRIMITIVETYPE primitiveType, unsigned int startVertex, unsigned int primiveCount);
87		long __stdcall DrawPrimitiveUP(D3DPRIMITIVETYPE primitiveType, unsigned int primitiveCount, const void *vertexStreamZeroData, unsigned int vertexStreamZeroStride);
88		long __stdcall DrawRectPatch(unsigned int handle, const float *numSegs, const D3DRECTPATCH_INFO *rectPatchInfo);
89		long __stdcall DrawTriPatch(unsigned int handle, const float *numSegs, const D3DTRIPATCH_INFO *triPatchInfo);
90		long __stdcall EndScene();
91		long __stdcall EndStateBlock(IDirect3DStateBlock9 **stateBlock);
92		long __stdcall EvictManagedResources();
93		unsigned int __stdcall GetAvailableTextureMem();
94		long __stdcall GetBackBuffer(unsigned int swapChain, unsigned int index, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer);
95		long __stdcall GetClipPlane(unsigned long index, float *plane);
96		long __stdcall GetClipStatus(D3DCLIPSTATUS9 *clipStatus);
97		long __stdcall GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *parameters);
98		long __stdcall GetCurrentTexturePalette(unsigned int *paletteNumber);
99		long __stdcall GetDepthStencilSurface(IDirect3DSurface9 **depthStencilSurface);
100		long __stdcall GetDeviceCaps(D3DCAPS9 *caps);
101		long __stdcall GetDirect3D(IDirect3D9 **D3D);
102		long __stdcall GetDisplayMode(unsigned int swapChain ,D3DDISPLAYMODE *mode);
103		long __stdcall GetFrontBufferData(unsigned int swapChain, IDirect3DSurface9 *destSurface);
104		long __stdcall GetFVF(unsigned long *FVF);
105		void __stdcall GetGammaRamp(unsigned int swapChain, D3DGAMMARAMP *ramp);
106		long __stdcall GetIndices(IDirect3DIndexBuffer9 **indexData);
107		long __stdcall GetLight(unsigned long index, D3DLIGHT9 *p);
108		long __stdcall GetLightEnable(unsigned long index , int *enable);
109		long __stdcall GetMaterial(D3DMATERIAL9 *material);
110		float __stdcall GetNPatchMode();
111		unsigned int __stdcall GetNumberOfSwapChains();
112		long __stdcall GetPaletteEntries(unsigned int paletteNumber, PALETTEENTRY *entries);
113		long __stdcall GetPixelShader(IDirect3DPixelShader9 **shader);
114		long __stdcall GetPixelShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count);
115		long __stdcall GetPixelShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count);
116		long __stdcall GetPixelShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count);
117		long __stdcall GetRasterStatus(unsigned int swapChain, D3DRASTER_STATUS *rasterStatus);
118		long __stdcall GetRenderState(D3DRENDERSTATETYPE State, unsigned long *value);
119		long __stdcall GetRenderTarget(unsigned long index, IDirect3DSurface9 **renderTarget);
120		long __stdcall GetRenderTargetData(IDirect3DSurface9 *renderTarget, IDirect3DSurface9 *destSurface);
121		long __stdcall GetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE type, unsigned long *value);
122		long __stdcall GetScissorRect(RECT *rect);
123		int __stdcall GetSoftwareVertexProcessing();
124		long __stdcall GetStreamSource(unsigned int streamNumber, IDirect3DVertexBuffer9 **streamData, unsigned int *offset, unsigned int *stride);
125		long __stdcall GetStreamSourceFreq(unsigned int streamNumber, unsigned int *divider);
126		long __stdcall GetSwapChain(unsigned int index, IDirect3DSwapChain9 **swapChain);
127		long __stdcall GetTexture(unsigned long sampler, IDirect3DBaseTexture9 **texture);
128		long __stdcall GetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long *value);
129		long __stdcall GetTransform(D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix);
130		long __stdcall GetVertexDeclaration(IDirect3DVertexDeclaration9 **declaration);
131		long __stdcall GetVertexShader(IDirect3DVertexShader9 **shader);
132		long __stdcall GetVertexShaderConstantB(unsigned int startRegister, int *constantData, unsigned int count);
133		long __stdcall GetVertexShaderConstantF(unsigned int startRegister, float *constantData, unsigned int count);
134		long __stdcall GetVertexShaderConstantI(unsigned int startRegister, int *constantData, unsigned int count);
135		long __stdcall GetViewport(D3DVIEWPORT9 *viewport);
136		long __stdcall LightEnable(unsigned long index, int enable);
137		long __stdcall MultiplyTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix);
138		long __stdcall Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion);
139		long __stdcall ProcessVertices(unsigned int srcStartIndex, unsigned int destIndex, unsigned int vertexCount, IDirect3DVertexBuffer9 *destBuffer, IDirect3DVertexDeclaration9 *vertexDeclaration, unsigned long flags);
140		long __stdcall Reset(D3DPRESENT_PARAMETERS *presentParameters);
141		long __stdcall SetClipPlane(unsigned long index, const float *plane);
142		long __stdcall SetClipStatus(const D3DCLIPSTATUS9 *clipStatus);
143		long __stdcall SetCurrentTexturePalette(unsigned int paletteNumber);
144		void __stdcall SetCursorPosition(int x, int y, unsigned long flags);
145		long __stdcall SetCursorProperties(unsigned int x, unsigned int y, IDirect3DSurface9 *cursorBitmap);
146		long __stdcall SetDepthStencilSurface(IDirect3DSurface9 *newDepthStencil);
147		long __stdcall SetDialogBoxMode(int enableDialogs);
148		long __stdcall SetFVF(unsigned long FVF);
149		void __stdcall SetGammaRamp(unsigned int swapChain, unsigned long flags, const D3DGAMMARAMP *ramp);
150		long __stdcall SetIndices(IDirect3DIndexBuffer9 *indexData);
151		long __stdcall SetLight(unsigned long index, const D3DLIGHT9 *light);
152		long __stdcall SetMaterial(const D3DMATERIAL9 *material);
153		long __stdcall SetNPatchMode(float segments);
154		long __stdcall SetPaletteEntries(unsigned int paletteNumber, const PALETTEENTRY *entries);
155		long __stdcall SetPixelShader(IDirect3DPixelShader9 *shader);
156		long __stdcall SetPixelShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count);
157		long __stdcall SetPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
158		long __stdcall SetPixelShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count);
159		long __stdcall SetRenderState(D3DRENDERSTATETYPE state, unsigned long value);
160		long __stdcall SetRenderTarget(unsigned long index, IDirect3DSurface9 *renderTarget);
161		long __stdcall SetSamplerState(unsigned long sampler, D3DSAMPLERSTATETYPE state, unsigned long value);
162		long __stdcall SetScissorRect(const RECT *rect);
163		long __stdcall SetSoftwareVertexProcessing(int software);
164		long __stdcall SetStreamSource(unsigned int stream, IDirect3DVertexBuffer9 *data, unsigned int offset, unsigned int stride);
165		long __stdcall SetStreamSourceFreq(unsigned int streamNumber, unsigned int divider);
166		long __stdcall SetTexture(unsigned long sampler, IDirect3DBaseTexture9 *texture);
167		long __stdcall SetTextureStageState(unsigned long stage, D3DTEXTURESTAGESTATETYPE type, unsigned long value);
168		long __stdcall SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix);
169		long __stdcall SetVertexDeclaration(IDirect3DVertexDeclaration9 *declaration);
170		long __stdcall SetVertexShader(IDirect3DVertexShader9 *shader);
171		long __stdcall SetVertexShaderConstantB(unsigned int startRegister, const int *constantData, unsigned int count);
172		long __stdcall SetVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
173		long __stdcall SetVertexShaderConstantI(unsigned int startRegister, const int *constantData, unsigned int count);
174		long __stdcall SetViewport(const D3DVIEWPORT9 *viewport);
175		int __stdcall ShowCursor(int show);
176		long __stdcall StretchRect(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter);
177		long __stdcall TestCooperativeLevel();
178		long __stdcall UpdateSurface(IDirect3DSurface9 *sourceSurface, const RECT *sourceRect, IDirect3DSurface9 *destinationSurface, const POINT *destPoint);
179		long __stdcall UpdateTexture(IDirect3DBaseTexture9 *sourceTexture, IDirect3DBaseTexture9 *destinationTexture);
180		long __stdcall ValidateDevice(unsigned long *numPasses);
181
182		// Internal methods
183		long getAdapterDisplayMode(unsigned int adapter, D3DDISPLAYMODE *mode);
184		bool isRecording() const;   // In a state recording mode
185		void setOcclusionEnabled(bool enable);
186		void removeQuery(sw::Query *query);
187		void addQuery(sw::Query *query);
188		void stretchRect(Direct3DSurface9 *sourceSurface, const RECT *sourceRect, Direct3DSurface9 *destSurface, const RECT *destRect, D3DTEXTUREFILTERTYPE filter);
189
190	private:
191		static int typeStride(unsigned char streamType);
192		bool instanceData();
193		bool bindResources(Direct3DIndexBuffer9 *indexBuffer);
194		void bindVertexStreams(int base, bool instancing, int instance);
195		void bindIndexBuffer(Direct3DIndexBuffer9 *indexBuffer);
196		void bindShaderConstants();
197		void bindLights();
198		bool bindViewport();   // Also adjusts for scissoring
199		void bindTextures();
200
201		long updateVolume(IDirect3DVolume9 *sourceVolume, IDirect3DVolume9 *destinationVolume);
202		bool validRectangle(const RECT *rect, IDirect3DSurface9 *surface);
203		void configureFPU();
204
205		// Creation parameters
206		const HINSTANCE instance;
207		Direct3D9 *d3d9;
208		const unsigned int adapter;
209		const D3DDEVTYPE deviceType;
210		const HWND focusWindow;
211		const unsigned long behaviourFlags;
212
213		HWND deviceWindow;
214
215		D3DVIEWPORT9 viewport;
216		D3DMATRIX matrix[512];
217		Direct3DBaseTexture9 *texture[16 + 4];
218		D3DMATERIAL9 material;
219		float plane[6][4];
220		D3DCLIPSTATUS9 clipStatus;
221		RECT scissorRect;
222		bool scissorEnable;
223
224		struct Light : D3DLIGHT9
225		{
226			Light &operator=(const D3DLIGHT9 &light)
227			{
228				Type = light.Type;
229				Diffuse = light.Diffuse;
230				Specular = light.Specular;
231				Ambient = light.Ambient;
232				Position = light.Position;
233				Direction = light.Direction;
234				Range = light.Range;
235				Falloff = light.Falloff;
236				Attenuation0 = light.Attenuation0;
237				Attenuation1 = light.Attenuation1;
238				Attenuation2 = light.Attenuation2;
239				Theta = light.Theta;
240				Phi = light.Phi;
241
242				return *this;
243			}
244
245			bool enable;
246		};
247
248		struct Lights : std::map<int, Light>
249		{
250			bool exists(int index)
251			{
252				return find(index) != end();
253			}
254		};
255
256		Lights light;
257		bool softwareVertexProcessing;
258		Direct3DPixelShader9 *pixelShader;
259		Direct3DVertexShader9 *vertexShader;
260
261		bool lightsDirty;
262		bool pixelShaderDirty;
263		unsigned int pixelShaderConstantsBDirty;
264		unsigned int pixelShaderConstantsFDirty;
265		unsigned int pixelShaderConstantsIDirty;
266		bool vertexShaderDirty;
267		unsigned int vertexShaderConstantsBDirty;
268		unsigned int vertexShaderConstantsFDirty;
269		unsigned int vertexShaderConstantsIDirty;
270
271		float pixelShaderConstantF[MAX_PIXEL_SHADER_CONST][4];
272		int pixelShaderConstantI[16][4];
273		int pixelShaderConstantB[16];
274
275		float vertexShaderConstantF[MAX_VERTEX_SHADER_CONST][4];
276		int vertexShaderConstantI[16][4];
277		int vertexShaderConstantB[16];
278
279		Direct3DVertexDeclaration9 *vertexDeclaration;
280		Direct3DVertexBuffer9 *dataStream[MAX_VERTEX_INPUTS];
281		int streamStride[MAX_VERTEX_INPUTS];
282		int streamOffset[MAX_VERTEX_INPUTS];
283		unsigned int streamSourceFreq[MAX_VERTEX_INPUTS];
284		Direct3DIndexBuffer9 *indexData;
285
286		Direct3DSwapChain9 *swapChain;
287		Direct3DSurface9 *renderTarget[4];
288		Direct3DSurface9 *depthStencil;
289		Direct3DSurface9 *autoDepthStencil;
290
291		Direct3DStateBlock9 *stateRecorder;
292
293		unsigned long renderState[D3DRS_BLENDOPALPHA + 1];
294		unsigned long textureStageState[8][D3DTSS_CONSTANT + 1];
295		unsigned long samplerState[16 + 4][D3DSAMP_DMAPOFFSET + 1];
296		bool init;
297
298		struct Palette
299		{
300			PALETTEENTRY entry[256];
301		};
302
303		unsigned int currentPalette;
304		std::map<int, Palette> palette;
305
306		sw::Context *context;
307		sw::Renderer *renderer;
308
309		bool instancingEnabled;
310
311		sw::Surface *cursor;
312		bool showCursor;
313
314		CRITICAL_SECTION criticalSection;
315	};
316
317	class CriticalSection
318	{
319	public:
320		CriticalSection(Direct3DDevice9 *device) : device(device)
321		{
322			if(device->behaviourFlags & D3DCREATE_MULTITHREADED)
323			{
324				EnterCriticalSection(&device->criticalSection);
325			}
326		}
327
328		~CriticalSection()
329		{
330			if(device->behaviourFlags & D3DCREATE_MULTITHREADED)
331			{
332				LeaveCriticalSection(&device->criticalSection);
333			}
334		}
335
336	private:
337		Direct3DDevice9 *const device;
338	};
339}
340
341#endif // D3D9_Direct3DDevice9_hpp
342