- hook up the present shader

This commit is contained in:
Magnus Norddahl 2019-03-06 22:59:21 +01:00
parent 30756ec112
commit 0679b493ec
7 changed files with 180 additions and 37 deletions

View file

@ -16,6 +16,7 @@ Postprocess::Postprocess()
Managers.Push(new PPColormap()); Managers.Push(new PPColormap());
Managers.Push(new PPTonemap()); Managers.Push(new PPTonemap());
Managers.Push(new PPAmbientOcclusion()); Managers.Push(new PPAmbientOcclusion());
Managers.Push(new PPPresent());
} }
Postprocess::~Postprocess() Postprocess::~Postprocess()
@ -854,3 +855,40 @@ void PPAmbientOcclusion::UpdateSteps()
hw_postprocess.Effects["AmbientOccludeScene"] = steps; 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<void> 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()
{
}

View file

@ -11,7 +11,7 @@ typedef IntRect PPViewport;
enum class PPFilterMode { Nearest, Linear }; enum class PPFilterMode { Nearest, Linear };
enum class PPWrapMode { Clamp, Repeat }; 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 class PPTextureInput
{ {
@ -144,6 +144,12 @@ public:
Output.Texture = ""; Output.Texture = "";
} }
void SetOutputSwapChain()
{
Output.Type = PPTextureType::SwapChain;
Output.Texture = "";
}
void SetNoBlend() void SetNoBlend()
{ {
BlendMode.BlendOp = STYLEOP_Add; BlendMode.BlendOp = STYLEOP_Add;
@ -597,3 +603,39 @@ private:
enum { NumAmbientRandomTextures = 3 }; enum { NumAmbientRandomTextures = 3 };
PPTextureName AmbientRandomTexture[NumAmbientRandomTextures]; 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<UniformFieldDesc> 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;
};

View file

@ -30,7 +30,7 @@
void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program_name) 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.reset(screen->CreateShaderProgram());
mShader->Compile(IShaderProgram::Vertex, "shaders/glsl/screenquadscale.vp", prolog, 330); mShader->Compile(IShaderProgram::Vertex, "shaders/glsl/screenquadscale.vp", prolog, 330);

View file

