From 0c4361a693624cb97cfba3d984650f0fdbefa064 Mon Sep 17 00:00:00 2001 From: butilly Date: Sat, 10 Oct 2026 18:59:00 +0000 Subject: [PATCH] LSFG: initialize loader data for adopted-device framegen command buffers --- framegen/src/core/device.cpp | 3 +++ src/layer.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/framegen/src/core/device.cpp b/framegen/src/core/device.cpp index 6a178873..885790b4 100644 --- a/framegen/src/core/device.cpp +++ b/framegen/src/core/device.cpp @@ -586,9 +586,12 @@ Device::Device(const Instance& instance, VkPhysicalDevice physical, new VkDevice(external), [](VkDevice* device) { delete device; } ); + LSFG_FRAMEGEN_LOGI("Adopted-device init: creating fallback descriptor image"); this->fallbackDescriptorImage = std::make_shared(*this, VkExtent2D{1, 1}, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + LSFG_FRAMEGEN_LOGI("Adopted-device init: clearing fallback descriptor image"); Utils::clearImage(*this, *this->fallbackDescriptorImage); + LSFG_FRAMEGEN_LOGI("Adopted-device init: fallback descriptor ready"); } diff --git a/src/layer.cpp b/src/layer.cpp index fa9c173c..04e2c978 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include namespace { @@ -76,6 +77,31 @@ namespace { PFN_vkInvalidateMappedMemoryRanges next_vkInvalidateMappedMemoryRanges{}; PFN_vkCmdCopyImageToBuffer next_vkCmdCopyImageToBuffer{}; + // Framegen adopts the game's device but allocates below the loader via + // Volk. Dispatchable objects created by a layer must receive loader data, + // just like the command buffers allocated by Mini::CommandBuffer. + VkResult framegenAllocateCommandBuffers( + VkDevice device, + const VkCommandBufferAllocateInfo* info, + VkCommandBuffer* buffers) { + auto res = next_vkAllocateCommandBuffers(device, info, buffers); + if (res != VK_SUCCESS) + return res; + for (uint32_t i = 0; i < info->commandBufferCount; ++i) { + res = next_vSetDeviceLoaderData(device, buffers[i]); + if (res != VK_SUCCESS) { + std::cerr << "lsfg-vk: framegen command buffer loader setup failed: " + << res << '\n'; + next_vkFreeCommandBuffers(device, info->commandPool, + info->commandBufferCount, buffers); + for (uint32_t j = 0; j < info->commandBufferCount; ++j) + buffers[j] = VK_NULL_HANDLE; + return res; + } + } + return VK_SUCCESS; + } + template bool initInstanceFunc(VkInstance instance, const char* name, T* func) { *func = reinterpret_cast(next_vkGetInstanceProcAddr(instance, name)); @@ -361,11 +387,17 @@ namespace Layer { PFN_vkVoidFunction ovkGetInstanceProcAddr( VkInstance instance, const char* pName) { + // Keep Volk's adopted-device dispatch below our hooks, while routing + // its allocations through the loader-data adapter above. + if (std::strcmp(pName, "vkGetDeviceProcAddr") == 0) + return reinterpret_cast(ovkGetDeviceProcAddr); return next_vkGetInstanceProcAddr(instance, pName); } PFN_vkVoidFunction ovkGetDeviceProcAddr( VkDevice device, const char* pName) { + if (std::strcmp(pName, "vkAllocateCommandBuffers") == 0) + return reinterpret_cast(framegenAllocateCommandBuffers); return next_vkGetDeviceProcAddr(device, pName); }