1 // Copyright (c) 2012- PPSSPP Project.
2 
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0 or later versions.
6 
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 // GNU General Public License 2.0 for more details.
11 
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
14 
15 // Official git repository and contact information can be found at
16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17 
18 #pragma once
19 
20 #include <d3d9.h>
21 
22 #include "Common/Data/Collections/Hashmaps.h"
23 #include "GPU/GPUState.h"
24 #include "GPU/Common/GPUDebugInterface.h"
25 #include "GPU/Common/IndexGenerator.h"
26 #include "GPU/Common/VertexDecoderCommon.h"
27 #include "GPU/Common/DrawEngineCommon.h"
28 #include "GPU/Common/GPUStateUtils.h"
29 
30 struct DecVtxFormat;
31 struct UVScale;
32 
33 namespace DX9 {
34 
35 class VSShader;
36 class ShaderManagerDX9;
37 class TextureCacheDX9;
38 class FramebufferManagerDX9;
39 
40 // States transitions:
41 // On creation: DRAWN_NEW
42 // DRAWN_NEW -> DRAWN_HASHING
43 // DRAWN_HASHING -> DRAWN_RELIABLE
44 // DRAWN_HASHING -> DRAWN_UNRELIABLE
45 // DRAWN_ONCE -> UNRELIABLE
46 // DRAWN_RELIABLE -> DRAWN_SAFE
47 // UNRELIABLE -> death
48 // DRAWN_ONCE -> death
49 // DRAWN_RELIABLE -> death
50 
51 enum {
52 	VAI_FLAG_VERTEXFULLALPHA = 1,
53 };
54 
55 // Try to keep this POD.
56 class VertexArrayInfoDX9 {
57 public:
58 	VertexArrayInfoDX9() {
59 		status = VAI_NEW;
60 		vbo = 0;
61 		ebo = 0;
62 		prim = GE_PRIM_INVALID;
63 		numDraws = 0;
64 		numFrames = 0;
65 		lastFrame = gpuStats.numFlips;
66 		numVerts = 0;
D3DPrimCount(D3DPRIMITIVETYPE prim,int size)67 		drawsUntilNextFullHash = 0;
68 		flags = 0;
69 	}
70 	~VertexArrayInfoDX9();
71 
72 	enum Status : uint8_t {
73 		VAI_NEW,
74 		VAI_HASHING,
75 		VAI_RELIABLE,  // cache, don't hash
76 		VAI_UNRELIABLE,  // never cache
77 	};
78 
79 	uint64_t hash;
80 	u32 minihash;
81 
82 	LPDIRECT3DVERTEXBUFFER9 vbo;
83 	LPDIRECT3DINDEXBUFFER9 ebo;
84 
85 	// Precalculated parameter for drawRangeElements
86 	u16 numVerts;
DrawEngineDX9(Draw::DrawContext * draw)87 	u16 maxIndex;
88 	s8 prim;
89 	Status status;
90 
91 	// ID information
92 	int numDraws;
93 	int numFrames;
94 	int lastFrame;  // So that we can forget.
95 	u16 drawsUntilNextFullHash;
96 	u8 flags;
97 };
98 
99 class TessellationDataTransferDX9 : public TessellationDataTransfer {
100 public:
101 	TessellationDataTransferDX9() {}
102 	~TessellationDataTransferDX9() {}
103 	void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) override;
104 };
105 
106 // Handles transform, lighting and drawing.
107 class DrawEngineDX9 : public DrawEngineCommon {
108 public:
~DrawEngineDX9()109 	DrawEngineDX9(Draw::DrawContext *draw);
110 	virtual ~DrawEngineDX9();
111 
112 	void SetShaderManager(ShaderManagerDX9 *shaderManager) {
113 		shaderManager_ = shaderManager;
114 	}
115 	void SetTextureCache(TextureCacheDX9 *textureCache) {
116 		textureCache_ = textureCache;
__anone53890b60302(const uint32_t &key, IDirect3DVertexDeclaration9 *decl) 117 	}
118 	void SetFramebufferManager(FramebufferManagerDX9 *fbManager) {
119 		framebufferManager_ = fbManager;
120 	}
121 	void InitDeviceObjects();
122 	void DestroyDeviceObjects();
123 
124 	void ClearTrackedVertexArrays() override;
125 
InitDeviceObjects()126 	void BeginFrame();
127 
128 	// So that this can be inlined
129 	void Flush() {
DestroyDeviceObjects()130 		if (!numDrawCalls)
131 			return;
132 		DoFlush();
133 	}
134 
135 	void FinishDeferred() {
136 		if (!numDrawCalls)
137 			return;
138 		DecodeVerts(decoded);
139 	}
140 
141 	void DispatchFlush() override { Flush(); }
142 
143 protected:
144 	// Not currently supported.
145 	bool UpdateUseHWTessellation(bool enable) override { return false; }
146 	void DecimateTrackedVertexArrays();
147 
148 private:
149 	void DoFlush();
150 
151 	void ApplyDrawState(int prim);
152 	void ApplyDrawStateLate();
153 	void ResetFramebufferRead();
154 
155 	IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(VSShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt);
156 
157 	void MarkUnreliable(VertexArrayInfoDX9 *vai);
158 
VertexAttribSetup(D3DVERTEXELEMENT9 * VertexElement,u8 fmt,u8 offset,u8 usage,u8 usage_index=0)159 	LPDIRECT3DDEVICE9 device_ = nullptr;
160 	Draw::DrawContext *draw_;
161 
162 	PrehashMap<VertexArrayInfoDX9 *, nullptr> vai_;
163 	DenseHashMap<u32, IDirect3DVertexDeclaration9 *, nullptr> vertexDeclMap_;
164 
165 	// SimpleVertex
166 	IDirect3DVertexDeclaration9* transformedVertexDecl_ = nullptr;
SetupDecFmtForDraw(VSShader * vshader,const DecVtxFormat & decFmt,u32 pspFmt)167 
168 	// Other
169 	ShaderManagerDX9 *shaderManager_ = nullptr;
170 	TextureCacheDX9 *textureCache_ = nullptr;
171 	FramebufferManagerDX9 *framebufferManager_ = nullptr;
172 
173 	// Hardware tessellation
174 	TessellationDataTransferDX9 *tessDataTransferDX9;
175 
176 	int lastRenderStepId_ = -1;
177 };
178 
179 }  // namespace
180