summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--externals/CMakeLists.txt83
-rw-r--r--src/core/CMakeLists.txt7
-rw-r--r--src/core/hle/service/time/interface.cpp2
-rw-r--r--src/core/hle/service/time/time.cpp23
-rw-r--r--src/core/hle/service/time/time.h1
-rw-r--r--src/input_common/CMakeLists.txt2
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h47
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp18
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h12
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp39
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/utils.cpp62
-rw-r--r--src/video_core/renderer_opengl/utils.h43
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.cpp12
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.h10
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pass.cpp16
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pass.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_memory_manager.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp30
-rw-r--r--src/video_core/renderer_vulkan/vk_update_descriptor.cpp5
-rw-r--r--src/video_core/renderer_vulkan/vk_update_descriptor.h16
-rw-r--r--src/video_core/shader/control_flow.cpp6
-rw-r--r--src/video_core/shader/decode/shift.cpp1
-rw-r--r--src/video_core/texture_cache/surface_base.cpp6
-rw-r--r--src/video_core/texture_cache/surface_base.h4
-rw-r--r--src/video_core/texture_cache/surface_view.cpp4
-rw-r--r--src/video_core/texture_cache/surface_view.h1
-rw-r--r--src/video_core/texture_cache/texture_cache.h8
-rw-r--r--src/web_service/CMakeLists.txt7
30 files changed, 208 insertions, 269 deletions
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index 61ad3487a..d4421f697 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -3,13 +3,27 @@
3set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules) 3set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
4include(DownloadExternals) 4include(DownloadExternals)
5 5
6# pkgconfig -- it is used to find shared libraries without cmake modules on linux systems
7find_package(PkgConfig)
8if (NOT PkgConfig_FOUND)
9 function(pkg_check_modules)
10 # STUB
11 endfunction()
12endif()
13
6# Catch 14# Catch
7add_library(catch-single-include INTERFACE) 15add_library(catch-single-include INTERFACE)
8target_include_directories(catch-single-include INTERFACE catch/single_include) 16target_include_directories(catch-single-include INTERFACE catch/single_include)
9 17
10# libfmt 18# libfmt
11add_subdirectory(fmt) 19pkg_check_modules(FMT IMPORTED_TARGET GLOBAL fmt>=6.1.0)
12add_library(fmt::fmt ALIAS fmt) 20if (FMT_FOUND)
21 add_library(fmt::fmt ALIAS PkgConfig::FMT)
22else()
23 message(STATUS "fmt 6.1.0 or newer not found, falling back to externals")
24 add_subdirectory(fmt)
25 add_library(fmt::fmt ALIAS fmt)
26endif()
13 27
14# Dynarmic 28# Dynarmic
15if (ARCHITECTURE_x86_64) 29if (ARCHITECTURE_x86_64)
@@ -30,9 +44,15 @@ add_subdirectory(glad)
30add_subdirectory(inih) 44add_subdirectory(inih)
31 45
32# lz4 46# lz4
33set(LZ4_BUNDLED_MODE ON) 47pkg_check_modules(LIBLZ4 IMPORTED_TARGET GLOBAL liblz4>=1.8.0)
34add_subdirectory(lz4/contrib/cmake_unofficial EXCLUDE_FROM_ALL) 48if (LIBLZ4_FOUND)
35target_include_directories(lz4_static INTERFACE ./lz4/lib) 49 add_library(lz4_static ALIAS PkgConfig::LIBLZ4)
50else()
51 message(STATUS "liblz4 1.8.0 or newer not found, falling back to externals")
52 set(LZ4_BUNDLED_MODE ON)
53 add_subdirectory(lz4/contrib/cmake_unofficial EXCLUDE_FROM_ALL)
54 target_include_directories(lz4_static INTERFACE ./lz4/lib)
55endif()
36 56
37# mbedtls 57# mbedtls
38add_subdirectory(mbedtls EXCLUDE_FROM_ALL) 58add_subdirectory(mbedtls EXCLUDE_FROM_ALL)
@@ -47,15 +67,27 @@ add_library(unicorn-headers INTERFACE)
47target_include_directories(unicorn-headers INTERFACE ./unicorn/include) 67target_include_directories(unicorn-headers INTERFACE ./unicorn/include)
48 68
49# Zstandard 69# Zstandard
50add_subdirectory(zstd/build/cmake EXCLUDE_FROM_ALL) 70pkg_check_modules(LIBZSTD IMPORTED_TARGET GLOBAL libzstd>=1.3.8)
51target_include_directories(libzstd_static INTERFACE ./zstd/lib) 71if (LIBZSTD_FOUND)
72 add_library(libzstd_static ALIAS PkgConfig::LIBZSTD)
73else()
74 message(STATUS "libzstd 1.3.8 or newer not found, falling back to externals")
75 add_subdirectory(zstd/build/cmake EXCLUDE_FROM_ALL)
76 target_include_directories(libzstd_static INTERFACE ./zstd/lib)
77endif()
52 78
53# SoundTouch 79# SoundTouch
54add_subdirectory(soundtouch) 80add_subdirectory(soundtouch)
55 81
56# Opus 82# Opus
57add_subdirectory(opus) 83pkg_check_modules(OPUS IMPORTED_TARGET GLOBAL opus>=1.3.1)
58target_include_directories(opus INTERFACE ./opus/include) 84if (OPUS_FOUND)
85 add_library(opus ALIAS PkgConfig::OPUS)
86else()
87 message(STATUS "opus 1.3.1 or newer not found, falling back to externals")
88 add_subdirectory(opus)
89 target_include_directories(opus INTERFACE ./opus/include)
90endif()
59 91
60# Cubeb 92# Cubeb
61if(ENABLE_CUBEB) 93if(ENABLE_CUBEB)
@@ -75,18 +107,35 @@ if (ENABLE_VULKAN)
75endif() 107endif()
76 108
77# zlib 109# zlib
78add_subdirectory(zlib EXCLUDE_FROM_ALL) 110find_package(ZLIB 1.2.11)
79set(ZLIB_LIBRARIES z) 111if (NOT ZLIB_FOUND)
112 message(STATUS "zlib 1.2.11 or newer not found, falling back to externals")
113 add_subdirectory(zlib EXCLUDE_FROM_ALL)
114 set(ZLIB_LIBRARIES z)
115endif()
80 116
81# libzip 117# libzip
82add_subdirectory(libzip EXCLUDE_FROM_ALL) 118pkg_check_modules(LIBZIP IMPORTED_TARGET GLOBAL libzip>=1.5.3)
119if (LIBZIP_FOUND)
120 add_library(zip ALIAS PkgConfig::LIBZIP)
121else()
122 message(STATUS "libzip 1.5.3 or newer not found, falling back to externals")
123 add_subdirectory(libzip EXCLUDE_FROM_ALL)
124endif()
83 125
84if (ENABLE_WEB_SERVICE) 126if (ENABLE_WEB_SERVICE)
85 # LibreSSL 127 # LibreSSL
86 set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "") 128 find_package(OpenSSL COMPONENTS Crypto SSL)
87 add_subdirectory(libressl EXCLUDE_FROM_ALL) 129 if (NOT OpenSSL_FOUND)
88 target_include_directories(ssl INTERFACE ./libressl/include) 130 message(STATUS "OpenSSL not found, falling back to externals")
89 target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP) 131 set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
132 add_subdirectory(libressl EXCLUDE_FROM_ALL)
133 target_include_directories(ssl INTERFACE ./libressl/include)
134 target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
135 get_directory_property(OPENSSL_LIBRARIES
136 DIRECTORY libressl
137 DEFINITION OPENSSL_LIBS)
138 endif()
90 139
91 # lurlparser 140 # lurlparser
92 add_subdirectory(lurlparser EXCLUDE_FROM_ALL) 141 add_subdirectory(lurlparser EXCLUDE_FROM_ALL)
@@ -94,6 +143,8 @@ if (ENABLE_WEB_SERVICE)
94 # httplib 143 # httplib
95 add_library(httplib INTERFACE) 144 add_library(httplib INTERFACE)
96 target_include_directories(httplib INTERFACE ./httplib) 145 target_include_directories(httplib INTERFACE ./httplib)
146 target_compile_definitions(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
147 target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
97 148
98 # JSON 149 # JSON
99 add_library(json-headers INTERFACE) 150 add_library(json-headers INTERFACE)
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 66497a386..c15d9f52f 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -591,11 +591,8 @@ target_link_libraries(core PUBLIC common PRIVATE audio_core video_core)
591target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt json-headers mbedtls opus unicorn) 591target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt json-headers mbedtls opus unicorn)
592 592
593if (YUZU_ENABLE_BOXCAT) 593if (YUZU_ENABLE_BOXCAT)
594 get_directory_property(OPENSSL_LIBS 594 target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT)
595 DIRECTORY ${PROJECT_SOURCE_DIR}/externals/libressl 595 target_link_libraries(core PRIVATE httplib json-headers zip)
596 DEFINITION OPENSSL_LIBS)
597 target_compile_definitions(core PRIVATE -DCPPHTTPLIB_OPENSSL_SUPPORT -DYUZU_ENABLE_BOXCAT)
598 target_link_libraries(core PRIVATE httplib json-headers ${OPENSSL_LIBS} zip)
599endif() 596endif()
600 597
601if (ENABLE_WEB_SERVICE) 598if (ENABLE_WEB_SERVICE)
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp
index f509653a3..ba8fd6152 100644
--- a/src/core/hle/service/time/interface.cpp
+++ b/src/core/hle/service/time/interface.cpp
@@ -29,7 +29,7 @@ Time::Time(std::shared_ptr<Module> module, Core::System& system, const char* nam
29 {300, &Time::CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"}, 29 {300, &Time::CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"},
30 {400, &Time::GetClockSnapshot, "GetClockSnapshot"}, 30 {400, &Time::GetClockSnapshot, "GetClockSnapshot"},
31 {401, &Time::GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"}, 31 {401, &Time::GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"},
32 {500, nullptr, "CalculateStandardUserSystemClockDifferenceByUser"}, 32 {500, &Time::CalculateStandardUserSystemClockDifferenceByUser, "CalculateStandardUserSystemClockDifferenceByUser"},
33 {501, &Time::CalculateSpanBetween, "CalculateSpanBetween"}, 33 {501, &Time::CalculateSpanBetween, "CalculateSpanBetween"},
34 }; 34 };
35 // clang-format on 35 // clang-format on
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index ce859f18d..e722886de 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -308,6 +308,29 @@ void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLEReques
308 ctx.WriteBuffer(&clock_snapshot, sizeof(Clock::ClockSnapshot)); 308 ctx.WriteBuffer(&clock_snapshot, sizeof(Clock::ClockSnapshot));
309} 309}
310 310
311void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser(
312 Kernel::HLERequestContext& ctx) {
313 LOG_DEBUG(Service_Time, "called");
314
315 IPC::RequestParser rp{ctx};
316 const auto snapshot_a = rp.PopRaw<Clock::ClockSnapshot>();
317 const auto snapshot_b = rp.PopRaw<Clock::ClockSnapshot>();
318
319 auto time_span_type{Clock::TimeSpanType::FromSeconds(snapshot_b.user_context.offset -
320 snapshot_a.user_context.offset)};
321
322 if ((snapshot_b.user_context.steady_time_point.clock_source_id !=
323 snapshot_a.user_context.steady_time_point.clock_source_id) ||
324 (snapshot_b.is_automatic_correction_enabled &&
325 snapshot_a.is_automatic_correction_enabled)) {
326 time_span_type.nanoseconds = 0;
327 }
328
329 IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2};
330 rb.Push(RESULT_SUCCESS);
331 rb.PushRaw(time_span_type.nanoseconds);
332}
333
311void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) { 334void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) {
312 LOG_DEBUG(Service_Time, "called"); 335 LOG_DEBUG(Service_Time, "called");
313 336
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index 351988468..41f3002e9 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -32,6 +32,7 @@ public:
32 void CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx); 32 void CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx);
33 void GetClockSnapshot(Kernel::HLERequestContext& ctx); 33 void GetClockSnapshot(Kernel::HLERequestContext& ctx);
34 void GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx); 34 void GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx);
35 void CalculateStandardUserSystemClockDifferenceByUser(Kernel::HLERequestContext& ctx);
35 void CalculateSpanBetween(Kernel::HLERequestContext& ctx); 36 void CalculateSpanBetween(Kernel::HLERequestContext& ctx);
36 void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx); 37 void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx);
37 38
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index 2520ba321..a9c2392b1 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -27,4 +27,4 @@ if(SDL2_FOUND)
27endif() 27endif()
28 28
29create_target_directory_groups(input_common) 29create_target_directory_groups(input_common)
30target_link_libraries(input_common PUBLIC core PRIVATE common ${Boost_LIBRARIES}) 30target_link_libraries(input_common PUBLIC core PRIVATE common Boost::boost)
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index b57c0d4d4..83e7a1cde 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -29,10 +29,10 @@ namespace VideoCommon {
29 29
30using MapInterval = std::shared_ptr<MapIntervalBase>; 30using MapInterval = std::shared_ptr<MapIntervalBase>;
31 31
32template <typename TBuffer, typename TBufferType, typename StreamBuffer> 32template <typename OwnerBuffer, typename BufferType, typename StreamBuffer>
33class BufferCache { 33class BufferCache {
34public: 34public:
35 using BufferInfo = std::pair<const TBufferType*, u64>; 35 using BufferInfo = std::pair<BufferType, u64>;
36 36
37 BufferInfo UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment = 4, 37 BufferInfo UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment = 4,
38 bool is_written = false, bool use_fast_cbuf = false) { 38 bool is_written = false, bool use_fast_cbuf = false) {
@@ -89,9 +89,7 @@ public:
89 } 89 }
90 } 90 }
91 91
92 const u64 offset = static_cast<u64>(block->GetOffset(cpu_addr)); 92 return {ToHandle(block), static_cast<u64>(block->GetOffset(cpu_addr))};
93
94 return {ToHandle(block), offset};
95 } 93 }
96 94
97 /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset. 95 /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset.
@@ -156,7 +154,7 @@ public:
156 } 154 }
157 } 155 }
158 156
159 virtual const TBufferType* GetEmptyBuffer(std::size_t size) = 0; 157 virtual BufferType GetEmptyBuffer(std::size_t size) = 0;
160 158
161protected: 159protected:
162 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system, 160 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system,
@@ -166,19 +164,19 @@ protected:
166 164
167 ~BufferCache() = default; 165 ~BufferCache() = default;
168 166
169 virtual const TBufferType* ToHandle(const TBuffer& storage) = 0; 167 virtual BufferType ToHandle(const OwnerBuffer& storage) = 0;
170 168
171 virtual void WriteBarrier() = 0; 169 virtual void WriteBarrier() = 0;
172 170
173 virtual TBuffer CreateBlock(VAddr cpu_addr, std::size_t size) = 0; 171 virtual OwnerBuffer CreateBlock(VAddr cpu_addr, std::size_t size) = 0;
174 172
175 virtual void UploadBlockData(const TBuffer& buffer, std::size_t offset, std::size_t size, 173 virtual void UploadBlockData(const OwnerBuffer& buffer, std::size_t offset, std::size_t size,
176 const u8* data) = 0; 174 const u8* data) = 0;
177 175
178 virtual void DownloadBlockData(const TBuffer& buffer, std::size_t offset, std::size_t size, 176 virtual void DownloadBlockData(const OwnerBuffer& buffer, std::size_t offset, std::size_t size,
179 u8* data) = 0; 177 u8* data) = 0;
180 178
181 virtual void CopyBlock(const TBuffer& src, const TBuffer& dst, std::size_t src_offset, 179 virtual void CopyBlock(const OwnerBuffer& src, const OwnerBuffer& dst, std::size_t src_offset,
182 std::size_t dst_offset, std::size_t size) = 0; 180 std::size_t dst_offset, std::size_t size) = 0;
183 181
184 virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) { 182 virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) {
@@ -221,9 +219,8 @@ private:
221 return std::make_shared<MapIntervalBase>(start, end, gpu_addr); 219 return std::make_shared<MapIntervalBase>(start, end, gpu_addr);
222 } 220 }
223 221
224 MapInterval MapAddress(const TBuffer& block, const GPUVAddr gpu_addr, const VAddr cpu_addr, 222 MapInterval MapAddress(const OwnerBuffer& block, const GPUVAddr gpu_addr, const VAddr cpu_addr,
225 const std::size_t size) { 223 const std::size_t size) {
226
227 std::vector<MapInterval> overlaps = GetMapsInRange(cpu_addr, size); 224 std::vector<MapInterval> overlaps = GetMapsInRange(cpu_addr, size);
228 if (overlaps.empty()) { 225 if (overlaps.empty()) {
229 auto& memory_manager = system.GPU().MemoryManager(); 226 auto& memory_manager = system.GPU().MemoryManager();
@@ -272,7 +269,7 @@ private:
272 return new_map; 269 return new_map;
273 } 270 }
274 271
275 void UpdateBlock(const TBuffer& block, VAddr start, VAddr end, 272 void UpdateBlock(const OwnerBuffer& block, VAddr start, VAddr end,
276 std::vector<MapInterval>& overlaps) { 273 std::vector<MapInterval>& overlaps) {
277 const IntervalType base_interval{start, end}; 274 const IntervalType base_interval{start, end};
278 IntervalSet interval_set{}; 275 IntervalSet interval_set{};
@@ -313,7 +310,7 @@ private:
313 310
314 void FlushMap(MapInterval map) { 311 void FlushMap(MapInterval map) {
315 std::size_t size = map->GetEnd() - map->GetStart(); 312 std::size_t size = map->GetEnd() - map->GetStart();
316 TBuffer block = blocks[map->GetStart() >> block_page_bits]; 313 OwnerBuffer block = blocks[map->GetStart() >> block_page_bits];
317 staging_buffer.resize(size); 314 staging_buffer.resize(size);
318 DownloadBlockData(block, block->GetOffset(map->GetStart()), size, staging_buffer.data()); 315 DownloadBlockData(block, block->GetOffset(map->GetStart()), size, staging_buffer.data());
319 system.Memory().WriteBlockUnsafe(map->GetStart(), staging_buffer.data(), size); 316 system.Memory().WriteBlockUnsafe(map->GetStart(), staging_buffer.data(), size);
@@ -328,7 +325,7 @@ private:
328 325
329 buffer_ptr += size; 326 buffer_ptr += size;
330 buffer_offset += size; 327 buffer_offset += size;
331 return {&stream_buffer_handle, uploaded_offset}; 328 return {stream_buffer_handle, uploaded_offset};
332 } 329 }
333 330
334 void AlignBuffer(std::size_t alignment) { 331 void AlignBuffer(std::size_t alignment) {
@@ -338,11 +335,11 @@ private:
338 buffer_offset = offset_aligned; 335 buffer_offset = offset_aligned;
339 } 336 }
340 337
341 TBuffer EnlargeBlock(TBuffer buffer) { 338 OwnerBuffer EnlargeBlock(OwnerBuffer buffer) {
342 const std::size_t old_size = buffer->GetSize(); 339 const std::size_t old_size = buffer->GetSize();
343 const std::size_t new_size = old_size + block_page_size; 340 const std::size_t new_size = old_size + block_page_size;
344 const VAddr cpu_addr = buffer->GetCpuAddr(); 341 const VAddr cpu_addr = buffer->GetCpuAddr();
345 TBuffer new_buffer = CreateBlock(cpu_addr, new_size); 342 OwnerBuffer new_buffer = CreateBlock(cpu_addr, new_size);
346 CopyBlock(buffer, new_buffer, 0, 0, old_size); 343 CopyBlock(buffer, new_buffer, 0, 0, old_size);
347 buffer->SetEpoch(epoch); 344 buffer->SetEpoch(epoch);
348 pending_destruction.push_back(buffer); 345 pending_destruction.push_back(buffer);
@@ -356,14 +353,14 @@ private:
356 return new_buffer; 353 return new_buffer;
357 } 354 }
358 355
359 TBuffer MergeBlocks(TBuffer first, TBuffer second) { 356 OwnerBuffer MergeBlocks(OwnerBuffer first, OwnerBuffer second) {
360 const std::size_t size_1 = first->GetSize(); 357 const std::size_t size_1 = first->GetSize();
361 const std::size_t size_2 = second->GetSize(); 358 const std::size_t size_2 = second->GetSize();
362 const VAddr first_addr = first->GetCpuAddr(); 359 const VAddr first_addr = first->GetCpuAddr();
363 const VAddr second_addr = second->GetCpuAddr(); 360 const VAddr second_addr = second->GetCpuAddr();
364 const VAddr new_addr = std::min(first_addr, second_addr); 361 const VAddr new_addr = std::min(first_addr, second_addr);
365 const std::size_t new_size = size_1 + size_2; 362 const std::size_t new_size = size_1 + size_2;
366 TBuffer new_buffer = CreateBlock(new_addr, new_size); 363 OwnerBuffer new_buffer = CreateBlock(new_addr, new_size);
367 CopyBlock(first, new_buffer, 0, new_buffer->GetOffset(first_addr), size_1); 364 CopyBlock(first, new_buffer, 0, new_buffer->GetOffset(first_addr), size_1);
368 CopyBlock(second, new_buffer, 0, new_buffer->GetOffset(second_addr), size_2); 365 CopyBlock(second, new_buffer, 0, new_buffer->GetOffset(second_addr), size_2);
369 first->SetEpoch(epoch); 366 first->SetEpoch(epoch);
@@ -380,8 +377,8 @@ private:
380 return new_buffer; 377 return new_buffer;
381 } 378 }
382 379
383 TBuffer GetBlock(const VAddr cpu_addr, const std::size_t size) { 380 OwnerBuffer GetBlock(const VAddr cpu_addr, const std::size_t size) {
384 TBuffer found{}; 381 OwnerBuffer found;
385 const VAddr cpu_addr_end = cpu_addr + size - 1; 382 const VAddr cpu_addr_end = cpu_addr + size - 1;
386 u64 page_start = cpu_addr >> block_page_bits; 383 u64 page_start = cpu_addr >> block_page_bits;
387 const u64 page_end = cpu_addr_end >> block_page_bits; 384 const u64 page_end = cpu_addr_end >> block_page_bits;
@@ -457,7 +454,7 @@ private:
457 Core::System& system; 454 Core::System& system;
458 455
459 std::unique_ptr<StreamBuffer> stream_buffer; 456 std::unique_ptr<StreamBuffer> stream_buffer;
460 TBufferType stream_buffer_handle{}; 457 BufferType stream_buffer_handle{};
461 458
462 bool invalidated = false; 459 bool invalidated = false;
463 460
@@ -475,9 +472,9 @@ private:
475 472
476 static constexpr u64 block_page_bits = 21; 473 static constexpr u64 block_page_bits = 21;
477 static constexpr u64 block_page_size = 1ULL << block_page_bits; 474 static constexpr u64 block_page_size = 1ULL << block_page_bits;
478 std::unordered_map<u64, TBuffer> blocks; 475 std::unordered_map<u64, OwnerBuffer> blocks;
479 476
480 std::list<TBuffer> pending_destruction; 477 std::list<OwnerBuffer> pending_destruction;
481 u64 epoch = 0; 478 u64 epoch = 0;
482 u64 modified_ticks = 0; 479 u64 modified_ticks = 0;
483 480
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 4eb37a96c..cb5792407 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -55,33 +55,31 @@ void OGLBufferCache::WriteBarrier() {
55 glMemoryBarrier(GL_ALL_BARRIER_BITS); 55 glMemoryBarrier(GL_ALL_BARRIER_BITS);
56} 56}
57 57
58const GLuint* OGLBufferCache::ToHandle(const Buffer& buffer) { 58GLuint OGLBufferCache::ToHandle(const Buffer& buffer) {
59 return buffer->GetHandle(); 59 return buffer->GetHandle();
60} 60}
61 61
62const GLuint* OGLBufferCache::GetEmptyBuffer(std::size_t) { 62GLuint OGLBufferCache::GetEmptyBuffer(std::size_t) {
63 static const GLuint null_buffer = 0; 63 return 0;
64 return &null_buffer;
65} 64}
66 65
67void OGLBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 66void OGLBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
68 const u8* data) { 67 const u8* data) {
69 glNamedBufferSubData(*buffer->GetHandle(), static_cast<GLintptr>(offset), 68 glNamedBufferSubData(buffer->GetHandle(), static_cast<GLintptr>(offset),
70 static_cast<GLsizeiptr>(size), data); 69 static_cast<GLsizeiptr>(size), data);
71} 70}
72 71
73void OGLBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 72void OGLBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
74 u8* data) { 73 u8* data) {
75 MICROPROFILE_SCOPE(OpenGL_Buffer_Download); 74 MICROPROFILE_SCOPE(OpenGL_Buffer_Download);
76 glGetNamedBufferSubData(*buffer->GetHandle(), static_cast<GLintptr>(offset), 75 glGetNamedBufferSubData(buffer->GetHandle(), static_cast<GLintptr>(offset),
77 static_cast<GLsizeiptr>(size), data); 76 static_cast<GLsizeiptr>(size), data);
78} 77}
79 78
80void OGLBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset, 79void OGLBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
81 std::size_t dst_offset, std::size_t size) { 80 std::size_t dst_offset, std::size_t size) {
82 glCopyNamedBufferSubData(*src->GetHandle(), *dst->GetHandle(), 81 glCopyNamedBufferSubData(src->GetHandle(), dst->GetHandle(), static_cast<GLintptr>(src_offset),
83 static_cast<GLintptr>(src_offset), static_cast<GLintptr>(dst_offset), 82 static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size));
84 static_cast<GLsizeiptr>(size));
85} 83}
86 84
87OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_pointer, 85OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_pointer,
@@ -89,7 +87,7 @@ OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_poi
89 DEBUG_ASSERT(cbuf_cursor < std::size(cbufs)); 87 DEBUG_ASSERT(cbuf_cursor < std::size(cbufs));
90 const GLuint& cbuf = cbufs[cbuf_cursor++]; 88 const GLuint& cbuf = cbufs[cbuf_cursor++];
91 glNamedBufferSubData(cbuf, 0, static_cast<GLsizeiptr>(size), raw_pointer); 89 glNamedBufferSubData(cbuf, 0, static_cast<GLsizeiptr>(size), raw_pointer);
92 return {&cbuf, 0}; 90 return {cbuf, 0};
93} 91}
94 92
95} // namespace OpenGL 93} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index d94a11252..a74817857 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -34,12 +34,12 @@ public:
34 explicit CachedBufferBlock(VAddr cpu_addr, const std::size_t size); 34 explicit CachedBufferBlock(VAddr cpu_addr, const std::size_t size);
35 ~CachedBufferBlock(); 35 ~CachedBufferBlock();
36 36
37 const GLuint* GetHandle() const { 37 GLuint GetHandle() const {
38 return &gl_buffer.handle; 38 return gl_buffer.handle;
39 } 39 }
40 40
41private: 41private:
42 OGLBuffer gl_buffer{}; 42 OGLBuffer gl_buffer;
43}; 43};
44 44
45class OGLBufferCache final : public GenericBufferCache { 45class OGLBufferCache final : public GenericBufferCache {
@@ -48,7 +48,7 @@ public:
48 const Device& device, std::size_t stream_size); 48 const Device& device, std::size_t stream_size);
49 ~OGLBufferCache(); 49 ~OGLBufferCache();
50 50
51 const GLuint* GetEmptyBuffer(std::size_t) override; 51 GLuint GetEmptyBuffer(std::size_t) override;
52 52
53 void Acquire() noexcept { 53 void Acquire() noexcept {
54 cbuf_cursor = 0; 54 cbuf_cursor = 0;
@@ -57,9 +57,9 @@ public:
57protected: 57protected:
58 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override; 58 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override;
59 59
60 void WriteBarrier() override; 60 GLuint ToHandle(const Buffer& buffer) override;
61 61
62 const GLuint* ToHandle(const Buffer& buffer) override; 62 void WriteBarrier() override;
63 63
64 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 64 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
65 const u8* data) override; 65 const u8* data) override;
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index c286502ba..d83dca25a 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -87,7 +87,7 @@ u32 Extract(u32& base, u32& num, u32 amount, std::optional<GLenum> limit = {}) {
87std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> BuildBaseBindings() noexcept { 87std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> BuildBaseBindings() noexcept {
88 std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> bindings; 88 std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> bindings;
89 89
90 static std::array<std::size_t, 5> stage_swizzle = {0, 1, 2, 3, 4}; 90 static constexpr std::array<std::size_t, 5> stage_swizzle{0, 1, 2, 3, 4};
91 const u32 total_ubos = GetInteger<u32>(GL_MAX_UNIFORM_BUFFER_BINDINGS); 91 const u32 total_ubos = GetInteger<u32>(GL_MAX_UNIFORM_BUFFER_BINDINGS);
92 const u32 total_ssbos = GetInteger<u32>(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS); 92 const u32 total_ssbos = GetInteger<u32>(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
93 const u32 total_samplers = GetInteger<u32>(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS); 93 const u32 total_samplers = GetInteger<u32>(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index f4598fbf7..175374f0d 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -188,10 +188,8 @@ void RasterizerOpenGL::SetupVertexBuffer() {
188 ASSERT(end > start); 188 ASSERT(end > start);
189 const u64 size = end - start + 1; 189 const u64 size = end - start + 1;
190 const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size); 190 const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
191 191 glBindVertexBuffer(static_cast<GLuint>(index), vertex_buffer, vertex_buffer_offset,
192 // Bind the vertex array to the buffer at the current offset. 192 vertex_array.stride);
193 vertex_array_pushbuffer.SetVertexBuffer(static_cast<GLuint>(index), vertex_buffer,
194 vertex_buffer_offset, vertex_array.stride);
195 } 193 }
196} 194}
197 195
@@ -222,7 +220,7 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer() {
222 const auto& regs = system.GPU().Maxwell3D().regs; 220 const auto& regs = system.GPU().Maxwell3D().regs;
223 const std::size_t size = CalculateIndexBufferSize(); 221 const std::size_t size = CalculateIndexBufferSize();
224 const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size); 222 const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size);
225 vertex_array_pushbuffer.SetIndexBuffer(buffer); 223 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
226 return offset; 224 return offset;
227} 225}
228 226
@@ -524,7 +522,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
524 522
525 // Prepare vertex array format. 523 // Prepare vertex array format.
526 SetupVertexFormat(); 524 SetupVertexFormat();
527 vertex_array_pushbuffer.Setup();
528 525
529 // Upload vertex and index data. 526 // Upload vertex and index data.
530 SetupVertexBuffer(); 527 SetupVertexBuffer();
@@ -534,17 +531,13 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
534 index_buffer_offset = SetupIndexBuffer(); 531 index_buffer_offset = SetupIndexBuffer();
535 } 532 }
536 533
537 // Prepare packed bindings.
538 bind_ubo_pushbuffer.Setup();
539 bind_ssbo_pushbuffer.Setup();
540
541 // Setup emulation uniform buffer. 534 // Setup emulation uniform buffer.
542 GLShader::MaxwellUniformData ubo; 535 GLShader::MaxwellUniformData ubo;
543 ubo.SetFromRegs(gpu); 536 ubo.SetFromRegs(gpu);
544 const auto [buffer, offset] = 537 const auto [buffer, offset] =
545 buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment()); 538 buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment());
546 bind_ubo_pushbuffer.Push(EmulationUniformBlockBinding, buffer, offset, 539 glBindBufferRange(GL_UNIFORM_BUFFER, EmulationUniformBlockBinding, buffer, offset,
547 static_cast<GLsizeiptr>(sizeof(ubo))); 540 static_cast<GLsizeiptr>(sizeof(ubo)));
548 541
549 // Setup shaders and their used resources. 542 // Setup shaders and their used resources.
550 texture_cache.GuardSamplers(true); 543 texture_cache.GuardSamplers(true);
@@ -557,11 +550,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
557 // Signal the buffer cache that we are not going to upload more things. 550 // Signal the buffer cache that we are not going to upload more things.
558 buffer_cache.Unmap(); 551 buffer_cache.Unmap();
559 552
560 // Now that we are no longer uploading data, we can safely bind the buffers to OpenGL.
561 vertex_array_pushbuffer.Bind();
562 bind_ubo_pushbuffer.Bind();
563 bind_ssbo_pushbuffer.Bind();
564
565 program_manager.BindGraphicsPipeline(); 553 program_manager.BindGraphicsPipeline();
566 554
567 if (texture_cache.TextureBarrier()) { 555 if (texture_cache.TextureBarrier()) {
@@ -630,17 +618,11 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
630 (Maxwell::MaxConstBufferSize + device.GetUniformBufferAlignment()); 618 (Maxwell::MaxConstBufferSize + device.GetUniformBufferAlignment());
631 buffer_cache.Map(buffer_size); 619 buffer_cache.Map(buffer_size);
632 620
633 bind_ubo_pushbuffer.Setup();
634 bind_ssbo_pushbuffer.Setup();
635
636 SetupComputeConstBuffers(kernel); 621 SetupComputeConstBuffers(kernel);
637 SetupComputeGlobalMemory(kernel); 622 SetupComputeGlobalMemory(kernel);
638 623
639 buffer_cache.Unmap(); 624 buffer_cache.Unmap();
640 625
641 bind_ubo_pushbuffer.Bind();
642 bind_ssbo_pushbuffer.Bind();
643
644 const auto& launch_desc = system.GPU().KeplerCompute().launch_description; 626 const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
645 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); 627 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z);
646 ++num_queued_commands; 628 ++num_queued_commands;
@@ -771,8 +753,8 @@ void RasterizerOpenGL::SetupConstBuffer(u32 binding, const Tegra::Engines::Const
771 const ConstBufferEntry& entry) { 753 const ConstBufferEntry& entry) {
772 if (!buffer.enabled) { 754 if (!buffer.enabled) {
773 // Set values to zero to unbind buffers 755 // Set values to zero to unbind buffers
774 bind_ubo_pushbuffer.Push(binding, buffer_cache.GetEmptyBuffer(sizeof(float)), 0, 756 glBindBufferRange(GL_UNIFORM_BUFFER, binding, buffer_cache.GetEmptyBuffer(sizeof(float)), 0,
775 sizeof(float)); 757 sizeof(float));
776 return; 758 return;
777 } 759 }
778 760
@@ -783,7 +765,7 @@ void RasterizerOpenGL::SetupConstBuffer(u32 binding, const Tegra::Engines::Const
783 const auto alignment = device.GetUniformBufferAlignment(); 765 const auto alignment = device.GetUniformBufferAlignment();
784 const auto [cbuf, offset] = buffer_cache.UploadMemory(buffer.address, size, alignment, false, 766 const auto [cbuf, offset] = buffer_cache.UploadMemory(buffer.address, size, alignment, false,
785 device.HasFastBufferSubData()); 767 device.HasFastBufferSubData());
786 bind_ubo_pushbuffer.Push(binding, cbuf, offset, size); 768 glBindBufferRange(GL_UNIFORM_BUFFER, binding, cbuf, offset, size);
787} 769}
788 770
789void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, const Shader& shader) { 771void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, const Shader& shader) {
@@ -819,7 +801,8 @@ void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& e
819 const auto alignment{device.GetShaderStorageBufferAlignment()}; 801 const auto alignment{device.GetShaderStorageBufferAlignment()};
820 const auto [ssbo, buffer_offset] = 802 const auto [ssbo, buffer_offset] =
821 buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.IsWritten()); 803 buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.IsWritten());
822 bind_ssbo_pushbuffer.Push(binding, ssbo, buffer_offset, static_cast<GLsizeiptr>(size)); 804 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, binding, ssbo, buffer_offset,
805 static_cast<GLsizeiptr>(size));
823} 806}
824 807
825void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader& shader) { 808void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader& shader) {
@@ -1432,7 +1415,7 @@ void RasterizerOpenGL::EndTransformFeedback() {
1432 const GPUVAddr gpu_addr = binding.Address(); 1415 const GPUVAddr gpu_addr = binding.Address();
1433 const std::size_t size = binding.buffer_size; 1416 const std::size_t size = binding.buffer_size;
1434 const auto [dest_buffer, offset] = buffer_cache.UploadMemory(gpu_addr, size, 4, true); 1417 const auto [dest_buffer, offset] = buffer_cache.UploadMemory(gpu_addr, size, 4, true);
1435 glCopyNamedBufferSubData(handle, *dest_buffer, 0, offset, static_cast<GLsizeiptr>(size)); 1418 glCopyNamedBufferSubData(handle, dest_buffer, 0, offset, static_cast<GLsizeiptr>(size));
1436 } 1419 }
1437} 1420}
1438 1421
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 435da4425..caea174d2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -231,9 +231,7 @@ private:
231 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; 231 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
232 OGLBufferCache buffer_cache; 232 OGLBufferCache buffer_cache;
233 233
234 VertexArrayPushBuffer vertex_array_pushbuffer{state_tracker}; 234 GLint vertex_binding = 0;
235 BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER};
236 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
237 235
238 std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> 236 std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers>
239 transform_feedback_buffers; 237 transform_feedback_buffers;
diff --git a/src/video_core/renderer_opengl/utils.cpp b/src/video_core/renderer_opengl/utils.cpp
index b751086fa..6d7bb16b2 100644
--- a/src/video_core/renderer_opengl/utils.cpp
+++ b/src/video_core/renderer_opengl/utils.cpp
@@ -14,68 +14,6 @@
14 14
15namespace OpenGL { 15namespace OpenGL {
16 16
17struct VertexArrayPushBuffer::Entry {
18 GLuint binding_index{};
19 const GLuint* buffer{};
20 GLintptr offset{};
21 GLsizei stride{};
22};
23
24VertexArrayPushBuffer::VertexArrayPushBuffer(StateTracker& state_tracker)
25 : state_tracker{state_tracker} {}
26
27VertexArrayPushBuffer::~VertexArrayPushBuffer() = default;
28
29void VertexArrayPushBuffer::Setup() {
30 index_buffer = nullptr;
31 vertex_buffers.clear();
32}
33
34void VertexArrayPushBuffer::SetIndexBuffer(const GLuint* buffer) {
35 index_buffer = buffer;
36}
37
38void VertexArrayPushBuffer::SetVertexBuffer(GLuint binding_index, const GLuint* buffer,
39 GLintptr offset, GLsizei stride) {
40 vertex_buffers.push_back(Entry{binding_index, buffer, offset, stride});
41}
42
43void VertexArrayPushBuffer::Bind() {
44 if (index_buffer) {
45 state_tracker.BindIndexBuffer(*index_buffer);
46 }
47
48 for (const auto& entry : vertex_buffers) {
49 glBindVertexBuffer(entry.binding_index, *entry.buffer, entry.offset, entry.stride);
50 }
51}
52
53struct BindBuffersRangePushBuffer::Entry {
54 GLuint binding;
55 const GLuint* buffer;
56 GLintptr offset;
57 GLsizeiptr size;
58};
59
60BindBuffersRangePushBuffer::BindBuffersRangePushBuffer(GLenum target) : target{target} {}
61
62BindBuffersRangePushBuffer::~BindBuffersRangePushBuffer() = default;
63
64void BindBuffersRangePushBuffer::Setup() {
65 entries.clear();
66}
67
68void BindBuffersRangePushBuffer::Push(GLuint binding, const GLuint* buffer, GLintptr offset,
69 GLsizeiptr size) {
70 entries.push_back(Entry{binding, buffer, offset, size});
71}
72
73void BindBuffersRangePushBuffer::Bind() {
74 for (const Entry& entry : entries) {
75 glBindBufferRange(target, entry.binding, *entry.buffer, entry.offset, entry.size);
76 }
77}
78
79void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info) { 17void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info) {
80 if (!GLAD_GL_KHR_debug) { 18 if (!GLAD_GL_KHR_debug) {
81 // We don't need to throw an error as this is just for debugging 19 // We don't need to throw an error as this is just for debugging
diff --git a/src/video_core/renderer_opengl/utils.h b/src/video_core/renderer_opengl/utils.h
index 47ee3177b..9c09ee12c 100644
--- a/src/video_core/renderer_opengl/utils.h
+++ b/src/video_core/renderer_opengl/utils.h
@@ -11,49 +11,6 @@
11 11
12namespace OpenGL { 12namespace OpenGL {
13 13
14class StateTracker;
15
16class VertexArrayPushBuffer final {
17public:
18 explicit VertexArrayPushBuffer(StateTracker& state_tracker);
19 ~VertexArrayPushBuffer();
20
21 void Setup();
22
23 void SetIndexBuffer(const GLuint* buffer);
24
25 void SetVertexBuffer(GLuint binding_index, const GLuint* buffer, GLintptr offset,
26 GLsizei stride);
27
28 void Bind();
29
30private:
31 struct Entry;
32
33 StateTracker& state_tracker;
34
35 const GLuint* index_buffer{};
36 std::vector<Entry> vertex_buffers;
37};
38
39class BindBuffersRangePushBuffer final {
40public:
41 explicit BindBuffersRangePushBuffer(GLenum target);
42 ~BindBuffersRangePushBuffer();
43
44 void Setup();
45
46 void Push(GLuint binding, const GLuint* buffer, GLintptr offset, GLsizeiptr size);
47
48 void Bind();
49
50private:
51 struct Entry;
52
53 GLenum target;
54 std::vector<Entry> entries;
55};
56
57void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info = {}); 14void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info = {});
58 15
59} // namespace OpenGL 16} // namespace OpenGL
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index 0d167afbd..81e1de2be 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -74,18 +74,18 @@ Buffer VKBufferCache::CreateBlock(VAddr cpu_addr, std::size_t size) {
74 return std::make_shared<CachedBufferBlock>(device, memory_manager, cpu_addr, size); 74 return std::make_shared<CachedBufferBlock>(device, memory_manager, cpu_addr, size);
75} 75}
76 76
77const VkBuffer* VKBufferCache::ToHandle(const Buffer& buffer) { 77VkBuffer VKBufferCache::ToHandle(const Buffer& buffer) {
78 return buffer->GetHandle(); 78 return buffer->GetHandle();
79} 79}
80 80
81const VkBuffer* VKBufferCache::GetEmptyBuffer(std::size_t size) { 81VkBuffer VKBufferCache::GetEmptyBuffer(std::size_t size) {
82 size = std::max(size, std::size_t(4)); 82 size = std::max(size, std::size_t(4));
83 const auto& empty = staging_pool.GetUnusedBuffer(size, false); 83 const auto& empty = staging_pool.GetUnusedBuffer(size, false);
84 scheduler.RequestOutsideRenderPassOperationContext(); 84 scheduler.RequestOutsideRenderPassOperationContext();
85 scheduler.Record([size, buffer = *empty.handle](vk::CommandBuffer cmdbuf) { 85 scheduler.Record([size, buffer = *empty.handle](vk::CommandBuffer cmdbuf) {
86 cmdbuf.FillBuffer(buffer, 0, size, 0); 86 cmdbuf.FillBuffer(buffer, 0, size, 0);
87 }); 87 });
88 return empty.handle.address(); 88 return *empty.handle;
89} 89}
90 90
91void VKBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 91void VKBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
@@ -94,7 +94,7 @@ void VKBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, st
94 std::memcpy(staging.commit->Map(size), data, size); 94 std::memcpy(staging.commit->Map(size), data, size);
95 95
96 scheduler.RequestOutsideRenderPassOperationContext(); 96 scheduler.RequestOutsideRenderPassOperationContext();
97 scheduler.Record([staging = *staging.handle, buffer = *buffer->GetHandle(), offset, 97 scheduler.Record([staging = *staging.handle, buffer = buffer->GetHandle(), offset,
98 size](vk::CommandBuffer cmdbuf) { 98 size](vk::CommandBuffer cmdbuf) {
99 cmdbuf.CopyBuffer(staging, buffer, VkBufferCopy{0, offset, size}); 99 cmdbuf.CopyBuffer(staging, buffer, VkBufferCopy{0, offset, size});
100 100
@@ -117,7 +117,7 @@ void VKBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset,
117 u8* data) { 117 u8* data) {
118 const auto& staging = staging_pool.GetUnusedBuffer(size, true); 118 const auto& staging = staging_pool.GetUnusedBuffer(size, true);
119 scheduler.RequestOutsideRenderPassOperationContext(); 119 scheduler.RequestOutsideRenderPassOperationContext();
120 scheduler.Record([staging = *staging.handle, buffer = *buffer->GetHandle(), offset, 120 scheduler.Record([staging = *staging.handle, buffer = buffer->GetHandle(), offset,
121 size](vk::CommandBuffer cmdbuf) { 121 size](vk::CommandBuffer cmdbuf) {
122 VkBufferMemoryBarrier barrier; 122 VkBufferMemoryBarrier barrier;
123 barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 123 barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
@@ -144,7 +144,7 @@ void VKBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset,
144void VKBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset, 144void VKBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
145 std::size_t dst_offset, std::size_t size) { 145 std::size_t dst_offset, std::size_t size) {
146 scheduler.RequestOutsideRenderPassOperationContext(); 146 scheduler.RequestOutsideRenderPassOperationContext();
147 scheduler.Record([src_buffer = *src->GetHandle(), dst_buffer = *dst->GetHandle(), src_offset, 147 scheduler.Record([src_buffer = src->GetHandle(), dst_buffer = dst->GetHandle(), src_offset,
148 dst_offset, size](vk::CommandBuffer cmdbuf) { 148 dst_offset, size](vk::CommandBuffer cmdbuf) {
149 cmdbuf.CopyBuffer(src_buffer, dst_buffer, VkBufferCopy{src_offset, dst_offset, size}); 149 cmdbuf.CopyBuffer(src_buffer, dst_buffer, VkBufferCopy{src_offset, dst_offset, size});
150 150
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
index d3c23da98..3cd2e2774 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.h
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -33,8 +33,8 @@ public:
33 VAddr cpu_addr, std::size_t size); 33 VAddr cpu_addr, std::size_t size);
34 ~CachedBufferBlock(); 34 ~CachedBufferBlock();
35 35
36 const VkBuffer* GetHandle() const { 36 VkBuffer GetHandle() const {
37 return buffer.handle.address(); 37 return *buffer.handle;
38 } 38 }
39 39
40private: 40private:
@@ -50,15 +50,15 @@ public:
50 VKScheduler& scheduler, VKStagingBufferPool& staging_pool); 50 VKScheduler& scheduler, VKStagingBufferPool& staging_pool);
51 ~VKBufferCache(); 51 ~VKBufferCache();
52 52
53 const VkBuffer* GetEmptyBuffer(std::size_t size) override; 53 VkBuffer GetEmptyBuffer(std::size_t size) override;
54 54
55protected: 55protected:
56 VkBuffer ToHandle(const Buffer& buffer) override;
57
56 void WriteBarrier() override {} 58 void WriteBarrier() override {}
57 59
58 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override; 60 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override;
59 61
60 const VkBuffer* ToHandle(const Buffer& buffer) override;
61
62 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 62 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
63 const u8* data) override; 63 const u8* data) override;
64 64
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
index 9d92305f4..878a78755 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
@@ -343,13 +343,13 @@ QuadArrayPass::QuadArrayPass(const VKDevice& device, VKScheduler& scheduler,
343 343
344QuadArrayPass::~QuadArrayPass() = default; 344QuadArrayPass::~QuadArrayPass() = default;
345 345
346std::pair<const VkBuffer*, VkDeviceSize> QuadArrayPass::Assemble(u32 num_vertices, u32 first) { 346std::pair<VkBuffer, VkDeviceSize> QuadArrayPass::Assemble(u32 num_vertices, u32 first) {
347 const u32 num_triangle_vertices = num_vertices * 6 / 4; 347 const u32 num_triangle_vertices = num_vertices * 6 / 4;
348 const std::size_t staging_size = num_triangle_vertices * sizeof(u32); 348 const std::size_t staging_size = num_triangle_vertices * sizeof(u32);
349 auto& buffer = staging_buffer_pool.GetUnusedBuffer(staging_size, false); 349 auto& buffer = staging_buffer_pool.GetUnusedBuffer(staging_size, false);
350 350
351 update_descriptor_queue.Acquire(); 351 update_descriptor_queue.Acquire();
352 update_descriptor_queue.AddBuffer(buffer.handle.address(), 0, staging_size); 352 update_descriptor_queue.AddBuffer(*buffer.handle, 0, staging_size);
353 const auto set = CommitDescriptorSet(update_descriptor_queue, scheduler.GetFence()); 353 const auto set = CommitDescriptorSet(update_descriptor_queue, scheduler.GetFence());
354 354
355 scheduler.RequestOutsideRenderPassOperationContext(); 355 scheduler.RequestOutsideRenderPassOperationContext();
@@ -377,7 +377,7 @@ std::pair<const VkBuffer*, VkDeviceSize> QuadArrayPass::Assemble(u32 num_vertice
377 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 377 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
378 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, {}, {barrier}, {}); 378 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, {}, {barrier}, {});
379 }); 379 });
380 return {buffer.handle.address(), 0}; 380 return {*buffer.handle, 0};
381} 381}
382 382
383Uint8Pass::Uint8Pass(const VKDevice& device, VKScheduler& scheduler, 383Uint8Pass::Uint8Pass(const VKDevice& device, VKScheduler& scheduler,
@@ -391,14 +391,14 @@ Uint8Pass::Uint8Pass(const VKDevice& device, VKScheduler& scheduler,
391 391
392Uint8Pass::~Uint8Pass() = default; 392Uint8Pass::~Uint8Pass() = default;
393 393
394std::pair<const VkBuffer*, u64> Uint8Pass::Assemble(u32 num_vertices, VkBuffer src_buffer, 394std::pair<VkBuffer, u64> Uint8Pass::Assemble(u32 num_vertices, VkBuffer src_buffer,
395 u64 src_offset) { 395 u64 src_offset) {
396 const auto staging_size = static_cast<u32>(num_vertices * sizeof(u16)); 396 const auto staging_size = static_cast<u32>(num_vertices * sizeof(u16));
397 auto& buffer = staging_buffer_pool.GetUnusedBuffer(staging_size, false); 397 auto& buffer = staging_buffer_pool.GetUnusedBuffer(staging_size, false);
398 398
399 update_descriptor_queue.Acquire(); 399 update_descriptor_queue.Acquire();
400 update_descriptor_queue.AddBuffer(&src_buffer, src_offset, num_vertices); 400 update_descriptor_queue.AddBuffer(src_buffer, src_offset, num_vertices);
401 update_descriptor_queue.AddBuffer(buffer.handle.address(), 0, staging_size); 401 update_descriptor_queue.AddBuffer(*buffer.handle, 0, staging_size);
402 const auto set = CommitDescriptorSet(update_descriptor_queue, scheduler.GetFence()); 402 const auto set = CommitDescriptorSet(update_descriptor_queue, scheduler.GetFence());
403 403
404 scheduler.RequestOutsideRenderPassOperationContext(); 404 scheduler.RequestOutsideRenderPassOperationContext();
@@ -422,7 +422,7 @@ std::pair<const VkBuffer*, u64> Uint8Pass::Assemble(u32 num_vertices, VkBuffer s
422 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 422 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
423 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, {}, barrier, {}); 423 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, {}, barrier, {});
424 }); 424 });
425 return {buffer.handle.address(), 0}; 425 return {*buffer.handle, 0};
426} 426}
427 427
428} // namespace Vulkan 428} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.h b/src/video_core/renderer_vulkan/vk_compute_pass.h
index c62516bff..ec80c8683 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pass.h
+++ b/src/video_core/renderer_vulkan/vk_compute_pass.h
@@ -50,7 +50,7 @@ public:
50 VKUpdateDescriptorQueue& update_descriptor_queue); 50 VKUpdateDescriptorQueue& update_descriptor_queue);
51 ~QuadArrayPass(); 51 ~QuadArrayPass();
52 52
53 std::pair<const VkBuffer*, VkDeviceSize> Assemble(u32 num_vertices, u32 first); 53 std::pair<VkBuffer, VkDeviceSize> Assemble(u32 num_vertices, u32 first);
54 54
55private: 55private:
56 VKScheduler& scheduler; 56 VKScheduler& scheduler;
@@ -65,7 +65,7 @@ public:
65 VKUpdateDescriptorQueue& update_descriptor_queue); 65 VKUpdateDescriptorQueue& update_descriptor_queue);
66 ~Uint8Pass(); 66 ~Uint8Pass();
67 67
68 std::pair<const VkBuffer*, u64> Assemble(u32 num_vertices, VkBuffer src_buffer, u64 src_offset); 68 std::pair<VkBuffer, u64> Assemble(u32 num_vertices, VkBuffer src_buffer, u64 src_offset);
69 69
70private: 70private:
71 VKScheduler& scheduler; 71 VKScheduler& scheduler;
diff --git a/src/video_core/renderer_vulkan/vk_memory_manager.h b/src/video_core/renderer_vulkan/vk_memory_manager.h
index 35ee54d30..5b6858e9b 100644
--- a/src/video_core/renderer_vulkan/vk_memory_manager.h
+++ b/src/video_core/renderer_vulkan/vk_memory_manager.h
@@ -32,7 +32,7 @@ public:
32 * memory. When passing false, it will try to allocate device local memory. 32 * memory. When passing false, it will try to allocate device local memory.
33 * @returns A memory commit. 33 * @returns A memory commit.
34 */ 34 */
35 VKMemoryCommit Commit(const VkMemoryRequirements& reqs, bool host_visible); 35 VKMemoryCommit Commit(const VkMemoryRequirements& requirements, bool host_visible);
36 36
37 /// Commits memory required by the buffer and binds it. 37 /// Commits memory required by the buffer and binds it.
38 VKMemoryCommit Commit(const vk::Buffer& buffer, bool host_visible); 38 VKMemoryCommit Commit(const vk::Buffer& buffer, bool host_visible);
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 774ba1f26..4ca0febb8 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -137,13 +137,13 @@ Tegra::Texture::FullTextureInfo GetTextureInfo(const Engine& engine, const Entry
137 137
138class BufferBindings final { 138class BufferBindings final {
139public: 139public:
140 void AddVertexBinding(const VkBuffer* buffer, VkDeviceSize offset) { 140 void AddVertexBinding(VkBuffer buffer, VkDeviceSize offset) {
141 vertex.buffer_ptrs[vertex.num_buffers] = buffer; 141 vertex.buffers[vertex.num_buffers] = buffer;
142 vertex.offsets[vertex.num_buffers] = offset; 142 vertex.offsets[vertex.num_buffers] = offset;
143 ++vertex.num_buffers; 143 ++vertex.num_buffers;
144 } 144 }
145 145
146 void SetIndexBinding(const VkBuffer* buffer, VkDeviceSize offset, VkIndexType type) { 146 void SetIndexBinding(VkBuffer buffer, VkDeviceSize offset, VkIndexType type) {
147 index.buffer = buffer; 147 index.buffer = buffer;
148 index.offset = offset; 148 index.offset = offset;
149 index.type = type; 149 index.type = type;
@@ -227,19 +227,19 @@ private:
227 // Some of these fields are intentionally left uninitialized to avoid initializing them twice. 227 // Some of these fields are intentionally left uninitialized to avoid initializing them twice.
228 struct { 228 struct {
229 std::size_t num_buffers = 0; 229 std::size_t num_buffers = 0;
230 std::array<const VkBuffer*, Maxwell::NumVertexArrays> buffer_ptrs; 230 std::array<VkBuffer, Maxwell::NumVertexArrays> buffers;
231 std::array<VkDeviceSize, Maxwell::NumVertexArrays> offsets; 231 std::array<VkDeviceSize, Maxwell::NumVertexArrays> offsets;
232 } vertex; 232 } vertex;
233 233
234 struct { 234 struct {
235 const VkBuffer* buffer = nullptr; 235 VkBuffer buffer = nullptr;
236 VkDeviceSize offset; 236 VkDeviceSize offset;
237 VkIndexType type; 237 VkIndexType type;
238 } index; 238 } index;
239 239
240 template <std::size_t N> 240 template <std::size_t N>
241 void BindStatic(VKScheduler& scheduler) const { 241 void BindStatic(VKScheduler& scheduler) const {
242 if (index.buffer != nullptr) { 242 if (index.buffer) {
243 BindStatic<N, true>(scheduler); 243 BindStatic<N, true>(scheduler);
244 } else { 244 } else {
245 BindStatic<N, false>(scheduler); 245 BindStatic<N, false>(scheduler);
@@ -254,18 +254,14 @@ private:
254 } 254 }
255 255
256 std::array<VkBuffer, N> buffers; 256 std::array<VkBuffer, N> buffers;
257 std::transform(vertex.buffer_ptrs.begin(), vertex.buffer_ptrs.begin() + N, buffers.begin(),
258 [](const auto ptr) { return *ptr; });
259
260 std::array<VkDeviceSize, N> offsets; 257 std::array<VkDeviceSize, N> offsets;
258 std::copy(vertex.buffers.begin(), vertex.buffers.begin() + N, buffers.begin());
261 std::copy(vertex.offsets.begin(), vertex.offsets.begin() + N, offsets.begin()); 259 std::copy(vertex.offsets.begin(), vertex.offsets.begin() + N, offsets.begin());
262 260
263 if constexpr (is_indexed) { 261 if constexpr (is_indexed) {
264 // Indexed draw 262 // Indexed draw
265 scheduler.Record([buffers, offsets, index_buffer = *index.buffer, 263 scheduler.Record([buffers, offsets, index = index](vk::CommandBuffer cmdbuf) {
266 index_offset = index.offset, 264 cmdbuf.BindIndexBuffer(index.buffer, index.offset, index.type);
267 index_type = index.type](vk::CommandBuffer cmdbuf) {
268 cmdbuf.BindIndexBuffer(index_buffer, index_offset, index_type);
269 cmdbuf.BindVertexBuffers(0, static_cast<u32>(N), buffers.data(), offsets.data()); 265 cmdbuf.BindVertexBuffers(0, static_cast<u32>(N), buffers.data(), offsets.data());
270 }); 266 });
271 } else { 267 } else {
@@ -790,7 +786,7 @@ void RasterizerVulkan::BeginTransformFeedback() {
790 const std::size_t size = binding.buffer_size; 786 const std::size_t size = binding.buffer_size;
791 const auto [buffer, offset] = buffer_cache.UploadMemory(gpu_addr, size, 4, true); 787 const auto [buffer, offset] = buffer_cache.UploadMemory(gpu_addr, size, 4, true);
792 788
793 scheduler.Record([buffer = *buffer, offset = offset, size](vk::CommandBuffer cmdbuf) { 789 scheduler.Record([buffer = buffer, offset = offset, size](vk::CommandBuffer cmdbuf) {
794 cmdbuf.BindTransformFeedbackBuffersEXT(0, 1, &buffer, &offset, &size); 790 cmdbuf.BindTransformFeedbackBuffersEXT(0, 1, &buffer, &offset, &size);
795 cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr); 791 cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr);
796 }); 792 });
@@ -870,7 +866,7 @@ void RasterizerVulkan::SetupIndexBuffer(BufferBindings& buffer_bindings, DrawPar
870 auto format = regs.index_array.format; 866 auto format = regs.index_array.format;
871 const bool is_uint8 = format == Maxwell::IndexFormat::UnsignedByte; 867 const bool is_uint8 = format == Maxwell::IndexFormat::UnsignedByte;
872 if (is_uint8 && !device.IsExtIndexTypeUint8Supported()) { 868 if (is_uint8 && !device.IsExtIndexTypeUint8Supported()) {
873 std::tie(buffer, offset) = uint8_pass.Assemble(params.num_vertices, *buffer, offset); 869 std::tie(buffer, offset) = uint8_pass.Assemble(params.num_vertices, buffer, offset);
874 format = Maxwell::IndexFormat::UnsignedShort; 870 format = Maxwell::IndexFormat::UnsignedShort;
875 } 871 }
876 872
@@ -1007,8 +1003,8 @@ void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAdd
1007 const auto size = memory_manager.Read<u32>(address + 8); 1003 const auto size = memory_manager.Read<u32>(address + 8);
1008 1004
1009 if (size == 0) { 1005 if (size == 0) {
1010 // Sometimes global memory pointers don't have a proper size. Upload a dummy entry because 1006 // Sometimes global memory pointers don't have a proper size. Upload a dummy entry
1011 // Vulkan doesn't like empty buffers. 1007 // because Vulkan doesn't like empty buffers.
1012 constexpr std::size_t dummy_size = 4; 1008 constexpr std::size_t dummy_size = 4;
1013 const auto buffer = buffer_cache.GetEmptyBuffer(dummy_size); 1009 const auto buffer = buffer_cache.GetEmptyBuffer(dummy_size);
1014 update_descriptor_queue.AddBuffer(buffer, 0, dummy_size); 1010 update_descriptor_queue.AddBuffer(buffer, 0, dummy_size);
diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.cpp b/src/video_core/renderer_vulkan/vk_update_descriptor.cpp
index 4bfec0077..681ecde98 100644
--- a/src/video_core/renderer_vulkan/vk_update_descriptor.cpp
+++ b/src/video_core/renderer_vulkan/vk_update_descriptor.cpp
@@ -35,12 +35,13 @@ void VKUpdateDescriptorQueue::Send(VkDescriptorUpdateTemplateKHR update_template
35 payload.clear(); 35 payload.clear();
36 } 36 }
37 37
38 // TODO(Rodrigo): Rework to write the payload directly
38 const auto payload_start = payload.data() + payload.size(); 39 const auto payload_start = payload.data() + payload.size();
39 for (const auto& entry : entries) { 40 for (const auto& entry : entries) {
40 if (const auto image = std::get_if<VkDescriptorImageInfo>(&entry)) { 41 if (const auto image = std::get_if<VkDescriptorImageInfo>(&entry)) {
41 payload.push_back(*image); 42 payload.push_back(*image);
42 } else if (const auto buffer = std::get_if<Buffer>(&entry)) { 43 } else if (const auto buffer = std::get_if<VkDescriptorBufferInfo>(&entry)) {
43 payload.emplace_back(*buffer->buffer, buffer->offset, buffer->size); 44 payload.push_back(*buffer);
44 } else if (const auto texel = std::get_if<VkBufferView>(&entry)) { 45 } else if (const auto texel = std::get_if<VkBufferView>(&entry)) {
45 payload.push_back(*texel); 46 payload.push_back(*texel);
46 } else { 47 } else {
diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.h b/src/video_core/renderer_vulkan/vk_update_descriptor.h
index a9e3d5dba..6ba2c9997 100644
--- a/src/video_core/renderer_vulkan/vk_update_descriptor.h
+++ b/src/video_core/renderer_vulkan/vk_update_descriptor.h
@@ -18,12 +18,11 @@ class VKScheduler;
18 18
19class DescriptorUpdateEntry { 19class DescriptorUpdateEntry {
20public: 20public:
21 explicit DescriptorUpdateEntry() : image{} {} 21 explicit DescriptorUpdateEntry() {}
22 22
23 DescriptorUpdateEntry(VkDescriptorImageInfo image) : image{image} {} 23 DescriptorUpdateEntry(VkDescriptorImageInfo image) : image{image} {}
24 24
25 DescriptorUpdateEntry(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size) 25 DescriptorUpdateEntry(VkDescriptorBufferInfo buffer) : buffer{buffer} {}
26 : buffer{buffer, offset, size} {}
27 26
28 DescriptorUpdateEntry(VkBufferView texel_buffer) : texel_buffer{texel_buffer} {} 27 DescriptorUpdateEntry(VkBufferView texel_buffer) : texel_buffer{texel_buffer} {}
29 28
@@ -54,8 +53,8 @@ public:
54 entries.emplace_back(VkDescriptorImageInfo{{}, image_view, {}}); 53 entries.emplace_back(VkDescriptorImageInfo{{}, image_view, {}});
55 } 54 }
56 55
57 void AddBuffer(const VkBuffer* buffer, u64 offset, std::size_t size) { 56 void AddBuffer(VkBuffer buffer, u64 offset, std::size_t size) {
58 entries.push_back(Buffer{buffer, offset, size}); 57 entries.emplace_back(VkDescriptorBufferInfo{buffer, offset, size});
59 } 58 }
60 59
61 void AddTexelBuffer(VkBufferView texel_buffer) { 60 void AddTexelBuffer(VkBufferView texel_buffer) {
@@ -67,12 +66,7 @@ public:
67 } 66 }
68 67
69private: 68private:
70 struct Buffer { 69 using Variant = std::variant<VkDescriptorImageInfo, VkDescriptorBufferInfo, VkBufferView>;
71 const VkBuffer* buffer = nullptr;
72 u64 offset = 0;
73 std::size_t size = 0;
74 };
75 using Variant = std::variant<VkDescriptorImageInfo, Buffer, VkBufferView>;
76 70
77 const VKDevice& device; 71 const VKDevice& device;
78 VKScheduler& scheduler; 72 VKScheduler& scheduler;
diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp
index 2e2711350..6d313963a 100644
--- a/src/video_core/shader/control_flow.cpp
+++ b/src/video_core/shader/control_flow.cpp
@@ -484,17 +484,17 @@ bool TryInspectAddress(CFGRebuildState& state) {
484 } 484 }
485 case BlockCollision::Inside: { 485 case BlockCollision::Inside: {
486 // This case is the tricky one: 486 // This case is the tricky one:
487 // We need to Split the block in 2 sepparate blocks 487 // We need to split the block into 2 separate blocks
488 const u32 end = state.block_info[block_index].end; 488 const u32 end = state.block_info[block_index].end;
489 BlockInfo& new_block = CreateBlockInfo(state, address, end); 489 BlockInfo& new_block = CreateBlockInfo(state, address, end);
490 BlockInfo& current_block = state.block_info[block_index]; 490 BlockInfo& current_block = state.block_info[block_index];
491 current_block.end = address - 1; 491 current_block.end = address - 1;
492 new_block.branch = current_block.branch; 492 new_block.branch = std::move(current_block.branch);
493 BlockBranchInfo forward_branch = MakeBranchInfo<SingleBranch>(); 493 BlockBranchInfo forward_branch = MakeBranchInfo<SingleBranch>();
494 const auto branch = std::get_if<SingleBranch>(forward_branch.get()); 494 const auto branch = std::get_if<SingleBranch>(forward_branch.get());
495 branch->address = address; 495 branch->address = address;
496 branch->ignore = true; 496 branch->ignore = true;
497 current_block.branch = forward_branch; 497 current_block.branch = std::move(forward_branch);
498 return true; 498 return true;
499 } 499 }
500 default: 500 default:
diff --git a/src/video_core/shader/decode/shift.cpp b/src/video_core/shader/decode/shift.cpp
index 3b391d3e6..d4ffa8014 100644
--- a/src/video_core/shader/decode/shift.cpp
+++ b/src/video_core/shader/decode/shift.cpp
@@ -23,7 +23,6 @@ Node IsFull(Node shift) {
23} 23}
24 24
25Node Shift(OperationCode opcode, Node value, Node shift) { 25Node Shift(OperationCode opcode, Node value, Node shift) {
26 Node is_full = Operation(OperationCode::LogicalIEqual, shift, Immediate(32));
27 Node shifted = Operation(opcode, move(value), shift); 26 Node shifted = Operation(opcode, move(value), shift);
28 return Operation(OperationCode::Select, IsFull(move(shift)), Immediate(0), move(shifted)); 27 return Operation(OperationCode::Select, IsFull(move(shift)), Immediate(0), move(shifted));
29} 28}
diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp
index 7af0e792c..715f39d0d 100644
--- a/src/video_core/texture_cache/surface_base.cpp
+++ b/src/video_core/texture_cache/surface_base.cpp
@@ -248,8 +248,14 @@ void SurfaceBaseImpl::FlushBuffer(Tegra::MemoryManager& memory_manager,
248 248
249 // Use an extra temporal buffer 249 // Use an extra temporal buffer
250 auto& tmp_buffer = staging_cache.GetBuffer(1); 250 auto& tmp_buffer = staging_cache.GetBuffer(1);
251 // Special case for 3D Texture Segments
252 const bool must_read_current_data =
253 params.block_depth > 0 && params.target == VideoCore::Surface::SurfaceTarget::Texture2D;
251 tmp_buffer.resize(guest_memory_size); 254 tmp_buffer.resize(guest_memory_size);
252 host_ptr = tmp_buffer.data(); 255 host_ptr = tmp_buffer.data();
256 if (must_read_current_data) {
257 memory_manager.ReadBlockUnsafe(gpu_addr, host_ptr, guest_memory_size);
258 }
253 259
254 if (params.is_tiled) { 260 if (params.is_tiled) {
255 ASSERT_MSG(params.block_width == 0, "Block width is defined as {}", params.block_width); 261 ASSERT_MSG(params.block_width == 0, "Block width is defined as {}", params.block_width);
diff --git a/src/video_core/texture_cache/surface_base.h b/src/video_core/texture_cache/surface_base.h
index a39a8661b..c5ab21f56 100644
--- a/src/video_core/texture_cache/surface_base.h
+++ b/src/video_core/texture_cache/surface_base.h
@@ -72,9 +72,9 @@ public:
72 return (cpu_addr < end) && (cpu_addr_end > start); 72 return (cpu_addr < end) && (cpu_addr_end > start);
73 } 73 }
74 74
75 bool IsInside(const GPUVAddr other_start, const GPUVAddr other_end) { 75 bool IsInside(const GPUVAddr other_start, const GPUVAddr other_end) const {
76 const GPUVAddr gpu_addr_end = gpu_addr + guest_memory_size; 76 const GPUVAddr gpu_addr_end = gpu_addr + guest_memory_size;
77 return (gpu_addr <= other_start && other_end <= gpu_addr_end); 77 return gpu_addr <= other_start && other_end <= gpu_addr_end;
78 } 78 }
79 79
80 // Use only when recycling a surface 80 // Use only when recycling a surface
diff --git a/src/video_core/texture_cache/surface_view.cpp b/src/video_core/texture_cache/surface_view.cpp
index 57a1f5803..6b5f5984b 100644
--- a/src/video_core/texture_cache/surface_view.cpp
+++ b/src/video_core/texture_cache/surface_view.cpp
@@ -20,4 +20,8 @@ bool ViewParams::operator==(const ViewParams& rhs) const {
20 std::tie(rhs.base_layer, rhs.num_layers, rhs.base_level, rhs.num_levels, rhs.target); 20 std::tie(rhs.base_layer, rhs.num_layers, rhs.base_level, rhs.num_levels, rhs.target);
21} 21}
22 22
23bool ViewParams::operator!=(const ViewParams& rhs) const {
24 return !operator==(rhs);
25}
26
23} // namespace VideoCommon 27} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/surface_view.h b/src/video_core/texture_cache/surface_view.h
index b17fd11a9..90a8bb0ae 100644
--- a/src/video_core/texture_cache/surface_view.h
+++ b/src/video_core/texture_cache/surface_view.h
@@ -21,6 +21,7 @@ struct ViewParams {
21 std::size_t Hash() const; 21 std::size_t Hash() const;
22 22
23 bool operator==(const ViewParams& rhs) const; 23 bool operator==(const ViewParams& rhs) const;
24 bool operator!=(const ViewParams& rhs) const;
24 25
25 bool IsLayered() const { 26 bool IsLayered() const {
26 switch (target) { 27 switch (target) {
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 47881d527..69ca08fd1 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -614,10 +614,10 @@ private:
614 * textures within the GPU if possible. Falls back to LLE when it isn't possible to use any of 614 * textures within the GPU if possible. Falls back to LLE when it isn't possible to use any of
615 * the HLE methods. 615 * the HLE methods.
616 * 616 *
617 * @param overlaps The overlapping surfaces registered in the cache. 617 * @param overlaps The overlapping surfaces registered in the cache.
618 * @param params The parameters on the new surface. 618 * @param params The parameters on the new surface.
619 * @param gpu_addr The starting address of the new surface. 619 * @param gpu_addr The starting address of the new surface.
620 * @param cache_addr The starting address of the new surface on physical memory. 620 * @param cpu_addr The starting address of the new surface on physical memory.
621 */ 621 */
622 std::optional<std::pair<TSurface, TView>> Manage3DSurfaces(std::vector<TSurface>& overlaps, 622 std::optional<std::pair<TSurface, TView>> Manage3DSurfaces(std::vector<TSurface>& overlaps,
623 const SurfaceParams& params, 623 const SurfaceParams& params,
diff --git a/src/web_service/CMakeLists.txt b/src/web_service/CMakeLists.txt
index 01f2d129d..0c9bb0d55 100644
--- a/src/web_service/CMakeLists.txt
+++ b/src/web_service/CMakeLists.txt
@@ -8,9 +8,4 @@ add_library(web_service STATIC
8) 8)
9 9
10create_target_directory_groups(web_service) 10create_target_directory_groups(web_service)
11 11target_link_libraries(web_service PRIVATE common json-headers httplib lurlparser)
12get_directory_property(OPENSSL_LIBS
13 DIRECTORY ${PROJECT_SOURCE_DIR}/externals/libressl
14 DEFINITION OPENSSL_LIBS)
15target_compile_definitions(web_service PRIVATE -DCPPHTTPLIB_OPENSSL_SUPPORT)
16target_link_libraries(web_service PRIVATE common json-headers ${OPENSSL_LIBS} httplib lurlparser)