Get rid of BindFramebufferForRead

This commit is contained in:
Henrik Rydgård 2017-10-10 14:46:47 +02:00
parent 5bbe0eb69a
commit 16e68aa7c7
6 changed files with 52 additions and 76 deletions

View File

@ -930,9 +930,7 @@ void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) {
u32 bufSize = vfb->fb_stride * vfb->height * pixelSize;
u32 fb_address = (0x04000000) | vfb->fb_address;
if (vfb->fbo) {
draw_->BindFramebufferForRead(vfb->fbo);
} else {
if (!vfb->fbo) {
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferAsync_: vfb->fbo == 0");
return;
}
@ -946,7 +944,7 @@ void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) {
}
// TODO: Change to CopyFramebufferToBuffer with a proper pointer.
draw_->CopyFramebufferToMemorySync(0, 0, vfb->fb_stride, vfb->height, dataFmt, nullptr);
draw_->CopyFramebufferToMemorySync(vfb->fbo, 0, 0, vfb->fb_stride, vfb->height, dataFmt, nullptr);
unbind = true;
@ -967,9 +965,7 @@ void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) {
}
void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
if (vfb->fbo) {
draw_->BindFramebufferForRead(vfb->fbo);
} else {
if (!vfb->fbo) {
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferSync_: vfb->fbo == 0");
return;
}
@ -1006,7 +1002,7 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x
if (packed) {
DEBUG_LOG(FRAMEBUF, "Reading framebuffer to mem, bufSize = %u, fb_address = %08x", bufSize, fb_address);
int packW = h == 1 ? packWidth : vfb->fb_stride; // TODO: What's this about?
draw_->CopyFramebufferToMemorySync(0, y, packW, h, Draw::DataFormat::R8G8B8A8_UNORM, packed);
draw_->CopyFramebufferToMemorySync(vfb->fbo, 0, y, packW, h, Draw::DataFormat::R8G8B8A8_UNORM, packed);
if (convert) {
ConvertFromRGBA8888(dst, packed, vfb->fb_stride, vfb->fb_stride, packWidth, h, vfb->format);
}
@ -1028,9 +1024,7 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x
}
void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
if (vfb->fbo) {
draw_->BindFramebufferForRead(vfb->fbo);
} else {
if (!vfb->fbo) {
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackDepthbuffer: vfb->fbo == 0");
return;
}
@ -1048,7 +1042,7 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int
DEBUG_LOG(FRAMEBUF, "Reading depthbuffer to mem at %08x for vfb=%08x", z_address, vfb->fb_address);
draw_->CopyFramebufferToMemorySync(0, y, h == 1 ? packWidth : vfb->z_stride, h, Draw::DataFormat::D32F, convBuf_);
draw_->CopyFramebufferToMemorySync(vfb->fbo, 0, y, h == 1 ? packWidth : vfb->z_stride, h, Draw::DataFormat::D32F, convBuf_);
int dstByteOffset = y * vfb->fb_stride * sizeof(u16);
u16 *depth = (u16 *)Memory::GetPointer(z_address + dstByteOffset);
@ -1185,6 +1179,9 @@ bool FramebufferManagerGLES::GetFramebuffer(u32 fb_address, int fb_stride, GEBuf
}
int w = vfb->renderWidth, h = vfb->renderHeight;
Draw::Framebuffer *bound = nullptr;
if (vfb->fbo) {
if (maxRes > 0 && vfb->renderWidth > vfb->width * maxRes) {
w = vfb->width * maxRes;
@ -1199,17 +1196,14 @@ bool FramebufferManagerGLES::GetFramebuffer(u32 fb_address, int fb_stride, GEBuf
tempVfb.renderHeight = h;
BlitFramebuffer(&tempVfb, 0, 0, vfb, 0, 0, vfb->width, vfb->height, 0);
draw_->BindFramebufferForRead(tempFBO);
bound = tempFBO;
} else {
draw_->BindFramebufferForRead(vfb->fbo);
bound = vfb->fbo;
}
}
buffer.Allocate(w, h, GE_FORMAT_8888, !useBufferedRendering_, true);
if (gl_extensions.GLES3 || !gl_extensions.IsGLES)
glReadBuffer(GL_COLOR_ATTACHMENT0);
draw_->CopyFramebufferToMemorySync(0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData());
draw_->CopyFramebufferToMemorySync(bound, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData());
// We may have blitted to a temp FBO.
RebindFramebuffer();
@ -1223,7 +1217,7 @@ bool FramebufferManagerGLES::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
// The backbuffer is flipped (last bool)
buffer.Allocate(pw, ph, GPU_DBG_FORMAT_888_RGB, true);
draw_->CopyFramebufferToMemorySync(0, 0, pw, ph, Draw::DataFormat::R8G8B8_UNORM, buffer.GetData());
draw_->CopyFramebufferToMemorySync(nullptr, 0, 0, pw, ph, Draw::DataFormat::R8G8B8_UNORM, buffer.GetData());
CHECK_GL_ERROR_IF_DEBUG();
return true;
}
@ -1249,9 +1243,7 @@ bool FramebufferManagerGLES::GetDepthbuffer(u32 fb_address, int fb_stride, u32 z
} else {
buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_FLOAT, !useBufferedRendering_);
}
if (vfb->fbo)
draw_->BindFramebufferForRead(vfb->fbo);
draw_->CopyFramebufferToMemorySync(0, 0, vfb->renderWidth, vfb->renderHeight, Draw::DataFormat::D32F, buffer.GetData());
draw_->CopyFramebufferToMemorySync(vfb->fbo, 0, 0, vfb->renderWidth, vfb->renderHeight, Draw::DataFormat::D32F, buffer.GetData());
CHECK_GL_ERROR_IF_DEBUG();
return true;
}
@ -1271,9 +1263,7 @@ bool FramebufferManagerGLES::GetStencilbuffer(u32 fb_address, int fb_stride, GPU
#ifndef USING_GLES2
buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_8BIT, !useBufferedRendering_);
if (vfb->fbo)
draw_->BindFramebufferForRead(vfb->fbo);
draw_->CopyFramebufferToMemorySync(0, 0, vfb->renderWidth, vfb->renderHeight, Draw::DataFormat::S8, buffer.GetData());
draw_->CopyFramebufferToMemorySync(vfb->fbo, 0, 0, vfb->renderWidth, vfb->renderHeight, Draw::DataFormat::S8, buffer.GetData());
CHECK_GL_ERROR_IF_DEBUG();
return true;
#else

