aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpineappleEA <pineaea@gmail.com>2021-01-19 00:14:45 +0100
committerpineappleEA <pineaea@gmail.com>2021-01-19 00:14:45 +0100
commitfab33e730a9c198910ab133895d62581b753e5a8 (patch)
tree6c26dd1aef74ae9309ce952b95f1e841505f2eed
parentcd088d656c326b253abbd2fb81ca24d0550d5be7 (diff)
early-access version 1341EA-1341
-rwxr-xr-xREADME.md2
-rwxr-xr-xsrc/core/memory.cpp38
-rwxr-xr-xsrc/video_core/buffer_cache/buffer_base.h11
-rwxr-xr-xsrc/video_core/buffer_cache/buffer_cache.h103
-rwxr-xr-xsrc/video_core/renderer_opengl/gl_buffer_cache.cpp95
-rwxr-xr-xsrc/video_core/renderer_opengl/gl_buffer_cache.h32
-rwxr-xr-xsrc/video_core/renderer_opengl/gl_device.cpp5
-rwxr-xr-xsrc/video_core/renderer_opengl/gl_device.h2
-rwxr-xr-xsrc/video_core/renderer_opengl/gl_rasterizer.cpp4
-rwxr-xr-xsrc/video_core/renderer_opengl/gl_rasterizer.h7
-rwxr-xr-xsrc/video_core/renderer_opengl/renderer_opengl.cpp88
-rwxr-xr-xsrc/video_core/renderer_opengl/renderer_opengl.h3
-rwxr-xr-xsrc/video_core/vulkan_common/vulkan_wrapper.cpp2
-rwxr-xr-xsrc/yuzu/configuration/config.cpp2
14 files changed, 152 insertions, 242 deletions
diff --git a/README.md b/README.md
index d851a7df5..ec04f01fe 100755
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
1yuzu emulator early access 1yuzu emulator early access
2============= 2=============
3 3
4This is the source code for early-access 1339. 4This is the source code for early-access 1341.
5 5
6## Legal Notice 6## Legal Notice
7 7
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 961f1c028..11609682a 100755
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -195,9 +195,8 @@ struct Memory::Impl {
195 switch (type) { 195 switch (type) {
196 case Common::PageType::Unmapped: { 196 case Common::PageType::Unmapped: {
197 LOG_ERROR(HW_Memory, 197 LOG_ERROR(HW_Memory,
198 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {}) " 198 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
199 "at PC 0x{:08X}", 199 current_vaddr, src_addr, size);
200 current_vaddr, src_addr, size, system.CurrentArmInterface().GetPC());
201 std::memset(dest_buffer, 0, copy_amount); 200 std::memset(dest_buffer, 0, copy_amount);
202 break; 201 break;
203 } 202 }
@@ -241,9 +240,8 @@ struct Memory::Impl {
241 switch (type) { 240 switch (type) {
242 case Common::PageType::Unmapped: { 241 case Common::PageType::Unmapped: {
243 LOG_ERROR(HW_Memory, 242 LOG_ERROR(HW_Memory,
244 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {}) " 243 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
245 "at PC 0x{:08X}", 244 current_vaddr, src_addr, size);
246 current_vaddr, src_addr, size, system.CurrentArmInterface().GetPC());
247 std::memset(dest_buffer, 0, copy_amount); 245 std::memset(dest_buffer, 0, copy_amount);
248 break; 246 break;
249 } 247 }
@@ -293,9 +291,8 @@ struct Memory::Impl {
293 switch (type) { 291 switch (type) {
294 case Common::PageType::Unmapped: { 292 case Common::PageType::Unmapped: {
295 LOG_ERROR(HW_Memory, 293 LOG_ERROR(HW_Memory,
296 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {}) " 294 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
297 "at PC 0x{:08X}", 295 current_vaddr, dest_addr, size);
298 current_vaddr, dest_addr, size, system.CurrentArmInterface().GetPC());
299 break; 296 break;
300 } 297 }
301 case Common::PageType::Memory: { 298 case Common::PageType::Memory: {
@@ -337,9 +334,8 @@ struct Memory::Impl {
337 switch (type) { 334 switch (type) {
338 case Common::PageType::Unmapped: { 335 case Common::PageType::Unmapped: {
339 LOG_ERROR(HW_Memory, 336 LOG_ERROR(HW_Memory,
340 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {}) " 337 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
341 "at PC 0x{:08X}", 338 current_vaddr, dest_addr, size);
342 current_vaddr, dest_addr, size, system.CurrentArmInterface().GetPC());
343 break; 339 break;
344 } 340 }
345 case Common::PageType::Memory: { 341 case Common::PageType::Memory: {
@@ -387,9 +383,8 @@ struct Memory::Impl {
387 switch (type) { 383 switch (type) {
388 case Common::PageType::Unmapped: { 384 case Common::PageType::Unmapped: {
389 LOG_ERROR(HW_Memory, 385 LOG_ERROR(HW_Memory,
390 "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {}) " 386 "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
391 "at PC 0x{:08X}", 387 current_vaddr, dest_addr, size);
392 current_vaddr, dest_addr, size, system.CurrentArmInterface().GetPC());
393 break; 388 break;
394 } 389 }
395 case Common::PageType::Memory: { 390 case Common::PageType::Memory: {
@@ -434,9 +429,8 @@ struct Memory::Impl {
434 switch (type) { 429 switch (type) {
435 case Common::PageType::Unmapped: { 430 case Common::PageType::Unmapped: {
436 LOG_ERROR(HW_Memory, 431 LOG_ERROR(HW_Memory,
437 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {}) " 432 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
438 "at PC 0x{:08X}", 433 current_vaddr, src_addr, size);
439 current_vaddr, src_addr, size, system.CurrentArmInterface().GetPC());
440 ZeroBlock(process, dest_addr, copy_amount); 434 ZeroBlock(process, dest_addr, copy_amount);
441 break; 435 break;
442 } 436 }
@@ -607,8 +601,7 @@ struct Memory::Impl {
607 } 601 }
608 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) { 602 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
609 case Common::PageType::Unmapped: 603 case Common::PageType::Unmapped:
610 LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X} at PC 0x{:08X}", sizeof(T) * 8, vaddr, 604 LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr);
611 system.CurrentArmInterface().GetPC());
612 return 0; 605 return 0;
613 case Common::PageType::Memory: 606 case Common::PageType::Memory:
614 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); 607 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
@@ -645,9 +638,8 @@ struct Memory::Impl {
645 } 638 }
646 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) { 639 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
647 case Common::PageType::Unmapped: 640 case Common::PageType::Unmapped:
648 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X} at PC 0x{:08X}", 641 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8,
649 sizeof(data) * 8, static_cast<u32>(data), vaddr, 642 static_cast<u32>(data), vaddr);
650 system.CurrentArmInterface().GetPC());
651 return; 643 return;
652 case Common::PageType::Memory: 644 case Common::PageType::Memory:
653 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); 645 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
diff --git a/src/video_core/buffer_cache/buffer_base.h b/src/video_core/buffer_cache/buffer_base.h
index 8a5e6a3e7..0c00ae280 100755
--- a/src/video_core/buffer_cache/buffer_base.h
+++ b/src/video_core/buffer_cache/buffer_base.h
@@ -251,6 +251,16 @@ public:
251 flags &= ~BufferFlagBits::Picked; 251 flags &= ~BufferFlagBits::Picked;
252 } 252 }
253 253
254 /// Increases the likeliness of this being a stream buffer
255 void IncreaseStreamScore(int score) noexcept {
256 stream_score += score;
257 }
258
259 /// Returns the likeliness of this being a stream buffer
260 [[nodiscard]] int StreamScore() const noexcept {
261 return stream_score;
262 }
263
254 /// Returns true when vaddr -> vaddr+size is fully contained in the buffer 264 /// Returns true when vaddr -> vaddr+size is fully contained in the buffer
255 [[nodiscard]] bool IsInBounds(VAddr addr, u64 size) const noexcept { 265 [[nodiscard]] bool IsInBounds(VAddr addr, u64 size) const noexcept {
256 return addr >= cpu_addr && addr + size <= cpu_addr + SizeBytes(); 266 return addr >= cpu_addr && addr + size <= cpu_addr + SizeBytes();
@@ -574,6 +584,7 @@ private:
574 VAddr cpu_addr = 0; 584 VAddr cpu_addr = 0;
575 Words words; 585 Words words;
576 BufferFlagBits flags{}; 586 BufferFlagBits flags{};
587 int stream_score = 0;
577}; 588};
578 589
579} // namespace VideoCommon 590} // namespace VideoCommon
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index bd8507610..a296036f4 100755
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -71,6 +71,13 @@ class BufferCache {
71 71
72 struct Empty {}; 72 struct Empty {};
73 73
74 struct OverlapResult {
75 std::vector<BufferId> ids;
76 VAddr begin;
77 VAddr end;
78 bool has_stream_leap = false;
79 };
80
74 struct Binding { 81 struct Binding {
75 VAddr cpu_addr{}; 82 VAddr cpu_addr{};
76 u32 size{}; 83 u32 size{};
@@ -84,7 +91,7 @@ class BufferCache {
84 }; 91 };
85 92
86public: 93public:
87 static constexpr size_t SKIP_CACHE_SIZE = 4096; 94 static constexpr u32 SKIP_CACHE_SIZE = 4096;
88 95
89 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer_, 96 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer_,
90 Tegra::Engines::Maxwell3D& maxwell3d_, 97 Tegra::Engines::Maxwell3D& maxwell3d_,
@@ -220,6 +227,10 @@ private:
220 227
221 [[nodiscard]] BufferId FindBuffer(VAddr cpu_addr, u32 size); 228 [[nodiscard]] BufferId FindBuffer(VAddr cpu_addr, u32 size);
222 229
230 [[nodiscard]] OverlapResult ResolveOverlaps(VAddr cpu_addr, u32 wanted_size);
231
232 void JoinOverlap(BufferId new_buffer_id, BufferId overlap_id, bool accumulate_stream_score);
233
223 [[nodiscard]] BufferId CreateBuffer(VAddr cpu_addr, u32 wanted_size); 234 [[nodiscard]] BufferId CreateBuffer(VAddr cpu_addr, u32 wanted_size);
224 235
225 void Register(BufferId buffer_id); 236 void Register(BufferId buffer_id);
@@ -988,12 +999,15 @@ BufferId BufferCache<P>::FindBuffer(VAddr cpu_addr, u32 size) {
988} 999}
989 1000
990template <class P> 1001template <class P>
991BufferId BufferCache<P>::CreateBuffer(VAddr cpu_addr, u32 wanted_size) { 1002typename BufferCache<P>::OverlapResult BufferCache<P>::ResolveOverlaps(VAddr cpu_addr,
1003 u32 wanted_size) {
1004 static constexpr int STREAM_LEAP_THRESHOLD = 16;
992 std::vector<BufferId> overlap_ids; 1005 std::vector<BufferId> overlap_ids;
993 VAddr cpu_addr_begin = cpu_addr; 1006 VAddr begin = cpu_addr;
994 VAddr cpu_addr_end = cpu_addr + wanted_size; 1007 VAddr end = cpu_addr + wanted_size;
995 for (; cpu_addr >> PAGE_BITS < Common::DivCeil(cpu_addr_end, PAGE_SIZE); 1008 int stream_score = 0;
996 cpu_addr += PAGE_SIZE) { 1009 bool has_stream_leap = false;
1010 for (; cpu_addr >> PAGE_BITS < Common::DivCeil(end, PAGE_SIZE); cpu_addr += PAGE_SIZE) {
997 const BufferId overlap_id = page_table[cpu_addr >> PAGE_BITS]; 1011 const BufferId overlap_id = page_table[cpu_addr >> PAGE_BITS];
998 if (!overlap_id) { 1012 if (!overlap_id) {
999 continue; 1013 continue;
@@ -1002,38 +1016,63 @@ BufferId BufferCache<P>::CreateBuffer(VAddr cpu_addr, u32 wanted_size) {
1002 if (overlap.IsPicked()) { 1016 if (overlap.IsPicked()) {
1003 continue; 1017 continue;
1004 } 1018 }
1005 overlap.Pick();
1006 overlap_ids.push_back(overlap_id); 1019 overlap_ids.push_back(overlap_id);
1020 overlap.Pick();
1007 const VAddr overlap_cpu_addr = overlap.CpuAddr(); 1021 const VAddr overlap_cpu_addr = overlap.CpuAddr();
1008 if (overlap_cpu_addr < cpu_addr_begin) { 1022 if (overlap_cpu_addr < begin) {
1009 cpu_addr = cpu_addr_begin = overlap_cpu_addr; 1023 cpu_addr = begin = overlap_cpu_addr;
1024 }
1025 end = std::max(end, overlap_cpu_addr + overlap.SizeBytes());
1026
1027 stream_score += overlap.StreamScore();
1028 if (stream_score > STREAM_LEAP_THRESHOLD && !has_stream_leap) {
1029 // When this memory region has been joined a bunch of times, we assume it's being used
1030 // as a stream buffer. Increase the size to skip constantly recreating buffers.
1031 has_stream_leap = true;
1032 end += PAGE_SIZE * 256;
1010 } 1033 }
1011 cpu_addr_end = std::max(cpu_addr_end, overlap_cpu_addr + overlap.SizeBytes());
1012 } 1034 }
1013 const u32 size = static_cast<u32>(cpu_addr_end - cpu_addr_begin); 1035 return OverlapResult{
1014 const BufferId new_buffer_id = slot_buffers.insert(runtime, rasterizer, cpu_addr_begin, size); 1036 .ids = std::move(overlap_ids),
1015 Buffer& new_buffer = slot_buffers[new_buffer_id]; 1037 .begin = begin,
1016 1038 .end = end,
1017 for (const BufferId overlap_id : overlap_ids) { 1039 .has_stream_leap = has_stream_leap,
1018 Buffer& overlap = slot_buffers[overlap_id]; 1040 };
1019 overlap.Unpick(); 1041}
1020 1042
1021 std::vector<BufferCopy> copies; 1043template <class P>
1022 const size_t dst_base_offset = overlap.CpuAddr() - new_buffer.CpuAddr(); 1044void BufferCache<P>::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id,
1023 overlap.ForEachDownloadRange([&](u64 begin, u64 range_size) { 1045 bool accumulate_stream_score) {
1024 copies.push_back(BufferCopy{ 1046 Buffer& new_buffer = slot_buffers[new_buffer_id];
1025 .src_offset = begin, 1047 Buffer& overlap = slot_buffers[overlap_id];
1026 .dst_offset = dst_base_offset + begin, 1048 if (accumulate_stream_score) {
1027 .size = range_size, 1049 new_buffer.IncreaseStreamScore(overlap.StreamScore() + 1);
1028 }); 1050 }
1029 new_buffer.UnmarkRegionAsCpuModified(begin, range_size); 1051 std::vector<BufferCopy> copies;
1030 new_buffer.MarkRegionAsGpuModified(begin, range_size); 1052 const size_t dst_base_offset = overlap.CpuAddr() - new_buffer.CpuAddr();
1053 overlap.ForEachDownloadRange([&](u64 begin, u64 range_size) {
1054 copies.push_back(BufferCopy{
1055 .src_offset = begin,
1056 .dst_offset = dst_base_offset + begin,
1057 .size = range_size,
1031 }); 1058 });
1032 if (!copies.empty()) { 1059 new_buffer.UnmarkRegionAsCpuModified(begin, range_size);
1033 runtime.CopyBuffer(slot_buffers[new_buffer_id], overlap, copies); 1060 new_buffer.MarkRegionAsGpuModified(begin, range_size);
1034 } 1061 });
1035 ReplaceBufferDownloads(overlap_id, new_buffer_id); 1062 if (!copies.empty()) {
1036 DeleteBuffer(overlap_id); 1063 runtime.CopyBuffer(slot_buffers[new_buffer_id], overlap, copies);
1064 }
1065 ReplaceBufferDownloads(overlap_id, new_buffer_id);
1066 DeleteBuffer(overlap_id);
1067}
1068
1069template <class P>
1070BufferId BufferCache<P>::CreateBuffer(VAddr cpu_addr, u32 wanted_size) {
1071 const OverlapResult overlap = ResolveOverlaps(cpu_addr, wanted_size);
1072 const u32 size = static_cast<u32>(overlap.end - overlap.begin);
1073 const BufferId new_buffer_id = slot_buffers.insert(runtime, rasterizer, overlap.begin, size);
1074 for (const BufferId overlap_id : overlap.ids) {
1075 JoinOverlap(new_buffer_id, overlap_id, !overlap.has_stream_leap);
1037 } 1076 }
1038 Register(new_buffer_id); 1077 Register(new_buffer_id);
1039 return new_buffer_id; 1078 return new_buffer_id;
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 889ad6c56..6da3906a4 100755
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -7,10 +7,6 @@
7#include "video_core/buffer_cache/buffer_cache.h" 7#include "video_core/buffer_cache/buffer_cache.h"
8#include "video_core/renderer_opengl/gl_buffer_cache.h" 8#include "video_core/renderer_opengl/gl_buffer_cache.h"
9#include "video_core/renderer_opengl/gl_device.h" 9#include "video_core/renderer_opengl/gl_device.h"
10#include "video_core/vulkan_common/vulkan_device.h"
11#include "video_core/vulkan_common/vulkan_instance.h"
12#include "video_core/vulkan_common/vulkan_library.h"
13#include "video_core/vulkan_common/vulkan_memory_allocator.h"
14 10
15namespace OpenGL { 11namespace OpenGL {
16namespace { 12namespace {
@@ -36,13 +32,8 @@ Buffer::Buffer(BufferCacheRuntime& runtime, VideoCore::RasterizerInterface& rast
36 buffer.Create(); 32 buffer.Create();
37 const std::string name = fmt::format("Buffer 0x{:x}", CpuAddr()); 33 const std::string name = fmt::format("Buffer 0x{:x}", CpuAddr());
38 glObjectLabel(GL_BUFFER, buffer.handle, static_cast<GLsizei>(name.size()), name.data()); 34 glObjectLabel(GL_BUFFER, buffer.handle, static_cast<GLsizei>(name.size()), name.data());
39 if (runtime.device.UseAssemblyShaders()) { 35 glNamedBufferData(buffer.handle, SizeBytes(), nullptr, GL_DYNAMIC_DRAW);
40 CreateMemoryObjects(runtime); 36
41 glNamedBufferStorageMemEXT(buffer.handle, SizeBytes(), memory_commit.ExportOpenGLHandle(),
42 memory_commit.Offset());
43 } else {
44 glNamedBufferData(buffer.handle, SizeBytes(), nullptr, GL_DYNAMIC_DRAW);
45 }
46 if (runtime.has_unified_vertex_buffers) { 37 if (runtime.has_unified_vertex_buffers) {
47 glGetNamedBufferParameterui64vNV(buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &address); 38 glGetNamedBufferParameterui64vNV(buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &address);
48 } 39 }
@@ -71,61 +62,30 @@ void Buffer::MakeResident(GLenum access) noexcept {
71 glMakeNamedBufferResidentNV(buffer.handle, access); 62 glMakeNamedBufferResidentNV(buffer.handle, access);
72} 63}
73 64
74GLuint Buffer::SubBuffer(u32 offset) { 65BufferCacheRuntime::BufferCacheRuntime(const Device& device_)
75 if (offset == 0) { 66 : device{device_}, has_fast_buffer_sub_data{device.HasFastBufferSubData()},
76 return buffer.handle; 67 use_assembly_shaders{device.UseAssemblyShaders()},
77 } 68 has_unified_vertex_buffers{device.HasVertexBufferUnifiedMemory()},
78 for (const auto& [sub_buffer, sub_offset] : subs) { 69 stream_buffer{has_fast_buffer_sub_data ? std::nullopt : std::make_optional<StreamBuffer>()} {
79 if (sub_offset == offset) {
80 return sub_buffer.handle;
81 }
82 }
83 OGLBuffer sub_buffer;
84 sub_buffer.Create();
85 glNamedBufferStorageMemEXT(sub_buffer.handle, SizeBytes() - offset,
86 memory_commit.ExportOpenGLHandle(), memory_commit.Offset() + offset);
87 return subs.emplace_back(std::move(sub_buffer), offset).first.handle;
88}
89
90void Buffer::CreateMemoryObjects(BufferCacheRuntime& runtime) {
91 auto& allocator = runtime.vulkan_memory_allocator;
92 auto& device = runtime.vulkan_device->GetLogical();
93 auto vulkan_buffer = device.CreateBuffer(VkBufferCreateInfo{
94 .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
95 .pNext = nullptr,
96 .flags = 0,
97 .size = SizeBytes(),
98 .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
99 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
100 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
101 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
102 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
103 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
104 .queueFamilyIndexCount = 0,
105 .pQueueFamilyIndices = nullptr,
106 });
107 const VkMemoryRequirements requirements = device.GetBufferMemoryRequirements(*vulkan_buffer);
108 memory_commit = allocator->Commit(requirements, Vulkan::MemoryUsage::DeviceLocal);
109}
110
111BufferCacheRuntime::BufferCacheRuntime(const Device& device_, const Vulkan::Device* vulkan_device_,
112 Vulkan::MemoryAllocator* vulkan_memory_allocator_)
113 : device{device_}, vulkan_device{vulkan_device_},
114 vulkan_memory_allocator{vulkan_memory_allocator_},
115 stream_buffer{device.HasFastBufferSubData() ? std::nullopt
116 : std::make_optional<StreamBuffer>()} {
117 GLint gl_max_attributes; 70 GLint gl_max_attributes;
118 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &gl_max_attributes); 71 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &gl_max_attributes);
119 max_attributes = static_cast<u32>(gl_max_attributes); 72 max_attributes = static_cast<u32>(gl_max_attributes);
120 use_assembly_shaders = device.UseAssemblyShaders();
121 has_unified_vertex_buffers = device.HasVertexBufferUnifiedMemory();
122
123 for (auto& stage_uniforms : fast_uniforms) { 73 for (auto& stage_uniforms : fast_uniforms) {
124 for (OGLBuffer& buffer : stage_uniforms) { 74 for (OGLBuffer& buffer : stage_uniforms) {
125 buffer.Create(); 75 buffer.Create();
126 glNamedBufferData(buffer.handle, BufferCache::SKIP_CACHE_SIZE, nullptr, GL_STREAM_DRAW); 76 glNamedBufferData(buffer.handle, BufferCache::SKIP_CACHE_SIZE, nullptr, GL_STREAM_DRAW);
127 } 77 }
128 } 78 }
79 for (auto& stage_uniforms : copy_uniforms) {
80 for (OGLBuffer& buffer : stage_uniforms) {
81 buffer.Create();
82 glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY);
83 }
84 }
85 for (OGLBuffer& buffer : copy_compute_uniforms) {
86 buffer.Create();
87 glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY);
88 }
129} 89}
130 90
131void BufferCacheRuntime::CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer, 91void BufferCacheRuntime::CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer,
@@ -167,8 +127,14 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, Buffer& buffer, u32 offset,
167void BufferCacheRuntime::BindUniformBuffer(size_t stage, u32 binding_index, Buffer& buffer, 127void BufferCacheRuntime::BindUniformBuffer(size_t stage, u32 binding_index, Buffer& buffer,
168 u32 offset, u32 size) { 128 u32 offset, u32 size) {
169 if (use_assembly_shaders) { 129 if (use_assembly_shaders) {
170 const GLuint sub_buffer = buffer.SubBuffer(offset); 130 GLuint handle;
171 glBindBufferRangeNV(PABO_LUT[stage], binding_index, sub_buffer, 0, 131 if (offset != 0) {
132 handle = copy_uniforms[stage][binding_index].handle;
133 glCopyNamedBufferSubData(buffer.Handle(), handle, offset, 0, size);
134 } else {
135 handle = buffer.Handle();
136 }
137 glBindBufferRangeNV(PABO_LUT[stage], binding_index, handle, 0,
172 static_cast<GLsizeiptr>(size)); 138 static_cast<GLsizeiptr>(size));
173 } else { 139 } else {
174 const GLuint base_binding = device.GetBaseBindings(stage).uniform_buffer; 140 const GLuint base_binding = device.GetBaseBindings(stage).uniform_buffer;
@@ -181,8 +147,15 @@ void BufferCacheRuntime::BindUniformBuffer(size_t stage, u32 binding_index, Buff
181void BufferCacheRuntime::BindComputeUniformBuffer(u32 binding_index, Buffer& buffer, u32 offset, 147void BufferCacheRuntime::BindComputeUniformBuffer(u32 binding_index, Buffer& buffer, u32 offset,
182 u32 size) { 148 u32 size) {
183 if (use_assembly_shaders) { 149 if (use_assembly_shaders) {
184 glBindBufferRangeNV(GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV, binding_index, 150 GLuint handle;
185 buffer.SubBuffer(offset), 0, static_cast<GLsizeiptr>(size)); 151 if (offset != 0) {
152 handle = copy_compute_uniforms[binding_index].handle;
153 glCopyNamedBufferSubData(buffer.Handle(), handle, offset, 0, size);
154 } else {
155 handle = buffer.Handle();
156 }
157 glBindBufferRangeNV(GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV, binding_index, handle, 0,
158 static_cast<GLsizeiptr>(size));
186 } else { 159 } else {
187 glBindBufferRange(GL_UNIFORM_BUFFER, binding_index, buffer.Handle(), 160 glBindBufferRange(GL_UNIFORM_BUFFER, binding_index, buffer.Handle(),
188 static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size)); 161 static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size));
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index f4d8871a9..d8b20a9af 100755
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -15,13 +15,6 @@
15#include "video_core/renderer_opengl/gl_device.h" 15#include "video_core/renderer_opengl/gl_device.h"
16#include "video_core/renderer_opengl/gl_resource_manager.h" 16#include "video_core/renderer_opengl/gl_resource_manager.h"
17#include "video_core/renderer_opengl/gl_stream_buffer.h" 17#include "video_core/renderer_opengl/gl_stream_buffer.h"
18#include "video_core/vulkan_common/vulkan_device.h"
19#include "video_core/vulkan_common/vulkan_memory_allocator.h"
20
21namespace Vulkan {
22class Device;
23class MemoryAllocator;
24} // namespace Vulkan
25 18
26namespace OpenGL { 19namespace OpenGL {
27 20
@@ -39,8 +32,6 @@ public:
39 32
40 void MakeResident(GLenum access) noexcept; 33 void MakeResident(GLenum access) noexcept;
41 34
42 [[nodiscard]] GLuint SubBuffer(u32 offset);
43
44 [[nodiscard]] GLuint64EXT HostGpuAddr() const noexcept { 35 [[nodiscard]] GLuint64EXT HostGpuAddr() const noexcept {
45 return address; 36 return address;
46 } 37 }
@@ -50,13 +41,9 @@ public:
50 } 41 }
51 42
52private: 43private:
53 void CreateMemoryObjects(BufferCacheRuntime& runtime);
54
55 GLuint64EXT address = 0; 44 GLuint64EXT address = 0;
56 Vulkan::MemoryCommit memory_commit;
57 OGLBuffer buffer; 45 OGLBuffer buffer;
58 GLenum current_residency_access = GL_NONE; 46 GLenum current_residency_access = GL_NONE;
59 std::vector<std::pair<OGLBuffer, u32>> subs;
60}; 47};
61 48
62class BufferCacheRuntime { 49class BufferCacheRuntime {
@@ -65,8 +52,7 @@ class BufferCacheRuntime {
65public: 52public:
66 static constexpr u8 INVALID_BINDING = std::numeric_limits<u8>::max(); 53 static constexpr u8 INVALID_BINDING = std::numeric_limits<u8>::max();
67 54
68 explicit BufferCacheRuntime(const Device& device_, const Vulkan::Device* vulkan_device_, 55 explicit BufferCacheRuntime(const Device& device_);
69 Vulkan::MemoryAllocator* vulkan_memory_allocator_);
70 56
71 void CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer, 57 void CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer,
72 std::span<const VideoCommon::BufferCopy> copies); 58 std::span<const VideoCommon::BufferCopy> copies);
@@ -127,7 +113,7 @@ public:
127 } 113 }
128 114
129 [[nodiscard]] bool HasFastBufferSubData() const noexcept { 115 [[nodiscard]] bool HasFastBufferSubData() const noexcept {
130 return device.HasFastBufferSubData(); 116 return has_fast_buffer_sub_data;
131 } 117 }
132 118
133private: 119private:
@@ -138,18 +124,22 @@ private:
138 }; 124 };
139 125
140 const Device& device; 126 const Device& device;
141 const Vulkan::Device* vulkan_device;
142 Vulkan::MemoryAllocator* vulkan_memory_allocator;
143 std::optional<StreamBuffer> stream_buffer;
144
145 u32 max_attributes = 0;
146 127
128 bool has_fast_buffer_sub_data = false;
147 bool use_assembly_shaders = false; 129 bool use_assembly_shaders = false;
148 bool has_unified_vertex_buffers = false; 130 bool has_unified_vertex_buffers = false;
149 131
132 u32 max_attributes = 0;
133
134 std::optional<StreamBuffer> stream_buffer;
135
150 std::array<std::array<OGLBuffer, VideoCommon::NUM_GRAPHICS_UNIFORM_BUFFERS>, 136 std::array<std::array<OGLBuffer, VideoCommon::NUM_GRAPHICS_UNIFORM_BUFFERS>,
151 VideoCommon::NUM_STAGES> 137 VideoCommon::NUM_STAGES>
152 fast_uniforms; 138 fast_uniforms;
139 std::array<std::array<OGLBuffer, VideoCommon::NUM_GRAPHICS_UNIFORM_BUFFERS>,
140 VideoCommon::NUM_STAGES>
141 copy_uniforms;
142 std::array<OGLBuffer, VideoCommon::NUM_COMPUTE_UNIFORM_BUFFERS> copy_compute_uniforms;
153 143
154 u32 index_buffer_offset = 0; 144 u32 index_buffer_offset = 0;
155}; 145};
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 7310185e6..703391ca5 100755
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -197,7 +197,7 @@ bool IsASTCSupported() {
197} 197}
198} // Anonymous namespace 198} // Anonymous namespace
199 199
200Device::Device(bool has_vulkan_instance) { 200Device::Device() {
201 if (!GLAD_GL_VERSION_4_3) { 201 if (!GLAD_GL_VERSION_4_3) {
202 LOG_ERROR(Render_OpenGL, "OpenGL 4.3 is not available"); 202 LOG_ERROR(Render_OpenGL, "OpenGL 4.3 is not available");
203 throw std::runtime_error{"Insufficient version"}; 203 throw std::runtime_error{"Insufficient version"};
@@ -246,8 +246,7 @@ Device::Device(bool has_vulkan_instance) {
246 246
247 use_assembly_shaders = Settings::values.use_assembly_shaders.GetValue() && 247 use_assembly_shaders = Settings::values.use_assembly_shaders.GetValue() &&
248 GLAD_GL_NV_gpu_program5 && GLAD_GL_NV_compute_program5 && 248 GLAD_GL_NV_gpu_program5 && GLAD_GL_NV_compute_program5 &&
249 GLAD_GL_NV_transform_feedback && GLAD_GL_NV_transform_feedback2 && 249 GLAD_GL_NV_transform_feedback && GLAD_GL_NV_transform_feedback2;
250 has_vulkan_instance;
251 250
252 use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue(); 251 use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue();
253 252
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h
index 21a38544f..9e620f603 100755
--- a/src/video_core/renderer_opengl/gl_device.h
+++ b/src/video_core/renderer_opengl/gl_device.h
@@ -19,7 +19,7 @@ public:
19 u32 image{}; 19 u32 image{};
20 }; 20 };
21 21
22 explicit Device(bool has_vulkan_instance); 22 explicit Device();
23 explicit Device(std::nullptr_t); 23 explicit Device(std::nullptr_t);
24 24
25 u32 GetMaxUniformBuffers(Tegra::Engines::ShaderType shader_type) const noexcept { 25 u32 GetMaxUniformBuffers(Tegra::Engines::ShaderType shader_type) const noexcept {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 3e90e6481..8298d6787 100755
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -170,8 +170,6 @@ ImageViewType ImageViewTypeFromEntry(const ImageEntry& entry) {
170 170
171RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, 171RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
172 Core::Memory::Memory& cpu_memory_, const Device& device_, 172 Core::Memory::Memory& cpu_memory_, const Device& device_,
173 const Vulkan::Device* vulkan_device,
174 Vulkan::MemoryAllocator* vulkan_memory_allocator,
175 ScreenInfo& screen_info_, ProgramManager& program_manager_, 173 ScreenInfo& screen_info_, ProgramManager& program_manager_,
176 StateTracker& state_tracker_) 174 StateTracker& state_tracker_)
177 : RasterizerAccelerated(cpu_memory_), gpu(gpu_), maxwell3d(gpu.Maxwell3D()), 175 : RasterizerAccelerated(cpu_memory_), gpu(gpu_), maxwell3d(gpu.Maxwell3D()),
@@ -179,7 +177,7 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra
179 screen_info(screen_info_), program_manager(program_manager_), state_tracker(state_tracker_), 177 screen_info(screen_info_), program_manager(program_manager_), state_tracker(state_tracker_),
180 texture_cache_runtime(device, program_manager, state_tracker), 178 texture_cache_runtime(device, program_manager, state_tracker),
181 texture_cache(texture_cache_runtime, *this, maxwell3d, kepler_compute, gpu_memory), 179 texture_cache(texture_cache_runtime, *this, maxwell3d, kepler_compute, gpu_memory),
182 buffer_cache_runtime(device, vulkan_device, vulkan_memory_allocator), 180 buffer_cache_runtime(device),
183 buffer_cache(*this, maxwell3d, kepler_compute, gpu_memory, cpu_memory_, buffer_cache_runtime), 181 buffer_cache(*this, maxwell3d, kepler_compute, gpu_memory, cpu_memory_, buffer_cache_runtime),
184 shader_cache(*this, emu_window_, gpu, maxwell3d, kepler_compute, gpu_memory, device), 182 shader_cache(*this, emu_window_, gpu, maxwell3d, kepler_compute, gpu_memory, device),
185 query_cache(*this, maxwell3d, gpu_memory), 183 query_cache(*this, maxwell3d, gpu_memory),
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index b1094075a..9730544d9 100755
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -46,11 +46,6 @@ namespace Tegra {
46class MemoryManager; 46class MemoryManager;
47} 47}
48 48
49namespace Vulkan {
50class Device;
51class MemoryAllocator;
52} // namespace Vulkan
53
54namespace OpenGL { 49namespace OpenGL {
55 50
56struct ScreenInfo; 51struct ScreenInfo;
@@ -67,8 +62,6 @@ class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
67public: 62public:
68 explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, 63 explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
69 Core::Memory::Memory& cpu_memory_, const Device& device_, 64 Core::Memory::Memory& cpu_memory_, const Device& device_,
70 const Vulkan::Device* vulkan_device,
71 Vulkan::MemoryAllocator* vulkan_memory_allocator,
72 ScreenInfo& screen_info_, ProgramManager& program_manager_, 65 ScreenInfo& screen_info_, ProgramManager& program_manager_,
73 StateTracker& state_tracker_); 66 StateTracker& state_tracker_);
74 ~RasterizerOpenGL() override; 67 ~RasterizerOpenGL() override;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 8fcb86581..9d2acd4d9 100755
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -27,11 +27,6 @@
27#include "video_core/renderer_opengl/gl_shader_manager.h" 27#include "video_core/renderer_opengl/gl_shader_manager.h"
28#include "video_core/renderer_opengl/renderer_opengl.h" 28#include "video_core/renderer_opengl/renderer_opengl.h"
29#include "video_core/textures/decoders.h" 29#include "video_core/textures/decoders.h"
30#include "video_core/vulkan_common/vulkan_debug_callback.h"
31#include "video_core/vulkan_common/vulkan_device.h"
32#include "video_core/vulkan_common/vulkan_instance.h"
33#include "video_core/vulkan_common/vulkan_library.h"
34#include "video_core/vulkan_common/vulkan_memory_allocator.h"
35 30
36namespace OpenGL { 31namespace OpenGL {
37namespace { 32namespace {
@@ -127,93 +122,16 @@ void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severit
127 break; 122 break;
128 } 123 }
129} 124}
130
131Vulkan::vk::PhysicalDevice FindPhysicalDevice(Vulkan::vk::Instance& instance) {
132 using namespace Vulkan;
133 using UUID = std::array<GLubyte, GL_UUID_SIZE_EXT>;
134
135 GLint num_device_uuids;
136 glGetIntegerv(GL_NUM_DEVICE_UUIDS_EXT, &num_device_uuids);
137 std::vector<UUID> device_uuids(num_device_uuids);
138 for (GLint index = 0; index < num_device_uuids; ++index) {
139 glGetUnsignedBytei_vEXT(GL_DEVICE_UUID_EXT, 0, device_uuids[index].data());
140 }
141 UUID driver_uuid;
142 glGetUnsignedBytevEXT(GL_DRIVER_UUID_EXT, driver_uuid.data());
143
144 for (const VkPhysicalDevice raw_physical_device : instance.EnumeratePhysicalDevices()) {
145 VkPhysicalDeviceIDProperties device_id_properties{};
146 device_id_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
147
148 VkPhysicalDeviceProperties2KHR properties{
149 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
150 .pNext = &device_id_properties,
151 .properties{},
152 };
153 vk::PhysicalDevice physical_device(raw_physical_device, instance.Dispatch());
154 physical_device.GetProperties2KHR(properties);
155 if (!std::ranges::equal(device_id_properties.driverUUID, driver_uuid)) {
156 continue;
157 }
158 const auto it =
159 std::ranges::find_if(device_uuids, [&device_id_properties, driver_uuid](UUID uuid) {
160 return std::ranges::equal(device_id_properties.deviceUUID, uuid);
161 });
162 if (it != device_uuids.end()) {
163 return physical_device;
164 }
165 }
166 throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER);
167}
168} // Anonymous namespace 125} // Anonymous namespace
169 126
170struct VulkanObjects {
171 static std::unique_ptr<VulkanObjects> TryCreate() {
172 if (!GLAD_GL_EXT_memory_object) {
173 // Interop is not present
174 return nullptr;
175 }
176 const std::string_view vendor{reinterpret_cast<const char*>(glGetString(GL_VENDOR))};
177 if (vendor == "ATI Technologies Inc.") {
178 // Avoid using GL_EXT_memory_object on AMD, as it makes the GL driver crash
179 return nullptr;
180 }
181 if (!Settings::values.use_assembly_shaders.GetValue()) {
182 // We only need interop when assembly shaders are enabled
183 return nullptr;
184 }
185#ifdef __linux__
186 LOG_WARNING(Render_OpenGL, "Interop doesn't work on Linux at the moment");
187 return nullptr;
188#endif
189 try {
190 return std::make_unique<VulkanObjects>();
191 } catch (const Vulkan::vk::Exception& exception) {
192 LOG_ERROR(Render_OpenGL, "Failed to initialize Vulkan objects with error: {}",
193 exception.what());
194 return nullptr;
195 }
196 }
197
198 Common::DynamicLibrary library{Vulkan::OpenLibrary()};
199 Vulkan::vk::InstanceDispatch dld;
200 Vulkan::vk::Instance instance{Vulkan::CreateInstance(library, dld, VK_API_VERSION_1_1)};
201 Vulkan::Device device{*instance, FindPhysicalDevice(instance), nullptr, dld};
202 Vulkan::MemoryAllocator memory_allocator{device, true};
203};
204
205RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_, 127RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_,
206 Core::Frontend::EmuWindow& emu_window_, 128 Core::Frontend::EmuWindow& emu_window_,
207 Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, 129 Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_,
208 std::unique_ptr<Core::Frontend::GraphicsContext> context_) 130 std::unique_ptr<Core::Frontend::GraphicsContext> context_)
209 : RendererBase{emu_window_, std::move(context_)}, telemetry_session{telemetry_session_}, 131 : RendererBase{emu_window_, std::move(context_)}, telemetry_session{telemetry_session_},
210 emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, 132 emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, state_tracker{gpu},
211 vulkan_objects{VulkanObjects::TryCreate()}, device{vulkan_objects != nullptr}, 133 program_manager{device},
212 state_tracker{gpu}, program_manager{device}, 134 rasterizer(emu_window, gpu, cpu_memory, device, screen_info, program_manager, state_tracker) {
213 rasterizer(emu_window, gpu, cpu_memory, device,
214 vulkan_objects ? &vulkan_objects->device : nullptr,
215 vulkan_objects ? &vulkan_objects->memory_allocator : nullptr, screen_info,
216 program_manager, state_tracker) {
217 if (Settings::values.renderer_debug && GLAD_GL_KHR_debug) { 135 if (Settings::values.renderer_debug && GLAD_GL_KHR_debug) {
218 glEnable(GL_DEBUG_OUTPUT); 136 glEnable(GL_DEBUG_OUTPUT);
219 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); 137 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index f210190dd..cc19a110f 100755
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -38,8 +38,6 @@ class GPU;
38 38
39namespace OpenGL { 39namespace OpenGL {
40 40
41struct VulkanObjects;
42
43/// Structure used for storing information about the textures for the Switch screen 41/// Structure used for storing information about the textures for the Switch screen
44struct TextureInfo { 42struct TextureInfo {
45 OGLTexture resource; 43 OGLTexture resource;
@@ -101,7 +99,6 @@ private:
101 Core::Memory::Memory& cpu_memory; 99 Core::Memory::Memory& cpu_memory;
102 Tegra::GPU& gpu; 100 Tegra::GPU& gpu;
103 101
104 std::unique_ptr<VulkanObjects> vulkan_objects;
105 Device device; 102 Device device;
106 StateTracker state_tracker; 103 StateTracker state_tracker;
107 ProgramManager program_manager; 104 ProgramManager program_manager;
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp
index 311d3d22d..2aa0ffbe6 100755
--- a/src/video_core/vulkan_common/vulkan_wrapper.cpp
+++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp
@@ -787,7 +787,7 @@ DeviceMemory Device::AllocateMemory(const VkMemoryAllocateInfo& ai) const {
787} 787}
788 788
789VkMemoryRequirements Device::GetBufferMemoryRequirements(VkBuffer buffer, 789VkMemoryRequirements Device::GetBufferMemoryRequirements(VkBuffer buffer,
790 void* pnext) const noexcept { 790 void* pnext) const noexcept {
791 const VkBufferMemoryRequirementsInfo2 info{ 791 const VkBufferMemoryRequirementsInfo2 info{
792 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, 792 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
793 .pNext = nullptr, 793 .pNext = nullptr,
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 5e4d22299..72e69cdfe 100755
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -785,7 +785,7 @@ void Config::ReadRendererValues() {
785 true); 785 true);
786 ReadSettingGlobal(Settings::values.use_vsync, QStringLiteral("use_vsync"), true); 786 ReadSettingGlobal(Settings::values.use_vsync, QStringLiteral("use_vsync"), true);
787 ReadSettingGlobal(Settings::values.use_assembly_shaders, QStringLiteral("use_assembly_shaders"), 787 ReadSettingGlobal(Settings::values.use_assembly_shaders, QStringLiteral("use_assembly_shaders"),
788 true); 788 false);
789 ReadSettingGlobal(Settings::values.use_asynchronous_shaders, 789 ReadSettingGlobal(Settings::values.use_asynchronous_shaders,
790 QStringLiteral("use_asynchronous_shaders"), false); 790 QStringLiteral("use_asynchronous_shaders"), false);
791 ReadSettingGlobal(Settings::values.use_fast_gpu_time, QStringLiteral("use_fast_gpu_time"), 791 ReadSettingGlobal(Settings::values.use_fast_gpu_time, QStringLiteral("use_fast_gpu_time"),