~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Source/Core/VideoBackends/Software/Src/DebugUtil.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Dolphin Emulator Project
 
2
// Licensed under GPLv2
 
3
// Refer to the license.txt file included.
 
4
 
 
5
#include "Common.h"
 
6
 
 
7
#include "DebugUtil.h"
 
8
#include "BPMemLoader.h"
 
9
#include "TextureSampler.h"
 
10
#include "SWVideoConfig.h"
 
11
#include "EfbInterface.h"
 
12
#include "SWStatistics.h"
 
13
#include "HwRasterizer.h"
 
14
#include "StringUtil.h"
 
15
#include "SWCommandProcessor.h"
 
16
#include "ImageWrite.h"
 
17
#include "FileUtil.h"
 
18
 
 
19
namespace DebugUtil
 
20
{
 
21
 
 
22
u32 skipFrames = 0;
 
23
bool drawingHwTriangles = false;
 
24
 
 
25
enum { NumObjectBuffers = 40};
 
26
 
 
27
u32 ObjectBuffer[NumObjectBuffers][EFB_WIDTH*EFB_HEIGHT];
 
28
u32 TempBuffer[NumObjectBuffers];
 
29
 
 
30
bool DrawnToBuffer[NumObjectBuffers];
 
31
const char* ObjectBufferName[NumObjectBuffers];
 
32
int BufferBase[NumObjectBuffers];
 
33
 
 
34
void Init()
 
35
{
 
36
        for (int i = 0; i < NumObjectBuffers; i++)
 
37
        {
 
38
                memset(ObjectBuffer[i], 0, sizeof(ObjectBuffer[i]));
 
39
                DrawnToBuffer[i] = false;
 
40
                ObjectBufferName[i] = 0;
 
41
                BufferBase[i] = 0;
 
42
        }
 
43
}
 
44
 
 
45
void SaveTexture(const char* filename, u32 texmap, s32 mip)
 
46
{
 
47
        FourTexUnits& texUnit = bpmem.tex[(texmap >> 2) & 1];
 
48
        u8 subTexmap = texmap & 3;
 
49
 
 
50
        TexImage0& ti0 = texUnit.texImage0[subTexmap];
 
51
 
 
52
        u32 width = ti0.width + 1;
 
53
        u32 height = ti0.height + 1;
 
54
 
 
55
        u8 *data = new u8[width * height * 4];
 
56
 
 
57
        GetTextureBGRA(data, texmap, mip, width, height);
 
58
 
 
59
        (void)SaveTGA(filename, width, height, data);
 
60
 
 
61
        delete []data;
 
62
}
 
63
 
 
64
void GetTextureBGRA(u8 *dst, u32 texmap, s32 mip, u32 width, u32 height)
 
65
{
 
66
        u8 sample[4];
 
67
 
 
68
        for (u32 y = 0; y < height; y++)
 
69
        {
 
70
                for (u32 x = 0; x < width; x++)
 
71
                {
 
72
                        TextureSampler::SampleMip(x << 7, y << 7, mip, false, texmap, sample);
 
73
 
 
74
                        // RGBA to BGRA
 
75
                        *(dst++) = sample[2];
 
76
                        *(dst++) = sample[1];
 
77
                        *(dst++) = sample[0];
 
78
                        *(dst++) = sample[3];
 
79
                }
 
80
        }
 
81
}
 
82
 
 
83
s32 GetMaxTextureLod(u32 texmap)
 
84
{
 
85
        FourTexUnits& texUnit = bpmem.tex[(texmap >> 2) & 1];
 
86
        u8 subTexmap = texmap & 3;
 
87
 
 
88
        u8 maxLod = texUnit.texMode1[subTexmap].max_lod;
 
89
        u8 mip = maxLod >> 4;
 
90
        u8 fract = maxLod & 0xf;
 
91
 
 
92
        if(fract)
 
93
                ++mip;
 
94
 
 
95
        return (s32)mip;
 
96
}
 
97
 
 
98
void DumpActiveTextures()
 
99
{
 
100
        for (unsigned int stageNum = 0; stageNum < bpmem.genMode.numindstages; stageNum++)
 
101
        {
 
102
                u32 texmap = bpmem.tevindref.getTexMap(stageNum);
 
103
 
 
104
                s32 maxLod = GetMaxTextureLod(texmap);
 
105
                for (s32 mip = 0; mip <= maxLod; ++mip)
 
106
                {
 
107
                        SaveTexture(StringFromFormat("%star%i_ind%i_map%i_mip%i.tga",
 
108
                                                File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
 
109
                                                swstats.thisFrame.numDrawnObjects, stageNum, texmap, mip).c_str(), texmap, mip);
 
110
                }
 
111
        }
 
112
 
 
113
        for (unsigned int stageNum = 0; stageNum <= bpmem.genMode.numtevstages; stageNum++)
 
114
        {
 
115
                int stageNum2 = stageNum >> 1;
 
116
                int stageOdd = stageNum&1;
 
117
                TwoTevStageOrders &order = bpmem.tevorders[stageNum2];
 
118
 
 
119
                int texmap = order.getTexMap(stageOdd);
 
120
 
 
121
                s32 maxLod = GetMaxTextureLod(texmap);
 
122
                for (s32 mip = 0; mip <= maxLod; ++mip)
 
123
                {
 
124
                        SaveTexture(StringFromFormat("%star%i_stage%i_map%i_mip%i.tga",
 
125
                                                File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
 
126
                                                swstats.thisFrame.numDrawnObjects, stageNum, texmap, mip).c_str(), texmap, mip);
 
127
                }
 
128
        }
 
129
}
 
130
 
 
131
void DumpEfb(const char* filename)
 
132
{
 
133
        u8 *data = new u8[EFB_WIDTH * EFB_HEIGHT * 4];
 
134
        u8 *writePtr = data;
 
135
        u8 sample[4];
 
136
 
 
137
        for (int y = 0; y < EFB_HEIGHT; y++)
 
138
        {
 
139
                for (int x = 0; x < EFB_WIDTH; x++)
 
140
                {
 
141
                        EfbInterface::GetColor(x, y, sample);
 
142
                        // ABGR to BGRA
 
143
                        *(writePtr++) = sample[1];
 
144
                        *(writePtr++) = sample[2];
 
145
                        *(writePtr++) = sample[3];
 
146
                        *(writePtr++) = sample[0];
 
147
                }
 
148
        }
 
149
 
 
150
        (void)SaveTGA(filename, EFB_WIDTH, EFB_HEIGHT, data);
 
151
 
 
152
        delete []data;
 
153
}
 
154
 
 
155
void DumpDepth(const char* filename)
 
156
{
 
157
        u8 *data = new u8[EFB_WIDTH * EFB_HEIGHT * 4];
 
158
        u8 *writePtr = data;
 
159
 
 
160
        for (int y = 0; y < EFB_HEIGHT; y++)
 
161
        {
 
162
                for (int x = 0; x < EFB_WIDTH; x++)
 
163
                {
 
164
                        u32 depth = EfbInterface::GetDepth(x, y);
 
165
                        // depth to bgra
 
166
                        *(writePtr++) = (depth >> 16) & 0xff;
 
167
                        *(writePtr++) = (depth >> 8) & 0xff;
 
168
                        *(writePtr++) = depth & 0xff;
 
169
                        *(writePtr++) = 255;
 
170
                }
 
171
        }
 
172
 
 
173
        (void)SaveTGA(filename, EFB_WIDTH, EFB_HEIGHT, data);
 
174
 
 
175
        delete []data;
 
176
}
 
177
 
 
178
void DrawObjectBuffer(s16 x, s16 y, u8 *color, int bufferBase, int subBuffer, const char *name)
 
179
{
 
180
        int buffer = bufferBase + subBuffer;
 
181
 
 
182
        u32 offset = (x + y * EFB_WIDTH) * 4;
 
183
        u8 *dst = (u8*)&ObjectBuffer[buffer][offset];
 
184
        *(dst++) = color[2];
 
185
        *(dst++) = color[1];
 
186
        *(dst++) = color[0];
 
187
        *(dst++) = color[3];
 
188
 
 
189
        DrawnToBuffer[buffer] = true;
 
190
        ObjectBufferName[buffer] = name;
 
191
        BufferBase[buffer] = bufferBase;
 
192
}
 
193
 
 
194
void DrawTempBuffer(u8 *color, int buffer)
 
195
{
 
196
        u8 *dst = (u8*)&TempBuffer[buffer];
 
197
        *(dst++) = color[2];
 
198
        *(dst++) = color[1];
 
199
        *(dst++) = color[0];
 
200
        *(dst++) = color[3];
 
201
}
 
202
 
 
203
void CopyTempBuffer(s16 x, s16 y, int bufferBase, int subBuffer, const char *name)
 
204
{
 
205
        int buffer = bufferBase + subBuffer;
 
206
 
 
207
        u32 offset = (x + y * EFB_WIDTH);
 
208
        ObjectBuffer[buffer][offset] = TempBuffer[buffer];
 
209
 
 
210
        DrawnToBuffer[buffer] = true;
 
211
        ObjectBufferName[buffer] = name;
 
212
        BufferBase[buffer] = bufferBase;
 
213
}
 
214
 
 
215
void OnObjectBegin()
 
216
{
 
217
        if (!g_bSkipCurrentFrame)
 
218
        {
 
219
                if (g_SWVideoConfig.bDumpTextures && swstats.thisFrame.numDrawnObjects >= g_SWVideoConfig.drawStart && swstats.thisFrame.numDrawnObjects < g_SWVideoConfig.drawEnd)
 
220
                        DumpActiveTextures();
 
221
 
 
222
                if (g_SWVideoConfig.bHwRasterizer)
 
223
                {
 
224
                        HwRasterizer::BeginTriangles();
 
225
                        drawingHwTriangles = true;
 
226
                }
 
227
        }
 
228
}
 
229
 
 
230
void OnObjectEnd()
 
231
{
 
232
        if (!g_bSkipCurrentFrame)
 
233
        {
 
234
                if (g_SWVideoConfig.bDumpObjects && swstats.thisFrame.numDrawnObjects >= g_SWVideoConfig.drawStart && swstats.thisFrame.numDrawnObjects < g_SWVideoConfig.drawEnd)
 
235
                        DumpEfb(StringFromFormat("%sobject%i.tga",
 
236
                                                File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
 
237
                                                swstats.thisFrame.numDrawnObjects).c_str());
 
238
 
 
239
                if (g_SWVideoConfig.bHwRasterizer || drawingHwTriangles)
 
240
                {
 
241
                        HwRasterizer::EndTriangles();
 
242
                        drawingHwTriangles = false;
 
243
                }
 
244
 
 
245
                for (int i = 0; i < NumObjectBuffers; i++)
 
246
                {
 
247
                        if (DrawnToBuffer[i])
 
248
                        {
 
249
                                DrawnToBuffer[i] = false;
 
250
                                (void)SaveTGA(StringFromFormat("%sobject%i_%s(%i).tga",
 
251
                                                        File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
 
252
                                                        swstats.thisFrame.numDrawnObjects, ObjectBufferName[i], i - BufferBase[i]).c_str(),
 
253
                                                EFB_WIDTH, EFB_HEIGHT, ObjectBuffer[i]);
 
254
                                memset(ObjectBuffer[i], 0, sizeof(ObjectBuffer[i]));
 
255
                        }
 
256
                }
 
257
 
 
258
                swstats.thisFrame.numDrawnObjects++;
 
259
        }
 
260
}
 
261
 
 
262
void OnFrameEnd()
 
263
{
 
264
        if (!g_bSkipCurrentFrame)
 
265
        {
 
266
                if (g_SWVideoConfig.bDumpFrames)
 
267
                {
 
268
                        DumpEfb(StringFromFormat("%sframe%i_color.tga",
 
269
                                                File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount).c_str());
 
270
                        DumpDepth(StringFromFormat("%sframe%i_depth.tga",
 
271
                                                File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), swstats.frameCount).c_str());
 
272
                }
 
273
        }
 
274
}
 
275
 
 
276
}