View File

@ -620,7 +620,7 @@ public:
virtual bool CopyFramebufferToBuffer(Framebuffer *src, Buffer *buffer, Draw::DataFormat bufferFormat) {
return false;
}
virtual bool CopyFramebufferToMemorySync(int x, int y, int w, int h, Draw::DataFormat format, void *pixels) {
virtual bool CopyFramebufferToMemorySync(Framebuffer *src, int x, int y, int w, int h, Draw::DataFormat format, void *pixels) {
return false;
}
@ -630,7 +630,6 @@ public:
// color must be 0, for now.
virtual void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) = 0;
virtual void BindFramebufferForRead(Framebuffer *fbo) = 0;
virtual uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) = 0;

View File

@ -61,7 +61,6 @@ public:
void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) override;
// color must be 0, for now.
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
void BindFramebufferForRead(Framebuffer *fbo) override;
uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) override;
@ -1327,10 +1326,6 @@ void D3D11DrawContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, F
context_->PSSetShaderResources(binding, 1, &fb->colorSRView);
}
void D3D11DrawContext::BindFramebufferForRead(Framebuffer *fbo) {
// This is meaningless in D3D11
}
uintptr_t D3D11DrawContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) {
D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
switch (channelBit) {

View File

@ -490,7 +490,6 @@ public:
void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) override;
// color must be 0, for now.
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
void BindFramebufferForRead(Framebuffer *fbo) override {}
uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) override;

View File

