From 0679b493ec1d63baa871b3c6e74d1779f9801529 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Wed, 6 Mar 2019 22:59:21 +0100 Subject: [PATCH] - hook up the present shader --- .../postprocessing/hw_postprocess.cpp | 38 +++++++++ .../postprocessing/hw_postprocess.h | 44 +++++++++- .../postprocessing/hw_presentshader.cpp | 2 +- .../postprocessing/hw_presentshader.h | 31 +------ .../vulkan/renderer/vk_postprocess.cpp | 82 ++++++++++++++++++- .../vulkan/renderer/vk_postprocess.h | 4 +- .../vulkan/system/vk_framebuffer.cpp | 16 +++- 7 files changed, 180 insertions(+), 37 deletions(-) diff --git a/src/rendering/hwrenderer/postprocessing/hw_postprocess.cpp b/src/rendering/hwrenderer/postprocessing/hw_postprocess.cpp index 9432dcb02..8d6f9361a 100644 --- a/src/rendering/hwrenderer/postprocessing/hw_postprocess.cpp +++ b/src/rendering/hwrenderer/postprocessing/hw_postprocess.cpp @@ -16,6 +16,7 @@ Postprocess::Postprocess() Managers.Push(new PPColormap()); Managers.Push(new PPTonemap()); Managers.Push(new PPAmbientOcclusion()); + Managers.Push(new PPPresent()); } Postprocess::~Postprocess() @@ -854,3 +855,40 @@ void PPAmbientOcclusion::UpdateSteps() hw_postprocess.Effects["AmbientOccludeScene"] = steps; } + +///////////////////////////////////////////////////////////////////////////// + +void PPPresent::DeclareShaders() +{ + hw_postprocess.Shaders["Present"] = { "shaders/glsl/present.fp", "", PresentUniforms::Desc() }; + hw_postprocess.Shaders["Present.Checker3D"] = { "shaders/glsl/present_checker3d.fp", "", PresentUniforms::Desc() }; + hw_postprocess.Shaders["Present.Column3D"] = { "shaders/glsl/present_column3d.fp", "", PresentUniforms::Desc() }; + hw_postprocess.Shaders["Present.Row3D"] = { "shaders/glsl/present_row3d.fp", "", PresentUniforms::Desc() }; +} + +void PPPresent::UpdateTextures() +{ + auto &tex = hw_postprocess.Textures["PresentDither"]; + if (!tex.Data) + { + static const float data[64] = + { + .0078125, .2578125, .1328125, .3828125, .0234375, .2734375, .1484375, .3984375, + .7578125, .5078125, .8828125, .6328125, .7734375, .5234375, .8984375, .6484375, + .0703125, .3203125, .1953125, .4453125, .0859375, .3359375, .2109375, .4609375, + .8203125, .5703125, .9453125, .6953125, .8359375, .5859375, .9609375, .7109375, + .0390625, .2890625, .1640625, .4140625, .0546875, .3046875, .1796875, .4296875, + .7890625, .5390625, .9140625, .6640625, .8046875, .5546875, .9296875, .6796875, + .1015625, .3515625, .2265625, .4765625, .1171875, .3671875, .2421875, .4921875, + .8515625, .6015625, .9765625, .7265625, .8671875, .6171875, .9921875, .7421875, + }; + + std::shared_ptr pixels(new float[64], [](void *p) { delete[](float*)p; }); + memcpy(pixels.get(), data, 64 * sizeof(float)); + tex = { 8, 8, PixelFormat::R32f, pixels }; + } +} + +void PPPresent::UpdateSteps() +{ +} diff --git a/src/rendering/hwrenderer/postprocessing/hw_postprocess.h b/src/rendering/hwrenderer/postprocessing/hw_postprocess.h index 67b95b56c..905649f87 100644 --- a/src/rendering/hwrenderer/postprocessing/hw_postprocess.h +++ b/src/rendering/hwrenderer/postprocessing/hw_postprocess.h @@ -11,7 +11,7 @@ typedef IntRect PPViewport; enum class PPFilterMode { Nearest, Linear }; enum class PPWrapMode { Clamp, Repeat }; -enum class PPTextureType { CurrentPipelineTexture, NextPipelineTexture, PPTexture, SceneColor, SceneFog, SceneNormal, SceneDepth }; +enum class PPTextureType { CurrentPipelineTexture, NextPipelineTexture, PPTexture, SceneColor, SceneFog, SceneNormal, SceneDepth, SwapChain }; class PPTextureInput { @@ -144,6 +144,12 @@ public: Output.Texture = ""; } + void SetOutputSwapChain() + { + Output.Type = PPTextureType::SwapChain; + Output.Texture = ""; + } + void SetNoBlend() { BlendMode.BlendOp = STYLEOP_Add; @@ -597,3 +603,39 @@ private: enum { NumAmbientRandomTextures = 3 }; PPTextureName AmbientRandomTexture[NumAmbientRandomTextures]; }; + +struct PresentUniforms +{ + float InvGamma; + float Contrast; + float Brightness; + float Saturation; + int GrayFormula; + int WindowPositionParity; // top-of-window might not be top-of-screen + FVector2 Scale; + float ColorScale; + float Padding1, Padding2, Padding3; + + static std::vector Desc() + { + return + { + { "InvGamma", UniformType::Float, offsetof(PresentUniforms, InvGamma) }, + { "Contrast", UniformType::Float, offsetof(PresentUniforms, Contrast) }, + { "Brightness", UniformType::Float, offsetof(PresentUniforms, Brightness) }, + { "Saturation", UniformType::Float, offsetof(PresentUniforms, Saturation) }, + { "GrayFormula", UniformType::Int, offsetof(PresentUniforms, GrayFormula) }, + { "WindowPositionParity", UniformType::Int, offsetof(PresentUniforms, WindowPositionParity) }, + { "UVScale", UniformType::Vec2, offsetof(PresentUniforms, Scale) }, + { "ColorScale", UniformType::Float, offsetof(PresentUniforms, ColorScale) }, + }; + } +}; + +class PPPresent : public PPEffectManager +{ +public: + void DeclareShaders() override; + void UpdateTextures() override; + void UpdateSteps() override; +}; diff --git a/src/rendering/hwrenderer/postprocessing/hw_presentshader.cpp b/src/rendering/hwrenderer/postprocessing/hw_presentshader.cpp index ae231d8c3..3740ebc18 100644 --- a/src/rendering/hwrenderer/postprocessing/hw_presentshader.cpp +++ b/src/rendering/hwrenderer/postprocessing/hw_presentshader.cpp @@ -30,7 +30,7 @@ void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program_name) { - FString prolog = Uniforms.CreateDeclaration("Uniforms", UniformBlock::Desc()); + FString prolog = Uniforms.CreateDeclaration("Uniforms", PresentUniforms::Desc()); mShader.reset(screen->CreateShaderProgram()); mShader->Compile(IShaderProgram::Vertex, "shaders/glsl/screenquadscale.vp", prolog, 330); diff --git a/src/rendering/hwrenderer/postprocessing/hw_presentshader.h b/src/rendering/hwrenderer/postprocessing/hw_presentshader.h index feba2c435..f8dc15a7a 100644 --- a/src/rendering/hwrenderer/postprocessing/hw_presentshader.h +++ b/src/rendering/hwrenderer/postprocessing/hw_presentshader.h @@ -2,6 +2,7 @@ #define __GL_PRESENTSHADER_H #include "hwrenderer/postprocessing/hw_shaderprogram.h" +#include "hwrenderer/postprocessing/hw_postprocess.h" class FPresentShaderBase { @@ -9,35 +10,7 @@ public: virtual ~FPresentShaderBase() {} virtual void Bind(IRenderQueue *q) = 0; - struct UniformBlock - { - float InvGamma; - float Contrast; - float Brightness; - float Saturation; - int GrayFormula; - int WindowPositionParity; // top-of-window might not be top-of-screen - FVector2 Scale; - float ColorScale; - float Padding1, Padding2, Padding3; - - static std::vector Desc() - { - return - { - { "InvGamma", UniformType::Float, offsetof(UniformBlock, InvGamma) }, - { "Contrast", UniformType::Float, offsetof(UniformBlock, Contrast) }, - { "Brightness", UniformType::Float, offsetof(UniformBlock, Brightness) }, - { "Saturation", UniformType::Float, offsetof(UniformBlock, Saturation) }, - { "GrayFormula", UniformType::Int, offsetof(UniformBlock, GrayFormula) }, - { "WindowPositionParity", UniformType::Int, offsetof(UniformBlock, WindowPositionParity) }, - { "UVScale", UniformType::Vec2, offsetof(UniformBlock, Scale) }, - { "ColorScale", UniformType::Float, offsetof(UniformBlock, ColorScale) }, - }; - } - }; - - ShaderUniforms Uniforms; + ShaderUniforms Uniforms; protected: virtual void Init(const char * vtx_shader_name, const char * program_name); diff --git a/src/rendering/vulkan/renderer/vk_postprocess.cpp b/src/rendering/vulkan/renderer/vk_postprocess.cpp index 1f299446a..34c2e826b 100644 --- a/src/rendering/vulkan/renderer/vk_postprocess.cpp +++ b/src/rendering/vulkan/renderer/vk_postprocess.cpp @@ -5,6 +5,7 @@ #include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_framebuffer.h" #include "vulkan/system/vk_buffers.h" +#include "vulkan/system/vk_swapchain.h" #include "hwrenderer/utility/hw_cvars.h" #include "hwrenderer/postprocessing/hw_presentshader.h" #include "hwrenderer/postprocessing/hw_postprocess.h" @@ -14,6 +15,8 @@ #include "r_videoscale.h" #include "w_wad.h" +EXTERN_CVAR(Int, gl_dither_bpc) + VkPostprocess::VkPostprocess() { } @@ -49,6 +52,53 @@ void VkPostprocess::PostProcessScene(int fixedcm, const std::function &a //mCustomPostProcessShaders->Run("scene"); } +void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool clearBorders) +{ + auto fb = GetVulkanFrameBuffer(); + + hw_postprocess.DeclareShaders(); + hw_postprocess.UpdateTextures(); + hw_postprocess.UpdateSteps(); + CompileEffectShaders(); + UpdateEffectTextures(); + + PresentUniforms uniforms; + if (!applyGamma /*|| framebuffer->IsHWGammaActive()*/) + { + uniforms.InvGamma = 1.0f; + uniforms.Contrast = 1.0f; + uniforms.Brightness = 0.0f; + uniforms.Saturation = 1.0f; + } + else + { + uniforms.InvGamma = 1.0f / clamp(Gamma, 0.1f, 4.f); + uniforms.Contrast = clamp(vid_contrast, 0.1f, 3.f); + uniforms.Brightness = clamp(vid_brightness, -0.8f, 0.8f); + uniforms.Saturation = clamp(vid_saturation, -15.0f, 15.f); + uniforms.GrayFormula = static_cast(gl_satformula); + } + uniforms.ColorScale = (gl_dither_bpc == -1) ? 255.0f : (float)((1 << gl_dither_bpc) - 1); + uniforms.Scale = { screen->mScreenViewport.width / (float)fb->GetBuffers()->GetWidth(), screen->mScreenViewport.height / (float)fb->GetBuffers()->GetHeight() }; + + PPStep step; + step.ShaderName = "Present"; + step.Uniforms.Set(uniforms); + step.Viewport = box; + //step.SetInputCurrent(0, ViewportLinearScale() ? PPFilterMode::Linear : PPFilterMode::Nearest); + step.SetInputSceneColor(0, ViewportLinearScale() ? PPFilterMode::Linear : PPFilterMode::Nearest); + step.SetInputTexture(1, "PresentDither", PPFilterMode::Nearest, PPWrapMode::Repeat); + step.SetOutputSwapChain(); + step.SetNoBlend(); + //if (clearBorders) step.SetClearBorders(); + + TArray steps; + steps.Push(step); + hw_postprocess.Effects["Present"] = steps; + + RenderEffect("Present"); +} + void VkPostprocess::AmbientOccludeScene(float m5) { auto fb = GetVulkanFrameBuffer(); @@ -342,7 +392,7 @@ VulkanFramebuffer *VkPostprocess::GetOutput(VkPPRenderPassSetup *passSetup, cons TextureImage tex = GetTexture(output.Type, output.Texture); - if (*tex.layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + if (tex.layout && *tex.layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { PipelineBarrier barrier; barrier.addImage(tex.image, *tex.layout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); @@ -350,13 +400,28 @@ VulkanFramebuffer *VkPostprocess::GetOutput(VkPPRenderPassSetup *passSetup, cons *tex.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; } - auto &framebuffer = passSetup->Framebuffers[tex.view]; + VkImageView view; + int w, h; + if (tex.view) + { + view = tex.view->view; + w = tex.image->width; + h = tex.image->height; + } + else + { + view = fb->device->swapChain->swapChainImageViews[fb->device->presentImageIndex]; + w = fb->device->swapChain->actualExtent.width; + h = fb->device->swapChain->actualExtent.height; + } + + auto &framebuffer = passSetup->Framebuffers[view]; if (!framebuffer) { FramebufferBuilder builder; builder.setRenderPass(passSetup->RenderPass.get()); - builder.setSize(tex.image->width, tex.image->height); - builder.addAttachment(tex.view); + builder.setSize(w, h); + builder.addAttachment(view); framebuffer = builder.create(GetVulkanFrameBuffer()->device); } @@ -410,6 +475,12 @@ VkPostprocess::TextureImage VkPostprocess::GetTexture(const PPTextureType &type, tex.layout = &fb->GetBuffers()->SceneDepthStencilLayout; } #endif + else if (type == PPTextureType::SwapChain) + { + tex.image = nullptr; + tex.view = nullptr; + tex.layout = nullptr; + } else { I_FatalError("VkPostprocess::GetTexture not implemented yet for this texture type"); @@ -443,6 +514,9 @@ void VkPostprocess::NextEye(int eyeCount) VkPPRenderPassSetup::VkPPRenderPassSetup(const VkPPRenderPassKey &key) { CreateDescriptorLayout(key); + CreatePipelineLayout(key); + CreateRenderPass(key); + CreatePipeline(key); } void VkPPRenderPassSetup::CreateDescriptorLayout(const VkPPRenderPassKey &key) diff --git a/src/rendering/vulkan/renderer/vk_postprocess.h b/src/rendering/vulkan/renderer/vk_postprocess.h index b081326b4..75f4645a5 100644 --- a/src/rendering/vulkan/renderer/vk_postprocess.h +++ b/src/rendering/vulkan/renderer/vk_postprocess.h @@ -43,6 +43,8 @@ public: void BlurScene(float gameinfobluramount); void ClearTonemapPalette(); + void DrawPresentTexture(const IntRect &box, bool applyGamma, bool clearBorders); + private: void UpdateEffectTextures(); void CompileEffectShaders(); @@ -98,7 +100,7 @@ public: std::unique_ptr PipelineLayout; std::unique_ptr RenderPass; std::unique_ptr Pipeline; - std::map> Framebuffers; + std::map> Framebuffers; private: void CreateDescriptorLayout(const VkPPRenderPassKey &key); diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index c1a590408..96496d7d6 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -156,7 +156,8 @@ void VulkanFrameBuffer::Update() mRenderState->EndRenderPass(); - //DrawPresentTexture(mOutputLetterbox, true); + mPostprocess->DrawPresentTexture(mOutputLetterbox, true, true); +#if 0 { auto sceneColor = mScreenBuffers->SceneColor.get(); @@ -188,6 +189,7 @@ void VulkanFrameBuffer::Update() barrier1.addImage(device->swapChain->swapChainImages[device->presentImageIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_ACCESS_TRANSFER_WRITE_BIT, 0); barrier1.execute(GetDrawCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); } +#endif mDrawCommands->end(); @@ -554,14 +556,26 @@ void VulkanFrameBuffer::UnbindTexUnit(int no) void VulkanFrameBuffer::TextureFilterChanged() { + if (mSamplerManager) + { + // Destroy the texture descriptors as they used the old samplers + for (VkHardwareTexture *cur = VkHardwareTexture::First; cur; cur = cur->Next) + cur->Reset(); + + mSamplerManager->SetTextureFilterMode(); + } } void VulkanFrameBuffer::BlurScene(float amount) { + if (mPostprocess) + mPostprocess->BlurScene(amount); } void VulkanFrameBuffer::UpdatePalette() { + if (mPostprocess) + mPostprocess->ClearTonemapPalette(); } void VulkanFrameBuffer::BeginFrame()