mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-22 01:40:30 +00:00
Slightly improved OpenGL error handling on Windows
This commit is contained in:
parent
f5bb835dcb
commit
94e485e695
@ -21,7 +21,6 @@
|
||||
#include <string>
|
||||
#include "../Globals.h"
|
||||
|
||||
|
||||
class PMixer
|
||||
{
|
||||
public:
|
||||
@ -30,8 +29,6 @@ public:
|
||||
virtual int Mix(short *stereoout, int numSamples) {memset(stereoout,0,numSamples*2*sizeof(short)); return numSamples;}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Host
|
||||
{
|
||||
public:
|
||||
@ -44,7 +41,7 @@ public:
|
||||
|
||||
virtual void SetDebugMode(bool mode) { }
|
||||
|
||||
virtual void InitGL() = 0;
|
||||
virtual bool InitGL(std::string *error_string) = 0;
|
||||
virtual void BeginFrame() {}
|
||||
virtual void ShutdownGL() = 0;
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "base/threadutil.h"
|
||||
#include "Log.h"
|
||||
#include "StringUtil.h"
|
||||
#include "../Globals.h"
|
||||
#include "EmuThread.h"
|
||||
#include "../Core/MemMap.h"
|
||||
@ -53,18 +54,25 @@ char *GetCurrentFilename()
|
||||
return fileToStart;
|
||||
}
|
||||
|
||||
DWORD TheThread(LPVOID x)
|
||||
{
|
||||
DWORD TheThread(LPVOID x) {
|
||||
setCurrentThreadName("EmuThread");
|
||||
|
||||
g_State.bEmuThreadStarted = true;
|
||||
|
||||
CoreParameter coreParameter;
|
||||
|
||||
host->UpdateUI();
|
||||
host->InitGL();
|
||||
|
||||
std::string error_string;
|
||||
if (!host->InitGL(&error_string)) {
|
||||
std::string full_error = StringFromFormat( "Failed initializing OpenGL. Try upgrading your graphics drivers.\n\nError message:\n\n%s", error_string.c_str());
|
||||
MessageBoxA(0, full_error.c_str(), "OpenGL Error", MB_OK | MB_ICONERROR);
|
||||
ERROR_LOG(BOOT, full_error.c_str());
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
INFO_LOG(BOOT, "Starting up hardware.");
|
||||
|
||||
CoreParameter coreParameter;
|
||||
coreParameter.fileToStart = fileToStart;
|
||||
coreParameter.enableSound = true;
|
||||
coreParameter.gpuCore = GPU_GLES;
|
||||
@ -81,7 +89,7 @@ DWORD TheThread(LPVOID x)
|
||||
coreParameter.startPaused = !g_Config.bAutoRun;
|
||||
coreParameter.useMediaEngine = false;
|
||||
|
||||
std::string error_string;
|
||||
error_string = "";
|
||||
if (!PSP_Init(coreParameter, &error_string))
|
||||
{
|
||||
ERROR_LOG(BOOT, "Error loading: %s", error_string.c_str());
|
||||
|
@ -30,37 +30,32 @@ void setVSync(int interval=1)
|
||||
wglSwapIntervalEXT(interval);
|
||||
}
|
||||
|
||||
void GL_Resized() // Resize And Initialize The GL Window
|
||||
{
|
||||
// Resize And Initialize The GL Window
|
||||
void GL_Resized() {
|
||||
if (!hWnd)
|
||||
return;
|
||||
RECT rc;
|
||||
GetWindowRect(hWnd,&rc);
|
||||
xres=rc.right-rc.left; //account for border :P
|
||||
yres=rc.bottom-rc.top;
|
||||
xres = rc.right - rc.left; //account for border :P
|
||||
yres = rc.bottom - rc.top;
|
||||
|
||||
//swidth=width; // Set Scissor Width To Window Width
|
||||
//sheight=height; // Set Scissor Height To Window Height
|
||||
if (yres==0) // Prevent A Divide By Zero By
|
||||
{
|
||||
yres=1; // Making Height Equal One
|
||||
}
|
||||
if (yres == 0)
|
||||
yres = 1;
|
||||
glstate.viewport.set(0, 0, xres, yres);
|
||||
glstate.viewport.restore();
|
||||
}
|
||||
|
||||
void GL_SwapBuffers()
|
||||
{
|
||||
void GL_SwapBuffers() {
|
||||
SwapBuffers(hDC);
|
||||
}
|
||||
|
||||
void FormatDebugOutputARB(char outStr[], size_t outStrSize, GLenum source, GLenum type,
|
||||
GLuint id, GLenum severity, const char *msg)
|
||||
{
|
||||
GLuint id, GLenum severity, const char *msg) {
|
||||
char sourceStr[32];
|
||||
const char *sourceFmt = "UNDEFINED(0x%04X)";
|
||||
switch(source)
|
||||
{
|
||||
switch(source) {
|
||||
case GL_DEBUG_SOURCE_API_ARB: sourceFmt = "API"; break;
|
||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: sourceFmt = "WINDOW_SYSTEM"; break;
|
||||
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: sourceFmt = "SHADER_COMPILER"; break;
|
||||
@ -72,8 +67,7 @@ void FormatDebugOutputARB(char outStr[], size_t outStrSize, GLenum source, GLenu
|
||||
|
||||
char typeStr[32];
|
||||
const char *typeFmt = "UNDEFINED(0x%04X)";
|
||||
switch(type)
|
||||
{
|
||||
switch(type) {
|
||||
case GL_DEBUG_TYPE_ERROR_ARB: typeFmt = "ERROR"; break;
|
||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: typeFmt = "DEPRECATED_BEHAVIOR"; break;
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: typeFmt = "UNDEFINED_BEHAVIOR"; break;
|
||||
@ -98,8 +92,7 @@ void FormatDebugOutputARB(char outStr[], size_t outStrSize, GLenum source, GLenu
|
||||
}
|
||||
|
||||
void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
|
||||
GLsizei length, const GLchar *message, GLvoid *userParam)
|
||||
{
|
||||
GLsizei length, const GLchar *message, GLvoid *userParam) {
|
||||
(void)length;
|
||||
FILE *outFile = (FILE*)userParam;
|
||||
char finalMessage[256];
|
||||
@ -107,15 +100,13 @@ void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
|
||||
ERROR_LOG(HLE, "GL: %s", finalMessage);
|
||||
}
|
||||
|
||||
bool GL_Init(HWND window)
|
||||
{
|
||||
bool GL_Init(HWND window, std::string *error_message) {
|
||||
*error_message = "ok";
|
||||
hWnd = window;
|
||||
GLuint PixelFormat; // Holds The Results After Searching For A Match
|
||||
GLuint PixelFormat;
|
||||
|
||||
hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
|
||||
|
||||
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
|
||||
{
|
||||
hInstance = GetModuleHandle(NULL);
|
||||
static const PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
|
||||
1, // Version Number
|
||||
PFD_DRAW_TO_WINDOW | // Format Must Support Window
|
||||
@ -127,65 +118,68 @@ bool GL_Init(HWND window)
|
||||
0, // No Alpha Buffer
|
||||
0, // Shift Bit Ignored
|
||||
0, // No Accumulation Buffer
|
||||
0, 0, 0, 0, // Accumulation Bits Ignored
|
||||
0, 0, 0, 0, // Accumulation Bits Ignored
|
||||
16, // 16Bit Z-Buffer (Depth Buffer)
|
||||
0, // No Stencil Buffer
|
||||
0, // No Auxiliary Buffer
|
||||
PFD_MAIN_PLANE, // Main Drawing Layer
|
||||
PFD_MAIN_PLANE, // Main Drawing Layer
|
||||
0, // Reserved
|
||||
0, 0, 0 // Layer Masks Ignored
|
||||
0, 0, 0 // Layer Masks Ignored
|
||||
};
|
||||
|
||||
if (!(hDC = GetDC(hWnd))) // Did We Get A Device Context?
|
||||
{
|
||||
MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
hDC = GetDC(hWnd);
|
||||
|
||||
if (!hDC) {
|
||||
*error_message = "Failed to get a device context.";
|
||||
return false; // Return FALSE
|
||||
}
|
||||
|
||||
if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?
|
||||
// Did Windows Find A Matching Pixel Format?
|
||||
if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd)))
|
||||
{
|
||||
MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
*error_message = "Can't Find A Suitable PixelFormat.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format?
|
||||
{
|
||||
MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
// Are We Able To Set The Pixel Format?
|
||||
if (!SetPixelFormat(hDC,PixelFormat,&pfd)) {
|
||||
*error_message = "Can't Set The PixelFormat.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(hRC = wglCreateContext(hDC))) // Are We Able To Get A Rendering Context?
|
||||
{
|
||||
MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
// Are We Able To Get A Rendering Context?
|
||||
if (!(hRC = wglCreateContext(hDC))) {
|
||||
*error_message = "Can't Create A GL Rendering Context.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context
|
||||
{
|
||||
MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
// Try To Activate The Rendering Context
|
||||
if (!wglMakeCurrent(hDC,hRC)) {
|
||||
*error_message = "Can't activate the GL Rendering Context.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GLEW_OK != glewInit()) {
|
||||
*error_message = "Failed to initialize GLEW.";
|
||||
return false;
|
||||
}
|
||||
glewInit();
|
||||
|
||||
// Alright, now for the modernity.
|
||||
int attribs[] =
|
||||
{
|
||||
static const int attribs[] = {
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, 1,
|
||||
WGL_CONTEXT_FLAGS_ARB, enableGLDebug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
|
||||
0
|
||||
};
|
||||
|
||||
HGLRC m_hrc;
|
||||
if(wglewIsSupported("WGL_ARB_create_context") == 1)
|
||||
{
|
||||
HGLRC m_hrc;
|
||||
if(wglewIsSupported("WGL_ARB_create_context") == 1) {
|
||||
m_hrc = wglCreateContextAttribsARB(hDC,0, attribs);
|
||||
wglMakeCurrent(NULL,NULL);
|
||||
wglDeleteContext(hRC);
|
||||
wglMakeCurrent(hDC, m_hrc);
|
||||
}
|
||||
else
|
||||
{ //It's not possible to make a GL 3.x context. Use the old style context (GL 2.1 and before)
|
||||
} else {
|
||||
// We can't make a GL 3.x context. Use an old style context (GL 2.1 and before)
|
||||
m_hrc = hRC;
|
||||
}
|
||||
|
||||
@ -197,43 +191,41 @@ bool GL_Init(HWND window)
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &OpenGLVersion[0]);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &OpenGLVersion[1]);
|
||||
|
||||
if (!m_hrc) return false;
|
||||
if (!m_hrc) {
|
||||
*error_message = "No m_hrc";
|
||||
return false;
|
||||
}
|
||||
|
||||
hRC = m_hrc;
|
||||
|
||||
glstate.Initialize();
|
||||
setVSync(0);
|
||||
if (enableGLDebug && glewIsSupported("GL_ARB_debug_output"))
|
||||
{
|
||||
if (enableGLDebug && glewIsSupported("GL_ARB_debug_output")) {
|
||||
glDebugMessageCallbackARB((GLDEBUGPROCARB)&DebugCallbackARB, 0); // print debug output to stderr
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
||||
}
|
||||
|
||||
GL_Resized(); // Set Up Our Perspective GL Screen
|
||||
|
||||
return true; // Success
|
||||
}
|
||||
|
||||
void GL_Shutdown()
|
||||
{
|
||||
if (hRC) // Do We Have A Rendering Context?
|
||||
{
|
||||
if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts?
|
||||
{
|
||||
void GL_Shutdown() {
|
||||
if (hRC) {
|
||||
// Are We Able To Release The DC And RC Contexts?
|
||||
if (!wglMakeCurrent(NULL,NULL)) {
|
||||
MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
|
||||
{
|
||||
// Are We Able To Delete The RC?
|
||||
if (!wglDeleteContext(hRC)) {
|
||||
MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
hRC=NULL; // Set RC To NULL
|
||||
hRC = NULL;
|
||||
}
|
||||
|
||||
if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC
|
||||
{
|
||||
if (hDC && !ReleaseDC(hWnd,hDC)) {
|
||||
MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
|
||||
hDC=NULL; // Set DC To NULL
|
||||
hDC = NULL;
|
||||
}
|
||||
hWnd = NULL;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
bool GL_Init(HWND window);
|
||||
bool GL_Init(HWND window, std::string *error_message);
|
||||
void GL_Shutdown();
|
||||
void GL_Resized();
|
||||
void GL_SwapBuffers();
|
||||
|
@ -1,3 +1,20 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Config.h"
|
||||
#include "EmuThread.h"
|
||||
@ -26,9 +43,9 @@ int MyMix(short *buffer, int numSamples, int bits, int rate, int channels)
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsHost::InitGL()
|
||||
bool WindowsHost::InitGL(std::string *error_message)
|
||||
{
|
||||
GL_Init(MainWindow::GetDisplayHWND());
|
||||
return GL_Init(MainWindow::GetDisplayHWND(), error_message);
|
||||
}
|
||||
|
||||
void WindowsHost::ShutdownGL()
|
||||
|
@ -1,3 +1,20 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "../Core/Host.h"
|
||||
#include "InputDevice.h"
|
||||
#include <list>
|
||||
@ -19,7 +36,7 @@ public:
|
||||
|
||||
void AddSymbol(std::string name, u32 addr, u32 size, int type);
|
||||
|
||||
void InitGL();
|
||||
bool InitGL(std::string *error_message);
|
||||
void BeginFrame();
|
||||
void ShutdownGL();
|
||||
|
||||
|
@ -99,7 +99,7 @@ public:
|
||||
|
||||
virtual void SetDebugMode(bool mode) { }
|
||||
|
||||
virtual void InitGL() {}
|
||||
virtual bool InitGL(std::string *error_message) {}
|
||||
virtual void BeginFrame() {}
|
||||
virtual void ShutdownGL() {}
|
||||
|
||||
|
@ -137,7 +137,9 @@ int main(int argc, const char* argv[])
|
||||
|
||||
HeadlessHost *headlessHost = useGraphics ? new HEADLESSHOST_CLASS() : new HeadlessHost();
|
||||
host = headlessHost;
|
||||
host->InitGL();
|
||||
|
||||
std::string error_string;
|
||||
host->InitGL(&error_string);
|
||||
|
||||
LogManager::Init();
|
||||
LogManager *logman = LogManager::GetInstance();
|
||||
@ -176,7 +178,6 @@ int main(int argc, const char* argv[])
|
||||
g_Config.flashDirectory = g_Config.memCardDirectory+"/flash/";
|
||||
#endif
|
||||
|
||||
std::string error_string;
|
||||
|
||||
if (!PSP_Init(coreParameter, &error_string)) {
|
||||
fprintf(stderr, "Failed to start %s. Error: %s\n", coreParameter.fileToStart.c_str(), error_string.c_str());
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
|
||||
virtual void SetDebugMode(bool mode) { }
|
||||
|
||||
virtual void InitGL() {}
|
||||
virtual bool InitGL(std::string *error_message) {return true;}
|
||||
virtual void BeginFrame() {}
|
||||
virtual void ShutdownGL() {}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user