@ -466,13 +466,12 @@ public:
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) override;
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
bool CopyFramebufferToMemorySync(int x, int y, int w, int h, Draw::DataFormat format, void *pixels) override;
bool CopyFramebufferToMemorySync(Framebuffer *src, int x, int y, int w, int h, Draw::DataFormat format, void *pixels) override;
// These functions should be self explanatory.
void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) override;
// color must be 0, for now.
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
void BindFramebufferForRead(Framebuffer *fbo) override;
uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) override;
@ -731,6 +730,37 @@ void OpenGLTexture::AutoGenMipmaps() {
}
}
class OpenGLFramebuffer : public Framebuffer, public GfxResourceHolder {
public:
OpenGLFramebuffer() {
register_gl_resource_holder(this, "framebuffer", 0);
}
~OpenGLFramebuffer();
void GLLost() override {
handle = 0;
color_texture = 0;
z_stencil_buffer = 0;
z_buffer = 0;
stencil_buffer = 0;
}
void GLRestore() override {
ELOG("Restoring framebuffers not yet implemented");
}
GLuint handle = 0;
GLuint color_texture = 0;
GLuint z_stencil_buffer = 0; // Either this is set, or the two below.
GLuint z_buffer = 0;
GLuint stencil_buffer = 0;
int width;
int height;
FBColorDepth colorDepth;
};
// TODO: Also output storage format (GL_RGBA8 etc) for modern GL usage.
static bool Thin3DFormatToFormatAndType(DataFormat fmt, GLuint &internalFormat, GLuint &format, GLuint &type, int &alignment) {
alignment = 4;
@ -840,7 +870,10 @@ void OpenGLTexture::SetImageData(int x, int y, int z, int width, int height, int
CHECK_GL_ERROR_IF_DEBUG();
}
bool OpenGLContext::CopyFramebufferToMemorySync(int x, int y, int w, int h, Draw::DataFormat dataFormat, void *pixels) {
bool OpenGLContext::CopyFramebufferToMemorySync(Framebuffer *src, int x, int y, int w, int h, Draw::DataFormat dataFormat, void *pixels) {
OpenGLFramebuffer *fb = (OpenGLFramebuffer *)src;
fbo_bind_fb_target(true, fb ? fb->handle : 0);
// Reads from the "bound for read" framebuffer.
if (gl_extensions.GLES3 || !gl_extensions.IsGLES)
glReadBuffer(GL_COLOR_ATTACHMENT0);
@ -1341,36 +1374,6 @@ void OpenGLInputLayout::Unapply() {
}
}
class OpenGLFramebuffer : public Framebuffer, public GfxResourceHolder {
public:
OpenGLFramebuffer() {
register_gl_resource_holder(this, "framebuffer", 0);
}
~OpenGLFramebuffer();
void GLLost() override {
handle = 0;
color_texture = 0;
z_stencil_buffer = 0;
z_buffer = 0;
stencil_buffer = 0;
}
void GLRestore() override {
ELOG("Restoring framebuffers not yet implemented");
}
GLuint handle = 0;
GLuint color_texture = 0;
GLuint z_stencil_buffer = 0; // Either this is set, or the two below.
GLuint z_buffer = 0;
GLuint stencil_buffer = 0;
int width;
int height;
FBColorDepth colorDepth;
};
// On PC, we always use GL_DEPTH24_STENCIL8.
// On Android, we try to use what's available.
@ -1685,13 +1688,6 @@ void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Render
CHECK_GL_ERROR_IF_DEBUG();
}
// For GL_EXT_FRAMEBUFFER_BLIT and similar.
void OpenGLContext::BindFramebufferForRead(Framebuffer *fbo) {
OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo;
fbo_bind_fb_target(true, fb->handle);
CHECK_GL_ERROR_IF_DEBUG();
}
void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int srcX, int srcY, int srcZ, Framebuffer *fbdst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) {
OpenGLFramebuffer *src = (OpenGLFramebuffer *)fbsrc;
OpenGLFramebuffer *dst = (OpenGLFramebuffer *)fbdst;

View File

@ -392,7 +392,6 @@ public:
void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) override;
// color must be 0, for now.
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
void BindFramebufferForRead(Framebuffer *fbo) override;
uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) override;
@ -2022,8 +2021,6 @@ void VKContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChanne
fb->color.layout = barrier.newLayout;
}
void VKContext::BindFramebufferForRead(Framebuffer *fbo) { /* noop */ }
uintptr_t VKContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) {
// TODO: Insert transition at the end of the previous command buffer, or the one that rendered to it last.
VKFramebuffer *fb = (VKFramebuffer *)fbo;