diff options
| author | hrydgard <hrydgard@gmail.com> | 2008-11-25 21:15:31 +0000 |
|---|---|---|
| committer | hrydgard <hrydgard@gmail.com> | 2008-11-25 21:15:31 +0000 |
| commit | 30a5c91c995f1d51460caa53beba221bd74a0acf (patch) | |
| tree | eb0ebffd0587145460b9e6d9a109c9ceef982c16 /Source | |
| parent | f1ab625f5c93d44931eab0daa2c998af4c286ed7 (diff) | |
GL: Safer vertex loading (should fix the new zelda crash), added vertex format logging to "show some statistics"
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1295 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source')
7 files changed, 85 insertions, 37 deletions
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 573aa9cdbf..b962d6cac0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -39,6 +39,7 @@ #include "rasterfont.h"
#include "VertexShader.h"
#include "PixelShaderManager.h"
+#include "VertexLoaderManager.h"
#include "VertexLoader.h"
#include "XFB.h"
#if !defined(OSX64)
@@ -791,7 +792,11 @@ void Renderer::SwapBuffers() p+=sprintf(p,"Num BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
p+=sprintf(p,"Num vertex loaders: %i\n",stats.numVertexLoaders);
- Renderer::RenderText(st, 20, 20, 0xFF00FFFF);
+
+ std::string text = st;
+ VertexLoaderManager::AppendListToString(&text);
+
+ Renderer::RenderText(text.c_str(), 20, 20, 0xFF00FFFF);
}
else
{
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp index c426359b60..8d335467c5 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp @@ -23,6 +23,7 @@ #include "Config.h"
#include "Profiler.h"
#include "MemoryUtil.h"
+#include "StringUtil.h"
#include "x64Emitter.h"
#include "ABI.h"
@@ -110,6 +111,7 @@ void LOADERDECL TexMtx_Write_Short3() VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr)
{
+ m_numLoadedVertices = 0;
m_VertexSize = 0;
m_numPipelineStages = 0;
m_NativeFmt = new NativeVertexFormat();
@@ -135,9 +137,18 @@ void VertexLoader::CompileVertexTranslator() {
m_VertexSize = 0;
+#ifdef USE_JIT
u8 *old_code_ptr = GetWritableCodePtr();
SetCodePtr(m_compiledCode);
ABI_EmitPrologue(4);
+
+ // Start loop here
+ MOV(32, M(&tcIndex), Imm32(0));
+ MOV(32, M(&colIndex), Imm32(0));
+ MOV(32, M(&s_texmtxwrite), Imm32(0));
+ MOV(32, M(&s_texmtxread), Imm32(0));
+#endif
+
// Colors
const int col[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1};
// TextureCoord
@@ -450,6 +461,9 @@ void VertexLoader::CompileVertexTranslator() if (vtx_decl.stride != offset)
PanicAlert("offset/stride mismatch, %i %i", vtx_decl.stride, offset);
#ifdef USE_JIT
+ // End loop here
+ // SUB(32, M(&vtxCounter), Imm8(1));
+ // J_CC(CC_NZ, loop);
ABI_EmitEpilogue(4);
#endif
SetCodePtr(old_code_ptr);
@@ -565,6 +579,8 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) {
DVSTARTPROFILE();
+ m_numLoadedVertices += count;
+
// Flush if our vertex format is different from the currently set.
if (g_nativeVertexFmt != NULL && g_nativeVertexFmt != m_NativeFmt)
{
@@ -618,15 +634,9 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) if (VertexManager::GetRemainingSize() < 2 * native_stride)
VertexManager::Flush();
break;
- case 0: // quads
- granularity = 4;
- break;
- case 2: // tris
- granularity = 3;
- break;
- case 5: // lines
- granularity = 2;
- break;
+ case 0: granularity = 4; break; // quads
+ case 2: granularity = 3; break; // tris
+ case 5: granularity = 2; break; // lines
}
int startv = 0, extraverts = 0;
@@ -634,7 +644,8 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) while (v < count)
{
- if (VertexManager::GetRemainingSize() < granularity*native_stride) {
+ int remainingVerts = VertexManager::GetRemainingSize() / native_stride;
+ if (remainingVerts < granularity) {
INCSTAT(stats.thisFrame.numBufferSplits);
// This buffer full - break current primitive and flush, to switch to the next buffer.
u8* plastptr = VertexManager::s_pCurBufferPointer;
@@ -675,22 +686,26 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) }
startv = v;
}
+ int remainingPrims = remainingVerts / granularity;
+ remainingVerts = remainingPrims * granularity;
+ if (count - v < remainingVerts)
+ remainingVerts = count - v;
- for (int s = 0; s < granularity; s++)
+ // Clean tight loader loop. Todo - build the loop into the JIT code.
+ for (int s = 0; s < remainingVerts; s++)
{
- tcIndex = 0;
- colIndex = 0;
- s_texmtxwrite = s_texmtxread = 0;
#ifdef USE_JIT
((void (*)())(void*)m_compiledCode)();
#else
+ tcIndex = 0;
+ colIndex = 0;
+ s_texmtxwrite = s_texmtxread = 0;
for (int i = 0; i < m_numPipelineStages; i++)
m_PipelineStages[i]();
#endif
-
PRIM_LOG("\n");
- v++;
}
+ v += remainingVerts;
}
if (startv < count)
@@ -742,3 +757,18 @@ void VertexLoader::SetVAT(u32 _group0, u32 _group1, u32 _group2) m_VtxAttr.texCoord[7].Format = vat.g2.Tex7CoordFormat;
m_VtxAttr.texCoord[7].Frac = vat.g2.Tex7Frac;
};
+
+void VertexLoader::AppendToString(std::string *dest) {
+ static const char *posMode[4] = {
+ "Invalid",
+ "Direct",
+ "Idx8",
+ "Idx16",
+ };
+ static const char *posFormats[5] = {
+ "u8", "s8", "u16", "s16", "flt",
+ };
+ dest->append(StringFromFormat("sz: %i skin: %i Pos: %i %s %s Nrm: %i %s %s - %i vtx\n",
+ m_VertexSize, m_VtxDesc.PosMatIdx, m_VtxAttr.PosElements ? 3 : 2, posMode[m_VtxDesc.Position], posFormats[m_VtxAttr.PosFormat],
+ m_VtxAttr.NormalElements, posMode[m_VtxDesc.Normal], posFormats[m_VtxAttr.NormalFormat], m_numLoadedVertices));
+}
\ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h index 74586ad3db..b638ac9641 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h @@ -18,6 +18,8 @@ #ifndef _VERTEXLOADER_H
#define _VERTEXLOADER_H
+#include <string>
+
#include "CPMemory.h"
#include "DataReader.h"
@@ -59,6 +61,9 @@ public: int GetVertexSize() const {return m_VertexSize;}
void RunVertices(int vtx_attr_group, int primitive, int count);
+ // For debugging / profiling
+ void AppendToString(std::string *dest);
+
private:
enum
{
@@ -83,6 +88,8 @@ private: u8 *m_compiledCode;
+ int m_numLoadedVertices;
+
void SetupColor(int num, int _iMode, int _iFormat, int _iElements);
void SetupTexCoord(int num, int _iMode, int _iFormat, int _iElements, int _iFrac);
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.cpp index 447115db8e..464faf989f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.cpp @@ -50,6 +50,14 @@ void Shutdown() g_VertexLoaderMap.clear();
}
+void AppendListToString(std::string *dest)
+{
+ for (VertexLoaderMap::iterator iter = g_VertexLoaderMap.begin(); iter != g_VertexLoaderMap.end(); ++iter)
+ {
+ iter->second->AppendToString(dest);
+ }
+}
+
void MarkAllDirty()
{
s_attr_dirty = 0xff;
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.h index 8af8416474..ed07309210 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.h @@ -30,6 +30,9 @@ namespace VertexLoaderManager int GetVertexSize(int vtx_attr_group);
void RunVertices(int vtx_attr_group, int primitive, int count);
+ // For debugging
+ void AppendListToString(std::string *dest);
+
// TODO - don't expose these like this.
// static u8* s_pCurBufferPointer;
};
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index a772813fa7..c62791c989 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -85,19 +85,6 @@ void ResetBuffer() s_vStoredPrimitives.resize(0);
}
-void ResetComponents()
-{
- s_prevcomponents = 0;
- glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableVertexAttribArray(SHADER_NORM1_ATTRIB);
- glDisableVertexAttribArray(SHADER_NORM2_ATTRIB);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
- for (int i = 0; i < 8; i++)
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-}
-
int GetRemainingSize()
{
return MAX_BUFFER_SIZE - (int)(s_pCurBufferPointer - s_pBaseBufferPointer);
@@ -108,12 +95,21 @@ void AddVertices(int primitive, int numvertices) _assert_( numvertices > 0 );
ADDSTAT(stats.thisFrame.numPrims, numvertices);
- /*
- if (s_vStoredPrimitives.size() && s_vStoredPrimitives[s_vStoredPrimitives.size() - 1].first == primitive) {
- // Actually, just count potential primitive joins.
- // Doesn't seem worth it in Metroid Prime games.
- INCSTAT(stats.thisFrame.numPrimitiveJoins);
- }*/
+ if (s_vStoredPrimitives.size() && s_vStoredPrimitives[s_vStoredPrimitives.size() - 1].first == c_primitiveType[primitive]) {
+ // We can join primitives for free here. Not likely to help much, though, but whatever...
+ if (c_primitiveType[primitive] == GL_TRIANGLES ||
+ c_primitiveType[primitive] == GL_LINES ||
+ c_primitiveType[primitive] == GL_POINTS ||
+ c_primitiveType[primitive] == GL_QUADS) {
+ INCSTAT(stats.thisFrame.numPrimitiveJoins);
+ // Easy join
+ std::pair<int, int> &last_pair = s_vStoredPrimitives[s_vStoredPrimitives.size() - 1];
+ last_pair.second += numvertices;
+ return;
+ }
+ // Joining strips is a lot more work but would bring more gain. Not sure if it's worth it though.
+ }
+
s_vStoredPrimitives.push_back(std::pair<int, int>(c_primitiveType[primitive], numvertices));
#if defined(_DEBUG) || defined(DEBUGFAST)
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h index 214824f1d7..84e051ec03 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h @@ -30,7 +30,6 @@ bool Init(); void Shutdown();
void ResetBuffer();
-void ResetComponents();
void AddVertices(int primitive, int numvertices);
void Flush(); // flushes the current buffer
|
