implement emulate efb format changes on ogl backend
This commit is contained in:
parent
a963c621dc
commit
c6ae08fc39
|
@ -29,6 +29,12 @@ GLuint FramebufferManager::m_resolvedDepthTexture;
|
|||
|
||||
GLuint FramebufferManager::m_xfbFramebuffer;
|
||||
|
||||
// reinterpret pixel format
|
||||
GLuint FramebufferManager::m_pixel_format_vao;
|
||||
GLuint FramebufferManager::m_pixel_format_vbo;
|
||||
SHADER FramebufferManager::m_pixel_format_shaders[2];
|
||||
|
||||
|
||||
FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples)
|
||||
{
|
||||
m_efbFramebuffer = 0;
|
||||
|
@ -65,10 +71,11 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
|
|||
{
|
||||
// EFB targets will be textures in non-MSAA mode.
|
||||
|
||||
GLuint glObj[2];
|
||||
glGenTextures(2, glObj);
|
||||
GLuint glObj[3];
|
||||
glGenTextures(3, glObj);
|
||||
m_efbColor = glObj[0];
|
||||
m_efbDepth = glObj[1];
|
||||
m_resolvedColorTexture = glObj[2]; // needed for pixel format convertion
|
||||
|
||||
glBindTexture(getFbType(), m_efbColor);
|
||||
glTexParameteri(getFbType(), GL_TEXTURE_MAX_LEVEL, 0);
|
||||
|
@ -78,6 +85,10 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
|
|||
glTexParameteri(getFbType(), GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexImage2D(getFbType(), 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
|
||||
|
||||
glBindTexture(getFbType(), m_resolvedColorTexture);
|
||||
glTexParameteri(getFbType(), GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexImage2D(getFbType(), 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
// Bind target textures to the EFB framebuffer.
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer);
|
||||
|
@ -164,6 +175,60 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
|
|||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
glClearDepthf(1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// reinterpret pixel format
|
||||
glGenBuffers(1, &m_pixel_format_vbo);
|
||||
glGenVertexArrays(1, &m_pixel_format_vao);
|
||||
glBindVertexArray(m_pixel_format_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_pixel_format_vbo);
|
||||
glEnableVertexAttribArray(SHADER_POSITION_ATTRIB);
|
||||
glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*2, NULL);
|
||||
|
||||
float vertices[] = {
|
||||
-1.0, -1.0,
|
||||
1.0, -1.0,
|
||||
-1.0, 1.0,
|
||||
1.0, 1.0,
|
||||
};
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
char vs[] =
|
||||
"ATTRIN vec2 rawpos;\n"
|
||||
"void main(void) {\n"
|
||||
" gl_Position = vec4(rawpos,0,1);\n"
|
||||
"}\n";
|
||||
|
||||
char ps_rgba6_to_rgb8[] =
|
||||
"uniform sampler2DRect samp9;\n"
|
||||
"COLOROUT(ocol0)\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" ivec4 src6 = ivec4(round(texture2DRect(samp9, gl_FragCoord.xy) * 63.f));\n"
|
||||
" ivec4 dst8;\n"
|
||||
" dst8.r = (src6.r << 2) | (src6.g >> 4);\n"
|
||||
" dst8.g = ((src6.g & 0xF) << 4) | (src6.b >> 2);\n"
|
||||
" dst8.b = ((src6.b & 0x3) << 6) | src6.a;\n"
|
||||
" dst8.a = 255;\n"
|
||||
" ocol0 = float4(dst8) / 255.f;\n"
|
||||
"}";
|
||||
|
||||
char ps_rgb8_to_rgba6[] =
|
||||
"uniform sampler2DRect samp9;\n"
|
||||
"COLOROUT(ocol0)\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" ivec4 src8 = ivec4(round(texture2DRect(samp9, gl_FragCoord.xy) * 255.f));\n"
|
||||
" ivec4 dst6;\n"
|
||||
" dst6.r = src8.r >> 2;\n"
|
||||
" dst6.g = ((src8.r & 0x3) << 4) | (src8.g >> 4);\n"
|
||||
" dst6.b = ((src8.g & 0xF) << 2) | (src8.b >> 6);\n"
|
||||
" dst6.a = src8.b & 0x3F;\n"
|
||||
" ocol0 = float4(dst6) / 63.f;\n"
|
||||
"}";
|
||||
|
||||
ProgramShaderCache::CompileShader(m_pixel_format_shaders[0], vs, ps_rgb8_to_rgba6);
|
||||
ProgramShaderCache::CompileShader(m_pixel_format_shaders[1], vs, ps_rgba6_to_rgb8);
|
||||
|
||||
}
|
||||
|
||||
FramebufferManager::~FramebufferManager()
|
||||
|
@ -195,6 +260,12 @@ FramebufferManager::~FramebufferManager()
|
|||
glDeleteRenderbuffers(2, glObj);
|
||||
m_efbColor = 0;
|
||||
m_efbDepth = 0;
|
||||
|
||||
// reinterpret pixel format
|
||||
glDeleteVertexArrays(1, &m_pixel_format_vao);
|
||||
glDeleteBuffers(1, &m_pixel_format_vbo);
|
||||
m_pixel_format_shaders[0].Destroy();
|
||||
m_pixel_format_shaders[1].Destroy();
|
||||
}
|
||||
|
||||
GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc)
|
||||
|
@ -286,6 +357,49 @@ GLuint FramebufferManager::ResolveAndGetDepthTarget(const EFBRectangle &source_r
|
|||
return GetEFBDepthTexture(source_rect);
|
||||
}
|
||||
|
||||
void FramebufferManager::ReinterpretPixelData(unsigned int convtype)
|
||||
{
|
||||
g_renderer->ResetAPIState();
|
||||
|
||||
GLuint src_texture = 0;
|
||||
|
||||
if(m_msaaSamples > 1)
|
||||
{
|
||||
// MSAA mode, so resolve first
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_efbFramebuffer);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolvedFramebuffer);
|
||||
glBlitFramebuffer(
|
||||
0, 0, m_targetWidth, m_targetHeight,
|
||||
0, 0, m_targetWidth, m_targetHeight,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST
|
||||
);
|
||||
|
||||
// Return to EFB.
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_efbFramebuffer);
|
||||
|
||||
src_texture = m_resolvedColorTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
// non-MSAA mode, so switch textures
|
||||
src_texture = m_efbColor;
|
||||
m_efbColor = m_resolvedColorTexture;
|
||||
m_resolvedColorTexture = src_texture;
|
||||
|
||||
// also switch them on fbo
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, getFbType(), m_efbColor, 0);
|
||||
}
|
||||
glViewport(0,0, m_targetWidth, m_targetHeight);
|
||||
glActiveTexture(GL_TEXTURE0 + 9);
|
||||
glBindTexture(getFbType(), src_texture);
|
||||
|
||||
m_pixel_format_shaders[convtype ? 1 : 0].Bind();
|
||||
glBindVertexArray(m_pixel_format_vao);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
g_renderer->RestoreAPIState();
|
||||
}
|
||||
|
||||
XFBSource::~XFBSource()
|
||||
{
|
||||
glDeleteRenderbuffers(1, &renderbuf);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "GLUtil.h"
|
||||
#include "FramebufferManagerBase.h"
|
||||
#include "ProgramShaderCache.h"
|
||||
#include "Render.h"
|
||||
|
||||
// On the GameCube, the game sends a request for the graphics processor to
|
||||
|
@ -96,6 +97,10 @@ public:
|
|||
// After calling this, before you render anything else, you MUST bind the framebuffer you want to draw to.
|
||||
static GLuint ResolveAndGetDepthTarget(const EFBRectangle &rect);
|
||||
|
||||
// Convert EFB content on pixel format change.
|
||||
// convtype=0 -> rgb8->rgba6, convtype=2 -> rgba6->rgb8
|
||||
static void ReinterpretPixelData(unsigned int convtype);
|
||||
|
||||
private:
|
||||
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
|
||||
void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc);
|
||||
|
@ -111,12 +116,17 @@ private:
|
|||
static GLuint m_efbColor; // Renderbuffer in MSAA mode; Texture otherwise
|
||||
static GLuint m_efbDepth; // Renderbuffer in MSAA mode; Texture otherwise
|
||||
|
||||
// Only used in MSAA mode.
|
||||
static GLuint m_resolvedFramebuffer;
|
||||
// Only used in MSAA mode and to convert pixel format
|
||||
static GLuint m_resolvedFramebuffer; // will be hot swapped with m_efbColor on non-msaa pixel format change
|
||||
static GLuint m_resolvedColorTexture;
|
||||
static GLuint m_resolvedDepthTexture;
|
||||
|
||||
static GLuint m_xfbFramebuffer; // Only used in MSAA mode
|
||||
|
||||
// For pixel format draw
|
||||
static GLuint m_pixel_format_vbo;
|
||||
static GLuint m_pixel_format_vao;
|
||||
static SHADER m_pixel_format_shaders[2];
|
||||
};
|
||||
|
||||
} // namespace OGL
|
||||
|
|
|
@ -547,13 +547,6 @@ Renderer::Renderer()
|
|||
// options while running
|
||||
g_Config.bRunning = true;
|
||||
|
||||
if (GL_REPORT_ERROR() != GL_NO_ERROR)
|
||||
bSuccess = false;
|
||||
|
||||
// Initialize the FramebufferManager
|
||||
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
|
||||
s_MSAASamples, s_MSAACoverageSamples);
|
||||
|
||||
if (GL_REPORT_ERROR() != GL_NO_ERROR)
|
||||
bSuccess = false;
|
||||
|
||||
|
@ -601,12 +594,12 @@ Renderer::~Renderer()
|
|||
if (scrshotThread.joinable())
|
||||
scrshotThread.join();
|
||||
#endif
|
||||
|
||||
delete g_framebuffer_manager;
|
||||
}
|
||||
|
||||
void Renderer::Shutdown()
|
||||
{
|
||||
delete g_framebuffer_manager;
|
||||
|
||||
g_Config.bRunning = false;
|
||||
UpdateActiveConfig();
|
||||
|
||||
|
@ -621,6 +614,10 @@ void Renderer::Shutdown()
|
|||
|
||||
void Renderer::Init()
|
||||
{
|
||||
// Initialize the FramebufferManager
|
||||
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
|
||||
s_MSAASamples, s_MSAACoverageSamples);
|
||||
|
||||
s_pfont = new RasterFont();
|
||||
|
||||
ProgramShaderCache::CompileShader(s_ShowEFBCopyRegions,
|
||||
|
@ -1123,7 +1120,14 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
|
|||
|
||||
void Renderer::ReinterpretPixelData(unsigned int convtype)
|
||||
{
|
||||
// TODO
|
||||
if (convtype == 0 || convtype == 2)
|
||||
{
|
||||
FramebufferManager::ReinterpretPixelData(convtype);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Trying to reinterpret pixel data with unsupported conversion type %d", convtype);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::SetBlendMode(bool forceUpdate)
|
||||
|
|
|
@ -130,7 +130,7 @@ void InitBackendInfo()
|
|||
g_Config.backend_info.bUseMinimalMipCount = false;
|
||||
g_Config.backend_info.bSupports3DVision = false;
|
||||
//g_Config.backend_info.bSupportsDualSourceBlend = true; // is gpu dependent and must be set in renderer
|
||||
g_Config.backend_info.bSupportsFormatReinterpretation = false;
|
||||
g_Config.backend_info.bSupportsFormatReinterpretation = true;
|
||||
g_Config.backend_info.bSupportsPixelLighting = true;
|
||||
//g_Config.backend_info.bSupportsEarlyZ = true; // is gpu dependent and must be set in renderer
|
||||
|
||||
|
|
Loading…
Reference in New Issue