uses the ARB_framebuffer_object syntax

also require this extention (OGL3.0), but it have one _realy_ big advantage:
- now it's possible to blit between different texture sizes, so all util draw calls can be implemented as blit
This commit is contained in:
degasus 2013-01-03 12:06:47 +01:00
parent 91023e133b
commit ecedf56eb4
6 changed files with 110 additions and 158 deletions

View File

@ -26,8 +26,6 @@
namespace OGL namespace OGL
{ {
extern bool s_bHaveFramebufferBlit; // comes from Render.cpp. ugly.
static GLuint s_VBO = 0; static GLuint s_VBO = 0;
static GLuint s_VAO = 0; static GLuint s_VAO = 0;
static MathUtil::Rectangle<float> s_cached_sourcerc; static MathUtil::Rectangle<float> s_cached_sourcerc;
@ -87,7 +85,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
// Create EFB target. // Create EFB target.
glGenFramebuffersEXT(1, &m_efbFramebuffer); glGenFramebuffers(1, &m_efbFramebuffer);
if (m_msaaSamples <= 1) if (m_msaaSamples <= 1)
{ {
@ -98,20 +96,20 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
m_efbColor = glObj[0]; m_efbColor = glObj[0];
m_efbDepth = glObj[1]; m_efbDepth = glObj[1];
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbColor); glBindTexture(GL_TEXTURE_RECTANGLE, m_efbColor);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbDepth); glBindTexture(GL_TEXTURE_RECTANGLE, m_efbDepth);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE, 0);
// Bind target textures to the EFB framebuffer. // Bind target textures to the EFB framebuffer.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbColor, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, m_efbColor, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbDepth, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_RECTANGLE, m_efbDepth, 0);
GL_REPORT_FBO_ERROR(); GL_REPORT_FBO_ERROR();
} }
@ -124,66 +122,66 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
// Create EFB target renderbuffers. // Create EFB target renderbuffers.
GLuint glObj[2]; GLuint glObj[2];
glGenRenderbuffersEXT(2, glObj); glGenRenderbuffers(2, glObj);
m_efbColor = glObj[0]; m_efbColor = glObj[0];
m_efbDepth = glObj[1]; m_efbDepth = glObj[1];
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbColor); glBindRenderbuffer(GL_RENDERBUFFER, m_efbColor);
if (m_msaaCoverageSamples) if (m_msaaCoverageSamples)
glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight); glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER, m_msaaCoverageSamples, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
else else
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight); glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbDepth); glBindRenderbuffer(GL_RENDERBUFFER, m_efbDepth);
if (m_msaaCoverageSamples) if (m_msaaCoverageSamples)
glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight); glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER, m_msaaCoverageSamples, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
else else
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight); glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0);
// Bind target renderbuffers to EFB framebuffer. // Bind target renderbuffers to EFB framebuffer.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_efbColor); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_efbColor);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_efbDepth); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_efbDepth);
GL_REPORT_FBO_ERROR(); GL_REPORT_FBO_ERROR();
// Create resolved targets for transferring multisampled EFB to texture. // Create resolved targets for transferring multisampled EFB to texture.
glGenFramebuffersEXT(1, &m_resolvedFramebuffer); glGenFramebuffers(1, &m_resolvedFramebuffer);
glGenTextures(2, glObj); glGenTextures(2, glObj);
m_resolvedColorTexture = glObj[0]; m_resolvedColorTexture = glObj[0];
m_resolvedDepthTexture = glObj[1]; m_resolvedDepthTexture = glObj[1];
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture); glBindTexture(GL_TEXTURE_RECTANGLE, m_resolvedColorTexture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture); glBindTexture(GL_TEXTURE_RECTANGLE, m_resolvedDepthTexture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE, 0);
// Bind resolved textures to resolved framebuffer. // Bind resolved textures to resolved framebuffer.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_resolvedFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_resolvedFramebuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, m_resolvedColorTexture, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_RECTANGLE, m_resolvedDepthTexture, 0);
GL_REPORT_FBO_ERROR(); GL_REPORT_FBO_ERROR();
// Return to EFB framebuffer. // Return to EFB framebuffer.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer);
} }
// Create XFB framebuffer; targets will be created elsewhere. // Create XFB framebuffer; targets will be created elsewhere.
glGenFramebuffersEXT(1, &m_xfbFramebuffer); glGenFramebuffers(1, &m_xfbFramebuffer);
// Generate VBO & VAO - and initialize the VAO for "Draw" // Generate VBO & VAO - and initialize the VAO for "Draw"
glGenBuffers(1, &s_VBO); glGenBuffers(1, &s_VBO);
@ -216,7 +214,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
FramebufferManager::~FramebufferManager() FramebufferManager::~FramebufferManager()
{ {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteBuffers(1, &s_VBO); glDeleteBuffers(1, &s_VBO);
glDeleteVertexArrays(1, &s_VAO); glDeleteVertexArrays(1, &s_VAO);
@ -227,7 +225,7 @@ FramebufferManager::~FramebufferManager()
glObj[0] = m_efbFramebuffer; glObj[0] = m_efbFramebuffer;
glObj[1] = m_resolvedFramebuffer; glObj[1] = m_resolvedFramebuffer;
glObj[2] = m_xfbFramebuffer; glObj[2] = m_xfbFramebuffer;
glDeleteFramebuffersEXT(3, glObj); glDeleteFramebuffers(3, glObj);
m_efbFramebuffer = 0; m_efbFramebuffer = 0;
m_xfbFramebuffer = 0; m_xfbFramebuffer = 0;
@ -242,7 +240,7 @@ FramebufferManager::~FramebufferManager()
if (m_msaaSamples <= 1) if (m_msaaSamples <= 1)
glDeleteTextures(2, glObj); glDeleteTextures(2, glObj);
else else
glDeleteRenderbuffersEXT(2, glObj); glDeleteRenderbuffers(2, glObj);
m_efbColor = 0; m_efbColor = 0;
m_efbDepth = 0; m_efbDepth = 0;
} }
@ -262,16 +260,16 @@ GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc)
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight); targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
// Resolve. // Resolve.
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_efbFramebuffer);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolvedFramebuffer);
glBlitFramebufferEXT( glBlitFramebuffer(
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom, targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom, targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
GL_COLOR_BUFFER_BIT, GL_NEAREST GL_COLOR_BUFFER_BIT, GL_NEAREST
); );
// Return to EFB. // Return to EFB.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer);
return m_resolvedColorTexture; return m_resolvedColorTexture;
} }
@ -292,16 +290,16 @@ GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc)
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight); targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
// Resolve. // Resolve.
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_efbFramebuffer);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolvedFramebuffer);
glBlitFramebufferEXT( glBlitFramebuffer(
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom, targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom, targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
GL_DEPTH_BUFFER_BIT, GL_NEAREST GL_DEPTH_BUFFER_BIT, GL_NEAREST
); );
// Return to EFB. // Return to EFB.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer);
return m_resolvedDepthTexture; return m_resolvedDepthTexture;
} }
@ -322,7 +320,7 @@ void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c
void FramebufferManager::SetFramebuffer(GLuint fb) void FramebufferManager::SetFramebuffer(GLuint fb)
{ {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb != 0 ? fb : GetEFBFramebuffer()); glBindFramebuffer(GL_FRAMEBUFFER, fb != 0 ? fb : GetEFBFramebuffer());
} }
// Apply AA if enabled // Apply AA if enabled
@ -341,7 +339,7 @@ void XFBSource::Draw(const MathUtil::Rectangle<float> &sourcerc,
{ {
// Texture map xfbSource->texture onto the main buffer // Texture map xfbSource->texture onto the main buffer
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture(GL_TEXTURE_RECTANGLE, texture);
if(!(s_cached_sourcerc == sourcerc) || !(s_cached_drawrc == drawrc)) { if(!(s_cached_sourcerc == sourcerc) || !(s_cached_drawrc == drawrc)) {
GLfloat vertices[] = { GLfloat vertices[] = {
@ -384,45 +382,13 @@ void XFBSource::CopyEFB(float Gamma)
{ {
// Copy EFB data to XFB and restore render target again // Copy EFB data to XFB and restore render target again
#if 0 glBindFramebuffer(GL_FRAMEBUFFER, FramebufferManager::GetEFBFramebuffer());
if (m_msaaSamples <= 1)
#else
if (!s_bHaveFramebufferBlit)
#endif
{
// Just copy the EFB directly.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferManager::GetEFBFramebuffer()); glBindTexture(GL_TEXTURE_RECTANGLE, texture);
glCopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, 4, 0, 0, texWidth, texHeight, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture(GL_TEXTURE_RECTANGLE, 0);
glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, 0, 0, texWidth, texHeight, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
}
else
{
// OpenGL cannot copy directly from a multisampled framebuffer, so use
// EXT_framebuffer_blit.
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetEFBFramebuffer());
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, FramebufferManager::GetXFBFramebuffer());
// Bind texture.
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, texture, 0);
GL_REPORT_FBO_ERROR();
glBlitFramebufferEXT(
0, 0, texWidth, texHeight,
0, 0, texWidth, texHeight,
GL_COLOR_BUFFER_BIT, GL_NEAREST
);
// Unbind texture.
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
// Return to EFB.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferManager::GetEFBFramebuffer());
}
} }
XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height) XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height)
@ -433,17 +399,15 @@ XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, un
#if 0// XXX: Some video drivers don't handle glCopyTexImage2D correctly, so use EXT_framebuffer_blit whenever possible. #if 0// XXX: Some video drivers don't handle glCopyTexImage2D correctly, so use EXT_framebuffer_blit whenever possible.
if (m_msaaSamples > 1) if (m_msaaSamples > 1)
#else
if (s_bHaveFramebufferBlit)
#endif #endif
{ {
// In MSAA mode, allocate the texture image here. In non-MSAA mode, // In MSAA mode, allocate the texture image here. In non-MSAA mode,
// the image will be allocated by glCopyTexImage2D (later). // the image will be allocated by glCopyTexImage2D (later).
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture(GL_TEXTURE_RECTANGLE, texture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, target_width, target_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, 4, target_width, target_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE, 0);
} }
return new XFBSource(texture); return new XFBSource(texture);

View File

@ -157,32 +157,26 @@ void OpenGL_ReportARBProgramError()
bool OpenGL_ReportFBOError(const char *function, const char *file, int line) bool OpenGL_ReportFBOError(const char *function, const char *file, int line)
{ {
#ifndef USE_GLES #ifndef USE_GLES
unsigned int fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); unsigned int fbo_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (fbo_status != GL_FRAMEBUFFER_COMPLETE_EXT) if (fbo_status != GL_FRAMEBUFFER_COMPLETE)
{ {
const char *error = "-"; const char *error = "unknown error";
switch (fbo_status) switch (fbo_status)
{ {
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
error = "INCOMPLETE_ATTACHMENT_EXT"; error = "INCOMPLETE_ATTACHMENT";
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
error = "INCOMPLETE_MISSING_ATTACHMENT_EXT"; error = "INCOMPLETE_MISSING_ATTACHMENT";
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
error = "INCOMPLETE_DIMENSIONS_EXT"; error = "INCOMPLETE_DRAW_BUFFER";
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
error = "INCOMPLETE_FORMATS_EXT"; error = "INCOMPLETE_READ_BUFFER";
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: case GL_FRAMEBUFFER_UNSUPPORTED:
error = "INCOMPLETE_DRAW_BUFFER_EXT"; error = "UNSUPPORTED";
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
error = "INCOMPLETE_READ_BUFFER_EXT";
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
error = "UNSUPPORTED_EXT";
break; break;
} }
ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL FBO error - %s\n", ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL FBO error - %s\n",

View File

@ -57,7 +57,7 @@ void OpenGL_ReportARBProgramError();
GLuint OpenGL_ReportGLError(const char *function, const char *file, int line); GLuint OpenGL_ReportGLError(const char *function, const char *file, int line);
bool OpenGL_ReportFBOError(const char *function, const char *file, int line); bool OpenGL_ReportFBOError(const char *function, const char *file, int line);
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST) || 1
#define GL_REPORT_ERROR() OpenGL_ReportGLError(__FUNCTION__, __FILE__, __LINE__) #define GL_REPORT_ERROR() OpenGL_ReportGLError(__FUNCTION__, __FILE__, __LINE__)
#define GL_REPORT_ERRORD() OpenGL_ReportGLError(__FUNCTION__, __FILE__, __LINE__) #define GL_REPORT_ERRORD() OpenGL_ReportGLError(__FUNCTION__, __FILE__, __LINE__)
#define GL_REPORT_FBO_ERROR() OpenGL_ReportFBOError(__FUNCTION__, __FILE__, __LINE__) #define GL_REPORT_FBO_ERROR() OpenGL_ReportFBOError(__FUNCTION__, __FILE__, __LINE__)

View File

@ -121,7 +121,6 @@ static int s_MSAASamples = 1;
static int s_MSAACoverageSamples = 0; static int s_MSAACoverageSamples = 0;
static int s_LastMultisampleMode = 0; static int s_LastMultisampleMode = 0;
bool s_bHaveFramebufferBlit = false; // export to FramebufferManager.cpp
static bool s_bHaveCoverageMSAA = false; static bool s_bHaveCoverageMSAA = false;
static u32 s_blendMode; static u32 s_blendMode;
@ -201,10 +200,6 @@ void HandleCgError(CGcontext ctx, CGerror err, void* appdata)
int GetNumMSAASamples(int MSAAMode) int GetNumMSAASamples(int MSAAMode)
{ {
// required for MSAA
if (!s_bHaveFramebufferBlit)
return 1;
switch (MSAAMode) switch (MSAAMode)
{ {
case MULTISAMPLE_OFF: case MULTISAMPLE_OFF:
@ -311,13 +306,6 @@ Renderer::Renderer()
return; // TODO: fail return; // TODO: fail
} }
if (!GLEW_EXT_framebuffer_object)
{
ERROR_LOG(VIDEO, "GPU: ERROR: Need GL_EXT_framebufer_object for multiple render targets.\n"
"GPU: Does your video card support OpenGL 2.x?");
bSuccess = false;
}
if (!GLEW_EXT_secondary_color) if (!GLEW_EXT_secondary_color)
{ {
ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_EXT_secondary_color.\n" ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_EXT_secondary_color.\n"
@ -325,6 +313,13 @@ Renderer::Renderer()
bSuccess = false; bSuccess = false;
} }
if (!GLEW_ARB_framebuffer_object)
{
ERROR_LOG(VIDEO, "GPU: ERROR: Need GL_ARB_framebufer_object for multiple render targets.\n"
"GPU: Does your video card support OpenGL 3.0?");
bSuccess = false;
}
if (!GLEW_ARB_vertex_array_object) if (!GLEW_ARB_vertex_array_object)
{ {
ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_vertex_array_object.\n" ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_vertex_array_object.\n"
@ -332,7 +327,6 @@ Renderer::Renderer()
bSuccess = false; bSuccess = false;
} }
s_bHaveFramebufferBlit = strstr(ptoken, "GL_EXT_framebuffer_blit") != NULL;
s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL; s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL;
s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode; s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode;
@ -403,7 +397,7 @@ Renderer::Renderer()
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height, g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
s_MSAASamples, s_MSAACoverageSamples); s_MSAASamples, s_MSAACoverageSamples);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glDrawBuffer(GL_COLOR_ATTACHMENT0);
if (GL_REPORT_ERROR() != GL_NO_ERROR) if (GL_REPORT_ERROR() != GL_NO_ERROR)
bSuccess = false; bSuccess = false;
@ -524,7 +518,7 @@ Renderer::Renderer()
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, GetTargetWidth(), GetTargetHeight()); glScissor(0, 0, GetTargetWidth(), GetTargetHeight());
glBlendColorEXT(0, 0, 0, 0.5f); glBlendColor(0, 0, 0, 0.5f);
glClearDepth(1.0f); glClearDepth(1.0f);
// legacy multitexturing: select texture channel only. // legacy multitexturing: select texture channel only.
@ -866,7 +860,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
{ {
// Resolve our rectangle. // Resolve our rectangle.
FramebufferManager::GetEFBDepthTexture(efbPixelRc); FramebufferManager::GetEFBDepthTexture(efbPixelRc);
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer()); glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetResolvedFramebuffer());
} }
u32* depthMap = new u32[targetPixelRcWidth * targetPixelRcHeight]; u32* depthMap = new u32[targetPixelRcWidth * targetPixelRcHeight];
@ -915,7 +909,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
{ {
// Resolve our rectangle. // Resolve our rectangle.
FramebufferManager::GetEFBColorTexture(efbPixelRc); FramebufferManager::GetEFBColorTexture(efbPixelRc);
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer()); glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetResolvedFramebuffer());
} }
u32* colorMap = new u32[targetPixelRcWidth * targetPixelRcHeight]; u32* colorMap = new u32[targetPixelRcWidth * targetPixelRcHeight];
@ -1188,10 +1182,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// Texture map s_xfbTexture onto the main buffer // Texture map s_xfbTexture onto the main buffer
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_RECTANGLE_ARB); glEnable(GL_TEXTURE_RECTANGLE);
// Use linear filtering. // Use linear filtering.
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// We must call ApplyShader here even if no post proc is selected - it takes // We must call ApplyShader here even if no post proc is selected - it takes
// care of disabling it in that case. It returns false in case of no post processing. // care of disabling it in that case. It returns false in case of no post processing.
@ -1203,7 +1197,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
{ {
// draw each xfb source // draw each xfb source
// Render to the real buffer now. // Render to the real buffer now.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); // switch to the window backbuffer
for (u32 i = 0; i < xfbCount; ++i) for (u32 i = 0; i < xfbCount; ++i)
{ {
@ -1262,7 +1256,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
TargetRectangle targetRc = ConvertEFBRectangle(rc); TargetRectangle targetRc = ConvertEFBRectangle(rc);
GLuint read_texture = FramebufferManager::ResolveAndGetRenderTarget(rc); GLuint read_texture = FramebufferManager::ResolveAndGetRenderTarget(rc);
// Render to the real buffer now. // Render to the real buffer now.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); // switch to the window backbuffer
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture);
if(!( s_cached_targetRc == targetRc)) { if(!( s_cached_targetRc == targetRc)) {
@ -1464,7 +1458,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
delete g_framebuffer_manager; delete g_framebuffer_manager;
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height, g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
s_MSAASamples, s_MSAACoverageSamples); s_MSAASamples, s_MSAACoverageSamples);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glDrawBuffer(GL_COLOR_ATTACHMENT0);
} }
} }

