diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.h b/Source/Core/VideoCommon/Src/VertexManagerBase.h index 159e9ee52f..258d7e0c67 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.h +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.h @@ -39,6 +39,11 @@ public: virtual ::NativeVertexFormat* CreateNativeVertexFormat() = 0; + static u16* GetTriangleIndexBuffer() { return TIBuffer; } + static u16* GetLineIndexBuffer() { return LIBuffer; } + static u16* GetPointIndexBuffer() { return PIBuffer; } + static u8* GetVertexBuffer() { return LocalVBuffer; } + protected: // TODO: make private after Flush() is merged static void ResetBuffer(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp index 75fd76b2da..83b6e78a44 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Debugger/Debugger.cpp @@ -21,14 +21,17 @@ #include "FileUtil.h" #include "VideoConfig.h" +#include "IndexGenerator.h" #include "../Globals.h" #include "../D3DBase.h" #include "../FramebufferManager.h" #include "../TextureCache.h" #include "../VertexShaderCache.h" #include "../PixelShaderCache.h" +#include "../VertexManager.h" extern int g_Preset; +extern NativeVertexFormat *g_nativeVertexFmt; BEGIN_EVENT_TABLE(GFXDebuggerDX9, wxPanel) EVT_CLOSE(GFXDebuggerDX9::OnClose) @@ -313,39 +316,36 @@ void GFXDebuggerDX9::OnPauseAtNextFrameButton(wxCommandEvent& event) void GFXDebuggerDX9::OnDumpButton(wxCommandEvent& event) { + char dump_path[MAX_PATH]; + sprintf(dump_path, "%sDebug/%s", File::GetUserPath(D_DUMP_IDX), globals->unique_id); + if (!File::Exists(dump_path) || !File::IsDirectory(dump_path)) + if (!File::CreateDir(dump_path)) + return; + switch (m_pDumpList->GetSelection()) { case 0: // Pixel Shader { -#if defined(_DEBUG) || defined(DEBUGFAST) char filename[MAX_PATH]; - sprintf(filename, "%s/Debug/%s/dump_ps.txt", File::GetUserPath(D_DUMP_IDX), globals->unique_id); + sprintf(filename, "%s/dump_ps.txt", dump_path); File::CreateEmptyFile(filename); File::WriteStringToFile(true, PixelShaderCache::GetCurrentShaderCode(), filename); -#else - MessageBox(NULL, L"Dumping pixel shaders not supported in Release builds!", L"Error", MB_OK); -#endif break; } case 1: // Vertex Shader { -#if defined(_DEBUG) || defined(DEBUGFAST) char filename[MAX_PATH]; - sprintf(filename, "%s/Debug/%s/dump_vs.txt", File::GetUserPath(D_DUMP_IDX), globals->unique_id); + sprintf(filename, "%s/dump_vs.txt", dump_path); File::CreateEmptyFile(filename); File::WriteStringToFile(true, VertexShaderCache::GetCurrentShaderCode(), filename); -#else - MessageBox(NULL, L"Dumping vertex shaders not supported in Release builds!", L"Error", MB_OK); -#endif break; } case 2: // Pixel Shader Constants { char filename[MAX_PATH]; - sprintf(filename, "%s/Debug/%s/dump_ps_consts.txt", File::GetUserPath(D_DUMP_IDX), globals->unique_id); - + sprintf(filename, "%s/dump_ps_consts.txt", dump_path); FILE* file = fopen(filename, "w"); float constants[4*C_PENVCONST_END]; @@ -379,14 +379,13 @@ void GFXDebuggerDX9::OnDumpButton(wxCommandEvent& event) fprintf(file, "Constant COLORMATRIX %d: %f %f %f %f\n", i, constants[4*i], constants[4*i+1], constants[4*i+2], constants[4*i+3]); fclose(file); - break; } case 3: // Vertex Shader Constants { char filename[MAX_PATH]; - sprintf(filename, "%s/Debug/%s/dump_vs_consts.txt", File::GetUserPath(D_DUMP_IDX), globals->unique_id); + sprintf(filename, "%s/dump_vs_consts.txt", dump_path); FILE* file = fopen(filename, "w"); float constants[4*C_VENVCONST_END]; @@ -437,7 +436,7 @@ void GFXDebuggerDX9::OnDumpButton(wxCommandEvent& event) D3D::dev->GetTexture(stage, (IDirect3DBaseTexture9**)&texture); if(!texture) break; char filename[MAX_PATH]; - sprintf(filename, "%s/Debug/%s/dump_tex%d.png", File::GetUserPath(D_DUMP_IDX), globals->unique_id, stage); + sprintf(filename, "%s/dump_tex%d.png", dump_path, stage); IDirect3DSurface9* surface; texture->GetSurfaceLevel(0, &surface); HRESULT hr = PD3DXSaveSurfaceToFileA(filename, D3DXIFF_PNG, surface, NULL, NULL); @@ -453,17 +452,131 @@ void GFXDebuggerDX9::OnDumpButton(wxCommandEvent& event) break; case 13: // Vertices + { + D3DVERTEXELEMENT9* elements; + int num_elements; + ((DX9::VertexManager*)g_vertex_manager)->GetElements(g_nativeVertexFmt, &elements, &num_elements); + if (elements == NULL || num_elements == 0) + return; + + char filename[MAX_PATH]; + sprintf(filename, "%s/vertex_dump.txt", dump_path); + FILE* file = fopen(filename, "w"); + + u8* vertices = g_vertex_manager->GetVertexBuffer(); + u16* tri_indices = g_vertex_manager->GetTriangleIndexBuffer(); + u16* line_indices = g_vertex_manager->GetLineIndexBuffer(); + u16* point_indices = g_vertex_manager->GetPointIndexBuffer(); + + fprintf(file, "VERTICES\n"); + for (int i = 0; i < IndexGenerator::GetNumVerts(); ++i) + { + u8* cur_vertex = vertices + i * g_nativeVertexFmt->GetVertexStride(); + for (int elem = 0; elem < num_elements; elem++) + { + switch (elements[elem].Type) + { + case D3DDECLTYPE_FLOAT1: + fprintf(file, "%f\t", *(float*)&cur_vertex[elements[elem].Offset]); + break; + case D3DDECLTYPE_FLOAT2: + fprintf(file, "%f ", *(float*)&cur_vertex[elements[elem].Offset]); + fprintf(file, "%f\t", *(float*)&cur_vertex[4+elements[elem].Offset]); + break; + case D3DDECLTYPE_FLOAT3: + fprintf(file, "%f ", *(float*)&cur_vertex[elements[elem].Offset]); + fprintf(file, "%f ", *(float*)&cur_vertex[4+elements[elem].Offset]); + fprintf(file, "%f\t", *(float*)&cur_vertex[8+elements[elem].Offset]); + break; + case D3DDECLTYPE_FLOAT4: + fprintf(file, "%f ", *(float*)&cur_vertex[elements[elem].Offset]); + fprintf(file, "%f ", *(float*)&cur_vertex[4+elements[elem].Offset]); + fprintf(file, "%f ", *(float*)&cur_vertex[8+elements[elem].Offset]); + fprintf(file, "%f\t", *(float*)&cur_vertex[12+elements[elem].Offset]); + break; + case D3DDECLTYPE_UBYTE4N: + fprintf(file, "%f ", (float)(*(u8*)&cur_vertex[elements[elem].Offset])/255.f); + fprintf(file, "%f ", (float)(*(u8*)&cur_vertex[1+elements[elem].Offset])/255.f); + fprintf(file, "%f ", (float)(*(u8*)&cur_vertex[2+elements[elem].Offset])/255.f); + fprintf(file, "%f\t", (float)(*(u8*)&cur_vertex[3+elements[elem].Offset])/255.f); + break; + case D3DDECLTYPE_SHORT2N: + fprintf(file, "%f ", (float)(*(s16*)&cur_vertex[elements[elem].Offset])/32767.f); + fprintf(file, "%f\t", (float)(*(s16*)&cur_vertex[2+elements[elem].Offset])/32767.f); + break; + case D3DDECLTYPE_SHORT4N: + fprintf(file, "%f ", (float)(*(s16*)&cur_vertex[elements[elem].Offset])/32767.f); + fprintf(file, "%f ", (float)(*(s16*)&cur_vertex[2+elements[elem].Offset])/32767.f); + fprintf(file, "%f ", (float)(*(s16*)&cur_vertex[4+elements[elem].Offset])/32767.f); + fprintf(file, "%f\t", (float)(*(s16*)&cur_vertex[6+elements[elem].Offset])/32767.f); + break; + case D3DDECLTYPE_USHORT2N: + fprintf(file, "%f ", (float)(*(u16*)&cur_vertex[elements[elem].Offset])/65535.f); + fprintf(file, "%f\t", (float)(*(u16*)&cur_vertex[2+elements[elem].Offset])/65535.f); + break; + case D3DDECLTYPE_USHORT4N: + fprintf(file, "%f ", (float)(*(u16*)&cur_vertex[elements[elem].Offset])/65535.f); + fprintf(file, "%f ", (float)(*(u16*)&cur_vertex[2+elements[elem].Offset])/65535.f); + fprintf(file, "%f ", (float)(*(u16*)&cur_vertex[4+elements[elem].Offset])/65535.f); + fprintf(file, "%f\t", (float)(*(u16*)&cur_vertex[6+elements[elem].Offset])/65535.f); + break; + } + fprintf(file, "\t"); + } + fprintf(file, "\n"); + } + + fprintf(file, "\nTRIANGLE INDICES\n"); + for (int i = 0; i < IndexGenerator::GetNumTriangles(); ++i) + fprintf(file, "%d\t%d\t%d\n", tri_indices[3*i], tri_indices[3*i+1], tri_indices[3*i+2]); + + fprintf(file, "\nLINE INDICES\n"); + for (int i = 0; i < IndexGenerator::GetNumLines(); ++i) + fprintf(file, "%d\t%d\n", line_indices[2*i], line_indices[2*i+1]); + + fprintf(file, "\nPOINT INDICES\n"); + for (int i = 0; i < IndexGenerator::GetNumPoints(); ++i) + fprintf(file, "%d\n", point_indices[i]); + + fclose(file); break; + } case 14: // Vertex Description - break; + { + D3DVERTEXELEMENT9* elements; + int num_elements; + ((DX9::VertexManager*)g_vertex_manager)->GetElements(g_nativeVertexFmt, &elements, &num_elements); + if (elements == NULL || num_elements == 0) + return; + char filename[MAX_PATH]; + sprintf(filename, "%s/vertex_decl.txt", dump_path); + FILE* file = fopen(filename, "w"); + + fprintf(file, "Index\tOffset\tType\t\tUsage\t\tUsageIndex\n"); + for (int i = 0; i < num_elements; ++i) + { + const char* types[] = { + "FLOAT1 " , "FLOAT2 ", "FLOAT3 ", "FLOAT4 ", "D3DCOLOR", "UBYTE4 ", "SHORT2 ", "SHORT4 ", + "UBYTE4N " , "SHORT2N ", "SHORT4N ", "USHORT2N", "USHORT4N", "UDEC3 ", "DEC3N ", "FLOAT16_2", + "FLOAT16_4", "UNUSED ", + }; + const char* usages[] = { + "POSITION ", "BLENDWEIGHT ", "BLENDINDICES", "NORMAL ", "PSIZE ", "TEXCOORD ", "TANGENT ", "BINORMAL ", + "TESSFACTOR ", "POSITIONT ", "COLOR ", "FOG ", "DEPTH ", "SAMPLE ", + }; + fprintf(file, "%d\t%d\t%s\t%s\t%d\n", i, elements[i].Offset, types[elements[i].Type], usages[elements[i].Usage], elements[i].UsageIndex); + } + + fclose(file); + break; + } case 15: // Vertex Matrices break; case 16: // Statistics break; - } } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp index 13a7c37d36..a05883bab1 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp @@ -37,6 +37,11 @@ public: ~D3DVertexFormat(); virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); virtual void SetupVertexPointers() const; + +#if defined(_DEBUG) || defined(DEBUGFAST) + D3DVERTEXELEMENT9 elements[32]; + int num_elements; +#endif }; namespace DX9 @@ -49,6 +54,17 @@ NativeVertexFormat* VertexManager::CreateNativeVertexFormat() } +void DX9::VertexManager::GetElements(NativeVertexFormat* format, D3DVERTEXELEMENT9** elems, int* num) +{ +#if defined(_DEBUG) || defined(DEBUGFAST) + *elems = ((D3DVertexFormat*)format)->elements; + *num = ((D3DVertexFormat*)format)->num_elements; +#else + *elems = NULL; + *num = 0; +#endif +} + D3DVertexFormat::~D3DVertexFormat() { if (d3d_decl) @@ -163,6 +179,10 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) PanicAlert("Failed to create D3D vertex declaration!"); return; } +#if defined(_DEBUG) || defined(DEBUGFAST) + memcpy(&elements, elems, sizeof(elems)); + num_elements = elem_idx; +#endif } void D3DVertexFormat::SetupVertexPointers() const diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index 4732c58631..55247939de 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -352,6 +352,8 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) } #endif delete [] bytecode; + + DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true); return result; } @@ -381,12 +383,12 @@ bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytec } -#if defined(_DEBUG) || defined(DEBUGFAST) std::string PixelShaderCache::GetCurrentShaderCode() { +#if defined(_DEBUG) || defined(DEBUGFAST) if (last_entry) return last_entry->code; else - return "(no shader)\n"; -} #endif + return "(not available)\n"; +} diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h index 7291749080..0cfb29109f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h @@ -67,10 +67,7 @@ public: static LPDIRECT3DPIXELSHADER9 GetDepthMatrixProgram(int SSAAMode); static LPDIRECT3DPIXELSHADER9 GetClearProgram(); -#if defined(_DEBUG) || defined(DEBUGFAST) static std::string GetCurrentShaderCode(); -#endif - static LPDIRECT3DPIXELSHADER9 CompileCgShader(const char *pstrprogram); }; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 5cf0565e70..fa4d3fe3e7 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -1097,6 +1097,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons OSD::DrawMessages(); D3D::EndFrame(); + + DEBUGGER_PAUSE_AT(NEXT_FRAME,true); + frameCount++; DLCache::ProgressiveCleanup(); TextureCache::Cleanup(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index a70476a0d8..4bb33e1b2d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -66,6 +66,7 @@ bool TextureCache::TCacheEntry::Save(const char filename[]) void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, unsigned int expanded_width, unsigned int level, bool autogen_mips) { + DEBUGGER_PAUSE_AT(NEXT_TEXTURE_CHANGE,true); D3D::ReplaceTexture2D(texture, temp, width, height, expanded_width, d3d_fmt, swap_r_b, level); // D3D9 will automatically generate mip maps if necessary } @@ -214,6 +215,7 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, u entry->swap_r_b = swap_r_b; entry->d3d_fmt = d3d_fmt; + DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE,true); return entry; } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h index ee34e5c8b6..0d12616ac5 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h @@ -28,7 +28,9 @@ namespace DX9 class VertexManager : public ::VertexManager { +public: NativeVertexFormat* CreateNativeVertexFormat(); + void GetElements(NativeVertexFormat* format, D3DVERTEXELEMENT9** elems, int* num); private: void Draw(int stride); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 4310f5464b..1ab6fb2975 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -260,6 +260,7 @@ bool VertexShaderCache::SetShader(u32 components) } #endif delete [] bytecode; + DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE,true); return result; } @@ -286,12 +287,12 @@ bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, const u8 *byt return false; } -#if defined(_DEBUG) || defined(DEBUGFAST) std::string VertexShaderCache::GetCurrentShaderCode() { +#if defined(_DEBUG) || defined(DEBUGFAST) if (last_entry) return last_entry->code; else - return "(no shader)\n"; -} #endif + return "(not available)\n"; +} diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h index e855ecd3a7..63564fee07 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h @@ -58,10 +58,8 @@ public: static LPDIRECT3DVERTEXSHADER9 GetSimpleVertexShader(int level); static LPDIRECT3DVERTEXSHADER9 GetClearVertexShader(); static bool InsertByteCode(const VERTEXSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate); -#if defined(_DEBUG) || defined(DEBUGFAST) + static std::string GetCurrentShaderCode(); -#endif - static LPDIRECT3DVERTEXSHADER9 CompileCgShader(const char *pstrprogram); }; #endif // _VERTEXSHADERCACHE_H diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 7a4f5c1019..5ec9b2a301 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -180,7 +180,7 @@ void DllConfig(void *_hParent) { const D3D::Adapter &adapter = D3D::GetAdapter(g_Config.iAdapter); - for (int i = 0; i < adapter.aa_levels.size(); ++i) + for (int i = 0; i < (int)adapter.aa_levels.size(); ++i) g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name); }