From 5984c78588ce9f12af7adb8ca5e493cae6c70906 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Thu, 13 Apr 2023 23:14:20 +0200 Subject: [PATCH] implement display capture for compute renderer it's actually just all stolen from the regular OpenGL renderer --- src/GPU2D_Soft.cpp | 2 +- src/GPU3D.h | 2 ++ src/GPU3D_Compute.cpp | 33 +++++++++++++++++++++++++++++++-- src/GPU3D_Compute.h | 4 ++++ src/GPU3D_OpenGL.cpp | 2 ++ src/GPU3D_OpenGL.h | 2 ++ 6 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/GPU2D_Soft.cpp b/src/GPU2D_Soft.cpp index e9e6d326..070079a3 100644 --- a/src/GPU2D_Soft.cpp +++ b/src/GPU2D_Soft.cpp @@ -367,7 +367,7 @@ void SoftRenderer::VBlankEnd(Unit* unitA, Unit* unitB) { if ((unitA->CaptureCnt & (1<<31)) && (((unitA->CaptureCnt >> 29) & 0x3) != 1)) { - //reinterpret_cast(GPU3D::CurrentRenderer.get())->PrepareCaptureFrame(); + reinterpret_cast(GPU3D::CurrentRenderer.get())->PrepareCaptureFrame(); } } #endif diff --git a/src/GPU3D.h b/src/GPU3D.h index 713a98ce..e569d4bb 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -158,8 +158,10 @@ public: virtual u32* GetLine(int line) = 0; virtual void SetupAccelFrame() {} + protected: Renderer3D(bool Accelerated); + virtual void PrepareCaptureFrame() {} }; extern int Renderer; diff --git a/src/GPU3D_Compute.cpp b/src/GPU3D_Compute.cpp index d346a687..40222de0 100644 --- a/src/GPU3D_Compute.cpp +++ b/src/GPU3D_Compute.cpp @@ -154,12 +154,15 @@ bool ComputeRenderer::Init() } } + glGenBuffers(1, &PixelBuffer); + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelBuffer); + glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); + return true; } void ComputeRenderer::DeInit() { - } void ComputeRenderer::Reset() @@ -1395,7 +1398,26 @@ void ComputeRenderer::RestartFrame() u32* ComputeRenderer::GetLine(int line) { - return DummyLine; + int stride = 256; + + if (line == 0) + { + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelBuffer); + u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + if (data) memcpy(&FramebufferCPU[0], data, 4*stride*192); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + } + + u64* ptr = (u64*)&FramebufferCPU[stride * line]; + for (int i = 0; i < stride; i+=2) + { + u64 rgb = *ptr & 0x00FCFCFC00FCFCFC; + u64 a = *ptr & 0xF8000000F8000000; + + *ptr++ = (rgb >> 2) | (a >> 3); + } + + return &FramebufferCPU[stride * line]; } void ComputeRenderer::SetupAccelFrame() @@ -1403,4 +1425,11 @@ void ComputeRenderer::SetupAccelFrame() glBindTexture(GL_TEXTURE_2D, Framebuffer); } +void ComputeRenderer::PrepareCaptureFrame() +{ + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelBuffer); + glBindTexture(GL_TEXTURE_2D, Framebuffer); + glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr); +} + } \ No newline at end of file diff --git a/src/GPU3D_Compute.h b/src/GPU3D_Compute.h index ee5f9bd2..f417aa96 100644 --- a/src/GPU3D_Compute.h +++ b/src/GPU3D_Compute.h @@ -49,6 +49,7 @@ public: u32* GetLine(int line) override; void SetupAccelFrame() override; + void PrepareCaptureFrame() override; private: GLuint ShaderInterpXSpans[2]; GLuint ShaderBinCombined; @@ -240,6 +241,9 @@ private: u32 TextureDecodingBuffer[1024*1024]; GLuint Framebuffer; + GLuint PixelBuffer; + + u32 FramebufferCPU[256*192]; TexCacheEntry& GetTexture(u32 textureParam, u32 paletteParam); diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 3c35b7fb..6d7a021b 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -1278,6 +1278,7 @@ void GLRenderer::PrepareCaptureFrame() glDrawBuffer(GL_COLOR_ATTACHMENT0); glBlitFramebuffer(0, 0, ScreenW, ScreenH, 0, 0, 256, 192, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); glBindFramebuffer(GL_READ_FRAMEBUFFER, DownscaleFramebuffer); glReadPixels(0, 0, 256, 192, GL_BGRA, GL_UNSIGNED_BYTE, NULL); } @@ -1288,6 +1289,7 @@ u32* GLRenderer::GetLine(int line) if (line == 0) { + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); u8* data = (u8*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); if (data) memcpy(&Framebuffer[stride*0], data, 4*stride*192); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); diff --git a/src/GPU3D_OpenGL.h b/src/GPU3D_OpenGL.h index 425758c6..9505f50e 100644 --- a/src/GPU3D_OpenGL.h +++ b/src/GPU3D_OpenGL.h @@ -40,6 +40,8 @@ public: void SetupAccelFrame() override; void PrepareCaptureFrame(); + void PrepareCaptureFrame() override; + static std::unique_ptr New() noexcept; private: // Used by New()