@@ -1352,6 +1352,15 @@ CGSH_OpenGL::BitmapPtr CGSH_OpenGL::FindOrCreateBitmap(const FramebufferPtr& fra
13521352 return sharedPtr;
13531353}
13541354
1355+ CGSH_OpenGL::FramebufferPtr CGSH_OpenGL::FindFramebufferAtPtr (uint32 ptr, uint32 psm) const
1356+ {
1357+ auto framebufferIterator = std::find_if (m_framebuffers.begin (), m_framebuffers.end (),
1358+ [ptr, psm](const FramebufferPtr& framebuffer) {
1359+ return framebuffer->m_psm == psm && framebuffer->m_basePtr == ptr;
1360+ });
1361+ return (framebufferIterator != std::end (m_framebuffers)) ? *(framebufferIterator) : FramebufferPtr ();
1362+ }
1363+
13551364// ///////////////////////////////////////////////////////////
13561365// Individual Primitives Implementations
13571366// ///////////////////////////////////////////////////////////
@@ -1672,6 +1681,15 @@ void CGSH_OpenGL::FlushVertexBuffer()
16721681 }
16731682 DoRenderPass ();
16741683 m_vertexBuffer.clear ();
1684+
1685+ auto handle = m_renderState.framebufferHandle ;
1686+ auto framebufferIterator = std::find_if (m_framebuffers.begin (), m_framebuffers.end (),
1687+ [handle](const FramebufferPtr& framebuffer) {
1688+ return (framebuffer->m_framebuffer == handle);
1689+ });
1690+ const auto & framebuffer = (*framebufferIterator);
1691+
1692+ framebuffer->copiedToRam = false ;
16751693}
16761694
16771695void CGSH_OpenGL::DoRenderPass ()
@@ -1926,6 +1944,90 @@ void CGSH_OpenGL::WriteRegisterImpl(uint8 nRegister, uint64 nData)
19261944 }
19271945}
19281946
1947+ void CGSH_OpenGL::SyncCLUT (const TEX0& tex0)
1948+ {
1949+ if (!ProcessCLD (tex0)) return ;
1950+
1951+ // If we use a CLUT based texture, its possible that the memory
1952+ // referenced is inside a framebuffer. In that case, we need
1953+ // to persist the framebuffer content into the GS RAM.
1954+
1955+ if (CGsPixelFormats::IsPsmIDTEX (tex0.nPsm ))
1956+ {
1957+ const uint32 ptr = tex0.GetCLUTPtr ();
1958+
1959+ FramebufferPtr framebuffer = FindFramebufferAtPtr (ptr, PSMCT32);
1960+ if (framebuffer)
1961+ {
1962+ WriteFramebufferToMemory (framebuffer, true );
1963+ }
1964+ }
1965+
1966+ CGSHandler::SyncCLUT (tex0);
1967+ }
1968+
1969+ void CGSH_OpenGL::WriteFramebufferToMemory (const FramebufferPtr& framebuffer, bool downSample)
1970+ {
1971+ // If the framebuffer has already been persisted to RAM,
1972+ // we don't need to do that again.
1973+ if (framebuffer->copiedToRam )
1974+ {
1975+ return ;
1976+ }
1977+
1978+ FramebufferPtr targetFramebuffer = framebuffer;
1979+ uint32 scale = m_fbScale;
1980+
1981+ if (downSample && m_fbScale != 1 )
1982+ {
1983+ auto dstFramebuffer = FramebufferPtr (new CFramebuffer (
1984+ framebuffer->m_basePtr ,
1985+ framebuffer->m_width ,
1986+ framebuffer->m_height ,
1987+ framebuffer->m_psm ,
1988+ 1 ,
1989+ m_multisampleEnabled));
1990+ PopulateFramebuffer (dstFramebuffer);
1991+
1992+ glBindFramebuffer (GL_FRAMEBUFFER, dstFramebuffer->m_framebuffer );
1993+ glBindFramebuffer (GL_READ_FRAMEBUFFER, framebuffer->m_framebuffer );
1994+
1995+ // Copy buffers
1996+ glBlitFramebuffer (
1997+ 0 , 0 , framebuffer->m_width * m_fbScale, framebuffer->m_height * m_fbScale,
1998+ 0 , 0 , dstFramebuffer->m_width , dstFramebuffer->m_height ,
1999+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
2000+ CHECKGLERROR ();
2001+ glBindFramebuffer (GL_READ_FRAMEBUFFER, 0 );
2002+
2003+ targetFramebuffer = dstFramebuffer;
2004+ scale = 1 ;
2005+ }
2006+
2007+ glBindFramebuffer (GL_FRAMEBUFFER, targetFramebuffer->m_framebuffer );
2008+
2009+ // ----------------------
2010+
2011+ // Read data into ram
2012+
2013+ auto imgbuffer = FindOrCreateBitmap (targetFramebuffer, scale);
2014+ glReadPixels (0 , 0 , targetFramebuffer->m_width * scale, targetFramebuffer->m_height * scale, GL_RGBA, GL_UNSIGNED_BYTE, imgbuffer->GetPixels ());
2015+
2016+ CGsPixelFormats::CPixelIndexorPSMCT32 indexor (m_pRAM, targetFramebuffer->m_basePtr , targetFramebuffer->m_width / 64 );
2017+ for (uint32 y = 0 ; y < targetFramebuffer->m_height ; y++)
2018+ {
2019+ for (uint32 x = 0 ; x < targetFramebuffer->m_width ; x++)
2020+ {
2021+ auto pixel = imgbuffer->GetPixel (x * scale, y * scale);
2022+ indexor.SetPixel (x, y, MakeColor (pixel.r , pixel.g , pixel.b , pixel.a ));
2023+ }
2024+ }
2025+
2026+ framebuffer->copiedToRam = true ;
2027+
2028+ glBindFramebuffer (GL_FRAMEBUFFER, m_renderState.framebufferHandle );
2029+ }
2030+
19292031void CGSH_OpenGL::VertexKick (uint8 nRegister, uint64 nValue)
19302032{
19312033 if (m_nVtxCount == 0 ) return ;
0 commit comments