diff --git a/src/rendering/vulkan/renderer/vk_postprocess.cpp b/src/rendering/vulkan/renderer/vk_postprocess.cpp index be86a1fd41..d3d50ab973 100644 --- a/src/rendering/vulkan/renderer/vk_postprocess.cpp +++ b/src/rendering/vulkan/renderer/vk_postprocess.cpp @@ -12,6 +12,7 @@ #include "hwrenderer/utility/hw_vrmodes.h" #include "hwrenderer/data/flatvertices.h" #include "r_videoscale.h" +#include "w_wad.h" VkPostprocess::VkPostprocess() { @@ -101,6 +102,44 @@ void VkPostprocess::UpdateEffectTextures() void VkPostprocess::CompileEffectShaders() { + auto fb = GetVulkanFrameBuffer(); + + TMap::Iterator it(hw_postprocess.Shaders); + TMap::Pair *pair; + while (it.NextPair(pair)) + { + const auto &desc = pair->Value; + auto &vkshader = mShaders[pair->Key]; + if (!vkshader) + { + FString prolog; + if (!desc.Uniforms.empty()) + prolog = UniformBlockDecl::Create("Uniforms", desc.Uniforms, uniformbindingpoint); + prolog += desc.Defines; + + ShaderBuilder vertbuilder; + vertbuilder.setVertexShader(LoadShaderCode(desc.VertexShader, "", desc.Version)); + vkshader->VertexShader = vertbuilder.create(fb->device); + + ShaderBuilder fragbuilder; + fragbuilder.setFragmentShader(LoadShaderCode(desc.FragmentShader, prolog, desc.Version)); + vkshader->FragmentShader = fragbuilder.create(fb->device); + } + } +} + +FString VkPostprocess::LoadShaderCode(const FString &lumpName, const FString &defines, int version) +{ + int lump = Wads.CheckNumForFullName(lumpName, 0); + if (lump == -1) I_FatalError("Unable to load '%s'", lumpName); + FString code = Wads.ReadLump(lump).GetString().GetChars(); + + FString patchedCode; + patchedCode.AppendFormat("#version %d\n", 450); + patchedCode << defines; + patchedCode << "#line 1\n"; + patchedCode << code; + return patchedCode; } void VkPostprocess::RenderEffect(const FString &name) diff --git a/src/rendering/vulkan/renderer/vk_postprocess.h b/src/rendering/vulkan/renderer/vk_postprocess.h index e758cbc6fc..6c75ac9609 100644 --- a/src/rendering/vulkan/renderer/vk_postprocess.h +++ b/src/rendering/vulkan/renderer/vk_postprocess.h @@ -2,11 +2,16 @@ #pragma once #include +#include +#include "hwrenderer/postprocessing/hw_postprocess.h" #include "vulkan/system/vk_objects.h" class FString; +class VkPPShader; +class VkPPTexture; + class VkPostprocess { public: @@ -24,7 +29,27 @@ public: private: void UpdateEffectTextures(); void CompileEffectShaders(); + FString LoadShaderCode(const FString &lumpname, const FString &defines, int version); void RenderEffect(const FString &name); void NextEye(int eyeCount); void RenderScreenQuad(); + + std::map> mTextures; + std::map> mShaders; + + const static int uniformbindingpoint = 7; +}; + +class VkPPShader +{ +public: + std::unique_ptr VertexShader; + std::unique_ptr FragmentShader; +}; + +class VkPPTexture +{ +public: + std::unique_ptr Image; + std::unique_ptr View; }; diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index e429ac7d52..8d80daa206 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -102,6 +102,7 @@ void VulkanFrameBuffer::InitializeState() gl_vendorstring = "Vulkan"; hwcaps = RFL_SHADER_STORAGE_BUFFER | RFL_BUFFER_STORAGE; + glslversion = 4.50f; uniformblockalignment = (unsigned int)device->deviceProperties.limits.minUniformBufferOffsetAlignment; maxuniformblock = device->deviceProperties.limits.maxUniformBufferRange;