summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/stream.cpp4
-rw-r--r--src/common/logging/backend.cpp11
-rw-r--r--src/common/logging/backend.h14
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp3
-rw-r--r--src/core/hle/service/hid/hid.cpp2
-rw-r--r--src/video_core/CMakeLists.txt1
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp23
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h2
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.cpp188
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.h132
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h1
-rw-r--r--src/video_core/renderer_opengl/gl_stream_buffer.cpp5
-rw-r--r--src/video_core/surface.cpp3
-rw-r--r--src/video_core/surface.h1
-rw-r--r--src/yuzu/main.cpp9
-rw-r--r--src/yuzu/main.h1
-rw-r--r--src/yuzu/main.ui6
-rw-r--r--src/yuzu_cmd/yuzu.cpp3
18 files changed, 287 insertions, 122 deletions
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index 742a5e0a0..f35628e45 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -11,7 +11,6 @@
11#include "audio_core/stream.h" 11#include "audio_core/stream.h"
12#include "common/assert.h" 12#include "common/assert.h"
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/microprofile.h"
15#include "core/core_timing.h" 14#include "core/core_timing.h"
16#include "core/core_timing_util.h" 15#include "core/core_timing_util.h"
17#include "core/settings.h" 16#include "core/settings.h"
@@ -104,10 +103,7 @@ void Stream::PlayNextBuffer() {
104 CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {}); 103 CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {});
105} 104}
106 105
107MICROPROFILE_DEFINE(AudioOutput, "Audio", "ReleaseActiveBuffer", MP_RGB(100, 100, 255));
108
109void Stream::ReleaseActiveBuffer() { 106void Stream::ReleaseActiveBuffer() {
110 MICROPROFILE_SCOPE(AudioOutput);
111 ASSERT(active_buffer); 107 ASSERT(active_buffer);
112 released_buffers.push(std::move(active_buffer)); 108 released_buffers.push(std::move(active_buffer));
113 release_callback(); 109 release_callback();
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 6d5218465..5753b871a 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -12,7 +12,8 @@
12#include <thread> 12#include <thread>
13#include <vector> 13#include <vector>
14#ifdef _WIN32 14#ifdef _WIN32
15#include <share.h> // For _SH_DENYWR 15#include <share.h> // For _SH_DENYWR
16#include <windows.h> // For OutputDebugStringA
16#else 17#else
17#define _SH_DENYWR 0 18#define _SH_DENYWR 0
18#endif 19#endif
@@ -139,12 +140,18 @@ void FileBackend::Write(const Entry& entry) {
139 if (!file.IsOpen() || bytes_written > MAX_BYTES_WRITTEN) { 140 if (!file.IsOpen() || bytes_written > MAX_BYTES_WRITTEN) {
140 return; 141 return;
141 } 142 }
142 bytes_written += file.WriteString(FormatLogMessage(entry) + '\n'); 143 bytes_written += file.WriteString(FormatLogMessage(entry).append(1, '\n'));
143 if (entry.log_level >= Level::Error) { 144 if (entry.log_level >= Level::Error) {
144 file.Flush(); 145 file.Flush();
145 } 146 }
146} 147}
147 148
149void DebuggerBackend::Write(const Entry& entry) {
150#ifdef _WIN32
151 ::OutputDebugStringA(FormatLogMessage(entry).append(1, '\n').c_str());
152#endif
153}
154
148/// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this. 155/// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this.
149#define ALL_LOG_CLASSES() \ 156#define ALL_LOG_CLASSES() \
150 CLS(Log) \ 157 CLS(Log) \
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h
index 11edbf1b6..91bb0c309 100644
--- a/src/common/logging/backend.h
+++ b/src/common/logging/backend.h
@@ -103,6 +103,20 @@ private:
103 std::size_t bytes_written; 103 std::size_t bytes_written;
104}; 104};
105 105
106/**
107 * Backend that writes to Visual Studio's output window
108 */
109class DebuggerBackend : public Backend {
110public:
111 static const char* Name() {
112 return "debugger";
113 }
114 const char* GetName() const override {
115 return Name();
116 }
117 void Write(const Entry& entry) override;
118};
119
106void AddBackend(std::unique_ptr<Backend> backend); 120void AddBackend(std::unique_ptr<Backend> backend);
107 121
108void RemoveBackend(std::string_view backend_name); 122void RemoveBackend(std::string_view backend_name);
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 4b4d1324f..1ef789bd0 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -427,6 +427,9 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
427} 427}
428 428
429Kernel::SharedPtr<Kernel::Event> Controller_NPad::GetStyleSetChangedEvent() const { 429Kernel::SharedPtr<Kernel::Event> Controller_NPad::GetStyleSetChangedEvent() const {
430 // TODO(ogniK): Figure out the best time to signal this event. This event seems that it should
431 // be signalled at least once, and signaled after a new controller is connected?
432 styleset_changed_event->Signal();
430 return styleset_changed_event; 433 return styleset_changed_event;
431} 434}
432 435
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index a9aa9ec78..a45fd4954 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -96,6 +96,8 @@ public:
96 // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) 96 // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
97 97
98 CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event); 98 CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event);
99
100 ReloadInputDevices();
99 } 101 }
100 102
101 void ActivateController(HidController controller) { 103 void ActivateController(HidController controller) {
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index ddb1a1d69..0b1cc1290 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -33,6 +33,7 @@ add_library(video_core STATIC
33 renderer_opengl/gl_rasterizer.h 33 renderer_opengl/gl_rasterizer.h
34 renderer_opengl/gl_rasterizer_cache.cpp 34 renderer_opengl/gl_rasterizer_cache.cpp
35 renderer_opengl/gl_rasterizer_cache.h 35 renderer_opengl/gl_rasterizer_cache.h
36 renderer_opengl/gl_resource_manager.cpp
36 renderer_opengl/gl_resource_manager.h 37 renderer_opengl/gl_resource_manager.h
37 renderer_opengl/gl_shader_cache.cpp 38 renderer_opengl/gl_shader_cache.cpp
38 renderer_opengl/gl_shader_cache.h 39 renderer_opengl/gl_shader_cache.h
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 0e11557c4..49d63e6f3 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -16,6 +16,7 @@
16#include "core/settings.h" 16#include "core/settings.h"
17#include "video_core/engines/maxwell_3d.h" 17#include "video_core/engines/maxwell_3d.h"
18#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 18#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
19#include "video_core/renderer_opengl/gl_state.h"
19#include "video_core/renderer_opengl/utils.h" 20#include "video_core/renderer_opengl/utils.h"
20#include "video_core/surface.h" 21#include "video_core/surface.h"
21#include "video_core/textures/astc.h" 22#include "video_core/textures/astc.h"
@@ -126,6 +127,13 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only,
126 params.target = SurfaceTarget::Texture2D; 127 params.target = SurfaceTarget::Texture2D;
127 } 128 }
128 break; 129 break;
130 case SurfaceTarget::TextureCubeArray:
131 params.depth = config.tic.Depth() * 6;
132 if (!entry.IsArray()) {
133 ASSERT(params.depth == 6);
134 params.target = SurfaceTarget::TextureCubemap;
135 }
136 break;
129 default: 137 default:
130 LOG_CRITICAL(HW_GPU, "Unknown depth for target={}", static_cast<u32>(params.target)); 138 LOG_CRITICAL(HW_GPU, "Unknown depth for target={}", static_cast<u32>(params.target));
131 UNREACHABLE(); 139 UNREACHABLE();
@@ -334,6 +342,8 @@ static GLenum SurfaceTargetToGL(SurfaceTarget target) {
334 return GL_TEXTURE_2D_ARRAY; 342 return GL_TEXTURE_2D_ARRAY;
335 case SurfaceTarget::TextureCubemap: 343 case SurfaceTarget::TextureCubemap:
336 return GL_TEXTURE_CUBE_MAP; 344 return GL_TEXTURE_CUBE_MAP;
345 case SurfaceTarget::TextureCubeArray:
346 return GL_TEXTURE_CUBE_MAP_ARRAY_ARB;
337 } 347 }
338 LOG_CRITICAL(Render_OpenGL, "Unimplemented texture target={}", static_cast<u32>(target)); 348 LOG_CRITICAL(Render_OpenGL, "Unimplemented texture target={}", static_cast<u32>(target));
339 UNREACHABLE(); 349 UNREACHABLE();
@@ -552,9 +562,11 @@ void SwizzleFunc(const GLConversionArray& functions, const SurfaceParams& params
552 } 562 }
553} 563}
554 564
565MICROPROFILE_DEFINE(OpenGL_BlitSurface, "OpenGL", "BlitSurface", MP_RGB(128, 192, 64));
555static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface, 566static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
556 GLuint read_fb_handle, GLuint draw_fb_handle, GLenum src_attachment = 0, 567 GLuint read_fb_handle, GLuint draw_fb_handle, GLenum src_attachment = 0,
557 GLenum dst_attachment = 0, std::size_t cubemap_face = 0) { 568 GLenum dst_attachment = 0, std::size_t cubemap_face = 0) {
569 MICROPROFILE_SCOPE(OpenGL_BlitSurface);
558 570
559 const auto& src_params{src_surface->GetSurfaceParams()}; 571 const auto& src_params{src_surface->GetSurfaceParams()};
560 const auto& dst_params{dst_surface->GetSurfaceParams()}; 572 const auto& dst_params{dst_surface->GetSurfaceParams()};
@@ -694,9 +706,11 @@ static void FastCopySurface(const Surface& src_surface, const Surface& dst_surfa
694 0, 0, width, height, 1); 706 0, 0, width, height, 1);
695} 707}
696 708
709MICROPROFILE_DEFINE(OpenGL_CopySurface, "OpenGL", "CopySurface", MP_RGB(128, 192, 64));
697static void CopySurface(const Surface& src_surface, const Surface& dst_surface, 710static void CopySurface(const Surface& src_surface, const Surface& dst_surface,
698 GLuint copy_pbo_handle, GLenum src_attachment = 0, 711 GLuint copy_pbo_handle, GLenum src_attachment = 0,
699 GLenum dst_attachment = 0, std::size_t cubemap_face = 0) { 712 GLenum dst_attachment = 0, std::size_t cubemap_face = 0) {
713 MICROPROFILE_SCOPE(OpenGL_CopySurface);
700 ASSERT_MSG(dst_attachment == 0, "Unimplemented"); 714 ASSERT_MSG(dst_attachment == 0, "Unimplemented");
701 715
702 const auto& src_params{src_surface->GetSurfaceParams()}; 716 const auto& src_params{src_surface->GetSurfaceParams()};
@@ -761,6 +775,7 @@ static void CopySurface(const Surface& src_surface, const Surface& dst_surface,
761 break; 775 break;
762 case SurfaceTarget::Texture3D: 776 case SurfaceTarget::Texture3D:
763 case SurfaceTarget::Texture2DArray: 777 case SurfaceTarget::Texture2DArray:
778 case SurfaceTarget::TextureCubeArray:
764 glTextureSubImage3D(dst_surface->Texture().handle, 0, 0, 0, 0, width, height, 779 glTextureSubImage3D(dst_surface->Texture().handle, 0, 0, 0, 0, width, height,
765 static_cast<GLsizei>(dst_params.depth), dest_format.format, 780 static_cast<GLsizei>(dst_params.depth), dest_format.format,
766 dest_format.type, nullptr); 781 dest_format.type, nullptr);
@@ -813,6 +828,7 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
813 break; 828 break;
814 case SurfaceTarget::Texture3D: 829 case SurfaceTarget::Texture3D:
815 case SurfaceTarget::Texture2DArray: 830 case SurfaceTarget::Texture2DArray:
831 case SurfaceTarget::TextureCubeArray:
816 glTexStorage3D(SurfaceTargetToGL(params.target), params.max_mip_level, 832 glTexStorage3D(SurfaceTargetToGL(params.target), params.max_mip_level,
817 format_tuple.internal_format, rect.GetWidth(), rect.GetHeight(), 833 format_tuple.internal_format, rect.GetWidth(), rect.GetHeight(),
818 params.depth); 834 params.depth);
@@ -963,7 +979,7 @@ static void ConvertFormatAsNeeded_FlushGLBuffer(std::vector<u8>& data, PixelForm
963 } 979 }
964} 980}
965 981
966MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); 982MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 192, 64));
967void CachedSurface::LoadGLBuffer() { 983void CachedSurface::LoadGLBuffer() {
968 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); 984 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad);
969 gl_buffer.resize(params.max_mip_level); 985 gl_buffer.resize(params.max_mip_level);
@@ -1065,6 +1081,7 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
1065 &gl_buffer[mip_map][buffer_offset]); 1081 &gl_buffer[mip_map][buffer_offset]);
1066 break; 1082 break;
1067 case SurfaceTarget::Texture2DArray: 1083 case SurfaceTarget::Texture2DArray:
1084 case SurfaceTarget::TextureCubeArray:
1068 glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, 1085 glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format,
1069 static_cast<GLsizei>(params.MipWidth(mip_map)), 1086 static_cast<GLsizei>(params.MipWidth(mip_map)),
1070 static_cast<GLsizei>(params.MipHeight(mip_map)), 1087 static_cast<GLsizei>(params.MipHeight(mip_map)),
@@ -1114,6 +1131,7 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
1114 tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]); 1131 tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]);
1115 break; 1132 break;
1116 case SurfaceTarget::Texture2DArray: 1133 case SurfaceTarget::Texture2DArray:
1134 case SurfaceTarget::TextureCubeArray:
1117 glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0, 1135 glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0,
1118 static_cast<GLsizei>(rect.GetWidth()), 1136 static_cast<GLsizei>(rect.GetWidth()),
1119 static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format, 1137 static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format,
@@ -1143,7 +1161,7 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
1143 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 1161 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1144} 1162}
1145 1163
1146MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192)); 1164MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64));
1147void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) { 1165void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) {
1148 if (params.type == SurfaceType::Fill) 1166 if (params.type == SurfaceType::Fill)
1149 return; 1167 return;
@@ -1316,6 +1334,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
1316 break; 1334 break;
1317 case SurfaceTarget::TextureCubemap: 1335 case SurfaceTarget::TextureCubemap:
1318 case SurfaceTarget::Texture3D: 1336 case SurfaceTarget::Texture3D:
1337 case SurfaceTarget::TextureCubeArray:
1319 AccurateCopySurface(old_surface, new_surface); 1338 AccurateCopySurface(old_surface, new_surface);
1320 break; 1339 break;
1321 default: 1340 default:
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 46ad37897..c0b6bc4e6 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -49,6 +49,8 @@ struct SurfaceParams {
49 return "Texture2DArray"; 49 return "Texture2DArray";
50 case SurfaceTarget::TextureCubemap: 50 case SurfaceTarget::TextureCubemap:
51 return "TextureCubemap"; 51 return "TextureCubemap";
52 case SurfaceTarget::TextureCubeArray:
53 return "TextureCubeArray";
52 default: 54 default:
53 LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target)); 55 LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target));
54 UNREACHABLE(); 56 UNREACHABLE();
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp
new file mode 100644
index 000000000..161318c5f
--- /dev/null
+++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp
@@ -0,0 +1,188 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <utility>
6#include <glad/glad.h>
7#include "common/common_types.h"
8#include "common/microprofile.h"
9#include "video_core/renderer_opengl/gl_resource_manager.h"
10#include "video_core/renderer_opengl/gl_shader_util.h"
11#include "video_core/renderer_opengl/gl_state.h"
12
13MICROPROFILE_DEFINE(OpenGL_ResourceCreation, "OpenGL", "Resource Creation",
14 MP_RGB(128, 128, 192));
15MICROPROFILE_DEFINE(OpenGL_ResourceDeletion, "OpenGL", "Resource Deletion",
16 MP_RGB(128, 128, 192));
17
18namespace OpenGL {
19
20void OGLTexture::Create() {
21 if (handle != 0)
22 return;
23
24 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
25 glGenTextures(1, &handle);
26}
27
28void OGLTexture::Release() {
29 if (handle == 0)
30 return;
31
32 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
33 glDeleteTextures(1, &handle);
34 OpenGLState::GetCurState().UnbindTexture(handle).Apply();
35 handle = 0;
36}
37
38void OGLSampler::Create() {
39 if (handle != 0)
40 return;
41
42 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
43 glGenSamplers(1, &handle);
44}
45
46void OGLSampler::Release() {
47 if (handle == 0)
48 return;
49
50 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
51 glDeleteSamplers(1, &handle);
52 OpenGLState::GetCurState().ResetSampler(handle).Apply();
53 handle = 0;
54}
55
56void OGLShader::Create(const char* source, GLenum type) {
57 if (handle != 0)
58 return;
59 if (source == nullptr)
60 return;
61
62 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
63 handle = GLShader::LoadShader(source, type);
64}
65
66void OGLShader::Release() {
67 if (handle == 0)
68 return;
69
70 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
71 glDeleteShader(handle);
72 handle = 0;
73}
74
75void OGLProgram::CreateFromSource(const char* vert_shader, const char* geo_shader,
76 const char* frag_shader, bool separable_program) {
77 OGLShader vert, geo, frag;
78 if (vert_shader)
79 vert.Create(vert_shader, GL_VERTEX_SHADER);
80 if (geo_shader)
81 geo.Create(geo_shader, GL_GEOMETRY_SHADER);
82 if (frag_shader)
83 frag.Create(frag_shader, GL_FRAGMENT_SHADER);
84
85 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
86 Create(separable_program, vert.handle, geo.handle, frag.handle);
87}
88
89void OGLProgram::Release() {
90 if (handle == 0)
91 return;
92
93 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
94 glDeleteProgram(handle);
95 OpenGLState::GetCurState().ResetProgram(handle).Apply();
96 handle = 0;
97}
98
99void OGLPipeline::Create() {
100 if (handle != 0)
101 return;
102
103 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
104 glGenProgramPipelines(1, &handle);
105}
106
107void OGLPipeline::Release() {
108 if (handle == 0)
109 return;
110
111 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
112 glDeleteProgramPipelines(1, &handle);
113 OpenGLState::GetCurState().ResetPipeline(handle).Apply();
114 handle = 0;
115}
116
117void OGLBuffer::Create() {
118 if (handle != 0)
119 return;
120
121 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
122 glGenBuffers(1, &handle);
123}
124
125void OGLBuffer::Release() {
126 if (handle == 0)
127 return;
128
129 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
130 glDeleteBuffers(1, &handle);
131 OpenGLState::GetCurState().ResetBuffer(handle).Apply();
132 handle = 0;
133}
134
135void OGLSync::Create() {
136 if (handle != 0)
137 return;
138
139 // Don't profile here, this one is expected to happen ingame.
140 handle = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
141}
142
143void OGLSync::Release() {
144 if (handle == 0)
145 return;
146
147 // Don't profile here, this one is expected to happen ingame.
148 glDeleteSync(handle);
149 handle = 0;
150}
151
152void OGLVertexArray::Create() {
153 if (handle != 0)
154 return;
155
156 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
157 glGenVertexArrays(1, &handle);
158}
159
160void OGLVertexArray::Release() {
161 if (handle == 0)
162 return;
163
164 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
165 glDeleteVertexArrays(1, &handle);
166 OpenGLState::GetCurState().ResetVertexArray(handle).Apply();
167 handle = 0;
168}
169
170void OGLFramebuffer::Create() {
171 if (handle != 0)
172 return;
173
174 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
175 glGenFramebuffers(1, &handle);
176}
177
178void OGLFramebuffer::Release() {
179 if (handle == 0)
180 return;
181
182 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
183 glDeleteFramebuffers(1, &handle);
184 OpenGLState::GetCurState().ResetFramebuffer(handle).Apply();
185 handle = 0;
186}
187
188} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h
index 3bc1b83b5..e33f1e973 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.h
+++ b/src/video_core/renderer_opengl/gl_resource_manager.h
@@ -8,7 +8,6 @@
8#include <glad/glad.h> 8#include <glad/glad.h>
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "video_core/renderer_opengl/gl_shader_util.h" 10#include "video_core/renderer_opengl/gl_shader_util.h"
11#include "video_core/renderer_opengl/gl_state.h"
12 11
13namespace OpenGL { 12namespace OpenGL {
14 13
@@ -29,20 +28,10 @@ public:
29 } 28 }
30 29
31 /// Creates a new internal OpenGL resource and stores the handle 30 /// Creates a new internal OpenGL resource and stores the handle
32 void Create() { 31 void Create();
33 if (handle != 0)
34 return;
35 glGenTextures(1, &handle);
36 }
37 32
38 /// Deletes the internal OpenGL resource 33 /// Deletes the internal OpenGL resource
39 void Release() { 34 void Release();
40 if (handle == 0)
41 return;
42 glDeleteTextures(1, &handle);
43 OpenGLState::GetCurState().UnbindTexture(handle).Apply();
44 handle = 0;
45 }
46 35
47 GLuint handle = 0; 36 GLuint handle = 0;
48}; 37};
@@ -64,20 +53,10 @@ public:
64 } 53 }
65 54
66 /// Creates a new internal OpenGL resource and stores the handle 55 /// Creates a new internal OpenGL resource and stores the handle
67 void Create() { 56 void Create();
68 if (handle != 0)
69 return;
70 glGenSamplers(1, &handle);
71 }
72 57
73 /// Deletes the internal OpenGL resource 58 /// Deletes the internal OpenGL resource
74 void Release() { 59 void Release();
75 if (handle == 0)
76 return;
77 glDeleteSamplers(1, &handle);
78 OpenGLState::GetCurState().ResetSampler(handle).Apply();
79 handle = 0;
80 }
81 60
82 GLuint handle = 0; 61 GLuint handle = 0;
83}; 62};
@@ -98,20 +77,9 @@ public:
98 return *this; 77 return *this;
99 } 78 }
100 79
101 void Create(const char* source, GLenum type) { 80 void Create(const char* source, GLenum type);
102 if (handle != 0)
103 return;
104 if (source == nullptr)
105 return;
106 handle = GLShader::LoadShader(source, type);
107 }
108 81
109 void Release() { 82 void Release();
110 if (handle == 0)
111 return;
112 glDeleteShader(handle);
113 handle = 0;
114 }
115 83
116 GLuint handle = 0; 84 GLuint handle = 0;
117}; 85};
@@ -141,25 +109,10 @@ public:
141 109
142 /// Creates a new internal OpenGL resource and stores the handle 110 /// Creates a new internal OpenGL resource and stores the handle
143 void CreateFromSource(const char* vert_shader, const char* geo_shader, const char* frag_shader, 111 void CreateFromSource(const char* vert_shader, const char* geo_shader, const char* frag_shader,
144 bool separable_program = false) { 112 bool separable_program = false);
145 OGLShader vert, geo, frag;
146 if (vert_shader)
147 vert.Create(vert_shader, GL_VERTEX_SHADER);
148 if (geo_shader)
149 geo.Create(geo_shader, GL_GEOMETRY_SHADER);
150 if (frag_shader)
151 frag.Create(frag_shader, GL_FRAGMENT_SHADER);
152 Create(separable_program, vert.handle, geo.handle, frag.handle);
153 }
154 113
155 /// Deletes the internal OpenGL resource 114 /// Deletes the internal OpenGL resource
156 void Release() { 115 void Release();
157 if (handle == 0)
158 return;
159 glDeleteProgram(handle);
160 OpenGLState::GetCurState().ResetProgram(handle).Apply();
161 handle = 0;
162 }
163 116
164 GLuint handle = 0; 117 GLuint handle = 0;
165}; 118};
@@ -178,20 +131,10 @@ public:
178 } 131 }
179 132
180 /// Creates a new internal OpenGL resource and stores the handle 133 /// Creates a new internal OpenGL resource and stores the handle
181 void Create() { 134 void Create();
182 if (handle != 0)
183 return;
184 glGenProgramPipelines(1, &handle);
185 }
186 135
187 /// Deletes the internal OpenGL resource 136 /// Deletes the internal OpenGL resource
188 void Release() { 137 void Release();
189 if (handle == 0)
190 return;
191 glDeleteProgramPipelines(1, &handle);
192 OpenGLState::GetCurState().ResetPipeline(handle).Apply();
193 handle = 0;
194 }
195 138
196 GLuint handle = 0; 139 GLuint handle = 0;
197}; 140};
@@ -213,20 +156,10 @@ public:
213 } 156 }
214 157
215 /// Creates a new internal OpenGL resource and stores the handle 158 /// Creates a new internal OpenGL resource and stores the handle
216 void Create() { 159 void Create();
217 if (handle != 0)
218 return;
219 glGenBuffers(1, &handle);
220 }
221 160
222 /// Deletes the internal OpenGL resource 161 /// Deletes the internal OpenGL resource
223 void Release() { 162 void Release();
224 if (handle == 0)
225 return;
226 glDeleteBuffers(1, &handle);
227 OpenGLState::GetCurState().ResetBuffer(handle).Apply();
228 handle = 0;
229 }
230 163
231 GLuint handle = 0; 164 GLuint handle = 0;
232}; 165};
@@ -247,19 +180,10 @@ public:
247 } 180 }
248 181
249 /// Creates a new internal OpenGL resource and stores the handle 182 /// Creates a new internal OpenGL resource and stores the handle
250 void Create() { 183 void Create();
251 if (handle != 0)
252 return;
253 handle = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
254 }
255 184
256 /// Deletes the internal OpenGL resource 185 /// Deletes the internal OpenGL resource
257 void Release() { 186 void Release();
258 if (handle == 0)
259 return;
260 glDeleteSync(handle);
261 handle = 0;
262 }
263 187
264 GLsync handle = 0; 188 GLsync handle = 0;
265}; 189};
@@ -281,20 +205,10 @@ public:
281 } 205 }
282 206
283 /// Creates a new internal OpenGL resource and stores the handle 207 /// Creates a new internal OpenGL resource and stores the handle
284 void Create() { 208 void Create();
285 if (handle != 0)
286 return;
287 glGenVertexArrays(1, &handle);
288 }
289 209
290 /// Deletes the internal OpenGL resource 210 /// Deletes the internal OpenGL resource
291 void Release() { 211 void Release();
292 if (handle == 0)
293 return;
294 glDeleteVertexArrays(1, &handle);
295 OpenGLState::GetCurState().ResetVertexArray(handle).Apply();
296 handle = 0;
297 }
298 212
299 GLuint handle = 0; 213 GLuint handle = 0;
300}; 214};
@@ -316,20 +230,10 @@ public:
316 } 230 }
317 231
318 /// Creates a new internal OpenGL resource and stores the handle 232 /// Creates a new internal OpenGL resource and stores the handle
319 void Create() { 233 void Create();
320 if (handle != 0)
321 return;
322 glGenFramebuffers(1, &handle);
323 }
324 234
325 /// Deletes the internal OpenGL resource 235 /// Deletes the internal OpenGL resource
326 void Release() { 236 void Release();
327 if (handle == 0)
328 return;
329 glDeleteFramebuffers(1, &handle);
330 OpenGLState::GetCurState().ResetFramebuffer(handle).Apply();
331 handle = 0;
332 }
333 237
334 GLuint handle = 0; 238 GLuint handle = 0;
335}; 239};
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index 36fe1f04c..2a069cdd8 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -7,6 +7,7 @@
7#include <glad/glad.h> 7#include <glad/glad.h>
8 8
9#include "video_core/renderer_opengl/gl_resource_manager.h" 9#include "video_core/renderer_opengl/gl_resource_manager.h"
10#include "video_core/renderer_opengl/gl_state.h"
10#include "video_core/renderer_opengl/maxwell_to_gl.h" 11#include "video_core/renderer_opengl/maxwell_to_gl.h"
11 12
12namespace OpenGL::GLShader { 13namespace OpenGL::GLShader {
diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.cpp b/src/video_core/renderer_opengl/gl_stream_buffer.cpp
index e409228cc..b97b895a4 100644
--- a/src/video_core/renderer_opengl/gl_stream_buffer.cpp
+++ b/src/video_core/renderer_opengl/gl_stream_buffer.cpp
@@ -6,9 +6,13 @@
6#include <vector> 6#include <vector>
7#include "common/alignment.h" 7#include "common/alignment.h"
8#include "common/assert.h" 8#include "common/assert.h"
9#include "common/microprofile.h"
9#include "video_core/renderer_opengl/gl_state.h" 10#include "video_core/renderer_opengl/gl_state.h"
10#include "video_core/renderer_opengl/gl_stream_buffer.h" 11#include "video_core/renderer_opengl/gl_stream_buffer.h"
11 12
13MICROPROFILE_DEFINE(OpenGL_StreamBuffer, "OpenGL", "Stream Buffer Orphaning",
14 MP_RGB(128, 128, 192));
15
12namespace OpenGL { 16namespace OpenGL {
13 17
14OGLStreamBuffer::OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coherent) 18OGLStreamBuffer::OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coherent)
@@ -75,6 +79,7 @@ std::tuple<u8*, GLintptr, bool> OGLStreamBuffer::Map(GLsizeiptr size, GLintptr a
75 } 79 }
76 80
77 if (invalidate || !persistent) { 81 if (invalidate || !persistent) {
82 MICROPROFILE_SCOPE(OpenGL_StreamBuffer);
78 GLbitfield flags = GL_MAP_WRITE_BIT | (persistent ? GL_MAP_PERSISTENT_BIT : 0) | 83 GLbitfield flags = GL_MAP_WRITE_BIT | (persistent ? GL_MAP_PERSISTENT_BIT : 0) |
79 (coherent ? GL_MAP_COHERENT_BIT : GL_MAP_FLUSH_EXPLICIT_BIT) | 84 (coherent ? GL_MAP_COHERENT_BIT : GL_MAP_FLUSH_EXPLICIT_BIT) |
80 (invalidate ? GL_MAP_INVALIDATE_BUFFER_BIT : GL_MAP_UNSYNCHRONIZED_BIT); 85 (invalidate ? GL_MAP_INVALIDATE_BUFFER_BIT : GL_MAP_UNSYNCHRONIZED_BIT);
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index e284a4604..051ad3964 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -19,6 +19,8 @@ SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_t
19 return SurfaceTarget::Texture3D; 19 return SurfaceTarget::Texture3D;
20 case Tegra::Texture::TextureType::TextureCubemap: 20 case Tegra::Texture::TextureType::TextureCubemap:
21 return SurfaceTarget::TextureCubemap; 21 return SurfaceTarget::TextureCubemap;
22 case Tegra::Texture::TextureType::TextureCubeArray:
23 return SurfaceTarget::TextureCubeArray;
22 case Tegra::Texture::TextureType::Texture1DArray: 24 case Tegra::Texture::TextureType::Texture1DArray:
23 return SurfaceTarget::Texture1DArray; 25 return SurfaceTarget::Texture1DArray;
24 case Tegra::Texture::TextureType::Texture2DArray: 26 case Tegra::Texture::TextureType::Texture2DArray:
@@ -39,6 +41,7 @@ bool SurfaceTargetIsLayered(SurfaceTarget target) {
39 case SurfaceTarget::Texture1DArray: 41 case SurfaceTarget::Texture1DArray:
40 case SurfaceTarget::Texture2DArray: 42 case SurfaceTarget::Texture2DArray:
41 case SurfaceTarget::TextureCubemap: 43 case SurfaceTarget::TextureCubemap:
44 case SurfaceTarget::TextureCubeArray:
42 return true; 45 return true;
43 default: 46 default:
44 LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target)); 47 LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target));
diff --git a/src/video_core/surface.h b/src/video_core/surface.h
index 0ef7849a4..dfdb8d122 100644
--- a/src/video_core/surface.h
+++ b/src/video_core/surface.h
@@ -120,6 +120,7 @@ enum class SurfaceTarget {
120 Texture1DArray, 120 Texture1DArray,
121 Texture2DArray, 121 Texture2DArray,
122 TextureCubemap, 122 TextureCubemap,
123 TextureCubeArray,
123}; 124};
124 125
125/** 126/**
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 47d52c385..74a44be37 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -142,6 +142,9 @@ static void InitializeLogging() {
142 const std::string& log_dir = FileUtil::GetUserPath(FileUtil::UserPath::LogDir); 142 const std::string& log_dir = FileUtil::GetUserPath(FileUtil::UserPath::LogDir);
143 FileUtil::CreateFullPath(log_dir); 143 FileUtil::CreateFullPath(log_dir);
144 Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE)); 144 Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE));
145#ifdef _WIN32
146 Log::AddBackend(std::make_unique<Log::DebuggerBackend>());
147#endif
145} 148}
146 149
147GMainWindow::GMainWindow() 150GMainWindow::GMainWindow()
@@ -454,6 +457,7 @@ void GMainWindow::ConnectMenuEvents() {
454 connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); 457 connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
455 458
456 // Help 459 // Help
460 connect(ui.action_Open_yuzu_Folder, &QAction::triggered, this, &GMainWindow::OnOpenYuzuFolder);
457 connect(ui.action_Rederive, &QAction::triggered, this, 461 connect(ui.action_Rederive, &QAction::triggered, this,
458 std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning)); 462 std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning));
459 connect(ui.action_About, &QAction::triggered, this, &GMainWindow::OnAbout); 463 connect(ui.action_About, &QAction::triggered, this, &GMainWindow::OnAbout);
@@ -1374,6 +1378,11 @@ void GMainWindow::OnLoadAmiibo() {
1374 } 1378 }
1375} 1379}
1376 1380
1381void GMainWindow::OnOpenYuzuFolder() {
1382 QDesktopServices::openUrl(QUrl::fromLocalFile(
1383 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::UserDir))));
1384}
1385
1377void GMainWindow::OnAbout() { 1386void GMainWindow::OnAbout() {
1378 AboutDialog aboutDialog(this); 1387 AboutDialog aboutDialog(this);
1379 aboutDialog.exec(); 1388 aboutDialog.exec();
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index af637d89e..929250e8c 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -167,6 +167,7 @@ private slots:
167 void OnMenuRecentFile(); 167 void OnMenuRecentFile();
168 void OnConfigure(); 168 void OnConfigure();
169 void OnLoadAmiibo(); 169 void OnLoadAmiibo();
170 void OnOpenYuzuFolder();
170 void OnAbout(); 171 void OnAbout();
171 void OnToggleFilterBar(); 172 void OnToggleFilterBar();
172 void OnDisplayTitleBars(bool); 173 void OnDisplayTitleBars(bool);
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui
index 48d099591..28cf269e7 100644
--- a/src/yuzu/main.ui
+++ b/src/yuzu/main.ui
@@ -110,6 +110,7 @@
110 <string>&amp;Help</string> 110 <string>&amp;Help</string>
111 </property> 111 </property>
112 <addaction name="action_Report_Compatibility"/> 112 <addaction name="action_Report_Compatibility"/>
113 <addaction name="action_Open_yuzu_Folder" />
113 <addaction name="separator"/> 114 <addaction name="separator"/>
114 <addaction name="action_About"/> 115 <addaction name="action_About"/>
115 </widget> 116 </widget>
@@ -277,6 +278,11 @@
277 <bool>false</bool> 278 <bool>false</bool>
278 </property> 279 </property>
279 </action> 280 </action>
281 <action name="action_Open_yuzu_Folder">
282 <property name="text">
283 <string>Open yuzu Folder</string>
284 </property>
285 </action>
280 </widget> 286 </widget>
281 <resources/> 287 <resources/>
282 <connections/> 288 <connections/>
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index c8b93b85b..806127b12 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -76,6 +76,9 @@ static void InitializeLogging() {
76 const std::string& log_dir = FileUtil::GetUserPath(FileUtil::UserPath::LogDir); 76 const std::string& log_dir = FileUtil::GetUserPath(FileUtil::UserPath::LogDir);
77 FileUtil::CreateFullPath(log_dir); 77 FileUtil::CreateFullPath(log_dir);
78 Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE)); 78 Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE));
79#ifdef _WIN32
80 Log::AddBackend(std::make_unique<Log::DebuggerBackend>());
81#endif
79} 82}
80 83
81/// Application entry point 84/// Application entry point