diff --git a/Source/Core/VideoCommon/Src/NativeVertexFormat.h b/Source/Core/VideoCommon/Src/NativeVertexFormat.h index 817b5ded1f..42f925da01 100644 --- a/Source/Core/VideoCommon/Src/NativeVertexFormat.h +++ b/Source/Core/VideoCommon/Src/NativeVertexFormat.h @@ -62,13 +62,13 @@ typedef void (LOADERDECL *TPipelineFunction)(const void *); // The implementation of this class is specific for GL/DX, so NativeVertexFormat.cpp // is in the respective plugin, not here in VideoCommon. +// This class will also be split into NativeVertexFormat and VertexFormatConverter. +// VertexFormatConverters will be cached, indexed by TVtxDesc+TVtxAttr. + // Note that this class can't just invent arbitrary vertex formats out of its input - // all the data loading code must always be made compatible. class NativeVertexFormat { - void SetupColor(int num, int _iMode, int _iFormat, int _iElements); - void SetupTexCoord(int num, int _iMode, int _iFormat, int _iElements, int _iFrac); - public: NativeVertexFormat(); ~NativeVertexFormat(); @@ -76,6 +76,12 @@ public: void Initialize(const TVtxDesc &vtx_desc, const TVtxAttr &vtx_attr); void RunPipelineOnce(const TVtxAttr &vtx_attr) const; + void SetupVertexPointers() { + // Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to + // get around type checking errors, and call it. + ((void (*)())(void*)m_compiledCode)(); + } + // TODO: move these in under private: int m_VBVertexStride; // PC-side vertex stride int m_VBStridePad; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp index 1f4ee98bd4..a18f4dbaae 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp @@ -39,7 +39,7 @@ #include -extern void (*fnSetupVertexPointers)(); +NativeVertexFormat *g_nativeVertexFmt; //these don't need to be saved static float posScale; @@ -137,9 +137,6 @@ int VertexLoader::ComputeVertexSize() m_VtxDesc.Hex = VertexManager::GetVtxDesc().Hex; } - if (fnSetupVertexPointers != NULL && fnSetupVertexPointers == (void (*)())(void*)m_NativeFmt.m_compiledCode) - VertexManager::Flush(); - m_AttrDirty = AD_DIRTY; m_VertexSize = 0; // Position Matrix Index @@ -518,13 +515,18 @@ void VertexLoader::RunVertices(int primitive, int count) { DVSTARTPROFILE(); + // Flush if our vertex format is different from the currently set. + // TODO - this check should be moved. + if (g_nativeVertexFmt != NULL && g_nativeVertexFmt != &m_NativeFmt) + { + VertexManager::Flush(); + + // Also move the Set() here? + } + // This has dirty handling - won't actually recompute unless necessary. ComputeVertexSize(); - // Figure out a better check. Also, jitting fnSetupVertexPointers seems pretty silly - not likely to be a bottleneck. - if (fnSetupVertexPointers != NULL && fnSetupVertexPointers != (void (*)())(void*)m_NativeFmt.m_compiledCode) - VertexManager::Flush(); - if (bpmem.genMode.cullmode == 3 && primitive < 5) { // if cull mode is none, ignore triangles and quads @@ -535,7 +537,7 @@ void VertexLoader::RunVertices(int primitive, int count) // This has dirty handling - won't actually recompute unless necessary. PrepareForVertexFormat(); - fnSetupVertexPointers = (void (*)())(void*)m_NativeFmt.m_compiledCode; + g_nativeVertexFmt = &m_NativeFmt; VertexManager::EnableComponents(m_NativeFmt.m_components); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 8a572562c2..294bbbe8f7 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -41,7 +41,7 @@ static const GLenum c_primitiveType[8] = }; // internal state for loading vertices -void (*fnSetupVertexPointers)() = NULL; +extern NativeVertexFormat *g_nativeVertexFmt; bool VertexManager::Init() { @@ -60,7 +60,7 @@ bool VertexManager::Init() } glEnableClientState(GL_VERTEX_ARRAY); - fnSetupVertexPointers = NULL; + g_nativeVertexFmt = NULL; s_vStoredPrimitives.reserve(1000); GL_REPORT_ERRORD(); @@ -121,7 +121,6 @@ void VertexManager::Flush() if (s_vStoredPrimitives.size() == 0) return; - _assert_(fnSetupVertexPointers != NULL); _assert_(s_pCurBufferPointer != s_pBaseBufferPointer); #ifdef _DEBUG @@ -158,7 +157,7 @@ void VertexManager::Flush() GL_REPORT_ERRORD(); // setup the pointers - fnSetupVertexPointers(); + g_nativeVertexFmt->SetupVertexPointers(); GL_REPORT_ERRORD(); // set the textures @@ -184,7 +183,7 @@ void VertexManager::Flush() if (usedtextures & (1 << i)) { glActiveTexture(GL_TEXTURE0 + i); - FourTexUnits &tex = bpmem.tex[i>>2]; + FourTexUnits &tex = bpmem.tex[i >> 2]; TextureMngr::TCacheEntry* tentry = TextureMngr::Load(i, (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, tex.texImage0[i&3].width+1, tex.texImage0[i&3].height+1, tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, tex.texTlut[i&3].tlut_format); @@ -333,7 +332,7 @@ void VertexManager::EnableComponents(u32 components) { if (s_prevcomponents != components) { if (s_vStoredPrimitives.size() != 0) - PanicAlert("EnableComponents - report this bug"); + VertexManager::Flush(); // matrices if ((components & VB_HAS_POSMTXIDX) != (s_prevcomponents & VB_HAS_POSMTXIDX)) {