From 350d843223ed82411271887c0d447f3c6a5ce63c Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Sun, 21 Dec 2025 00:49:14 +0100 Subject: [PATCH] refactor(cleanup): remove format and memory model dependency --- .../src/extraction/shader_registry.cpp | 51 ++++++++++++++++++- .../src/extraction/shader_registry.hpp | 2 +- lsfg-vk-backend/src/shaderchains/generate.cpp | 6 ++- lsfg-vk-common/src/vulkan/vulkan.cpp | 4 +- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/lsfg-vk-backend/src/extraction/shader_registry.cpp b/lsfg-vk-backend/src/extraction/shader_registry.cpp index bd4f245..a92342b 100644 --- a/lsfg-vk-backend/src/extraction/shader_registry.cpp +++ b/lsfg-vk-backend/src/extraction/shader_registry.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -27,10 +28,57 @@ namespace { return it->second; } + /// patch the generate shader + void patchGenerateShader(std::vector& data, bool hdr) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container" + auto* _ptr = data.data(); + const std::span words( + reinterpret_cast(_ptr), + data.size() / sizeof(uint32_t) + ); +#pragma clang diagnostic pop + + const uint16_t SpvOpCapability = 17; + const uint16_t SpvOpTypeImage = 25; + const uint32_t SpvCapabilityStorageImageWriteWithoutFormat = 56; + const uint32_t SpvCapabilityShader = 1; + const uint32_t SpvImageFormatRgba16f = 2; + const uint32_t SpvImageFormatRgba8 = 4; + + for (size_t i = 5; i < words.size();) { + const uint32_t& word = words[i]; + const uint16_t wc = (word >> 16); + const uint16_t op = word & 0xFFFF; + + // remove write without format capability + if (op == SpvOpCapability && wc >= 2) { + uint32_t& cap = words[i + 1]; + if (cap == SpvCapabilityStorageImageWriteWithoutFormat) + cap = SpvCapabilityShader; + } + + // patch format in image instructions + if (op == SpvOpTypeImage && wc >= 9) { + const uint32_t sampled = words[i + 7]; + if (sampled == 2) + words[i + 8] = hdr ? SpvImageFormatRgba16f : SpvImageFormatRgba8; + } + + i += wc ? wc : 1; + } + } } ShaderRegistry extr::buildShaderRegistry(const vk::Vulkan& vk, bool fp16, const std::unordered_map>& resources) { + // patch the generate shader + std::vector generate_data = getShaderSource(256, fp16, false, resources); + std::vector generate_data_hdr = generate_data; + patchGenerateShader(generate_data, false); + patchGenerateShader(generate_data_hdr, true); + + // load all other shaders #define SHADER(id, p1, p2, p3, p4) \ vk::Shader(vk, getShaderSource(id, fp16, PERF, resources), \ p1, p2, p3, p4) @@ -38,7 +86,8 @@ ShaderRegistry extr::buildShaderRegistry(const vk::Vulkan& vk, bool fp16, return { #define PERF false .mipmaps = SHADER(255, 1, 7, 1, 1), - .generate = SHADER(256, 5, 1, 1, 2), + .generate = vk::Shader(vk, generate_data, 5, 1, 1, 2), + .generate_hdr = vk::Shader(vk, generate_data_hdr, 5, 1, 1, 2), .quality = { .alpha = { SHADER(267, 1, 2, 0, 1), diff --git a/lsfg-vk-backend/src/extraction/shader_registry.hpp b/lsfg-vk-backend/src/extraction/shader_registry.hpp index 3cb92d1..d1f1c36 100644 --- a/lsfg-vk-backend/src/extraction/shader_registry.hpp +++ b/lsfg-vk-backend/src/extraction/shader_registry.hpp @@ -20,7 +20,7 @@ namespace extr { /// shader registry struct struct ShaderRegistry { vk::Shader mipmaps; - vk::Shader generate; + vk::Shader generate, generate_hdr; Shaders quality; Shaders performance; diff --git a/lsfg-vk-backend/src/shaderchains/generate.cpp b/lsfg-vk-backend/src/shaderchains/generate.cpp index fb97467..592b0a0 100644 --- a/lsfg-vk-backend/src/shaderchains/generate.cpp +++ b/lsfg-vk-backend/src/shaderchains/generate.cpp @@ -20,6 +20,8 @@ Generate::Generate(const ls::Ctx& ctx, size_t idx, const vk::Image& inputImage3, const vk::Image& outputImage) { // create descriptor sets + const auto& shader = ctx.hdr ? + ctx.shaders.get().generate_hdr : ctx.shaders.get().generate; this->sets.reserve(2); this->sets.emplace_back(ls::ManagedShaderBuilder() .sampled(sourceImages.second) @@ -31,7 +33,7 @@ Generate::Generate(const ls::Ctx& ctx, size_t idx, .sampler(ctx.bnbSampler) .sampler(ctx.eabSampler) .buffer(ctx.constantBuffers.at(idx)) - .build(ctx.vk, ctx.pool, ctx.shaders.get().generate)); + .build(ctx.vk, ctx.pool, shader)); this->sets.emplace_back(ls::ManagedShaderBuilder() .sampled(sourceImages.first) .sampled(sourceImages.second) @@ -42,7 +44,7 @@ Generate::Generate(const ls::Ctx& ctx, size_t idx, .sampler(ctx.bnbSampler) .sampler(ctx.eabSampler) .buffer(ctx.constantBuffers.at(idx)) - .build(ctx.vk, ctx.pool, ctx.shaders.get().generate)); + .build(ctx.vk, ctx.pool, shader)); // store dispatch extent this->dispatchExtent = ls::add_shift_extent(ctx.sourceExtent, 15, 4); diff --git a/lsfg-vk-common/src/vulkan/vulkan.cpp b/lsfg-vk-common/src/vulkan/vulkan.cpp index 4317561..5adf000 100644 --- a/lsfg-vk-common/src/vulkan/vulkan.cpp +++ b/lsfg-vk-common/src/vulkan/vulkan.cpp @@ -161,8 +161,7 @@ namespace { const VkPhysicalDeviceVulkan12Features requestedFeaturesVulkan12{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, .shaderFloat16 = fp16, - .timelineSemaphore = VK_TRUE, - .vulkanMemoryModel = VK_TRUE + .timelineSemaphore = VK_TRUE }; const VkDeviceQueueCreateInfo requestedQueueInfo{ .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, @@ -173,7 +172,6 @@ namespace { const std::vector requestedExtensions{ VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, - VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME, // TODO: possibly attempt to get rid of VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME }; const VkDeviceCreateInfo deviceInfo{