diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index aa1665e3b7..7a12932807 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -46,8 +46,6 @@ #include "GPU/GLES/DrawEngineGLES.h" #include "GPU/GLES/ShaderManagerGLES.h" -// #define DEBUG_READ_PIXELS 1 - static const char tex_fs[] = "#if __VERSION__ >= 130\n" "#define varying in\n" @@ -807,42 +805,6 @@ void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u } } -#ifdef DEBUG_READ_PIXELS -// TODO: Make more generic. -static void LogReadPixelsError(GLenum error) { - switch (error) { - case GL_NO_ERROR: - break; - case GL_INVALID_ENUM: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_ENUM"); - break; - case GL_INVALID_VALUE: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_VALUE"); - break; - case GL_INVALID_OPERATION: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_OPERATION"); - break; - case GL_INVALID_FRAMEBUFFER_OPERATION: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_FRAMEBUFFER_OPERATION"); - break; - case GL_OUT_OF_MEMORY: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_OUT_OF_MEMORY"); - break; -#ifndef USING_GLES2 - case GL_STACK_UNDERFLOW: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_STACK_UNDERFLOW"); - break; - case GL_STACK_OVERFLOW: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_STACK_OVERFLOW"); - break; -#endif - default: - ERROR_LOG(FRAMEBUF, "glReadPixels: %08x", error); - break; - } -} -#endif - void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) { CHECK_GL_ERROR_IF_DEBUG(); const int MAX_PBO = 2; diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index f890dfb0a3..067b17f519 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -244,10 +244,12 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de } CreatePresets(); + // Temp texture for read-back of small images. Custom textures are created on demand for larger ones. + // TODO: Should really benchmark if this extra complexity has any benefit. D3D11_TEXTURE2D_DESC packDesc{}; packDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; packDesc.BindFlags = 0; - packDesc.Width = 512; // 512x512 is the maximum size of a framebuffer on the PSP. + packDesc.Width = 512; packDesc.Height = 512; packDesc.ArraySize = 1; packDesc.MipLevels = 1; @@ -1378,23 +1380,33 @@ bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channel switch (channelBits) { case FB_COLOR_BIT: packDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // TODO: fb->colorFormat; - device_->CreateTexture2D(&packDesc, nullptr, &packTex); - context_->CopySubresourceRegion(packTex, 0, bx, by, 0, fb->colorTex, 0, &srcBox); break; case FB_DEPTH_BIT: case FB_STENCIL_BIT: packDesc.Format = fb->depthStencilFormat; - device_->CreateTexture2D(&packDesc, nullptr, &packTex); - // For depth/stencil buffers, we can't reliably copy subrectangles, so just copy the whole resource. - context_->CopyResource(packTex, fb->colorTex); break; default: assert(false); } + device_->CreateTexture2D(&packDesc, nullptr, &packTex); } else { packTex = packTexture_; } + D3D11_BOX srcBox{ (UINT)bx, (UINT)by, 0, (UINT)(bx + bw), (UINT)(by + bh), 1 }; + switch (channelBits) { + case FB_COLOR_BIT: + context_->CopySubresourceRegion(packTex, 0, bx, by, 0, fb->colorTex, 0, &srcBox); + break; + case FB_DEPTH_BIT: + case FB_STENCIL_BIT: + // For depth/stencil buffers, we can't reliably copy subrectangles, so just copy the whole resource. + context_->CopyResource(packTex, fb->colorTex); + break; + default: + assert(false); + } + // Ideally, we'd round robin between two packTexture_, and simply use the other one. Though if the game // does a once-off copy, that won't work at all. diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index c48b027085..0d9108286f 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -19,6 +19,8 @@ extern void bindDefaultFBO(); #endif +// #define DEBUG_READ_PIXELS 1 + // Workaround for Retroarch. Simply declare // extern GLuint g_defaultFBO; // and set is as appropriate. Can adjust the variables in ext/native/base/display.h as @@ -870,6 +872,43 @@ void OpenGLTexture::SetImageData(int x, int y, int z, int width, int height, int CHECK_GL_ERROR_IF_DEBUG(); } + +#ifdef DEBUG_READ_PIXELS +// TODO: Make more generic. +static void LogReadPixelsError(GLenum error) { + switch (error) { + case GL_NO_ERROR: + break; + case GL_INVALID_ENUM: + ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_ENUM"); + break; + case GL_INVALID_VALUE: + ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_VALUE"); + break; + case GL_INVALID_OPERATION: + ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_OPERATION"); + break; + case GL_INVALID_FRAMEBUFFER_OPERATION: + ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_FRAMEBUFFER_OPERATION"); + break; + case GL_OUT_OF_MEMORY: + ERROR_LOG(FRAMEBUF, "glReadPixels: GL_OUT_OF_MEMORY"); + break; +#ifndef USING_GLES2 + case GL_STACK_UNDERFLOW: + ERROR_LOG(FRAMEBUF, "glReadPixels: GL_STACK_UNDERFLOW"); + break; + case GL_STACK_OVERFLOW: + ERROR_LOG(FRAMEBUF, "glReadPixels: GL_STACK_OVERFLOW"); + break; +#endif + default: + ERROR_LOG(FRAMEBUF, "glReadPixels: %08x", error); + break; + } +} +#endif + bool OpenGLContext::CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat dataFormat, void *pixels, int pixelStride) { OpenGLFramebuffer *fb = (OpenGLFramebuffer *)src; fbo_bind_fb_target(true, fb ? fb->handle : 0);