rpcsx/rpcs3/Emu/RSX/GL/GLHelpers.cpp
2022-07-13 02:09:58 +03:00

193 lines
5.3 KiB
C++

#include "stdafx.h"
#include "GLHelpers.h"
#include "GLTexture.h"
#include "GLCompute.h"
#include "util/logs.hpp"
#include "../Common/simple_array.hpp"
#include <unordered_map>
namespace gl
{
std::unordered_map<u32, std::unique_ptr<gl::compute_task>> g_compute_tasks;
capabilities g_driver_caps;
void flush_command_queue(fence& fence_obj)
{
fence_obj.check_signaled();
}
GLenum draw_mode(rsx::primitive_type in)
{
switch (in)
{
case rsx::primitive_type::points: return GL_POINTS;
case rsx::primitive_type::lines: return GL_LINES;
case rsx::primitive_type::line_loop: return GL_LINE_LOOP;
case rsx::primitive_type::line_strip: return GL_LINE_STRIP;
case rsx::primitive_type::triangles: return GL_TRIANGLES;
case rsx::primitive_type::triangle_strip: return GL_TRIANGLE_STRIP;
case rsx::primitive_type::triangle_fan: return GL_TRIANGLE_FAN;
case rsx::primitive_type::quads: return GL_TRIANGLES;
case rsx::primitive_type::quad_strip: return GL_TRIANGLE_STRIP;
case rsx::primitive_type::polygon: return GL_TRIANGLES;
default:
fmt::throw_exception("unknown primitive type");
}
}
void destroy_compute_tasks()
{
for (auto& [key, prog] : g_compute_tasks)
{
prog->destroy();
}
g_compute_tasks.clear();
}
// https://www.khronos.org/opengl/wiki/Debug_Output
void APIENTRY log_debug(GLenum source, GLenum type, GLuint id,
GLenum severity, GLsizei /*length*/, const GLchar* message,
const void* /*user_param*/)
{
// Message source
std::string str_source;
switch (source)
{
// Calls to the OpenGL API
case GL_DEBUG_SOURCE_API:
str_source = "API";
break;
// Calls to a window-system API
case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
str_source = "WINDOW_SYSTEM";
break;
// A compiler for a shading language
case GL_DEBUG_SOURCE_SHADER_COMPILER:
str_source = "SHADER_COMPILER";
break;
// An application associated with OpenGL
case GL_DEBUG_SOURCE_THIRD_PARTY:
str_source = "THIRD_PARTY";
break;
// Generated by the user of this application
case GL_DEBUG_SOURCE_APPLICATION:
str_source = "APPLICATION";
break;
// Some source that isn't one of these
case GL_DEBUG_SOURCE_OTHER:
str_source = "OTHER";
break;
// Not on documentation
default:
str_source = "UNKNOWN";
rsx_log.error("log_debug(source=%d): Unknown message source", source);
}
// Message type
std::string str_type;
switch (type)
{
// An error, typically from the API
case GL_DEBUG_TYPE_ERROR:
str_type = "ERROR";
break;
// Some behavior marked deprecated has been used
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
str_type = "DEPRECATED";
break;
// Something has invoked undefined behavior
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
str_type = "UNDEFINED";
break;
// Some functionality the user relies upon is not portable
case GL_DEBUG_TYPE_PORTABILITY:
str_type = "PORTABILITY";
break;
// Code has triggered possible performance issues
case GL_DEBUG_TYPE_PERFORMANCE:
str_type = "PERFORMANCE";
break;
// Command stream annotation
case GL_DEBUG_TYPE_MARKER:
str_type = "MARKER";
break;
// Group pushing
case GL_DEBUG_TYPE_PUSH_GROUP:
str_type = "PUSH_GROUP";
break;
// foo
case GL_DEBUG_TYPE_POP_GROUP:
str_type = "POP_GROUP";
break;
// Some type that isn't one of these
case GL_DEBUG_TYPE_OTHER:
str_type = "OTHER";
break;
// Not on documentation
default:
str_type = "UNKNOWN";
rsx_log.error("log_debug(type=%d): Unknown message type", type);
}
switch (severity)
{
// All OpenGL Errors, shader compilation/linking errors, or highly-dangerous undefined behavior
case GL_DEBUG_SEVERITY_HIGH:
// Major performance warnings, shader compilation/linking warnings, or the use of deprecated functionality
case GL_DEBUG_SEVERITY_MEDIUM:
rsx_log.error("[DEBUG_OUTPUT] [%s] [%s] [%d]: %s", str_source, str_type, id, message);
return;
// Redundant state change performance warning, or unimportant undefined behavior
case GL_DEBUG_SEVERITY_LOW:
rsx_log.warning("[DEBUG_OUTPUT] [%s] [%s] [%d]: %s", str_source, str_type, id, message);
return;
// Anything that isn't an error or performance issue
case GL_DEBUG_SEVERITY_NOTIFICATION:
rsx_log.notice("[DEBUG_OUTPUT] [%s] [%s] [%d]: %s", str_source, str_type, id, message);
return;
// Not on documentation
default:
rsx_log.error("log_debug(severity=%d): Unknown severity level", severity);
rsx_log.error("[DEBUG_OUTPUT] [%s] [%s] [%d]: %s", str_source, str_type, id, message);
return;
}
}
void enable_debugging()
{
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(log_debug, nullptr);
}
const capabilities& get_driver_caps()
{
if (!g_driver_caps.initialized)
g_driver_caps.initialize();
return g_driver_caps;
}
bool is_primitive_native(rsx::primitive_type in)
{
switch (in)
{
case rsx::primitive_type::points:
case rsx::primitive_type::lines:
case rsx::primitive_type::line_loop:
case rsx::primitive_type::line_strip:
case rsx::primitive_type::triangles:
case rsx::primitive_type::triangle_strip:
case rsx::primitive_type::triangle_fan:
case rsx::primitive_type::quad_strip:
return true;
case rsx::primitive_type::quads:
case rsx::primitive_type::polygon:
return false;
default:
fmt::throw_exception("unknown primitive type");
}
}
}