@ -2,6 +2,7 @@
#define __GL_PRESENTSHADER_H #define __GL_PRESENTSHADER_H
#include "hwrenderer/postprocessing/hw_shaderprogram.h" #include "hwrenderer/postprocessing/hw_shaderprogram.h"
#include "hwrenderer/postprocessing/hw_postprocess.h"
class FPresentShaderBase class FPresentShaderBase
{ {
@ -9,35 +10,7 @@ public:
virtual ~FPresentShaderBase() {} virtual ~FPresentShaderBase() {}
virtual void Bind(IRenderQueue *q) = 0; virtual void Bind(IRenderQueue *q) = 0;
struct UniformBlock ShaderUniforms<PresentUniforms, POSTPROCESS_BINDINGPOINT> Uniforms;
{
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<UniformFieldDesc> 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<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
protected: protected:
virtual void Init(const char * vtx_shader_name, const char * program_name); virtual void Init(const char * vtx_shader_name, const char * program_name);

View file

@ -5,6 +5,7 @@
#include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_builders.h"
#include "vulkan/system/vk_framebuffer.h" #include "vulkan/system/vk_framebuffer.h"
#include "vulkan/system/vk_buffers.h" #include "vulkan/system/vk_buffers.h"
#include "vulkan/system/vk_swapchain.h"
#include "hwrenderer/utility/hw_cvars.h" #include "hwrenderer/utility/hw_cvars.h"
#include "hwrenderer/postprocessing/hw_presentshader.h" #include "hwrenderer/postprocessing/hw_presentshader.h"
#include "hwrenderer/postprocessing/hw_postprocess.h" #include "hwrenderer/postprocessing/hw_postprocess.h"
@ -14,6 +15,8 @@
#include "r_videoscale.h" #include "r_videoscale.h"
#include "w_wad.h" #include "w_wad.h"
EXTERN_CVAR(Int, gl_dither_bpc)
VkPostprocess::VkPostprocess() VkPostprocess::VkPostprocess()
{ {
} }
@ -49,6 +52,53 @@ void VkPostprocess::PostProcessScene(int fixedcm, const std::function<void()> &a
//mCustomPostProcessShaders->Run("scene"); //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<float>(Gamma, 0.1f, 4.f);
uniforms.Contrast = clamp<float>(vid_contrast, 0.1f, 3.f);
uniforms.Brightness = clamp<float>(vid_brightness, -0.8f, 0.8f);
uniforms.Saturation = clamp<float>(vid_saturation, -15.0f, 15.f);
uniforms.GrayFormula = static_cast<int>(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<PPStep> steps;
steps.Push(step);
hw_postprocess.Effects["Present"] = steps;
RenderEffect("Present");
}
void VkPostprocess::AmbientOccludeScene(float m5) void VkPostprocess::AmbientOccludeScene(float m5)
{ {
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
@ -342,7 +392,7 @@ VulkanFramebuffer *VkPostprocess::GetOutput(VkPPRenderPassSetup *passSetup, cons
TextureImage tex = GetTexture(output.Type, output.Texture); 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; 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); 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; *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) if (!framebuffer)
{ {
FramebufferBuilder builder; FramebufferBuilder builder;
builder.setRenderPass(passSetup->RenderPass.get()); builder.setRenderPass(passSetup->RenderPass.get());
builder.setSize(tex.image->width, tex.image->height); builder.setSize(w, h);
builder.addAttachment(tex.view); builder.addAttachment(view);
framebuffer = builder.create(GetVulkanFrameBuffer()->device); framebuffer = builder.create(GetVulkanFrameBuffer()->device);
} }
@ -410,6 +475,12 @@ VkPostprocess::TextureImage VkPostprocess::GetTexture(const PPTextureType &type,
tex.layout = &fb->GetBuffers()->SceneDepthStencilLayout; tex.layout = &fb->GetBuffers()->SceneDepthStencilLayout;
} }
#endif #endif
else if (type == PPTextureType::SwapChain)
{
tex.image = nullptr;
tex.view = nullptr;
tex.layout = nullptr;
}
else else
{ {
I_FatalError("VkPostprocess::GetTexture not implemented yet for this texture type"); 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) VkPPRenderPassSetup::VkPPRenderPassSetup(const VkPPRenderPassKey &key)
{ {
CreateDescriptorLayout(key); CreateDescriptorLayout(key);
CreatePipelineLayout(key);
CreateRenderPass(key);
CreatePipeline(key);
} }
void VkPPRenderPassSetup::CreateDescriptorLayout(const VkPPRenderPassKey &key) void VkPPRenderPassSetup::CreateDescriptorLayout(const VkPPRenderPassKey &key)

View file

@ -43,6 +43,8 @@ public:
void BlurScene(float gameinfobluramount); void BlurScene(float gameinfobluramount);
void ClearTonemapPalette(); void ClearTonemapPalette();
void DrawPresentTexture(const IntRect &box, bool applyGamma, bool clearBorders);
private: private:
void UpdateEffectTextures(); void UpdateEffectTextures();
void CompileEffectShaders(); void CompileEffectShaders();
@ -98,7 +100,7 @@ public:
std::unique_ptr<VulkanPipelineLayout> PipelineLayout; std::unique_ptr<VulkanPipelineLayout> PipelineLayout;
std::unique_ptr<VulkanRenderPass> RenderPass; std::unique_ptr<VulkanRenderPass> RenderPass;
std::unique_ptr<VulkanPipeline> Pipeline; std::unique_ptr<VulkanPipeline> Pipeline;
std::map<VulkanImageView *, std::unique_ptr<VulkanFramebuffer>> Framebuffers; std::map<VkImageView, std::unique_ptr<VulkanFramebuffer>> Framebuffers;
private: private:
void CreateDescriptorLayout(const VkPPRenderPassKey &key); void CreateDescriptorLayout(const VkPPRenderPassKey &key);

View file

@ -156,7 +156,8 @@ void VulkanFrameBuffer::Update()
mRenderState->EndRenderPass(); mRenderState->EndRenderPass();
//DrawPresentTexture(mOutputLetterbox, true); mPostprocess->DrawPresentTexture(mOutputLetterbox, true, true);
#if 0
{ {
auto sceneColor = mScreenBuffers->SceneColor.get(); 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.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); barrier1.execute(GetDrawCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
} }
#endif
mDrawCommands->end(); mDrawCommands->end();
@ -554,14 +556,26 @@ void VulkanFrameBuffer::UnbindTexUnit(int no)
void VulkanFrameBuffer::TextureFilterChanged() 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) void VulkanFrameBuffer::BlurScene(float amount)
{ {
if (mPostprocess)
mPostprocess->BlurScene(amount);
} }
void VulkanFrameBuffer::UpdatePalette() void VulkanFrameBuffer::UpdatePalette()
{ {
if (mPostprocess)
mPostprocess->ClearTonemapPalette();
} }
void VulkanFrameBuffer::BeginFrame() void VulkanFrameBuffer::BeginFrame()