diff --git a/Source/Core/VideoCommon/Src/CPMemory.cpp b/Source/Core/VideoCommon/Src/CPMemory.cpp index 06aa8d6192..837dde70ac 100644 --- a/Source/Core/VideoCommon/Src/CPMemory.cpp +++ b/Source/Core/VideoCommon/Src/CPMemory.cpp @@ -24,3 +24,6 @@ u32 arraybases[16]; u32 arraystrides[16]; TMatrixIndexA MatrixIndexA; TMatrixIndexB MatrixIndexB; +TVtxDesc g_VtxDesc; +// Most games only use the first VtxAttr and simply reconfigure it all the time as needed. +VAT g_VtxAttr[8]; diff --git a/Source/Core/VideoCommon/Src/CPMemory.h b/Source/Core/VideoCommon/Src/CPMemory.h index 67e918292d..9557984ecf 100644 --- a/Source/Core/VideoCommon/Src/CPMemory.h +++ b/Source/Core/VideoCommon/Src/CPMemory.h @@ -248,4 +248,14 @@ extern u32 arraystrides[16]; extern TMatrixIndexA MatrixIndexA; extern TMatrixIndexB MatrixIndexB; +struct VAT +{ + UVAT_group0 g0; + UVAT_group1 g1; + UVAT_group2 g2; +}; + +extern TVtxDesc g_VtxDesc; +extern VAT g_VtxAttr[8]; + #endif diff --git a/Source/Core/VideoCommon/Src/NativeVertexFormat.h b/Source/Core/VideoCommon/Src/NativeVertexFormat.h index e0213c4ad2..2f3dd08f9b 100644 --- a/Source/Core/VideoCommon/Src/NativeVertexFormat.h +++ b/Source/Core/VideoCommon/Src/NativeVertexFormat.h @@ -55,17 +55,12 @@ enum { VB_HAS_UVTEXMTXSHIFT=13, }; - #define LOADERDECL __cdecl typedef void (LOADERDECL *TPipelineFunction)(const void *); -// This will soon be used in a cache of vertex formats, rather than used in-place. // 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 @@ -84,6 +79,4 @@ public: u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present. }; - - #endif // _NATIVEVERTEXFORMAT_H diff --git a/Source/Core/VideoCommon/Src/VideoState.cpp b/Source/Core/VideoCommon/Src/VideoState.cpp index 70a812e113..55b7c6f9f7 100644 --- a/Source/Core/VideoCommon/Src/VideoState.cpp +++ b/Source/Core/VideoCommon/Src/VideoState.cpp @@ -32,6 +32,9 @@ static void DoState(PointerWrap &p) { p.DoArray(arraystrides, 16); p.Do(MatrixIndexA); p.Do(MatrixIndexB); + p.Do(g_VtxDesc.Hex); + p.DoArray(g_VtxAttr, 8); + // XF Memory p.Do(xfregs); p.DoArray(xfmem, XFMEM_SIZE); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexHandler.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexHandler.cpp index f3d290a629..c22d665b32 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexHandler.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexHandler.cpp @@ -79,7 +79,7 @@ void CVertexHandler::Shutdown() void CVertexHandler::CreateDeviceObjects() { HRESULT hr; - if( FAILED( hr = D3D::dev->CreateVertexDeclaration( decl, &vDecl) ) ) + if (FAILED(hr = D3D::dev->CreateVertexDeclaration(decl, &vDecl))) { MessageBox(0,"Failed to create vertex declaration","sdfsd",0); return; @@ -96,7 +96,7 @@ void CVertexHandler::DestroyDeviceObjects() { if (vDecl) vDecl->Release(); - vDecl=0; + vDecl = 0; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/OpcodeDecoding.cpp b/Source/Plugins/Plugin_VideoOGL/Src/OpcodeDecoding.cpp index 2b93952d8b..aac013a2d2 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/OpcodeDecoding.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/OpcodeDecoding.cpp @@ -139,8 +139,7 @@ bool FifoCommandRunnable() { iCommandSize = 1 + 2; u16 numVertices = DataPeek16(1); - VertexLoader& vtxLoader = g_VertexLoaders[Cmd & GX_VAT_MASK]; - iCommandSize += numVertices * vtxLoader.ComputeVertexSize(); + iCommandSize += numVertices * VertexLoaderManager::GetVertexSize(Cmd & GX_VAT_MASK); } else { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index b5b51f3496..20862dbc26 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -80,7 +80,6 @@ int frameCount; void HandleCgError(CGcontext ctx, CGerror err, void* appdata); - bool Renderer::Create2() { bool bSuccess = true; @@ -189,7 +188,7 @@ bool Renderer::Create2() int nMaxMRT = 0; glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, (GLint *)&nMaxMRT); - if( nMaxMRT > 1 ) { + if (nMaxMRT > 1) { // create zbuffer target glGenTextures(1, (GLuint *)&s_ZBufferTarget); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget); @@ -210,11 +209,12 @@ bool Renderer::Create2() glGenRenderbuffersEXT( 1, (GLuint *)&s_DepthTarget); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_DepthTarget); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, nBackbufferWidth, nBackbufferHeight); - if( glGetError() != GL_NO_ERROR ) { + if (glGetError() != GL_NO_ERROR) { glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, nBackbufferWidth, nBackbufferHeight); s_bHaveStencilBuffer = false; - } - else s_bHaveStencilBuffer = true; + } else { + s_bHaveStencilBuffer = true; + } GL_REPORT_ERROR(); @@ -223,7 +223,7 @@ bool Renderer::Create2() glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget ); GL_REPORT_ERROR(); - if( s_ZBufferTarget != 0 ) { + if (s_ZBufferTarget != 0) { // test to make sure it works glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget, 0); bool bFailed = glGetError() != GL_NO_ERROR || glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT; @@ -235,7 +235,7 @@ bool Renderer::Create2() } } - if( s_ZBufferTarget == 0 ) + if (s_ZBufferTarget == 0) ERROR_LOG("disabling ztarget mrt feature (max mrt=%d)\n", nMaxMRT); //glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget ); @@ -244,7 +244,8 @@ bool Renderer::Create2() nZBufferRender = 0; GL_REPORT_ERROR(); - if (err != GL_NO_ERROR) bSuccess = false; + if (err != GL_NO_ERROR) + bSuccess = false; s_pfont = new RasterFont(); @@ -290,7 +291,6 @@ bool Renderer::Create2() //glEnable(GL_POLYGON_OFFSET_FILL); //glEnable(GL_POLYGON_OFFSET_LINE); //glPolygonOffset(0, 1); - if (!Initialize()) return false; @@ -329,7 +329,7 @@ bool Renderer::Initialize() glStencilFunc(GL_ALWAYS, 0, 0); glBlendFunc(GL_ONE, GL_ONE); - glViewport(0,0,GetTargetWidth(),GetTargetHeight()); // Reset The Current Viewport + glViewport(0, 0, GetTargetWidth(), GetTargetHeight()); // Reset The Current Viewport glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -345,10 +345,9 @@ bool Renderer::Initialize() glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // perspective correct interpolation of colors and tex coords - // setup the default vertex declaration glDisable(GL_STENCIL_TEST); glEnable(GL_SCISSOR_TEST); - glScissor(0,0,nBackbufferWidth,nBackbufferHeight); + glScissor(0, 0, nBackbufferWidth, nBackbufferHeight); glBlendColorEXT(0, 0, 0, 0.5f); glClearDepth(1.0f); @@ -357,12 +356,10 @@ bool Renderer::Initialize() glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - //Renderer::SetZBufferRender(); - - // legacy multitexturing: select texture channel only + // legacy multitexturing: select texture channel only. glActiveTexture(GL_TEXTURE0); glClientActiveTexture(GL_TEXTURE0); - glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); s_RenderMode = Renderer::RM_Normal; @@ -499,7 +496,7 @@ void Renderer::SetDepthTarget(u32 targ) void Renderer::SetFramebuffer(u32 fb) { - glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fb != 0 ? fb : s_uFramebuffer ); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb != 0 ? fb : s_uFramebuffer); } u32 Renderer::GetRenderTarget() @@ -516,21 +513,21 @@ void Renderer::ResetGLState() glDepthMask(GL_FALSE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glDisable( GL_VERTEX_PROGRAM_ARB ); - glDisable( GL_FRAGMENT_PROGRAM_ARB ); + glDisable(GL_VERTEX_PROGRAM_ARB); + glDisable(GL_FRAGMENT_PROGRAM_ARB); } void Renderer::RestoreGLState() { glEnable(GL_SCISSOR_TEST); - if (bpmem.genMode.cullmode>0) glEnable(GL_CULL_FACE); + if (bpmem.genMode.cullmode > 0) glEnable(GL_CULL_FACE); if (bpmem.zmode.testenable) glEnable(GL_DEPTH_TEST); if (bpmem.blendmode.blendenable) glEnable(GL_BLEND); if(bpmem.zmode.updateenable) glDepthMask(GL_TRUE); - glEnable( GL_VERTEX_PROGRAM_ARB ); - glEnable( GL_FRAGMENT_PROGRAM_ARB ); + glEnable(GL_VERTEX_PROGRAM_ARB); + glEnable(GL_FRAGMENT_PROGRAM_ARB); SetColorMask(); } @@ -547,9 +544,12 @@ bool Renderer::HaveStencilBuffer() void Renderer::SetZBufferRender() { nZBufferRender = 10; // give it 10 frames - GLenum s_drawbuffers[2] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT}; + GLenum s_drawbuffers[2] = { + GL_COLOR_ATTACHMENT0_EXT, + GL_COLOR_ATTACHMENT1_EXT + }; glDrawBuffers(2, s_drawbuffers); - glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget, 0); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget, 0); _assert_(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); } @@ -568,7 +568,8 @@ void Renderer::FlushZBufferAlphaToTarget() glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget); TextureMngr::EnableTexRECT(0); // disable all other stages - for(int i = 1; i < 8; ++i) TextureMngr::DisableStage(i); + for(int i = 1; i < 8; ++i) + TextureMngr::DisableStage(i); GL_REPORT_ERRORD(); if(g_Config.bStretchToFit) @@ -612,13 +613,13 @@ void Renderer::FlushZBufferAlphaToTarget() void Renderer::SetRenderMode(RenderMode mode) { - if( !s_bHaveStencilBuffer && mode == RM_ZBufferAlpha ) + if (!s_bHaveStencilBuffer && mode == RM_ZBufferAlpha) mode = RM_ZBufferOnly; - if( s_RenderMode == mode ) + if (s_RenderMode == mode) return; - if( mode == RM_Normal ) { + if (mode == RM_Normal) { // flush buffers if( s_RenderMode == RM_ZBufferAlpha ) { FlushZBufferAlphaToTarget(); @@ -629,7 +630,7 @@ void Renderer::SetRenderMode(RenderMode mode) SetZBufferRender(); GL_REPORT_ERRORD(); } - else if( s_RenderMode == RM_Normal ) { + else if (s_RenderMode == RM_Normal) { // setup buffers _assert_(GetZBufferTarget() && bpmem.zmode.updateenable); @@ -741,16 +742,12 @@ void Renderer::SwapBuffers() fpscount = 0; } - - // --------------------------------------------------------------------------------------- // Write logging data to debugger - // ----------------- if(m_frame) { Logging(0); } - if (g_Config.bOverlayStats) { char st[2048]; char *p = st; @@ -821,17 +818,14 @@ void Renderer::SwapBuffers() stats.ResetFrame(); glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, s_uFramebuffer ); - -// s_nCurTarget = !s_nCurTarget; -// SetRenderTarget(0); - - if( nZBufferRender > 0 ) { - if( --nZBufferRender == 0 ) { + + if (nZBufferRender > 0) { + if (--nZBufferRender == 0) { // turn off nZBufferRender = 0; glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0); - Renderer::SetRenderMode(RM_Normal); // turn off any zwrites + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0); + Renderer::SetRenderMode(RM_Normal); // turn off any zwrites } } } @@ -839,7 +833,7 @@ void Renderer::SwapBuffers() bool Renderer::SaveRenderTarget(const char* filename, int jpeg) { bool bflip = true; - std::vector data(nBackbufferWidth*nBackbufferHeight); + std::vector data(nBackbufferWidth * nBackbufferHeight); glReadPixels(0, 0, nBackbufferWidth, nBackbufferHeight, GL_BGRA, GL_UNSIGNED_BYTE, &data[0]); if (glGetError() != GL_NO_ERROR) return false; @@ -865,8 +859,9 @@ void Renderer::SetCgErrorOutput(bool bOutput) void HandleGLError() { const GLubyte* pstr = glGetString(GL_PROGRAM_ERROR_STRING_ARB); - if (pstr != NULL && pstr[0] != 0 ) { - GLint loc=0; + if (pstr != NULL && pstr[0] != 0) + { + GLint loc = 0; glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &loc); ERROR_LOG("program error at %d: ", loc); ERROR_LOG((char*)pstr); @@ -877,51 +872,53 @@ void HandleGLError() GLenum error = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // if error != GL_FRAMEBUFFER_COMPLETE_EXT, there's an error of some sort - if (error != 0) { - int w, h; - GLint fmt; - glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, &fmt); - glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_WIDTH_EXT, (GLint *)&w); - glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_HEIGHT_EXT, (GLint *)&h); + if (!error) + return; - switch(error) - { - case GL_FRAMEBUFFER_COMPLETE_EXT: - break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: - ERROR_LOG("Error! missing a required image/buffer attachment!\n"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: - ERROR_LOG("Error! has no images/buffers attached!\n"); - break; -// case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: -// ERROR_LOG("Error! has an image/buffer attached in multiple locations!\n"); -// break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: - ERROR_LOG("Error! has mismatched image/buffer dimensions!\n"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: - ERROR_LOG("Error! colorbuffer attachments have different types!\n"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: - ERROR_LOG("Error! trying to draw to non-attached color buffer!\n"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: - ERROR_LOG("Error! trying to read from a non-attached color buffer!\n"); - break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - ERROR_LOG("Error! format is not supported by current graphics card/driver!\n"); - break; - default: - ERROR_LOG("*UNKNOWN ERROR* reported from glCheckFramebufferStatusEXT()!\n"); - break; - } - } +// int w, h; +// GLint fmt; +// glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, &fmt); +// glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_WIDTH_EXT, (GLint *)&w); +// glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_HEIGHT_EXT, (GLint *)&h); + + switch(error) + { + case GL_FRAMEBUFFER_COMPLETE_EXT: + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + ERROR_LOG("Error! missing a required image/buffer attachment!\n"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: + ERROR_LOG("Error! has no images/buffers attached!\n"); + break; +// case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: +// ERROR_LOG("Error! has an image/buffer attached in multiple locations!\n"); +// break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + ERROR_LOG("Error! has mismatched image/buffer dimensions!\n"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: + ERROR_LOG("Error! colorbuffer attachments have different types!\n"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: + ERROR_LOG("Error! trying to draw to non-attached color buffer!\n"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: + ERROR_LOG("Error! trying to read from a non-attached color buffer!\n"); + break; + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + ERROR_LOG("Error! format is not supported by current graphics card/driver!\n"); + break; + default: + ERROR_LOG("*UNKNOWN ERROR* reported from glCheckFramebufferStatusEXT()!\n"); + break; + } } void HandleCgError(CGcontext ctx, CGerror err, void* appdata) { - if( s_bOutputCgErrors ) { + if (s_bOutputCgErrors) + { ERROR_LOG("Cg error: %s\n", cgGetErrorString(err)); const char* listing = cgGetLastListing(g_cgcontext); if (listing != NULL) { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp index 60ceeee532..824502c90a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp @@ -110,8 +110,6 @@ void LOADERDECL TexMtx_Write_Short3(const void *_p) #include "VertexLoader_Color.h" #include "VertexLoader_TextCoord.h" -VertexLoader g_VertexLoaders[8]; - VertexLoader::VertexLoader() { m_VertexSize = 0; @@ -128,15 +126,15 @@ int VertexLoader::ComputeVertexSize() { if (m_AttrDirty == AD_CLEAN) { // Compare the 33 desc bits. - if (m_VtxDesc.Hex0 == GetVtxDesc().Hex0 && - (m_VtxDesc.Hex1 & 1) == (GetVtxDesc().Hex1 & 1)) + if (m_VtxDesc.Hex0 == g_VtxDesc.Hex0 && + (m_VtxDesc.Hex1 & 1) == (g_VtxDesc.Hex1 & 1)) return m_VertexSize; - m_VtxDesc.Hex = GetVtxDesc().Hex; + m_VtxDesc.Hex = g_VtxDesc.Hex; } else { // Attributes are dirty so we have to recompute everything anyway. - m_VtxDesc.Hex = GetVtxDesc().Hex; + m_VtxDesc.Hex = g_VtxDesc.Hex; } m_AttrDirty = AD_DIRTY; @@ -245,13 +243,13 @@ int VertexLoader::ComputeVertexSize() } -void VertexLoader::PrepareForVertexFormat() +void VertexLoader::CompileVertexTranslator() { if (m_AttrDirty == AD_CLEAN) { // Check if local cached desc (in this VL) matches global desc - if (m_VtxDesc.Hex0 == GetVtxDesc().Hex0 && - (m_VtxDesc.Hex1 & 1) == (GetVtxDesc().Hex1 & 1)) + if (m_VtxDesc.Hex0 == g_VtxDesc.Hex0 && + (m_VtxDesc.Hex1 & 1) == (g_VtxDesc.Hex1 & 1)) { return; // same } @@ -261,7 +259,7 @@ void VertexLoader::PrepareForVertexFormat() m_AttrDirty = AD_CLEAN; } - m_VtxDesc.Hex = GetVtxDesc().Hex; + m_VtxDesc.Hex = g_VtxDesc.Hex; // Reset pipeline m_numPipelineStages = 0; @@ -525,9 +523,9 @@ void VertexLoader::RunVertices(int primitive, int count) if (g_nativeVertexFmt != NULL && g_nativeVertexFmt != &m_NativeFmt) { VertexManager::Flush(); - // Also move the Set() here? } + g_nativeVertexFmt = &m_NativeFmt; // This has dirty handling - won't actually recompute unless necessary. ComputeVertexSize(); @@ -540,9 +538,7 @@ void VertexLoader::RunVertices(int primitive, int count) } // This has dirty handling - won't actually recompute unless necessary. - PrepareForVertexFormat(); - - g_nativeVertexFmt = &m_NativeFmt; + CompileVertexTranslator(); VertexManager::EnableComponents(m_NativeFmt.m_components); @@ -646,3 +642,66 @@ void VertexLoader::RunPipelineOnce() const for (int i = 0; i < m_numPipelineStages; i++) m_PipelineStages[i](&m_VtxAttr); } + +void VertexLoader::SetVAT_group0(u32 _group0) +{ + // ignore frac bits - we don't need to recompute if all that's changed was the frac bits. + if ((m_group0.Hex & ~VAT_0_FRACBITS) != (_group0 & ~VAT_0_FRACBITS)) { + m_AttrDirty = AD_VAT_DIRTY; + } + m_group0.Hex = _group0; + + m_VtxAttr.PosElements = m_group0.PosElements; + m_VtxAttr.PosFormat = m_group0.PosFormat; + m_VtxAttr.PosFrac = m_group0.PosFrac; + m_VtxAttr.NormalElements = m_group0.NormalElements; + m_VtxAttr.NormalFormat = m_group0.NormalFormat; + m_VtxAttr.color[0].Elements = m_group0.Color0Elements; + m_VtxAttr.color[0].Comp = m_group0.Color0Comp; + m_VtxAttr.color[1].Elements = m_group0.Color1Elements; + m_VtxAttr.color[1].Comp = m_group0.Color1Comp; + m_VtxAttr.texCoord[0].Elements = m_group0.Tex0CoordElements; + m_VtxAttr.texCoord[0].Format = m_group0.Tex0CoordFormat; + m_VtxAttr.texCoord[0].Frac = m_group0.Tex0Frac; + m_VtxAttr.ByteDequant = m_group0.ByteDequant; + m_VtxAttr.NormalIndex3 = m_group0.NormalIndex3; +}; + +void VertexLoader::SetVAT_group1(u32 _group1) +{ + if ((m_group1.Hex & ~VAT_1_FRACBITS) != (_group1 & ~VAT_1_FRACBITS)) { + m_AttrDirty = AD_VAT_DIRTY; + } + m_group1.Hex = _group1; + + m_VtxAttr.texCoord[1].Elements = m_group1.Tex1CoordElements; + m_VtxAttr.texCoord[1].Format = m_group1.Tex1CoordFormat; + m_VtxAttr.texCoord[1].Frac = m_group1.Tex1Frac; + m_VtxAttr.texCoord[2].Elements = m_group1.Tex2CoordElements; + m_VtxAttr.texCoord[2].Format = m_group1.Tex2CoordFormat; + m_VtxAttr.texCoord[2].Frac = m_group1.Tex2Frac; + m_VtxAttr.texCoord[3].Elements = m_group1.Tex3CoordElements; + m_VtxAttr.texCoord[3].Format = m_group1.Tex3CoordFormat; + m_VtxAttr.texCoord[3].Frac = m_group1.Tex3Frac; + m_VtxAttr.texCoord[4].Elements = m_group1.Tex4CoordElements; + m_VtxAttr.texCoord[4].Format = m_group1.Tex4CoordFormat; +}; + +void VertexLoader::SetVAT_group2(u32 _group2) +{ + if ((m_group2.Hex & ~VAT_2_FRACBITS) != (_group2 & ~VAT_2_FRACBITS)) { + m_AttrDirty = AD_VAT_DIRTY; + } + m_group2.Hex = _group2; + + m_VtxAttr.texCoord[4].Frac = m_group2.Tex4Frac; + m_VtxAttr.texCoord[5].Elements = m_group2.Tex5CoordElements; + m_VtxAttr.texCoord[5].Format = m_group2.Tex5CoordFormat; + m_VtxAttr.texCoord[5].Frac = m_group2.Tex5Frac; + m_VtxAttr.texCoord[6].Elements = m_group2.Tex6CoordElements; + m_VtxAttr.texCoord[6].Format = m_group2.Tex6CoordFormat; + m_VtxAttr.texCoord[6].Frac = m_group2.Tex6Frac; + m_VtxAttr.texCoord[7].Elements = m_group2.Tex7CoordElements; + m_VtxAttr.texCoord[7].Format = m_group2.Tex7CoordFormat; + m_VtxAttr.texCoord[7].Frac = m_group2.Tex7Frac; +}; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h index d1699760ad..4d2dd9ed7f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.h @@ -23,9 +23,6 @@ #include "NativeVertexFormat.h" -// There are 8 of these. Most games only use the first, and just reconfigure it all the time -// as needed, unfortunately. -// TODO - clarify the role of this class. It seems to have taken on some irrelevant stuff. class VertexLoader { public: @@ -44,19 +41,20 @@ private: AD_VAT_DIRTY = 2, } m_AttrDirty; - // Flipper vertex format ============= int m_VertexSize; // number of bytes of a raw GC vertex + // Flipper vertex format + // Raw VAttr UVAT_group0 m_group0; UVAT_group1 m_group1; UVAT_group2 m_group2; TVtxAttr m_VtxAttr; // Decoded into easy format - // Common for all loaders (? then why is it here?) + // Vtx desc TVtxDesc m_VtxDesc; - // PC vertex format, + converter ====== + // PC vertex format, + converter NativeVertexFormat m_NativeFmt; // Pipeline. To be JIT compiled in the future. @@ -73,7 +71,7 @@ public: ~VertexLoader(); // run the pipeline - void PrepareForVertexFormat(); + void CompileVertexTranslator(); void RunVertices(int primitive, int count); void WriteCall(TPipelineFunction); @@ -82,70 +80,9 @@ public: int ComputeVertexSize(); - void SetVAT_group0(u32 _group0) - { - // ignore frac bits - we don't need to recompute if all that's changed was the frac bits. - if ((m_group0.Hex & ~VAT_0_FRACBITS) != (_group0 & ~VAT_0_FRACBITS)) { - m_AttrDirty = AD_VAT_DIRTY; - } - m_group0.Hex = _group0; - - m_VtxAttr.PosElements = m_group0.PosElements; - m_VtxAttr.PosFormat = m_group0.PosFormat; - m_VtxAttr.PosFrac = m_group0.PosFrac; - m_VtxAttr.NormalElements = m_group0.NormalElements; - m_VtxAttr.NormalFormat = m_group0.NormalFormat; - m_VtxAttr.color[0].Elements = m_group0.Color0Elements; - m_VtxAttr.color[0].Comp = m_group0.Color0Comp; - m_VtxAttr.color[1].Elements = m_group0.Color1Elements; - m_VtxAttr.color[1].Comp = m_group0.Color1Comp; - m_VtxAttr.texCoord[0].Elements = m_group0.Tex0CoordElements; - m_VtxAttr.texCoord[0].Format = m_group0.Tex0CoordFormat; - m_VtxAttr.texCoord[0].Frac = m_group0.Tex0Frac; - m_VtxAttr.ByteDequant = m_group0.ByteDequant; - m_VtxAttr.NormalIndex3 = m_group0.NormalIndex3; - }; - - void SetVAT_group1(u32 _group1) - { - if ((m_group1.Hex & ~VAT_1_FRACBITS) != (_group1 & ~VAT_1_FRACBITS)) { - m_AttrDirty = AD_VAT_DIRTY; - } - m_group1.Hex = _group1; - - m_VtxAttr.texCoord[1].Elements = m_group1.Tex1CoordElements; - m_VtxAttr.texCoord[1].Format = m_group1.Tex1CoordFormat; - m_VtxAttr.texCoord[1].Frac = m_group1.Tex1Frac; - m_VtxAttr.texCoord[2].Elements = m_group1.Tex2CoordElements; - m_VtxAttr.texCoord[2].Format = m_group1.Tex2CoordFormat; - m_VtxAttr.texCoord[2].Frac = m_group1.Tex2Frac; - m_VtxAttr.texCoord[3].Elements = m_group1.Tex3CoordElements; - m_VtxAttr.texCoord[3].Format = m_group1.Tex3CoordFormat; - m_VtxAttr.texCoord[3].Frac = m_group1.Tex3Frac; - m_VtxAttr.texCoord[4].Elements = m_group1.Tex4CoordElements; - m_VtxAttr.texCoord[4].Format = m_group1.Tex4CoordFormat; - }; - - void SetVAT_group2(u32 _group2) - { - if ((m_group2.Hex & ~VAT_2_FRACBITS) != (_group2 & ~VAT_2_FRACBITS)) { - m_AttrDirty = AD_VAT_DIRTY; - } - m_group2.Hex = _group2; - - m_VtxAttr.texCoord[4].Frac = m_group2.Tex4Frac; - m_VtxAttr.texCoord[5].Elements = m_group2.Tex5CoordElements; - m_VtxAttr.texCoord[5].Format = m_group2.Tex5CoordFormat; - m_VtxAttr.texCoord[5].Frac = m_group2.Tex5Frac; - m_VtxAttr.texCoord[6].Elements = m_group2.Tex6CoordElements; - m_VtxAttr.texCoord[6].Format = m_group2.Tex6CoordFormat; - m_VtxAttr.texCoord[6].Frac = m_group2.Tex6Frac; - m_VtxAttr.texCoord[7].Elements = m_group2.Tex7CoordElements; - m_VtxAttr.texCoord[7].Format = m_group2.Tex7CoordFormat; - m_VtxAttr.texCoord[7].Frac = m_group2.Tex7Frac; - }; + void SetVAT_group0(u32 _group0); + void SetVAT_group1(u32 _group1); + void SetVAT_group2(u32 _group2); }; -extern VertexLoader g_VertexLoaders[8]; - #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.cpp index 036eeffed8..fac7b1d7cd 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.cpp @@ -19,22 +19,24 @@ #include "VertexLoader.h" #include "VertexLoaderManager.h" -// The one and only vtx_desc -TVtxDesc g_vtx_desc; -// There are 8 vtx_attr structures. They will soon live here. +static bool s_desc_dirty; +static bool s_attr_dirty[8]; -const TVtxDesc &GetVtxDesc() +// TODO - change into array of pointers. Keep a map of all seen so far. +static VertexLoader g_VertexLoaders[8]; + +namespace VertexLoaderManager { - return g_vtx_desc; + +void Init() +{ + s_desc_dirty = false; + for (int i = 0; i < 8; i++) + s_attr_dirty[i] = false; } -namespace VertexLoaderManager { - -void Init() { - g_vtx_desc.Hex = 0; -} - -void Shutdown() { +void Shutdown() +{ } @@ -42,12 +44,17 @@ void RunVertices(int vtx_attr_group, int primitive, int count) { if (!count) return; - // TODO - grab load the correct vertex loader if anything is dirty. + // TODO - grab & load the correct vertex loader if anything is dirty. g_VertexLoaders[vtx_attr_group].RunVertices(primitive, count); } -} // namespace +int GetVertexSize(int vtx_attr_group) +{ + // The vertex loaders will soon cache the vertex size. + return g_VertexLoaders[vtx_attr_group].ComputeVertexSize(); +} +} // namespace void LoadCPReg(u32 sub_cmd, u32 value) { @@ -56,24 +63,51 @@ void LoadCPReg(u32 sub_cmd, u32 value) case 0x30: VertexShaderMngr::SetTexMatrixChangedA(value); break; + case 0x40: VertexShaderMngr::SetTexMatrixChangedB(value); break; case 0x50: - g_vtx_desc.Hex &= ~0x1FFFF; // keep the Upper bits - g_vtx_desc.Hex |= value; + g_VtxDesc.Hex &= ~0x1FFFF; // keep the Upper bits + g_VtxDesc.Hex |= value; + s_desc_dirty = true; break; + case 0x60: - g_vtx_desc.Hex &= 0x1FFFF; // keep the lower 17Bits - g_vtx_desc.Hex |= (u64)value << 17; + g_VtxDesc.Hex &= 0x1FFFF; // keep the lower 17Bits + g_VtxDesc.Hex |= (u64)value << 17; + s_desc_dirty = true; break; - case 0x70: g_VertexLoaders[sub_cmd & 7].SetVAT_group0(value); _assert_((sub_cmd & 0x0F) < 8); break; - case 0x80: g_VertexLoaders[sub_cmd & 7].SetVAT_group1(value); _assert_((sub_cmd & 0x0F) < 8); break; - case 0x90: g_VertexLoaders[sub_cmd & 7].SetVAT_group2(value); _assert_((sub_cmd & 0x0F) < 8); break; + case 0x70: + _assert_((sub_cmd & 0x0F) < 8); + g_VtxAttr[sub_cmd & 7].g0.Hex = value; + g_VertexLoaders[sub_cmd & 7].SetVAT_group0(value); + s_attr_dirty[sub_cmd & 7] = true; + break; - case 0xA0: arraybases[sub_cmd & 0xF] = value & 0xFFFFFFFF; break; - case 0xB0: arraystrides[sub_cmd & 0xF] = value & 0xFF; break; + case 0x80: + _assert_((sub_cmd & 0x0F) < 8); + g_VtxAttr[sub_cmd & 7].g1.Hex = value; + g_VertexLoaders[sub_cmd & 7].SetVAT_group1(value); + s_attr_dirty[sub_cmd & 7] = true; + break; + + case 0x90: + _assert_((sub_cmd & 0x0F) < 8); + g_VtxAttr[sub_cmd & 7].g2.Hex = value; + g_VertexLoaders[sub_cmd & 7].SetVAT_group2(value); + s_attr_dirty[sub_cmd & 7] = true; + break; + + // Pointers to vertex arrays in GC RAM + case 0xA0: + arraybases[sub_cmd & 0xF] = value & 0xFFFFFFFF; // huh, why the mask? + break; + + case 0xB0: + arraystrides[sub_cmd & 0xF] = value & 0xFF; + break; } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.h index 3a3f07eb75..59028f5891 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoaderManager.h @@ -24,15 +24,14 @@ namespace VertexLoaderManager { void Init(); void Shutdown(); + + int GetVertexSize(int vtx_attr_group); void RunVertices(int vtx_attr_group, int primitive, int count); // TODO - don't expose these like this. static u8* s_pCurBufferPointer; }; - -const TVtxDesc &GetVtxDesc(); - // Might move this into its own file later. void LoadCPReg(u32 SubCmd, u32 Value); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 10c2bc175c..6a910450b6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -33,7 +33,6 @@ static u32 s_prevcomponents; // previous state set u8* s_pCurBufferPointer = NULL; -TVtxDesc s_GlobalVtxDesc; static const GLenum c_primitiveType[8] = { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 62a366541d..fe68f85876 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -37,6 +37,7 @@ #include "TextureMngr.h" #include "BPStructs.h" #include "VertexLoader.h" +#include "VertexLoaderManager.h" #include "VertexManager.h" #include "PixelShaderManager.h" #include "VertexShaderManager.h" @@ -222,10 +223,12 @@ void Video_Prepare(void) VertexShaderMngr::Init(); PixelShaderMngr::Init(); GL_REPORT_ERRORD(); + VertexLoaderManager::Init(); } void Video_Shutdown(void) { + VertexLoaderManager::Shutdown(); VertexShaderMngr::Shutdown(); PixelShaderMngr::Shutdown(); Fifo_Shutdown();