View File

@ -295,18 +295,18 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture) if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture)
{ {
if (s_TempFramebuffer == 0) if (s_TempFramebuffer == 0)
glGenFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer); glGenFramebuffers(1, (GLuint*)&s_TempFramebuffer);
FramebufferManager::SetFramebuffer(s_TempFramebuffer); FramebufferManager::SetFramebuffer(s_TempFramebuffer);
// Bind texture to temporary framebuffer // Bind texture to temporary framebuffer
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
GL_REPORT_FBO_ERROR(); GL_REPORT_FBO_ERROR();
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glDrawBuffer(GL_COLOR_ATTACHMENT0);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_RECTANGLE_ARB); glEnable(GL_TEXTURE_RECTANGLE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture); glBindTexture(GL_TEXTURE_RECTANGLE, read_texture);
glViewport(0, 0, virtual_width, virtual_height); glViewport(0, 0, virtual_width, virtual_height);
@ -370,7 +370,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
// Unbind texture from temporary framebuffer // Unbind texture from temporary framebuffer
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
} }
if (false == g_ActiveConfig.bCopyEFBToTexture) if (false == g_ActiveConfig.bCopyEFBToTexture)
@ -461,7 +461,7 @@ TextureCache::~TextureCache()
if (s_TempFramebuffer) if (s_TempFramebuffer)
{ {
glDeleteFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer); glDeleteFramebuffers(1, (GLuint*)&s_TempFramebuffer);
s_TempFramebuffer = 0; s_TempFramebuffer = 0;
} }
} }
@ -470,7 +470,7 @@ void TextureCache::DisableStage(unsigned int stage)
{ {
glActiveTexture(GL_TEXTURE0 + stage); glActiveTexture(GL_TEXTURE0 + stage);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_RECTANGLE_ARB); glDisable(GL_TEXTURE_RECTANGLE);
} }
} }

