summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2020-03-17 03:52:42 +0100
committerGitHub <noreply@github.com>2020-03-17 03:52:42 +0100
commite8ded20d2402e03fca2007204e42b62f11ec92c8 (patch)
treea0138f450f0cb9ae37da6b57da05f507ca8523cb /src/video_core/renderer_opengl
parentMerge pull request #3515 from ReinUsesLisp/vertex-vk-assert (diff)
parentrenderer_opengl: Move some logic to an anonymous namespace (diff)
downloadyuzu-e8ded20d2402e03fca2007204e42b62f11ec92c8.tar
yuzu-e8ded20d2402e03fca2007204e42b62f11ec92c8.tar.gz
yuzu-e8ded20d2402e03fca2007204e42b62f11ec92c8.tar.bz2
yuzu-e8ded20d2402e03fca2007204e42b62f11ec92c8.tar.lz
yuzu-e8ded20d2402e03fca2007204e42b62f11ec92c8.tar.xz
yuzu-e8ded20d2402e03fca2007204e42b62f11ec92c8.tar.zst
yuzu-e8ded20d2402e03fca2007204e42b62f11ec92c8.zip
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_device.h5
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp297
3 files changed, 159 insertions, 144 deletions
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index e824e216d..1a2e2a9f7 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -157,7 +157,6 @@ Device::Device() : base_bindings{BuildBaseBindings()} {
has_precise_bug = TestPreciseBug();
has_broken_compute = is_intel_proprietary;
has_fast_buffer_sub_data = is_nvidia;
- has_debug_tool = HasExtension(extensions, "GL_EXT_debug_tool");
LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi);
LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug);
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h
index 7aaa3a077..d73b099d0 100644
--- a/src/video_core/renderer_opengl/gl_device.h
+++ b/src/video_core/renderer_opengl/gl_device.h
@@ -84,10 +84,6 @@ public:
return has_fast_buffer_sub_data;
}
- bool HasDebugTool() const {
- return has_debug_tool;
- }
-
private:
static bool TestVariableAoffi();
static bool TestPreciseBug();
@@ -106,7 +102,6 @@ private:
bool has_precise_bug{};
bool has_broken_compute{};
bool has_fast_buffer_sub_data{};
- bool has_debug_tool{};
};
} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index c91658cd1..fca5e3ec0 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -5,8 +5,11 @@
#include <algorithm>
#include <cstddef>
#include <cstdlib>
+#include <cstring>
#include <memory>
+
#include <glad/glad.h>
+
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/microprofile.h"
@@ -25,6 +28,8 @@
namespace OpenGL {
+namespace {
+
// If the size of this is too small, it ends up creating a soft cap on FPS as the renderer will have
// to wait on available presentation frames.
constexpr std::size_t SWAP_CHAIN_SIZE = 3;
@@ -41,6 +46,159 @@ struct Frame {
bool is_srgb{}; /// Framebuffer is sRGB or RGB
};
+constexpr char VERTEX_SHADER[] = R"(
+#version 430 core
+
+out gl_PerVertex {
+ vec4 gl_Position;
+};
+
+layout (location = 0) in vec2 vert_position;
+layout (location = 1) in vec2 vert_tex_coord;
+layout (location = 0) out vec2 frag_tex_coord;
+
+// This is a truncated 3x3 matrix for 2D transformations:
+// The upper-left 2x2 submatrix performs scaling/rotation/mirroring.
+// The third column performs translation.
+// The third row could be used for projection, which we don't need in 2D. It hence is assumed to
+// implicitly be [0, 0, 1]
+layout (location = 0) uniform mat3x2 modelview_matrix;
+
+void main() {
+ // Multiply input position by the rotscale part of the matrix and then manually translate by
+ // the last column. This is equivalent to using a full 3x3 matrix and expanding the vector
+ // to `vec3(vert_position.xy, 1.0)`
+ gl_Position = vec4(mat2(modelview_matrix) * vert_position + modelview_matrix[2], 0.0, 1.0);
+ frag_tex_coord = vert_tex_coord;
+}
+)";
+
+constexpr char FRAGMENT_SHADER[] = R"(
+#version 430 core
+
+layout (location = 0) in vec2 frag_tex_coord;
+layout (location = 0) out vec4 color;
+
+layout (binding = 0) uniform sampler2D color_texture;
+
+void main() {
+ color = vec4(texture(color_texture, frag_tex_coord).rgb, 1.0f);
+}
+)";
+
+constexpr GLint PositionLocation = 0;
+constexpr GLint TexCoordLocation = 1;
+constexpr GLint ModelViewMatrixLocation = 0;
+
+struct ScreenRectVertex {
+ constexpr ScreenRectVertex(u32 x, u32 y, GLfloat u, GLfloat v)
+ : position{{static_cast<GLfloat>(x), static_cast<GLfloat>(y)}}, tex_coord{{u, v}} {}
+
+ std::array<GLfloat, 2> position;
+ std::array<GLfloat, 2> tex_coord;
+};
+
+/// Returns true if any debug tool is attached
+bool HasDebugTool() {
+ const bool nsight = std::getenv("NVTX_INJECTION64_PATH") || std::getenv("NSIGHT_LAUNCHED");
+ if (nsight) {
+ return true;
+ }
+
+ GLint num_extensions;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
+ for (GLuint index = 0; index < static_cast<GLuint>(num_extensions); ++index) {
+ const auto name = reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, index));
+ if (!std::strcmp(name, "GL_EXT_debug_tool")) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Defines a 1:1 pixel ortographic projection matrix with (0,0) on the top-left
+ * corner and (width, height) on the lower-bottom.
+ *
+ * The projection part of the matrix is trivial, hence these operations are represented
+ * by a 3x2 matrix.
+ */
+std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(float width, float height) {
+ std::array<GLfloat, 3 * 2> matrix; // Laid out in column-major order
+
+ // clang-format off
+ matrix[0] = 2.f / width; matrix[2] = 0.f; matrix[4] = -1.f;
+ matrix[1] = 0.f; matrix[3] = -2.f / height; matrix[5] = 1.f;
+ // Last matrix row is implicitly assumed to be [0, 0, 1].
+ // clang-format on
+
+ return matrix;
+}
+
+const char* GetSource(GLenum source) {
+ switch (source) {
+ case GL_DEBUG_SOURCE_API:
+ return "API";
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
+ return "WINDOW_SYSTEM";
+ case GL_DEBUG_SOURCE_SHADER_COMPILER:
+ return "SHADER_COMPILER";
+ case GL_DEBUG_SOURCE_THIRD_PARTY:
+ return "THIRD_PARTY";
+ case GL_DEBUG_SOURCE_APPLICATION:
+ return "APPLICATION";
+ case GL_DEBUG_SOURCE_OTHER:
+ return "OTHER";
+ default:
+ UNREACHABLE();
+ return "Unknown source";
+ }
+}
+
+const char* GetType(GLenum type) {
+ switch (type) {
+ case GL_DEBUG_TYPE_ERROR:
+ return "ERROR";
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
+ return "DEPRECATED_BEHAVIOR";
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
+ return "UNDEFINED_BEHAVIOR";
+ case GL_DEBUG_TYPE_PORTABILITY:
+ return "PORTABILITY";
+ case GL_DEBUG_TYPE_PERFORMANCE:
+ return "PERFORMANCE";
+ case GL_DEBUG_TYPE_OTHER:
+ return "OTHER";
+ case GL_DEBUG_TYPE_MARKER:
+ return "MARKER";
+ default:
+ UNREACHABLE();
+ return "Unknown type";
+ }
+}
+
+void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
+ const GLchar* message, const void* user_param) {
+ const char format[] = "{} {} {}: {}";
+ const char* const str_source = GetSource(source);
+ const char* const str_type = GetType(type);
+
+ switch (severity) {
+ case GL_DEBUG_SEVERITY_HIGH:
+ LOG_CRITICAL(Render_OpenGL, format, str_source, str_type, id, message);
+ break;
+ case GL_DEBUG_SEVERITY_MEDIUM:
+ LOG_WARNING(Render_OpenGL, format, str_source, str_type, id, message);
+ break;
+ case GL_DEBUG_SEVERITY_NOTIFICATION:
+ case GL_DEBUG_SEVERITY_LOW:
+ LOG_DEBUG(Render_OpenGL, format, str_source, str_type, id, message);
+ break;
+ }
+}
+
+} // Anonymous namespace
+
/**
* For smooth Vsync rendering, we want to always present the latest frame that the core generates,
* but also make sure that rendering happens at the pace that the frontend dictates. This is a
@@ -56,7 +214,7 @@ public:
std::deque<Frame*> present_queue;
Frame* previous_frame{};
- FrameMailbox() : has_debug_tool{Device().HasDebugTool()} {
+ FrameMailbox() : has_debug_tool{HasDebugTool()} {
for (auto& frame : swap_chain) {
free_queue.push(&frame);
}
@@ -188,143 +346,6 @@ private:
}
};
-namespace {
-
-constexpr char VERTEX_SHADER[] = R"(
-#version 430 core
-
-out gl_PerVertex {
- vec4 gl_Position;
-};
-
-layout (location = 0) in vec2 vert_position;
-layout (location = 1) in vec2 vert_tex_coord;
-layout (location = 0) out vec2 frag_tex_coord;
-
-// This is a truncated 3x3 matrix for 2D transformations:
-// The upper-left 2x2 submatrix performs scaling/rotation/mirroring.
-// The third column performs translation.
-// The third row could be used for projection, which we don't need in 2D. It hence is assumed to
-// implicitly be [0, 0, 1]
-layout (location = 0) uniform mat3x2 modelview_matrix;
-
-void main() {
- // Multiply input position by the rotscale part of the matrix and then manually translate by
- // the last column. This is equivalent to using a full 3x3 matrix and expanding the vector
- // to `vec3(vert_position.xy, 1.0)`
- gl_Position = vec4(mat2(modelview_matrix) * vert_position + modelview_matrix[2], 0.0, 1.0);
- frag_tex_coord = vert_tex_coord;
-}
-)";
-
-constexpr char FRAGMENT_SHADER[] = R"(
-#version 430 core
-
-layout (location = 0) in vec2 frag_tex_coord;
-layout (location = 0) out vec4 color;
-
-layout (binding = 0) uniform sampler2D color_texture;
-
-void main() {
- color = vec4(texture(color_texture, frag_tex_coord).rgb, 1.0f);
-}
-)";
-
-constexpr GLint PositionLocation = 0;
-constexpr GLint TexCoordLocation = 1;
-constexpr GLint ModelViewMatrixLocation = 0;
-
-struct ScreenRectVertex {
- constexpr ScreenRectVertex(u32 x, u32 y, GLfloat u, GLfloat v)
- : position{{static_cast<GLfloat>(x), static_cast<GLfloat>(y)}}, tex_coord{{u, v}} {}
-
- std::array<GLfloat, 2> position;
- std::array<GLfloat, 2> tex_coord;
-};
-
-/**
- * Defines a 1:1 pixel ortographic projection matrix with (0,0) on the top-left
- * corner and (width, height) on the lower-bottom.
- *
- * The projection part of the matrix is trivial, hence these operations are represented
- * by a 3x2 matrix.
- */
-std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(float width, float height) {
- std::array<GLfloat, 3 * 2> matrix; // Laid out in column-major order
-
- // clang-format off
- matrix[0] = 2.f / width; matrix[2] = 0.f; matrix[4] = -1.f;
- matrix[1] = 0.f; matrix[3] = -2.f / height; matrix[5] = 1.f;
- // Last matrix row is implicitly assumed to be [0, 0, 1].
- // clang-format on
-
- return matrix;
-}
-
-const char* GetSource(GLenum source) {
- switch (source) {
- case GL_DEBUG_SOURCE_API:
- return "API";
- case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
- return "WINDOW_SYSTEM";
- case GL_DEBUG_SOURCE_SHADER_COMPILER:
- return "SHADER_COMPILER";
- case GL_DEBUG_SOURCE_THIRD_PARTY:
- return "THIRD_PARTY";
- case GL_DEBUG_SOURCE_APPLICATION:
- return "APPLICATION";
- case GL_DEBUG_SOURCE_OTHER:
- return "OTHER";
- default:
- UNREACHABLE();
- return "Unknown source";
- }
-}
-
-const char* GetType(GLenum type) {
- switch (type) {
- case GL_DEBUG_TYPE_ERROR:
- return "ERROR";
- case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
- return "DEPRECATED_BEHAVIOR";
- case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
- return "UNDEFINED_BEHAVIOR";
- case GL_DEBUG_TYPE_PORTABILITY:
- return "PORTABILITY";
- case GL_DEBUG_TYPE_PERFORMANCE:
- return "PERFORMANCE";
- case GL_DEBUG_TYPE_OTHER:
- return "OTHER";
- case GL_DEBUG_TYPE_MARKER:
- return "MARKER";
- default:
- UNREACHABLE();
- return "Unknown type";
- }
-}
-
-void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
- const GLchar* message, const void* user_param) {
- const char format[] = "{} {} {}: {}";
- const char* const str_source = GetSource(source);
- const char* const str_type = GetType(type);
-
- switch (severity) {
- case GL_DEBUG_SEVERITY_HIGH:
- LOG_CRITICAL(Render_OpenGL, format, str_source, str_type, id, message);
- break;
- case GL_DEBUG_SEVERITY_MEDIUM:
- LOG_WARNING(Render_OpenGL, format, str_source, str_type, id, message);
- break;
- case GL_DEBUG_SEVERITY_NOTIFICATION:
- case GL_DEBUG_SEVERITY_LOW:
- LOG_DEBUG(Render_OpenGL, format, str_source, str_type, id, message);
- break;
- }
-}
-
-} // Anonymous namespace
-
RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system)
: VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system},
frame_mailbox{std::make_unique<FrameMailbox>()} {}