blob: 929725eb362d936d00108dcd4636c726893c2ad5 [file] [log] [blame]
José Fonsecacbb86172012-12-12 07:38:42 +00001/**************************************************************************
2 *
3 * Copyright 2011-2012 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 **************************************************************************/
25
26
Jose Fonseca64c4fdf2017-07-30 12:55:32 +010027#include <assert.h>
José Fonsecacbb86172012-12-12 07:38:42 +000028#include <stdio.h>
29
30#include <iostream>
Jose Fonseca0c85d0b2016-09-21 12:08:38 +010031#include <sstream>
Jose Fonseca64c4fdf2017-07-30 12:55:32 +010032#include <memory>
José Fonsecacbb86172012-12-12 07:38:42 +000033
Jose Fonsecae8ba0792015-05-01 12:38:03 +010034#include "state_writer.hpp"
José Fonseca1df5ed82014-06-13 10:45:46 +010035#include "com_ptr.hpp"
José Fonsecacbb86172012-12-12 07:38:42 +000036#include "d3d8imports.hpp"
37#include "d3dshader.hpp"
38#include "d3dstate.hpp"
José Fonsecacbb86172012-12-12 07:38:42 +000039
40
41namespace d3dstate {
42
43
44typedef HRESULT (STDMETHODCALLTYPE IDirect3DDevice8::*GetShaderFunctionMethod)(DWORD Handle, void* pData, DWORD* pSizeOfData);
45
46
47struct VertexShaderGetter
48{
49 HRESULT GetShader(IDirect3DDevice8 *pDevice, DWORD *pHandle) {
Jose Fonsecaeec77bb2016-09-21 11:38:00 +010050 HRESULT hr = pDevice->GetVertexShader(pHandle);
51 if (SUCCEEDED(hr) && (*pHandle & 1) == 0) {
52 // Handle is a FVF code.
53 *pHandle = 0;
54 }
55 return hr;
José Fonsecacbb86172012-12-12 07:38:42 +000056 }
57 HRESULT GetShaderFunction(IDirect3DDevice8 *pDevice, DWORD Handle, void* pData, DWORD* pSizeOfData) {
58 return pDevice->GetVertexShaderFunction(Handle, pData, pSizeOfData);
59 }
60};
61
62struct PixelShaderGetter
63{
64 HRESULT GetShader(IDirect3DDevice8 *pDevice, DWORD *pHandle) {
65 return pDevice->GetPixelShader(pHandle);
66 }
67 HRESULT GetShaderFunction(IDirect3DDevice8 *pDevice, DWORD Handle, void* pData, DWORD* pSizeOfData) {
68 return pDevice->GetPixelShaderFunction(Handle, pData, pSizeOfData);
69 }
70};
71
72template<class Getter>
73inline void
Jose Fonsecae8ba0792015-05-01 12:38:03 +010074dumpShader(StateWriter &writer, IDirect3DDevice8 *pDevice, const char *name) {
José Fonsecacbb86172012-12-12 07:38:42 +000075 Getter getter;
76 HRESULT hr;
77
78 DWORD dwShader = 0;
79 hr = getter.GetShader(pDevice, &dwShader);
80 if (FAILED(hr) || !dwShader) {
81 return;
82 }
83
84 DWORD SizeOfData = 0;
85
86 hr = getter.GetShaderFunction(pDevice, dwShader, NULL, &SizeOfData);
87 if (SUCCEEDED(hr)) {
Jose Fonseca64c4fdf2017-07-30 12:55:32 +010088 assert(SizeOfData % sizeof(DWORD) == 0);
89 std::unique_ptr<DWORD []> pData(new DWORD[SizeOfData / sizeof(DWORD)]);
90 hr = getter.GetShaderFunction(pDevice, dwShader, pData.get(), &SizeOfData);
91 if (SUCCEEDED(hr)) {
92 com_ptr<IDisassemblyBuffer> pDisassembly;
93 hr = DisassembleShader(pData.get(), &pDisassembly);
José Fonsecacbb86172012-12-12 07:38:42 +000094 if (SUCCEEDED(hr)) {
Jose Fonseca64c4fdf2017-07-30 12:55:32 +010095 writer.beginMember(name);
96 writer.writeString((const char *)pDisassembly->GetBufferPointer() /*, pDisassembly->GetBufferSize() */);
97 writer.endMember();
José Fonsecacbb86172012-12-12 07:38:42 +000098 }
José Fonsecacbb86172012-12-12 07:38:42 +000099 }
100 }
101}
102
103static void
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100104dumpShaders(StateWriter &writer, IDirect3DDevice8 *pDevice)
José Fonsecacbb86172012-12-12 07:38:42 +0000105{
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100106 writer.beginMember("shaders");
107 writer.beginObject();
José Fonsecacbb86172012-12-12 07:38:42 +0000108
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100109 dumpShader<VertexShaderGetter>(writer, pDevice, "vertex");
110 dumpShader<PixelShaderGetter>(writer, pDevice, "pixel");
José Fonsecacbb86172012-12-12 07:38:42 +0000111
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100112 writer.endObject();
113 writer.endMember(); // shaders
José Fonsecacbb86172012-12-12 07:38:42 +0000114}
115
Jose Fonseca0c85d0b2016-09-21 12:08:38 +0100116static void
117dumpTextureStates(StateWriter &writer, IDirect3DDevice8 *pDevice)
118{
119#define _DUMP_TS_INT(x) { \
120 DWORD rsDword = 0; \
121 pDevice->GetTextureStageState(i, x, &rsDword); \
122 writer.writeIntMember(#x, rsDword); \
123}
124
125#define _DUMP_TS_FLOAT(x) { \
126 float rsFloat = 0.0f; \
127 pDevice->GetTextureStageState(i, x, (DWORD *)&rsFloat); \
128 writer.writeFloatMember(#x, rsFloat); \
129}
130
131 for (int i = 0; i < 8; i++)
132 {
133 std::ostringstream oss;
134 oss << "TextureStageState" << i;
135 writer.beginMember(oss.str());
136 writer.beginObject();
137
138 _DUMP_TS_INT(D3DTSS_COLOROP);
139 _DUMP_TS_INT(D3DTSS_COLORARG1);
140 _DUMP_TS_INT(D3DTSS_COLORARG2);
141 _DUMP_TS_INT(D3DTSS_ALPHAOP);
142 _DUMP_TS_INT(D3DTSS_ALPHAARG1);
143 _DUMP_TS_INT(D3DTSS_ALPHAARG2);
144 _DUMP_TS_FLOAT(D3DTSS_BUMPENVMAT00);
145 _DUMP_TS_FLOAT(D3DTSS_BUMPENVMAT01);
146 _DUMP_TS_FLOAT(D3DTSS_BUMPENVMAT10);
147 _DUMP_TS_FLOAT(D3DTSS_BUMPENVMAT11);
148 _DUMP_TS_INT(D3DTSS_TEXCOORDINDEX);
149 _DUMP_TS_FLOAT(D3DTSS_BUMPENVLSCALE);
150 _DUMP_TS_FLOAT(D3DTSS_BUMPENVLOFFSET);
151 _DUMP_TS_INT(D3DTSS_TEXTURETRANSFORMFLAGS);
152 _DUMP_TS_INT(D3DTSS_COLORARG0);
153 _DUMP_TS_INT(D3DTSS_ALPHAARG0);
154 _DUMP_TS_INT(D3DTSS_RESULTARG);
155
156 writer.endObject();
157 writer.endMember();
158 }
159
160#undef _DUMP_TS_INT
161#undef _DUMP_TS_FLOAT
162}
163
164static void
165dumpViewport(StateWriter &writer, IDirect3DDevice8 *pDevice)
166{
167 writer.beginMember("Viewport");
168 writer.beginObject();
169
170 D3DVIEWPORT8 vp;
171 pDevice->GetViewport(&vp);
172 writer.writeIntMember("X", vp.X);
173 writer.writeIntMember("Y", vp.Y);
174 writer.writeIntMember("Width", vp.Width);
175 writer.writeIntMember("Height", vp.Height);
176 writer.writeFloatMember("MinZ", vp.MinZ);
177 writer.writeFloatMember("MaxZ", vp.MaxZ);
178
179 writer.endObject();
180 writer.endMember();
181}
182
183static void
184dumpRenderstate(StateWriter &writer, IDirect3DDevice8 *pDevice)
185{
186#define _DUMP_RS_INT(x) { \
187 DWORD rsDword = 0; \
188 pDevice->GetRenderState(x, &rsDword); \
189 writer.writeIntMember(#x, rsDword); \
190}
191
192#define _DUMP_RS_FLOAT(x) { \
193 float rsFloat = 0.0f; \
194 pDevice->GetRenderState(x, (DWORD *)&rsFloat); \
195 writer.writeFloatMember(#x, rsFloat); \
196}
197
198 writer.beginMember("parameters");
199 writer.beginObject();
200
201 _DUMP_RS_INT(D3DRS_ZENABLE);
202 _DUMP_RS_INT(D3DRS_FILLMODE);
203 _DUMP_RS_INT(D3DRS_SHADEMODE);
204 _DUMP_RS_INT(D3DRS_ZWRITEENABLE);
205 _DUMP_RS_INT(D3DRS_ALPHATESTENABLE);
206 _DUMP_RS_INT(D3DRS_LASTPIXEL);
207 _DUMP_RS_INT(D3DRS_SRCBLEND);
208 _DUMP_RS_INT(D3DRS_DESTBLEND);
209 _DUMP_RS_INT(D3DRS_CULLMODE);
210 _DUMP_RS_INT(D3DRS_ZFUNC);
211 _DUMP_RS_INT(D3DRS_ALPHAREF);
212 _DUMP_RS_INT(D3DRS_ALPHAFUNC);
213 _DUMP_RS_INT(D3DRS_DITHERENABLE);
214 _DUMP_RS_INT(D3DRS_ALPHABLENDENABLE);
215 _DUMP_RS_INT(D3DRS_FOGENABLE);
216 _DUMP_RS_INT(D3DRS_SPECULARENABLE);
217 _DUMP_RS_INT(D3DRS_FOGCOLOR);
218 _DUMP_RS_INT(D3DRS_FOGTABLEMODE);
219 _DUMP_RS_FLOAT(D3DRS_FOGSTART);
220 _DUMP_RS_FLOAT(D3DRS_FOGEND);
221 _DUMP_RS_FLOAT(D3DRS_FOGDENSITY);
222 _DUMP_RS_INT(D3DRS_ZBIAS);
223 _DUMP_RS_INT(D3DRS_RANGEFOGENABLE);
224 _DUMP_RS_INT(D3DRS_STENCILENABLE);
225 _DUMP_RS_INT(D3DRS_STENCILFAIL);
226 _DUMP_RS_INT(D3DRS_STENCILZFAIL);
227 _DUMP_RS_INT(D3DRS_STENCILPASS);
228 _DUMP_RS_INT(D3DRS_STENCILFUNC);
229 _DUMP_RS_INT(D3DRS_STENCILREF);
230 _DUMP_RS_INT(D3DRS_STENCILMASK);
231 _DUMP_RS_INT(D3DRS_STENCILWRITEMASK);
232 _DUMP_RS_INT(D3DRS_TEXTUREFACTOR);
233 _DUMP_RS_INT(D3DRS_WRAP0);
234 _DUMP_RS_INT(D3DRS_WRAP1);
235 _DUMP_RS_INT(D3DRS_WRAP2);
236 _DUMP_RS_INT(D3DRS_WRAP3);
237 _DUMP_RS_INT(D3DRS_WRAP4);
238 _DUMP_RS_INT(D3DRS_WRAP5);
239 _DUMP_RS_INT(D3DRS_WRAP6);
240 _DUMP_RS_INT(D3DRS_WRAP7);
241 _DUMP_RS_INT(D3DRS_CLIPPING);
242 _DUMP_RS_INT(D3DRS_LIGHTING);
243 _DUMP_RS_FLOAT(D3DRS_AMBIENT);
244 _DUMP_RS_INT(D3DRS_FOGVERTEXMODE);
245 _DUMP_RS_INT(D3DRS_COLORVERTEX);
246 _DUMP_RS_INT(D3DRS_LOCALVIEWER);
247 _DUMP_RS_INT(D3DRS_NORMALIZENORMALS);
248 _DUMP_RS_INT(D3DRS_DIFFUSEMATERIALSOURCE);
249 _DUMP_RS_INT(D3DRS_SPECULARMATERIALSOURCE);
250 _DUMP_RS_INT(D3DRS_AMBIENTMATERIALSOURCE);
251 _DUMP_RS_INT(D3DRS_EMISSIVEMATERIALSOURCE);
252 _DUMP_RS_INT(D3DRS_VERTEXBLEND);
253 _DUMP_RS_INT(D3DRS_CLIPPLANEENABLE);
254 _DUMP_RS_FLOAT(D3DRS_POINTSIZE);
255 _DUMP_RS_FLOAT(D3DRS_POINTSIZE_MIN);
256 _DUMP_RS_INT(D3DRS_POINTSPRITEENABLE);
257 _DUMP_RS_INT(D3DRS_POINTSCALEENABLE);
258 _DUMP_RS_FLOAT(D3DRS_POINTSCALE_A);
259 _DUMP_RS_FLOAT(D3DRS_POINTSCALE_B);
260 _DUMP_RS_FLOAT(D3DRS_POINTSCALE_C);
261 _DUMP_RS_INT(D3DRS_MULTISAMPLEANTIALIAS);
262 _DUMP_RS_INT(D3DRS_MULTISAMPLEMASK);
263 _DUMP_RS_INT(D3DRS_PATCHEDGESTYLE);
264 _DUMP_RS_INT(D3DRS_DEBUGMONITORTOKEN);
265 _DUMP_RS_FLOAT(D3DRS_POINTSIZE_MAX);
266 _DUMP_RS_INT(D3DRS_INDEXEDVERTEXBLENDENABLE);
267 _DUMP_RS_INT(D3DRS_COLORWRITEENABLE);
268 _DUMP_RS_INT(D3DRS_TWEENFACTOR);
269 _DUMP_RS_INT(D3DRS_BLENDOP);
270 _DUMP_RS_INT(D3DRS_POSITIONORDER);
271 _DUMP_RS_INT(D3DRS_NORMALORDER);
272
273#undef _DUMP_RS_INT
274#undef _DUMP_RS_FLOAT
275
276 dumpViewport(writer, pDevice);
277
278 dumpTextureStates(writer, pDevice);
279
280 writer.endObject();
281 writer.endMember();
282}
283
José Fonsecacbb86172012-12-12 07:38:42 +0000284void
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100285dumpDevice(StateWriter &writer, IDirect3DDevice8 *pDevice)
José Fonsecacbb86172012-12-12 07:38:42 +0000286{
Jose Fonseca0c85d0b2016-09-21 12:08:38 +0100287 dumpRenderstate(writer, pDevice);
José Fonsecacbb86172012-12-12 07:38:42 +0000288
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100289 dumpShaders(writer, pDevice);
José Fonsecacbb86172012-12-12 07:38:42 +0000290
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100291 writer.beginMember("textures");
292 writer.beginObject();
293 writer.endObject();
294 writer.endMember(); // textures
José Fonsecacbb86172012-12-12 07:38:42 +0000295
Jose Fonsecae8ba0792015-05-01 12:38:03 +0100296 dumpFramebuffer(writer, pDevice);
José Fonsecacbb86172012-12-12 07:38:42 +0000297}
298
299
300} /* namespace d3dstate */