From ca5cc349e908a4f51abc0f22248bf817c8bfa1cb Mon Sep 17 00:00:00 2001
From: Ishan09811 <156402647+Ishan09811@users.noreply.github.com>
Date: Mon, 30 Dec 2024 19:05:56 +0530
Subject: [PATCH 01/18] Android_Build: Implement ccache (#703)

* Android_Build: Implement ccache

* Update Android_Build.yml

* Update Android_Build.yml

---------

Co-authored-by: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
---
 .github/workflows/Android_Build.yml | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/Android_Build.yml b/.github/workflows/Android_Build.yml
index b7e64f5f..d9e75c47 100644
--- a/.github/workflows/Android_Build.yml
+++ b/.github/workflows/Android_Build.yml
@@ -23,6 +23,9 @@ jobs:
     - name: Fetch submodules
       run: git submodule update --init --recursive
 
+    - name: Setup CCache
+      uses: hendrikmuhs/ccache-action@v1.2
+
     - name: Set up gradle caches
       uses: actions/cache@v4
       with:
@@ -47,7 +50,7 @@ jobs:
         java-version: '17'
 
     - name: Configure CMake
-      run: cmake -B ${{github.workspace}}/build -DBUILD_HYDRA_CORE=1 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake -DANDROID_ABI=x86_64 -DENABLE_VULKAN=0 -DENABLE_USER_BUILD=ON
+      run: cmake -B ${{github.workspace}}/build -DBUILD_HYDRA_CORE=1 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake -DANDROID_ABI=x86_64 -DENABLE_VULKAN=0 -DENABLE_USER_BUILD=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
 
     - name: Build
       run: |
@@ -88,6 +91,9 @@ jobs:
     - name: Fetch submodules
       run: git submodule update --init --recursive
 
+    - name: Setup CCache
+      uses: hendrikmuhs/ccache-action@v1.2
+
     - name: Set up gradle caches
       uses: actions/cache@v4
       with:
@@ -112,7 +118,7 @@ jobs:
         java-version: '17'
 
     - name: Configure CMake
-      run: cmake -B ${{github.workspace}}/build -DBUILD_HYDRA_CORE=1 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DENABLE_VULKAN=0 -DENABLE_USER_BUILD=ON -DCMAKE_CXX_FLAGS="-march=armv8-a+crypto"
+      run: cmake -B ${{github.workspace}}/build -DBUILD_HYDRA_CORE=1 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DENABLE_VULKAN=0 -DENABLE_USER_BUILD=ON -DCMAKE_CXX_FLAGS="-march=armv8-a+crypto" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
 
     - name: Build
       run: |

From 0c6c455d4df4606996e0c3678ec2dddced6ce882 Mon Sep 17 00:00:00 2001
From: Auxy6858 <71662994+Auxy6858@users.noreply.github.com>
Date: Thu, 2 Jan 2025 08:37:08 +0000
Subject: [PATCH 02/18] Removed dead Citra link in readme (#706)

---
 readme.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/readme.md b/readme.md
index 7ffb7384..f58f316c 100644
--- a/readme.md
+++ b/readme.md
@@ -35,7 +35,7 @@ Panda3DS is still in the early stages of development. Many games boot, many don'
 
 For documenting game compatibility, make sure to visit the [games list repository](https://github.com/Panda3DS-emu/Panda3DS-Games-List). For miscellaneous issues or more technical issues, feel free to use this repo's issues tab.
 # Why?
-The 3DS emulation scene is already pretty mature, with offerings such as [Citra](https://github.com/citra-emu/citra) which can offer a great playing experience for most games in the library, [Corgi3DS](https://github.com/PSI-Rockin/Corgi3DS), an innovative LLE emulator, or [Mikage](https://mikage.app/). However, there's always room for more emulators! While Panda3DS was initially a mere curiosity, there's many different concepts I would like to explore with it in the future, such as:
+The 3DS emulation scene is already pretty mature, with offerings such as Citra which can offer a great playing experience for most games in the library, [Corgi3DS](https://github.com/PSI-Rockin/Corgi3DS), an innovative LLE emulator, or [Mikage](https://mikage.app/). However, there's always room for more emulators! While Panda3DS was initially a mere curiosity, there's many different concepts I would like to explore with it in the future, such as:
 
 - Virtualization. What motivated the creation of this emulator was actually a discussion on whether it is possible to get fast 3DS emulation on low-end hardware such as the Raspberry Pi 4, using the KVM API. At the moment, Panda3DS is powered by Dynarmic rather than using virtualization, but this is definitely a concept I want to explore in the future.
 

From 33c3e67b31ab31f92353197b3ebf5381aa94f11b Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Fri, 3 Jan 2025 19:14:31 +0200
Subject: [PATCH 03/18] CRO: Lighter icache flushes

---
 include/cpu_dynarmic.hpp     |  2 ++
 include/kernel/kernel.hpp    |  1 +
 src/core/kernel/kernel.cpp   |  1 +
 src/core/services/ldr_ro.cpp | 17 ++++++++---------
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/include/cpu_dynarmic.hpp b/include/cpu_dynarmic.hpp
index 43f31d30..24358533 100644
--- a/include/cpu_dynarmic.hpp
+++ b/include/cpu_dynarmic.hpp
@@ -181,5 +181,7 @@ class CPU {
     void addTicks(u64 ticks) { env.AddTicks(ticks); }
 
     void clearCache() { jit->ClearCache(); }
+    void clearCacheRange(u32 start, u32 size) { jit->InvalidateCacheRange(start, size); }
+
     void runFrame();
 };
\ No newline at end of file
diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp
index abc508ac..da5298a4 100644
--- a/include/kernel/kernel.hpp
+++ b/include/kernel/kernel.hpp
@@ -250,4 +250,5 @@ public:
 
 	void sendGPUInterrupt(GPUInterrupt type) { serviceManager.sendGPUInterrupt(type); }
 	void clearInstructionCache();
+	void clearInstructionCacheRange(u32 start, u32 size);
 };
\ No newline at end of file
diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp
index d4229b55..fe7bd301 100644
--- a/src/core/kernel/kernel.cpp
+++ b/src/core/kernel/kernel.cpp
@@ -298,6 +298,7 @@ void Kernel::duplicateHandle() {
 }
 
 void Kernel::clearInstructionCache() { cpu.clearCache(); }
+void Kernel::clearInstructionCacheRange(u32 start, u32 size) { cpu.clearCacheRange(start, size); }
 
 namespace SystemInfoType {
 	enum : u32 {
diff --git a/src/core/services/ldr_ro.cpp b/src/core/services/ldr_ro.cpp
index a6114729..48621986 100644
--- a/src/core/services/ldr_ro.cpp
+++ b/src/core/services/ldr_ro.cpp
@@ -22,6 +22,7 @@ namespace CROHeader {
 		NameOffset = 0x084,
 		NextCRO = 0x088,
 		PrevCRO = 0x08C,
+		FixedSize = 0x98,
 		OnUnresolved = 0x0AC,
 		CodeOffset = 0x0B0,
 		DataOffset = 0x0B8,
@@ -167,6 +168,10 @@ public:
 		return mem.read32(croPointer + CROHeader::PrevCRO);
 	}
 
+	u32 getFixedSize() {
+		return mem.read32(croPointer + CROHeader::FixedSize);
+	}
+
 	void setNextCRO(u32 nextCRO) {
 		mem.write32(croPointer + CROHeader::NextCRO, nextCRO);
 	}
@@ -1248,8 +1253,7 @@ void LDRService::initialize(u32 messagePointer) {
 		Helpers::panic("Failed to rebase CRS");
 	}
 
-	kernel.clearInstructionCache();
-
+	kernel.clearInstructionCacheRange(mapVaddr, size);
 	loadedCRS = mapVaddr;
 
 	mem.write32(messagePointer, IPC::responseHeader(0x1, 1, 0));
@@ -1278,8 +1282,6 @@ void LDRService::linkCRO(u32 messagePointer) {
 		Helpers::panic("Failed to link CRO");
 	}
 
-	kernel.clearInstructionCache();
-
 	mem.write32(messagePointer, IPC::responseHeader(0x6, 1, 0));
 	mem.write32(messagePointer + 4, Result::Success);
 }
@@ -1346,8 +1348,7 @@ void LDRService::loadCRO(u32 messagePointer, bool isNew) {
 
 	// TODO: add fixing
 	cro.fix(fixLevel);
-
-	kernel.clearInstructionCache();
+	kernel.clearInstructionCacheRange(mapVaddr, size);
 
 	if (isNew) {
 		mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 0));
@@ -1377,7 +1378,6 @@ void LDRService::unloadCRO(u32 messagePointer) {
 	}
 
 	CRO cro(mem, mapVaddr, true);
-
 	cro.unregisterCRO(loadedCRS);
 
 	if (!cro.unlink(loadedCRS)) {
@@ -1388,8 +1388,7 @@ void LDRService::unloadCRO(u32 messagePointer) {
 		Helpers::panic("Failed to unrebase CRO");
 	}
 
-	kernel.clearInstructionCache();
-
+	kernel.clearInstructionCacheRange(mapVaddr, cro.getFixedSize());
 	mem.write32(messagePointer, IPC::responseHeader(0x5, 1, 0));
 	mem.write32(messagePointer + 4, Result::Success);
 }
\ No newline at end of file

From 84c358660c0b38c29b5068de7aff4f591cbca081 Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Fri, 3 Jan 2025 19:21:45 +0200
Subject: [PATCH 04/18] Implement Luma icache SVCs

---
 include/kernel/kernel.hpp  |  2 ++
 src/core/kernel/kernel.cpp | 17 +++++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp
index da5298a4..45085e15 100644
--- a/include/kernel/kernel.hpp
+++ b/include/kernel/kernel.hpp
@@ -175,6 +175,8 @@ public:
 	void svcSignalEvent();
 	void svcSetTimer();
 	void svcSleepThread();
+	void svcInvalidateInstructionCacheRange();
+	void svcInvalidateEntireInstructionCache();
 	void connectToPort();
 	void outputDebugString();
 	void waitSynchronization1();
diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp
index fe7bd301..8208d4ac 100644
--- a/src/core/kernel/kernel.cpp
+++ b/src/core/kernel/kernel.cpp
@@ -69,6 +69,10 @@ void Kernel::serviceSVC(u32 svc) {
 		case 0x3A: getResourceLimitCurrentValues(); break;
 		case 0x3B: getThreadContext(); break;
 		case 0x3D: outputDebugString(); break;
+
+		// Luma SVCs
+		case 0x93: svcInvalidateInstructionCacheRange(); break;
+		case 0x94: svcInvalidateEntireInstructionCache(); break;
 		default: Helpers::panic("Unimplemented svc: %X @ %08X", svc, regs[15]); break;
 	}
 
@@ -300,6 +304,19 @@ void Kernel::duplicateHandle() {
 void Kernel::clearInstructionCache() { cpu.clearCache(); }
 void Kernel::clearInstructionCacheRange(u32 start, u32 size) { cpu.clearCacheRange(start, size); }
 
+void Kernel::svcInvalidateInstructionCacheRange() {
+	const u32 start = regs[0];
+	const u32 size = regs[1];
+
+	clearInstructionCacheRange(start, size);
+	regs[0] = Result::Success;
+}
+
+void Kernel::svcInvalidateEntireInstructionCache() {
+	clearInstructionCache();
+	regs[0] = Result::Success;
+}
+
 namespace SystemInfoType {
 	enum : u32 {
 		MemoryInformation = 0,

From 5042594f3b156344e86acf877529720fde08cf11 Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Fri, 3 Jan 2025 19:23:46 +0200
Subject: [PATCH 05/18] Add missing SVC logs

---
 src/core/kernel/kernel.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp
index 8208d4ac..e097fab6 100644
--- a/src/core/kernel/kernel.cpp
+++ b/src/core/kernel/kernel.cpp
@@ -307,12 +307,15 @@ void Kernel::clearInstructionCacheRange(u32 start, u32 size) { cpu.clearCacheRan
 void Kernel::svcInvalidateInstructionCacheRange() {
 	const u32 start = regs[0];
 	const u32 size = regs[1];
+	logSVC("svcInvalidateInstructionCacheRange(start = %08X, size = %08X)\n", start, size);
 
 	clearInstructionCacheRange(start, size);
 	regs[0] = Result::Success;
 }
 
 void Kernel::svcInvalidateEntireInstructionCache() {
+	logSVC("svcInvalidateEntireInstructionCache()\n");
+
 	clearInstructionCache();
 	regs[0] = Result::Success;
 }

From 86ea40a9e5946d0159bb1bff723c10e8b7ca08d1 Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Fri, 3 Jan 2025 21:24:46 +0200
Subject: [PATCH 06/18] GPU: Add sw texture copies

---
 include/renderer.hpp                   |  1 +
 src/core/renderer_gl/renderer_gl.cpp   |  2 ++
 src/core/renderer_mtl/renderer_mtl.cpp |  2 +-
 src/renderer.cpp                       | 38 ++++++++++++++++++++++++++
 4 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/include/renderer.hpp b/include/renderer.hpp
index b458ecce..ca28455f 100644
--- a/include/renderer.hpp
+++ b/include/renderer.hpp
@@ -53,6 +53,7 @@ class Renderer {
 
 	EmulatorConfig* emulatorConfig = nullptr;
 
+	void doSoftwareTextureCopy(u32 inputAddr, u32 outputAddr, u32 copySize, u32 inputWidth, u32 inputGap, u32 outputWidth, u32 outputGap);
   public:
 	Renderer(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs);
 	virtual ~Renderer();
diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp
index c1899655..2d54e586 100644
--- a/src/core/renderer_gl/renderer_gl.cpp
+++ b/src/core/renderer_gl/renderer_gl.cpp
@@ -792,6 +792,8 @@ void RendererGL::textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32
 			shutUpCounter++;
 			printf("RendererGL::TextureCopy failed to locate src framebuffer!\n");
 		}
+
+		doSoftwareTextureCopy(inputAddr, outputAddr, copySize, inputWidth, inputGap, outputWidth, outputGap);
 		return;
 	}
 
diff --git a/src/core/renderer_mtl/renderer_mtl.cpp b/src/core/renderer_mtl/renderer_mtl.cpp
index 9cf58716..14bca4d2 100644
--- a/src/core/renderer_mtl/renderer_mtl.cpp
+++ b/src/core/renderer_mtl/renderer_mtl.cpp
@@ -426,7 +426,7 @@ void RendererMTL::textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32
 	// Find the source surface.
 	auto srcFramebuffer = getColorRenderTarget(inputAddr, PICA::ColorFmt::RGBA8, copyStride, copyHeight, false);
 	if (!srcFramebuffer) {
-		Helpers::warn("RendererMTL::TextureCopy failed to locate src framebuffer!\n");
+		doSoftwareTextureCopy(inputAddr, outputAddr, copySize, inputWidth, inputGap, outputWidth, outputGap);
 		return;
 	}
 	nextRenderPassName = "Clear before texture copy";
diff --git a/src/renderer.cpp b/src/renderer.cpp
index 6a18df85..390a3fa6 100644
--- a/src/renderer.cpp
+++ b/src/renderer.cpp
@@ -3,6 +3,8 @@
 #include <algorithm>
 #include <unordered_map>
 
+#include "PICA/gpu.hpp"
+
 Renderer::Renderer(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs)
 	: gpu(gpu), regs(internalRegs), externalRegs(externalRegs) {}
 Renderer::~Renderer() {}
@@ -39,3 +41,39 @@ const char* Renderer::typeToString(RendererType rendererType) {
 		default: return "Invalid";
 	}
 }
+
+void Renderer::doSoftwareTextureCopy(u32 inputAddr, u32 outputAddr, u32 copySize, u32 inputWidth, u32 inputGap, u32 outputWidth, u32 outputGap) {
+	u8* inputPointer = gpu.getPointerPhys<u8>(inputAddr);
+	u8* outputPointer = gpu.getPointerPhys<u8>(outputAddr);
+
+	if (inputPointer == nullptr || outputPointer == nullptr) {
+		return;
+	}
+
+	u32 inputBytesLeft = inputWidth;
+	u32 outputBytesLeft = outputWidth;
+	u32 copyBytesLeft = copySize;
+
+	while (copyBytesLeft > 0) {
+		const u32 bytes = std::min<u32>({inputBytesLeft, outputBytesLeft, copyBytesLeft});
+		std::memcpy(outputPointer, inputPointer, bytes);
+
+		inputPointer += bytes;
+		outputPointer += bytes;
+
+		inputBytesLeft -= bytes;
+		outputBytesLeft -= bytes;
+		copyBytesLeft -= bytes;
+
+		// Apply input and output gap when an input or output line ends
+		if (inputBytesLeft == 0) {
+			inputBytesLeft = inputWidth;
+			inputPointer += inputGap;
+		}
+
+		if (outputBytesLeft == 0) {
+			outputBytesLeft = outputWidth;
+			outputPointer += outputGap;
+		}
+	}
+}

From d30f2646eccb8b5cae895ddc7b3461c11c97701e Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Mon, 6 Jan 2025 16:13:40 +0200
Subject: [PATCH 07/18] Use vk::detail::DynamicLoader instead of
 vk::DynamicLoader (#710)

* Use vk::detail::DynamicLoader instead of vk::DynamicLoader

* Update renderer_vk.cpp
---
 src/core/renderer_vk/renderer_vk.cpp | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/core/renderer_vk/renderer_vk.cpp b/src/core/renderer_vk/renderer_vk.cpp
index d05a070f..14bde2c8 100644
--- a/src/core/renderer_vk/renderer_vk.cpp
+++ b/src/core/renderer_vk/renderer_vk.cpp
@@ -885,10 +885,17 @@ void RendererVK::display() {
 	}
 }
 
+// DynamicLoader is in a different namespace in different versions of Vulkan-Hpp
+#if VK_HEADER_VERSION >= 301
+using VulkanDynamicLoader = vk::detail::DynamicLoader
+#else
+using VulkanDynamicLoader = vk::DynamicLoader;
+#endif
+
 void RendererVK::initGraphicsContext(SDL_Window* window) {
 	targetWindow = window;
 	// Resolve all instance function pointers
-	static vk::DynamicLoader dl;
+	static VulkanDynamicLoader dl;
 	VULKAN_HPP_DEFAULT_DISPATCHER.init(dl.getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr"));
 
 	// Create Instance
@@ -1588,4 +1595,4 @@ void RendererVK::deinitGraphicsContext() {
 
 	// TODO: Make it so that depth and colour buffers get written back to 3DS memory
 	printf("RendererVK::DeinitGraphicsContext called\n");
-}
\ No newline at end of file
+}

From c2fd85647a35f4472673258c32e014f85856de62 Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Fri, 17 Jan 2025 01:12:15 +0200
Subject: [PATCH 08/18] Vk: Fix typo

---
 src/core/renderer_vk/renderer_vk.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/renderer_vk/renderer_vk.cpp b/src/core/renderer_vk/renderer_vk.cpp
index 14bde2c8..57533bde 100644
--- a/src/core/renderer_vk/renderer_vk.cpp
+++ b/src/core/renderer_vk/renderer_vk.cpp
@@ -887,7 +887,7 @@ void RendererVK::display() {
 
 // DynamicLoader is in a different namespace in different versions of Vulkan-Hpp
 #if VK_HEADER_VERSION >= 301
-using VulkanDynamicLoader = vk::detail::DynamicLoader
+using VulkanDynamicLoader = vk::detail::DynamicLoader;
 #else
 using VulkanDynamicLoader = vk::DynamicLoader;
 #endif

From 154e92726489736f768e5e9404ceaed8b7c20261 Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Fri, 17 Jan 2025 01:59:58 +0200
Subject: [PATCH 09/18] Vk: Lock CI runners to SDK version 1.3.301 temporarily

---
 .github/workflows/Android_Build.yml        | 4 ++--
 .github/workflows/HTTP_Build.yml           | 2 +-
 .github/workflows/Hydra_Build.yml          | 8 ++++----
 .github/workflows/Linux_AppImage_Build.yml | 2 +-
 .github/workflows/Linux_Build.yml          | 2 +-
 .github/workflows/MacOS_Build.yml          | 2 +-
 .github/workflows/Qt_Build.yml             | 6 +++---
 .github/workflows/Windows_Build.yml        | 2 +-
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/.github/workflows/Android_Build.yml b/.github/workflows/Android_Build.yml
index d9e75c47..f149d9fd 100644
--- a/.github/workflows/Android_Build.yml
+++ b/.github/workflows/Android_Build.yml
@@ -39,7 +39,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -107,7 +107,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/HTTP_Build.yml b/.github/workflows/HTTP_Build.yml
index c4f7cfee..1aa660a0 100644
--- a/.github/workflows/HTTP_Build.yml
+++ b/.github/workflows/HTTP_Build.yml
@@ -32,7 +32,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Hydra_Build.yml b/.github/workflows/Hydra_Build.yml
index 1b31edf7..f4985b60 100644
--- a/.github/workflows/Hydra_Build.yml
+++ b/.github/workflows/Hydra_Build.yml
@@ -22,7 +22,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -65,7 +65,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -118,7 +118,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -165,7 +165,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Linux_AppImage_Build.yml b/.github/workflows/Linux_AppImage_Build.yml
index 3c5af88a..6726dee3 100644
--- a/.github/workflows/Linux_AppImage_Build.yml
+++ b/.github/workflows/Linux_AppImage_Build.yml
@@ -35,7 +35,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Linux_Build.yml b/.github/workflows/Linux_Build.yml
index 61f7eafa..99a15b0a 100644
--- a/.github/workflows/Linux_Build.yml
+++ b/.github/workflows/Linux_Build.yml
@@ -35,7 +35,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/MacOS_Build.yml b/.github/workflows/MacOS_Build.yml
index ab8702fd..903f99ea 100644
--- a/.github/workflows/MacOS_Build.yml
+++ b/.github/workflows/MacOS_Build.yml
@@ -27,7 +27,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Qt_Build.yml b/.github/workflows/Qt_Build.yml
index fc4072da..7c992e96 100644
--- a/.github/workflows/Qt_Build.yml
+++ b/.github/workflows/Qt_Build.yml
@@ -28,7 +28,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -66,7 +66,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -164,7 +164,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Windows_Build.yml b/.github/workflows/Windows_Build.yml
index 5497c3ef..8cb81601 100644
--- a/.github/workflows/Windows_Build.yml
+++ b/.github/workflows/Windows_Build.yml
@@ -26,7 +26,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.301.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 

From 5b409c39ac10116befea7a14cb2721734185dd2d Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Fri, 17 Jan 2025 02:05:27 +0200
Subject: [PATCH 10/18] Vk: Fixing CI pt 2

---
 .github/workflows/Android_Build.yml        | 4 ++--
 .github/workflows/HTTP_Build.yml           | 2 +-
 .github/workflows/Hydra_Build.yml          | 8 ++++----
 .github/workflows/Linux_AppImage_Build.yml | 2 +-
 .github/workflows/Linux_Build.yml          | 2 +-
 .github/workflows/MacOS_Build.yml          | 2 +-
 .github/workflows/Qt_Build.yml             | 6 +++---
 .github/workflows/Windows_Build.yml        | 2 +-
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/.github/workflows/Android_Build.yml b/.github/workflows/Android_Build.yml
index f149d9fd..5b00a849 100644
--- a/.github/workflows/Android_Build.yml
+++ b/.github/workflows/Android_Build.yml
@@ -39,7 +39,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -107,7 +107,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/HTTP_Build.yml b/.github/workflows/HTTP_Build.yml
index 1aa660a0..c5ced99b 100644
--- a/.github/workflows/HTTP_Build.yml
+++ b/.github/workflows/HTTP_Build.yml
@@ -32,7 +32,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Hydra_Build.yml b/.github/workflows/Hydra_Build.yml
index f4985b60..f8375fc7 100644
--- a/.github/workflows/Hydra_Build.yml
+++ b/.github/workflows/Hydra_Build.yml
@@ -22,7 +22,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -65,7 +65,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -118,7 +118,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -165,7 +165,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Linux_AppImage_Build.yml b/.github/workflows/Linux_AppImage_Build.yml
index 6726dee3..23195fb1 100644
--- a/.github/workflows/Linux_AppImage_Build.yml
+++ b/.github/workflows/Linux_AppImage_Build.yml
@@ -35,7 +35,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Linux_Build.yml b/.github/workflows/Linux_Build.yml
index 99a15b0a..2fb99f79 100644
--- a/.github/workflows/Linux_Build.yml
+++ b/.github/workflows/Linux_Build.yml
@@ -35,7 +35,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/MacOS_Build.yml b/.github/workflows/MacOS_Build.yml
index 903f99ea..a32ac774 100644
--- a/.github/workflows/MacOS_Build.yml
+++ b/.github/workflows/MacOS_Build.yml
@@ -27,7 +27,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Qt_Build.yml b/.github/workflows/Qt_Build.yml
index 7c992e96..44803dff 100644
--- a/.github/workflows/Qt_Build.yml
+++ b/.github/workflows/Qt_Build.yml
@@ -28,7 +28,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -66,7 +66,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -164,7 +164,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Windows_Build.yml b/.github/workflows/Windows_Build.yml
index 8cb81601..a55945d4 100644
--- a/.github/workflows/Windows_Build.yml
+++ b/.github/workflows/Windows_Build.yml
@@ -26,7 +26,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301.0
+        vulkan-query-version: 1.3.301
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 

From 1cae66f1639610ad191708b0c44a9afeb5de5406 Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Fri, 17 Jan 2025 02:10:18 +0200
Subject: [PATCH 11/18] Vulkan: Fixing CI pt 3

---
 .github/workflows/Android_Build.yml        | 4 ++--
 .github/workflows/HTTP_Build.yml           | 2 +-
 .github/workflows/Hydra_Build.yml          | 8 ++++----
 .github/workflows/Linux_AppImage_Build.yml | 2 +-
 .github/workflows/Linux_Build.yml          | 2 +-
 .github/workflows/MacOS_Build.yml          | 2 +-
 .github/workflows/Qt_Build.yml             | 6 +++---
 .github/workflows/Windows_Build.yml        | 2 +-
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/.github/workflows/Android_Build.yml b/.github/workflows/Android_Build.yml
index 5b00a849..3ddcffd5 100644
--- a/.github/workflows/Android_Build.yml
+++ b/.github/workflows/Android_Build.yml
@@ -39,7 +39,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -107,7 +107,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/HTTP_Build.yml b/.github/workflows/HTTP_Build.yml
index c5ced99b..1f95ce0c 100644
--- a/.github/workflows/HTTP_Build.yml
+++ b/.github/workflows/HTTP_Build.yml
@@ -32,7 +32,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Hydra_Build.yml b/.github/workflows/Hydra_Build.yml
index f8375fc7..df851b69 100644
--- a/.github/workflows/Hydra_Build.yml
+++ b/.github/workflows/Hydra_Build.yml
@@ -22,7 +22,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -65,7 +65,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -118,7 +118,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -165,7 +165,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Linux_AppImage_Build.yml b/.github/workflows/Linux_AppImage_Build.yml
index 23195fb1..be21a31f 100644
--- a/.github/workflows/Linux_AppImage_Build.yml
+++ b/.github/workflows/Linux_AppImage_Build.yml
@@ -35,7 +35,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Linux_Build.yml b/.github/workflows/Linux_Build.yml
index 2fb99f79..5dac55d1 100644
--- a/.github/workflows/Linux_Build.yml
+++ b/.github/workflows/Linux_Build.yml
@@ -35,7 +35,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/MacOS_Build.yml b/.github/workflows/MacOS_Build.yml
index a32ac774..8100079c 100644
--- a/.github/workflows/MacOS_Build.yml
+++ b/.github/workflows/MacOS_Build.yml
@@ -27,7 +27,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Qt_Build.yml b/.github/workflows/Qt_Build.yml
index 44803dff..bc545caf 100644
--- a/.github/workflows/Qt_Build.yml
+++ b/.github/workflows/Qt_Build.yml
@@ -28,7 +28,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -66,7 +66,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -164,7 +164,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Windows_Build.yml b/.github/workflows/Windows_Build.yml
index a55945d4..a4de2e60 100644
--- a/.github/workflows/Windows_Build.yml
+++ b/.github/workflows/Windows_Build.yml
@@ -26,7 +26,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: 1.3.301
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 

From d85c963c4e477b86759edbb96e3edcab6eb6db7b Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Fri, 17 Jan 2025 01:12:15 +0200
Subject: [PATCH 12/18] Vk: Fix typo

---
 .github/workflows/Android_Build.yml        | 4 ++--
 .github/workflows/HTTP_Build.yml           | 2 +-
 .github/workflows/Hydra_Build.yml          | 8 ++++----
 .github/workflows/Linux_AppImage_Build.yml | 2 +-
 .github/workflows/Linux_Build.yml          | 2 +-
 .github/workflows/MacOS_Build.yml          | 2 +-
 .github/workflows/Qt_Build.yml             | 6 +++---
 .github/workflows/Windows_Build.yml        | 2 +-
 src/core/renderer_vk/renderer_vk.cpp       | 2 +-
 9 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/.github/workflows/Android_Build.yml b/.github/workflows/Android_Build.yml
index d9e75c47..3ddcffd5 100644
--- a/.github/workflows/Android_Build.yml
+++ b/.github/workflows/Android_Build.yml
@@ -39,7 +39,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -107,7 +107,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/HTTP_Build.yml b/.github/workflows/HTTP_Build.yml
index c4f7cfee..1f95ce0c 100644
--- a/.github/workflows/HTTP_Build.yml
+++ b/.github/workflows/HTTP_Build.yml
@@ -32,7 +32,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Hydra_Build.yml b/.github/workflows/Hydra_Build.yml
index 1b31edf7..df851b69 100644
--- a/.github/workflows/Hydra_Build.yml
+++ b/.github/workflows/Hydra_Build.yml
@@ -22,7 +22,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -65,7 +65,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -118,7 +118,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -165,7 +165,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Linux_AppImage_Build.yml b/.github/workflows/Linux_AppImage_Build.yml
index 3c5af88a..be21a31f 100644
--- a/.github/workflows/Linux_AppImage_Build.yml
+++ b/.github/workflows/Linux_AppImage_Build.yml
@@ -35,7 +35,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Linux_Build.yml b/.github/workflows/Linux_Build.yml
index 61f7eafa..5dac55d1 100644
--- a/.github/workflows/Linux_Build.yml
+++ b/.github/workflows/Linux_Build.yml
@@ -35,7 +35,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/MacOS_Build.yml b/.github/workflows/MacOS_Build.yml
index ab8702fd..8100079c 100644
--- a/.github/workflows/MacOS_Build.yml
+++ b/.github/workflows/MacOS_Build.yml
@@ -27,7 +27,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Qt_Build.yml b/.github/workflows/Qt_Build.yml
index fc4072da..bc545caf 100644
--- a/.github/workflows/Qt_Build.yml
+++ b/.github/workflows/Qt_Build.yml
@@ -28,7 +28,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -66,7 +66,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
@@ -164,7 +164,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/.github/workflows/Windows_Build.yml b/.github/workflows/Windows_Build.yml
index 5497c3ef..a4de2e60 100644
--- a/.github/workflows/Windows_Build.yml
+++ b/.github/workflows/Windows_Build.yml
@@ -26,7 +26,7 @@ jobs:
     - name: Setup Vulkan SDK
       uses: humbletim/setup-vulkan-sdk@v1.2.0
       with:
-        vulkan-query-version: latest
+        vulkan-query-version: 1.3.296.0
         vulkan-use-cache: true
         vulkan-components: Vulkan-Headers, Vulkan-Loader, SPIRV-Tools, Glslang
 
diff --git a/src/core/renderer_vk/renderer_vk.cpp b/src/core/renderer_vk/renderer_vk.cpp
index 14bde2c8..57533bde 100644
--- a/src/core/renderer_vk/renderer_vk.cpp
+++ b/src/core/renderer_vk/renderer_vk.cpp
@@ -887,7 +887,7 @@ void RendererVK::display() {
 
 // DynamicLoader is in a different namespace in different versions of Vulkan-Hpp
 #if VK_HEADER_VERSION >= 301
-using VulkanDynamicLoader = vk::detail::DynamicLoader
+using VulkanDynamicLoader = vk::detail::DynamicLoader;
 #else
 using VulkanDynamicLoader = vk::DynamicLoader;
 #endif

From 86d1bde8458a239cd10571c235400b74f3920904 Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Sun, 2 Feb 2025 23:18:54 +0200
Subject: [PATCH 13/18] Temporarily give 80MB to all processes (#715)

---
 include/kernel/kernel.hpp             |  1 +
 include/kernel/resource_limits.hpp    |  4 ++--
 include/memory.hpp                    |  2 +-
 src/core/kernel/memory_management.cpp | 10 +++++++++-
 src/core/services/apt.cpp             |  2 +-
 5 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp
index 45085e15..3f20b5e1 100644
--- a/include/kernel/kernel.hpp
+++ b/include/kernel/kernel.hpp
@@ -253,4 +253,5 @@ public:
 	void sendGPUInterrupt(GPUInterrupt type) { serviceManager.sendGPUInterrupt(type); }
 	void clearInstructionCache();
 	void clearInstructionCacheRange(u32 start, u32 size);
+	u32 getSharedFontVaddr();
 };
\ No newline at end of file
diff --git a/include/kernel/resource_limits.hpp b/include/kernel/resource_limits.hpp
index 85f1a59b..fe1154ff 100644
--- a/include/kernel/resource_limits.hpp
+++ b/include/kernel/resource_limits.hpp
@@ -19,7 +19,7 @@ struct ResourceLimitValues {
 // APPLICATION resource limit
 static constexpr ResourceLimitValues appResourceLimits = {
 	.maxPriority = 0x18,
-	.maxCommit = 0x4000000,
+	.maxCommit = 64_MB + 16_MB,  // We're currently giving 80MB to all apps. TODO: Implement extended memory properly
 	.maxThreads = 0x20,
 	.maxEvents = 0x20,
 	.maxMutexes = 0x20,
@@ -33,7 +33,7 @@ static constexpr ResourceLimitValues appResourceLimits = {
 // SYS_APPLET resource limit
 static constexpr ResourceLimitValues sysAppletResourceLimits = {
 	.maxPriority = 0x4,
-	.maxCommit = 0x5E00000,
+	.maxCommit = 0x5E00000 - 16_MB,
 	.maxThreads = 0x1D,
 	.maxEvents = 0xB,
 	.maxMutexes = 0x8,
diff --git a/include/memory.hpp b/include/memory.hpp
index bd002c54..b1dd09de 100644
--- a/include/memory.hpp
+++ b/include/memory.hpp
@@ -132,7 +132,7 @@ public:
 	static constexpr u32 totalPageCount = 1 << (32 - pageShift);
 	
 	static constexpr u32 FCRAM_SIZE = u32(128_MB);
-	static constexpr u32 FCRAM_APPLICATION_SIZE = u32(64_MB);
+	static constexpr u32 FCRAM_APPLICATION_SIZE = u32(80_MB);
 	static constexpr u32 FCRAM_PAGE_COUNT = FCRAM_SIZE / pageSize;
 	static constexpr u32 FCRAM_APPLICATION_PAGE_COUNT = FCRAM_APPLICATION_SIZE / pageSize;
 
diff --git a/src/core/kernel/memory_management.cpp b/src/core/kernel/memory_management.cpp
index 26f50023..18038d2e 100644
--- a/src/core/kernel/memory_management.cpp
+++ b/src/core/kernel/memory_management.cpp
@@ -122,7 +122,10 @@ void Kernel::mapMemoryBlock() {
 	}
 
 	if (KernelHandles::isSharedMemHandle(block)) {
-		if (block == KernelHandles::FontSharedMemHandle && addr == 0) addr = 0x18000000;
+		if (block == KernelHandles::FontSharedMemHandle && addr == 0) {
+			addr = getSharedFontVaddr();
+		}
+
 		u8* ptr = mem.mapSharedMemory(block, addr, myPerms, otherPerms); // Map shared memory block
 
 		// Pass pointer to shared memory to the appropriate service
@@ -216,3 +219,8 @@ void Kernel::unmapMemoryBlock() {
 	Helpers::warn("Stubbed svcUnmapMemoryBlock!");
 	regs[0] = Result::Success;
 }
+
+u32 Kernel::getSharedFontVaddr() {
+	// Place shared font at the very beginning of system FCRAM
+	return mem.getLinearHeapVaddr() + Memory::FCRAM_APPLICATION_SIZE;
+}
\ No newline at end of file
diff --git a/src/core/services/apt.cpp b/src/core/services/apt.cpp
index ddeb18de..b1e1d460 100644
--- a/src/core/services/apt.cpp
+++ b/src/core/services/apt.cpp
@@ -391,7 +391,7 @@ void APTService::setScreencapPostPermission(u32 messagePointer) {
 void APTService::getSharedFont(u32 messagePointer) {
 	log("APT::GetSharedFont\n");
 
-	constexpr u32 fontVaddr = 0x18000000;
+	const u32 fontVaddr = kernel.getSharedFontVaddr();
 	mem.write32(messagePointer, IPC::responseHeader(0x44, 2, 2));
 	mem.write32(messagePointer + 4, Result::Success);
 	mem.write32(messagePointer + 8, fontVaddr);

From 4cb66217c21325c9f5ead231d4ea52d78ffd7fed Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Sat, 8 Feb 2025 15:32:04 +0200
Subject: [PATCH 14/18] Try to cross-compile Libretro core for arm64 (#717)

* Try to cross-compile Libretro core for arm64

* Bonk

* Update Hydra_Build.yml
---
 .github/workflows/Hydra_Build.yml | 33 +++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/.github/workflows/Hydra_Build.yml b/.github/workflows/Hydra_Build.yml
index df851b69..e040a1f8 100644
--- a/.github/workflows/Hydra_Build.yml
+++ b/.github/workflows/Hydra_Build.yml
@@ -180,3 +180,36 @@ jobs:
       with:
         name: Android Hydra core
         path: '${{github.workspace}}/build/libAlber.so'
+
+  ARM-Libretro:
+    runs-on: ubuntu-24.04-arm
+
+    steps:
+    - uses: actions/checkout@v4
+    - name: Fetch submodules
+      run: git submodule update --init --recursive
+
+    - name: Install misc packages
+      run: |
+       sudo apt-get update && sudo apt install libx11-dev libxext-dev libgl1 libglx-mesa0 mesa-common-dev libfuse2 libwayland-dev
+      
+    - name: Install newer Clang
+      run: |
+       wget https://apt.llvm.org/llvm.sh
+       chmod +x ./llvm.sh
+       sudo ./llvm.sh 17
+
+    - name: Configure CMake
+      run: |
+        cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang-17 -DCMAKE_CXX_COMPILER=clang++-17 -DENABLE_USER_BUILD=ON -DBUILD_LIBRETRO_CORE=ON -DENABLE_VULKAN=OFF -DCRYPTOPP_OPT_DISABLE_ASM=ON
+
+    - name: Build
+      run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
+
+    - name: Upload Libretro core
+      uses: actions/upload-artifact@v4
+      with:
+        name: Linux arm64 Libretro core
+        path: |
+          ${{github.workspace}}/build/panda3ds_libretro.so
+          ${{github.workspace}}/docs/libretro/panda3ds_libretro.info

From 042ab6de0326a4fadccc6eeff8f9ef3ca7ed9641 Mon Sep 17 00:00:00 2001
From: Jonian Guveli <jonian@hardpixel.eu>
Date: Sun, 9 Feb 2025 05:04:36 +0200
Subject: [PATCH 15/18] [WIP] Libretro: Add audio support (#714)

* Libretro: Add audio support

* Adding audio interface part 1

* Audio device pt 2

* More audio device

* More audio device

* Morea uudi odevice

* More audio device

* More audio device

* More audio device

---------

Co-authored-by: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
---
 CMakeLists.txt                           |  3 +-
 include/audio/audio_device.hpp           |  9 ++++
 include/audio/audio_device_interface.hpp | 36 ++++++++++++++
 include/audio/libretro_audio_device.hpp  | 60 ++++++++++++++++++++++++
 include/audio/miniaudio_device.hpp       | 24 ++++------
 include/emulator.hpp                     |  7 +--
 src/core/audio/miniaudio_device.cpp      |  7 +--
 src/libretro_core.cpp                    |  2 +
 8 files changed, 125 insertions(+), 23 deletions(-)
 create mode 100644 include/audio/audio_device.hpp
 create mode 100644 include/audio/audio_device_interface.hpp
 create mode 100644 include/audio/libretro_audio_device.hpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index be70036c..f37ce28a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -402,7 +402,8 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp
                  include/align.hpp include/audio/aac_decoder.hpp include/PICA/pica_simd.hpp include/services/fonts.hpp
                  include/audio/audio_interpolation.hpp include/audio/hle_mixer.hpp include/audio/dsp_simd.hpp
                  include/services/dsp_firmware_db.hpp include/frontend_settings.hpp include/fs/archive_twl_photo.hpp
-                 include/fs/archive_twl_sound.hpp include/fs/archive_card_spi.hpp include/services/ns.hpp
+                 include/fs/archive_twl_sound.hpp include/fs/archive_card_spi.hpp include/services/ns.hpp include/audio/audio_device.hpp
+                 include/audio/audio_device_interface.hpp include/audio/libretro_audio_device.hpp
 )
 
 cmrc_add_resource_library(
diff --git a/include/audio/audio_device.hpp b/include/audio/audio_device.hpp
new file mode 100644
index 00000000..5c1f5fc1
--- /dev/null
+++ b/include/audio/audio_device.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#ifdef __LIBRETRO__
+#include "audio/libretro_audio_device.hpp"
+using AudioDevice = LibretroAudioDevice;
+#else
+#include "audio/miniaudio_device.hpp"
+using AudioDevice = MiniAudioDevice;
+#endif
\ No newline at end of file
diff --git a/include/audio/audio_device_interface.hpp b/include/audio/audio_device_interface.hpp
new file mode 100644
index 00000000..de70c77a
--- /dev/null
+++ b/include/audio/audio_device_interface.hpp
@@ -0,0 +1,36 @@
+#pragma once
+#include <array>
+
+#include "config.hpp"
+#include "helpers.hpp"
+#include "ring_buffer.hpp"
+
+class AudioDeviceInterface {
+  protected:
+	static constexpr usize maxFrameCount = 0x2000;
+
+	using Samples = Common::RingBuffer<s16, maxFrameCount * 2>;
+	using RenderBatchCallback = usize (*)(const s16*, usize);
+
+	Samples* samples = nullptr;
+
+	const AudioDeviceConfig& audioSettings;
+	// Store the last stereo sample we output. We play this when underruning to avoid pops.
+	std::array<s16, 2> lastStereoSample{};
+
+  public:
+	AudioDeviceInterface(Samples* samples, const AudioDeviceConfig& audioSettings) : samples(samples), audioSettings(audioSettings) {}
+
+	bool running = false;
+	Samples* getSamples() { return samples; }
+
+	// If safe is on, we create a null audio device
+	virtual void init(Samples& samples, bool safe = false) = 0;
+	virtual void close() = 0;
+
+	virtual void start() = 0;
+	virtual void stop() = 0;
+
+	// Only used for audio devices that render multiple audio frames in one go, eg the libretro audio device.
+	virtual void renderBatch(RenderBatchCallback callback) {}
+};
\ No newline at end of file
diff --git a/include/audio/libretro_audio_device.hpp b/include/audio/libretro_audio_device.hpp
new file mode 100644
index 00000000..047427ce
--- /dev/null
+++ b/include/audio/libretro_audio_device.hpp
@@ -0,0 +1,60 @@
+#pragma once
+#include <cstring>
+
+#include "audio/audio_device_interface.hpp"
+
+class LibretroAudioDevice : public AudioDeviceInterface {
+	bool initialized = false;
+
+  public:
+	LibretroAudioDevice(const AudioDeviceConfig& audioSettings) : AudioDeviceInterface(nullptr, audioSettings), initialized(false) {
+		running = false;
+	}
+
+	void init(Samples& samples, bool safe = false) override {
+		this->samples = &samples;
+
+		initialized = true;
+		running = false;
+	}
+
+	void close() override {
+		initialized = false;
+		running = false;
+	};
+
+	void start() override { running = true; }
+	void stop() override { running = false; };
+
+	void renderBatch(RenderBatchCallback callback) override {
+		if (running) {
+			static constexpr usize frameCount = 774;
+			static constexpr usize channelCount = 2;
+			static s16 audioBuffer[frameCount * channelCount];
+
+			usize samplesWritten = 0;
+			samplesWritten += samples->pop(audioBuffer, frameCount * channelCount);
+
+			// Get the last sample for underrun handling
+			if (samplesWritten != 0) {
+				std::memcpy(&lastStereoSample[0], &audioBuffer[(samplesWritten - 1) * 2], sizeof(lastStereoSample));
+			}
+
+			// If underruning, copy the last output sample
+			{
+				s16* pointer = &audioBuffer[samplesWritten * 2];
+				s16 l = lastStereoSample[0];
+				s16 r = lastStereoSample[1];
+
+				for (usize i = samplesWritten; i < frameCount; i++) {
+					*pointer++ = l;
+					*pointer++ = r;
+				}
+			}
+
+			callback(audioBuffer, sizeof(audioBuffer) / (channelCount * sizeof(s16)));
+		}
+	}
+
+	bool isInitialized() const { return initialized; }
+};
\ No newline at end of file
diff --git a/include/audio/miniaudio_device.hpp b/include/audio/miniaudio_device.hpp
index 0363aa44..deb6e31a 100644
--- a/include/audio/miniaudio_device.hpp
+++ b/include/audio/miniaudio_device.hpp
@@ -3,39 +3,31 @@
 #include <string>
 #include <vector>
 
-#include "config.hpp"
-#include "helpers.hpp"
+#include "audio/audio_device_interface.hpp"
 #include "miniaudio.h"
-#include "ring_buffer.hpp"
 
-class MiniAudioDevice {
-	using Samples = Common::RingBuffer<ma_int16, 0x2000 * 2>;
+class MiniAudioDevice : public AudioDeviceInterface {
 	static constexpr ma_uint32 sampleRate = 32768;  // 3DS sample rate
 	static constexpr ma_uint32 channelCount = 2;    // Audio output is stereo
 
+	bool initialized = false;
+
 	ma_device device;
 	ma_context context;
 	ma_device_config deviceConfig;
-	Samples* samples = nullptr;
-
-	const AudioDeviceConfig& audioSettings;
-
-	bool initialized = false;
-	bool running = false;
 
 	// Store the last stereo sample we output. We play this when underruning to avoid pops.
-	std::array<s16, 2> lastStereoSample;
 	std::vector<std::string> audioDevices;
 
   public:
 	MiniAudioDevice(const AudioDeviceConfig& audioSettings);
 
 	// If safe is on, we create a null audio device
-	void init(Samples& samples, bool safe = false);
-	void close();
+	void init(Samples& samples, bool safe = false) override;
+	void close() override;
 
-	void start();
-	void stop();
+	void start() override;
+	void stop() override;
 
 	bool isInitialized() const { return initialized; }
 };
\ No newline at end of file
diff --git a/include/emulator.hpp b/include/emulator.hpp
index a222a021..326eb232 100644
--- a/include/emulator.hpp
+++ b/include/emulator.hpp
@@ -7,8 +7,8 @@
 #include <span>
 
 #include "PICA/gpu.hpp"
+#include "audio/audio_device.hpp"
 #include "audio/dsp_core.hpp"
-#include "audio/miniaudio_device.hpp"
 #include "cheats.hpp"
 #include "config.hpp"
 #include "cpu.hpp"
@@ -48,14 +48,14 @@ class Emulator {
 	Scheduler scheduler;
 
 	Crypto::AESEngine aesEngine;
-	MiniAudioDevice audioDevice;
+	AudioDevice audioDevice;
 	Cheats cheats;
 
   public:
 	static constexpr u32 width = 400;
 	static constexpr u32 height = 240 * 2;  // * 2 because 2 screens
 	ROMType romType = ROMType::None;
-	bool running = false;         // Is the emulator running a game?
+	bool running = false;  // Is the emulator running a game?
 
   private:
 #ifdef PANDA3DS_ENABLE_HTTP_SERVER
@@ -126,6 +126,7 @@ class Emulator {
 	LuaManager& getLua() { return lua; }
 	Scheduler& getScheduler() { return scheduler; }
 	Memory& getMemory() { return memory; }
+	AudioDeviceInterface& getAudioDevice() { return audioDevice; }
 
 	RendererType getRendererType() const { return config.rendererType; }
 	Renderer* getRenderer() { return gpu.getRenderer(); }
diff --git a/src/core/audio/miniaudio_device.cpp b/src/core/audio/miniaudio_device.cpp
index 550fb039..8e2a1e71 100644
--- a/src/core/audio/miniaudio_device.cpp
+++ b/src/core/audio/miniaudio_device.cpp
@@ -7,8 +7,9 @@
 
 #include "helpers.hpp"
 
-MiniAudioDevice::MiniAudioDevice(const AudioDeviceConfig& audioSettings)
-	: initialized(false), running(false), samples(nullptr), audioSettings(audioSettings) {}
+MiniAudioDevice::MiniAudioDevice(const AudioDeviceConfig& audioSettings) : AudioDeviceInterface(nullptr, audioSettings), initialized(false) {
+	running = false;
+}
 
 void MiniAudioDevice::init(Samples& samples, bool safe) {
 	this->samples = &samples;
@@ -212,4 +213,4 @@ void MiniAudioDevice::close() {
 		ma_device_uninit(&device);
 		ma_context_uninit(&context);
 	}
-}
+}
\ No newline at end of file
diff --git a/src/libretro_core.cpp b/src/libretro_core.cpp
index 727da8d2..a9783320 100644
--- a/src/libretro_core.cpp
+++ b/src/libretro_core.cpp
@@ -389,6 +389,8 @@ void retro_run() {
 	emulator->runFrame();
 
 	videoCallback(RETRO_HW_FRAME_BUFFER_VALID, emulator->width, emulator->height, 0);
+	// Call audio batch callback
+	emulator->getAudioDevice().renderBatch(audioBatchCallback);
 }
 
 void retro_set_controller_port_device(uint port, uint device) {}

From a376bb5c9bcb22bbfaf765ba78c9e46fd13e257a Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Sun, 9 Feb 2025 14:31:19 +0200
Subject: [PATCH 16/18] Libretro audio device: Fix frame count

---
 include/audio/libretro_audio_device.hpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/audio/libretro_audio_device.hpp b/include/audio/libretro_audio_device.hpp
index 047427ce..5b3a70c1 100644
--- a/include/audio/libretro_audio_device.hpp
+++ b/include/audio/libretro_audio_device.hpp
@@ -28,7 +28,8 @@ class LibretroAudioDevice : public AudioDeviceInterface {
 
 	void renderBatch(RenderBatchCallback callback) override {
 		if (running) {
-			static constexpr usize frameCount = 774;
+			static constexpr usize sampleRate = 32768;            // 3DS samples per second
+			static constexpr usize frameCount = sampleRate / 60;  // 3DS samples per video frame
 			static constexpr usize channelCount = 2;
 			static s16 audioBuffer[frameCount * channelCount];
 
@@ -57,4 +58,4 @@ class LibretroAudioDevice : public AudioDeviceInterface {
 	}
 
 	bool isInitialized() const { return initialized; }
-};
\ No newline at end of file
+};

From d42974b5db701e7d65650a5cb9689fe60a674b17 Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Sun, 9 Feb 2025 14:45:56 +0200
Subject: [PATCH 17/18] Mark audio devices as final

---
 include/audio/libretro_audio_device.hpp | 2 +-
 include/audio/miniaudio_device.hpp      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/audio/libretro_audio_device.hpp b/include/audio/libretro_audio_device.hpp
index 5b3a70c1..9c6d19f8 100644
--- a/include/audio/libretro_audio_device.hpp
+++ b/include/audio/libretro_audio_device.hpp
@@ -3,7 +3,7 @@
 
 #include "audio/audio_device_interface.hpp"
 
-class LibretroAudioDevice : public AudioDeviceInterface {
+class LibretroAudioDevice final : public AudioDeviceInterface {
 	bool initialized = false;
 
   public:
diff --git a/include/audio/miniaudio_device.hpp b/include/audio/miniaudio_device.hpp
index deb6e31a..5cf7c801 100644
--- a/include/audio/miniaudio_device.hpp
+++ b/include/audio/miniaudio_device.hpp
@@ -6,7 +6,7 @@
 #include "audio/audio_device_interface.hpp"
 #include "miniaudio.h"
 
-class MiniAudioDevice : public AudioDeviceInterface {
+class MiniAudioDevice final : public AudioDeviceInterface {
 	static constexpr ma_uint32 sampleRate = 32768;  // 3DS sample rate
 	static constexpr ma_uint32 channelCount = 2;    // Audio output is stereo
 

From 7d5cedf4766c7b39f5df3d567a0c219cf9be6f2c Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Sun, 9 Feb 2025 14:58:17 +0200
Subject: [PATCH 18/18] Add toggle for libretro audio device (#719)

---
 CMakeLists.txt                 | 6 +++++-
 include/audio/audio_device.hpp | 2 +-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f37ce28a..92bff3d2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,6 +64,7 @@ option(BUILD_HYDRA_CORE "Build a Hydra core" OFF)
 option(BUILD_LIBRETRO_CORE "Build a Libretro core" OFF)
 option(ENABLE_RENDERDOC_API "Build with support for Renderdoc's capture API for graphics debugging" ON)
 option(DISABLE_SSE4 "Build with SSE4 instructions disabled, may reduce performance" OFF)
+option(USE_LIBRETRO_AUDIO "Enable to use the LR audio device with the LR core. Otherwise our own device is used" OFF)
 
 set(OPENGL_PROFILE ${DEFAULT_OPENGL_PROFILE} CACHE STRING "OpenGL profile to use if OpenGL is enabled. Valid values are 'OpenGL' and 'OpenGLES'.")
 set_property(CACHE OPENGL_PROFILE PROPERTY STRINGS OpenGL OpenGLES)
@@ -80,6 +81,10 @@ endif()
 if(BUILD_LIBRETRO_CORE)
     set(CMAKE_POSITION_INDEPENDENT_CODE ON)
     add_compile_definitions(__LIBRETRO__)
+
+    if(USE_LIBRETRO_AUDIO)
+        add_compile_definitions(USE_LIBRETRO_AUDIO_DEVICE)
+    endif()
 endif()
 
 if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND ENABLE_USER_BUILD)
@@ -157,7 +162,6 @@ if(ENABLE_DISCORD_RPC AND NOT ANDROID)
     include_directories(third_party/discord-rpc/include)
 endif()
 
-
 if (NOT ANDROID)
     if (USE_SYSTEM_SDL2)
         find_package(SDL2 CONFIG REQUIRED)
diff --git a/include/audio/audio_device.hpp b/include/audio/audio_device.hpp
index 5c1f5fc1..966fd667 100644
--- a/include/audio/audio_device.hpp
+++ b/include/audio/audio_device.hpp
@@ -1,6 +1,6 @@
 #pragma once
 
-#ifdef __LIBRETRO__
+#if defined(__LIBRETRO__) && defined(USE_LIBRETRO_AUDIO_DEVICE)
 #include "audio/libretro_audio_device.hpp"
 using AudioDevice = LibretroAudioDevice;
 #else