Skip to content

Commit

Permalink
Unify (well, almost) GetOutputFramebuffer (D3D11/GL)
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Oct 18, 2017
1 parent 214270d commit f2ea0ce
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 94 deletions.
9 changes: 9 additions & 0 deletions GPU/Common/FramebufferCommon.cpp
Expand Up @@ -1925,3 +1925,12 @@ bool FramebufferManagerCommon::GetStencilbuffer(u32 fb_address, int fb_stride, G
return false;
#endif
}

bool FramebufferManagerCommon::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
int w, h;
draw_->GetFramebufferDimensions(nullptr, &w, &h);
buffer.Allocate(w, h, GE_FORMAT_8888, false, true);
draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), w);
return true;
}

2 changes: 1 addition & 1 deletion GPU/Common/FramebufferCommon.h
Expand Up @@ -281,7 +281,7 @@ class FramebufferManagerCommon {
virtual bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes);
virtual bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer);
virtual bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer);
virtual bool GetOutputFramebuffer(GPUDebugBuffer &buffer) = 0;
virtual bool GetOutputFramebuffer(GPUDebugBuffer &buffer);

protected:
virtual void SetViewport2D(int x, int y, int w, int h);
Expand Down
41 changes: 0 additions & 41 deletions GPU/D3D11/FramebufferManagerD3D11.cpp
Expand Up @@ -873,44 +873,3 @@ void FramebufferManagerD3D11::Resized() {
// Might have a new post shader - let's compile it.
CompilePostShader();
}

bool FramebufferManagerD3D11::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
ID3D11Texture2D *backbuffer = (ID3D11Texture2D *)draw_->GetNativeObject(Draw::NativeObject::BACKBUFFER_COLOR_TEX);
if (!backbuffer) {
ERROR_LOG(G3D, "Failed to get backbuffer from draw context");
return false;
}
D3D11_TEXTURE2D_DESC desc;
backbuffer->GetDesc(&desc);
int w = desc.Width;
int h = desc.Height;
buffer.Allocate(w, h, GE_FORMAT_8888, !useBufferedRendering_, true);

ID3D11Texture2D *packTex;
D3D11_TEXTURE2D_DESC packDesc{};
packDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
packDesc.BindFlags = 0;
packDesc.Width = w;
packDesc.Height = h;
packDesc.ArraySize = 1;
packDesc.MipLevels = 1;
packDesc.Usage = D3D11_USAGE_STAGING;
packDesc.SampleDesc.Count = 1;
packDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
ASSERT_SUCCESS(device_->CreateTexture2D(&packDesc, nullptr, &packTex));

context_->CopyResource(packTex, backbuffer);

D3D11_MAPPED_SUBRESOURCE map;
context_->Map(packTex, 0, D3D11_MAP_READ, 0, &map);

for (int y = 0; y < h; y++) {
uint8_t *dest = (uint8_t *)buffer.GetData() + y * w * 4;
const uint8_t *src = ((const uint8_t *)map.pData) + map.RowPitch * y;
memcpy(dest, src, 4 * w);
}

context_->Unmap(packTex, 0);
packTex->Release();
return true;
}
2 changes: 0 additions & 2 deletions GPU/D3D11/FramebufferManagerD3D11.h
Expand Up @@ -67,8 +67,6 @@ class FramebufferManagerD3D11 : public FramebufferManagerCommon {

virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override;

bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;

virtual void RebindFramebuffer() override;

// TODO: Remove
Expand Down
11 changes: 4 additions & 7 deletions GPU/GLES/FramebufferManagerGLES.cpp
Expand Up @@ -1130,12 +1130,9 @@ void FramebufferManagerGLES::Resized() {
}

bool FramebufferManagerGLES::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
int pw = PSP_CoreParameter().pixelWidth;
int ph = PSP_CoreParameter().pixelHeight;

// The backbuffer is flipped (last bool)
buffer.Allocate(pw, ph, GPU_DBG_FORMAT_888_RGB, true);
draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, pw, ph, Draw::DataFormat::R8G8B8_UNORM, buffer.GetData(), pw);
CHECK_GL_ERROR_IF_DEBUG();
int w, h;
draw_->GetFramebufferDimensions(nullptr, &w, &h);
buffer.Allocate(w, h, GPU_DBG_FORMAT_888_RGB, true);
draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8_UNORM, buffer.GetData(), w);
return true;
}
36 changes: 0 additions & 36 deletions GPU/Vulkan/FramebufferVulkan.cpp
Expand Up @@ -756,42 +756,6 @@ void ConvertFromRGBA8888_Vulkan(u8 *dst, const u8 *src, u32 dstStride, u32 srcSt
}
}

#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

// One frame behind, but no stalling.
void FramebufferManagerVulkan::PackFramebufferAsync_(VirtualFramebuffer *vfb) {
const int MAX_PBO = 2;
Expand Down
20 changes: 15 additions & 5 deletions ext/native/thin3d/thin3d_d3d11.cpp
Expand Up @@ -1361,7 +1361,9 @@ void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 dstStride, u32 srcStride, u32 wid
bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int bx, int by, int bw, int bh, Draw::DataFormat format, void *pixels, int pixelStride) {
D3D11Framebuffer *fb = (D3D11Framebuffer *)src;

assert(fb->colorFormat == DXGI_FORMAT_R8G8B8A8_UNORM);
if (fb) {
assert(fb->colorFormat == DXGI_FORMAT_R8G8B8A8_UNORM);
}

bool useGlobalPacktex = (bx + bw <= 512 && by + bh <= 512) && channelBits == FB_COLOR_BIT;

Expand All @@ -1383,6 +1385,7 @@ bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channel
break;
case FB_DEPTH_BIT:
case FB_STENCIL_BIT:
assert(fb);
packDesc.Format = fb->depthStencilFormat;
break;
default:
Expand All @@ -1396,15 +1399,17 @@ bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channel
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);
context_->CopySubresourceRegion(packTex, 0, bx, by, 0, fb ? fb->colorTex : bbRenderTargetTex_, 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);
assert(fb); // We haven't got a texture for the backbuffer depth. Could make one but I don't think we need one.
context_->CopyResource(packTex, fb->depthStencilTex);
break;
default:
assert(false);
break;
}

// Ideally, we'd round robin between two packTexture_, and simply use the other one. Though if the game
Expand Down Expand Up @@ -1509,8 +1514,13 @@ uintptr_t D3D11DrawContext::GetFramebufferAPITexture(Framebuffer *fbo, int chann

void D3D11DrawContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {
D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
*w = fb->width;
*h = fb->height;
if (fb) {
*w = fb->width;
*h = fb->height;
} else {
*w = bbWidth_;
*h = bbHeight_;
}
}

DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, ID3D11Device1 *device1, ID3D11DeviceContext1 *context1, D3D_FEATURE_LEVEL featureLevel, HWND hWnd) {
Expand Down
9 changes: 7 additions & 2 deletions ext/native/thin3d/thin3d_gl.cpp
Expand Up @@ -1866,8 +1866,13 @@ OpenGLFramebuffer::~OpenGLFramebuffer() {

void OpenGLContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {
OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo;
*w = fb->width;
*h = fb->height;
if (fb) {
*w = fb->width;
*h = fb->height;
} else {
*w = targetWidth_;
*h = targetHeight_;
}
}

uint32_t OpenGLContext::GetDataFormatSupport(DataFormat fmt) const {
Expand Down

0 comments on commit f2ea0ce

Please sign in to comment.