View File

@ -147,7 +147,7 @@ FRAGMENTSHADER &GetOrCreateEncodingShader(u32 format)
void Init() void Init()
{ {
glGenFramebuffersEXT(1, &s_texConvFrameBuffer); glGenFramebuffers(1, &s_texConvFrameBuffer);
glGenBuffers(1, &s_encode_VBO ); glGenBuffers(1, &s_encode_VBO );
glGenVertexArrays(1, &s_encode_VAO ); glGenVertexArrays(1, &s_encode_VAO );
@ -179,10 +179,10 @@ void Init()
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenRenderbuffersEXT(1, &s_dstRenderBuffer); glGenRenderbuffers(1, &s_dstRenderBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, s_dstRenderBuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, renderBufferWidth, renderBufferHeight); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, renderBufferWidth, renderBufferHeight);
s_srcTextureWidth = 0; s_srcTextureWidth = 0;
s_srcTextureHeight = 0; s_srcTextureHeight = 0;
@ -199,8 +199,8 @@ void Init()
void Shutdown() void Shutdown()
{ {
glDeleteTextures(1, &s_srcTexture); glDeleteTextures(1, &s_srcTexture);
glDeleteRenderbuffersEXT(1, &s_dstRenderBuffer); glDeleteRenderbuffers(1, &s_dstRenderBuffer);
glDeleteFramebuffersEXT(1, &s_texConvFrameBuffer); glDeleteFramebuffers(1, &s_texConvFrameBuffer);
glDeleteBuffers(1, &s_encode_VBO ); glDeleteBuffers(1, &s_encode_VBO );
glDeleteVertexArrays(1, &s_encode_VAO ); glDeleteVertexArrays(1, &s_encode_VAO );
glDeleteBuffers(1, &s_decode_VBO ); glDeleteBuffers(1, &s_decode_VBO );
@ -227,8 +227,8 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar
// attach render buffer as color destination // attach render buffer as color destination
FramebufferManager::SetFramebuffer(s_texConvFrameBuffer); FramebufferManager::SetFramebuffer(s_texConvFrameBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, s_dstRenderBuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_dstRenderBuffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, s_dstRenderBuffer);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
for (int i = 1; i < 8; ++i) for (int i = 1; i < 8; ++i)
@ -236,18 +236,18 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar
// set source texture // set source texture
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_RECTANGLE_ARB); glEnable(GL_TEXTURE_RECTANGLE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, srcTexture); glBindTexture(GL_TEXTURE_RECTANGLE, srcTexture);
if (linearFilter) if (linearFilter)
{ {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} }
else else
{ {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
} }
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
@ -404,7 +404,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
// attach destTexture as color destination // attach destTexture as color destination
FramebufferManager::SetFramebuffer(s_texConvFrameBuffer); FramebufferManager::SetFramebuffer(s_texConvFrameBuffer);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, destTexture); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, destTexture);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, destTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, destTexture, 0);
GL_REPORT_FBO_ERROR(); GL_REPORT_FBO_ERROR();
@ -414,18 +414,18 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
// activate source texture // activate source texture
// set srcAddr as data for source texture // set srcAddr as data for source texture
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_RECTANGLE_ARB); glEnable(GL_TEXTURE_RECTANGLE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_srcTexture); glBindTexture(GL_TEXTURE_RECTANGLE, s_srcTexture);
// TODO: make this less slow. (How?) // TODO: make this less slow. (How?)
if((GLsizei)s_srcTextureWidth == (GLsizei)srcFmtWidth && (GLsizei)s_srcTextureHeight == (GLsizei)srcHeight) if((GLsizei)s_srcTextureWidth == (GLsizei)srcFmtWidth && (GLsizei)s_srcTextureHeight == (GLsizei)srcHeight)
{ {
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,0,0,s_srcTextureWidth, s_srcTextureHeight, glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0,0,0,s_srcTextureWidth, s_srcTextureHeight,
GL_BGRA, GL_UNSIGNED_BYTE, srcAddr); GL_BGRA, GL_UNSIGNED_BYTE, srcAddr);
} }
else else
{ {
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, (GLsizei)srcFmtWidth, (GLsizei)srcHeight, glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, (GLsizei)srcFmtWidth, (GLsizei)srcHeight,
0, GL_BGRA, GL_UNSIGNED_BYTE, srcAddr); 0, GL_BGRA, GL_UNSIGNED_BYTE, srcAddr);
s_srcTextureWidth = (GLsizei)srcFmtWidth; s_srcTextureWidth = (GLsizei)srcFmtWidth;
s_srcTextureHeight = (GLsizei)srcHeight; s_srcTextureHeight = (GLsizei)srcHeight;
@ -467,7 +467,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
// reset state // reset state
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, 0, 0);
TextureCache::DisableStage(0); TextureCache::DisableStage(0);
VertexShaderManager::SetViewportChanged(); VertexShaderManager::SetViewportChanged();