Skip to content
Permalink
Browse files

- change the images to be upside down until presentation to increase …

…compatibility with shaders designed for OpenGL

- clamp scissors fully to avoid NVidia's awful drivers locking up the entire system if they end up out of bounds
- perform buffer clears as part of the render pass. this puts some restrictions on how FRenderState.Clear can be used
- add an offset uniform to the present shaders so the vulkan target can flip the image during presentation
  • Loading branch information...
dpjudas committed Mar 12, 2019
1 parent 0620041 commit dca0b750388dabb125f009aac2b82e4185dba4ea
@@ -248,6 +248,7 @@ void FGLRenderer::DrawPresentTexture(const IntRect &box, bool applyGamma)
mPresentShader->Uniforms->ColorScale = (gl_dither_bpc == -1) ? 255.0f : (float)((1 << gl_dither_bpc) - 1);
}
mPresentShader->Uniforms->Scale = { screen->mScreenViewport.width / (float)mBuffers->GetWidth(), screen->mScreenViewport.height / (float)mBuffers->GetHeight() };
mPresentShader->Uniforms->Offset = { 0.0f, 0.0f };
mPresentShader->Uniforms.Set();
RenderScreenQuad();
}
@@ -173,6 +173,7 @@ void FGLRenderer::prepareInterleavedPresent(FPresentShaderBase& shader)
screen->mScreenViewport.width / (float)mBuffers->GetWidth(),
screen->mScreenViewport.height / (float)mBuffers->GetHeight()
};
shader.Uniforms->Offset = { 0.0f, 0.0f };
shader.Uniforms.Set();
}

@@ -613,8 +613,9 @@ struct PresentUniforms
int GrayFormula;
int WindowPositionParity; // top-of-window might not be top-of-screen
FVector2 Scale;
FVector2 Offset;
float ColorScale;
float Padding1, Padding2, Padding3;
float Padding;

static std::vector<UniformFieldDesc> Desc()
{
@@ -627,6 +628,7 @@ struct PresentUniforms
{ "GrayFormula", UniformType::Int, offsetof(PresentUniforms, GrayFormula) },
{ "WindowPositionParity", UniformType::Int, offsetof(PresentUniforms, WindowPositionParity) },
{ "UVScale", UniformType::Vec2, offsetof(PresentUniforms, Scale) },
{ "UVOffset", UniformType::Vec2, offsetof(PresentUniforms, Offset) },
{ "ColorScale", UniformType::Float, offsetof(PresentUniforms, ColorScale) },
};
}
@@ -43,15 +43,6 @@ void VkPostprocess::PostProcessScene(int fixedcm, const std::function<void()> &a
auto fb = GetVulkanFrameBuffer();

hw_postprocess.fixedcm = fixedcm;
hw_postprocess.SceneWidth = fb->GetBuffers()->GetSceneWidth();
hw_postprocess.SceneHeight = fb->GetBuffers()->GetSceneHeight();

hw_postprocess.DeclareShaders();
hw_postprocess.UpdateTextures();
hw_postprocess.UpdateSteps();

CompileEffectShaders();
UpdateEffectTextures();

RenderEffect("UpdateCameraExposure");
//mCustomPostProcessShaders->Run("beforebloom");
@@ -133,12 +124,6 @@ void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool
{
auto fb = GetVulkanFrameBuffer();

hw_postprocess.DeclareShaders();
hw_postprocess.UpdateTextures();
hw_postprocess.UpdateSteps();
CompileEffectShaders();
UpdateEffectTextures();

PresentUniforms uniforms;
if (!applyGamma /*|| framebuffer->IsHWGammaActive()*/)
{
@@ -156,7 +141,8 @@ void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool
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() };
uniforms.Scale = { screen->mScreenViewport.width / (float)fb->GetBuffers()->GetWidth(), -screen->mScreenViewport.height / (float)fb->GetBuffers()->GetHeight() };
uniforms.Offset = { 0.0f, 1.0f };

PPStep step;
step.ShaderName = "Present";
@@ -177,36 +163,15 @@ void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool

void VkPostprocess::AmbientOccludeScene(float m5)
{
auto fb = GetVulkanFrameBuffer();

hw_postprocess.SceneWidth = fb->GetBuffers()->GetSceneWidth();
hw_postprocess.SceneHeight = fb->GetBuffers()->GetSceneHeight();
hw_postprocess.m5 = m5;

hw_postprocess.DeclareShaders();
hw_postprocess.UpdateTextures();
hw_postprocess.UpdateSteps();

CompileEffectShaders();
UpdateEffectTextures();

RenderEffect("AmbientOccludeScene");
}

void VkPostprocess::BlurScene(float gameinfobluramount)
{
auto fb = GetVulkanFrameBuffer();
hw_postprocess.SceneWidth = fb->GetBuffers()->GetSceneWidth();
hw_postprocess.SceneHeight = fb->GetBuffers()->GetSceneHeight();
hw_postprocess.gameinfobluramount = gameinfobluramount;

hw_postprocess.DeclareShaders();
hw_postprocess.UpdateTextures();
hw_postprocess.UpdateSteps();

CompileEffectShaders();
UpdateEffectTextures();

auto vrmode = VRMode::GetVRMode(true);
int eyeCount = vrmode->mEyeCount;
for (int i = 0; i < eyeCount; ++i)
@@ -233,6 +198,17 @@ void VkPostprocess::BeginFrame()
mDescriptorPool = builder.create(GetVulkanFrameBuffer()->device);
mDescriptorPool->SetDebugName("VkPostprocess.mDescriptorPool");
}

auto fb = GetVulkanFrameBuffer();
hw_postprocess.SceneWidth = fb->GetBuffers()->GetSceneWidth();
hw_postprocess.SceneHeight = fb->GetBuffers()->GetSceneHeight();

hw_postprocess.DeclareShaders();
hw_postprocess.UpdateTextures();
hw_postprocess.UpdateSteps();

CompileEffectShaders();
UpdateEffectTextures();
}

void VkPostprocess::RenderBuffersReset()
@@ -401,11 +377,11 @@ void VkPostprocess::RenderEffect(const FString &name)
if (!passSetup)
passSetup.reset(new VkPPRenderPassSetup(key));

int framebufferHeight = 0;
int framebufferWidth = 0, framebufferHeight = 0;
VulkanDescriptorSet *input = GetInput(passSetup.get(), step.Textures);
VulkanFramebuffer *output = GetOutput(passSetup.get(), step.Output, framebufferHeight);
VulkanFramebuffer *output = GetOutput(passSetup.get(), step.Output, framebufferWidth, framebufferHeight);

RenderScreenQuad(passSetup.get(), input, output, framebufferHeight, step.Viewport.left, step.Viewport.top, step.Viewport.width, step.Viewport.height, step.Uniforms.Data.Data(), step.Uniforms.Data.Size());
RenderScreenQuad(passSetup.get(), input, output, framebufferWidth, framebufferHeight, step.Viewport.left, step.Viewport.top, step.Viewport.width, step.Viewport.height, step.Uniforms.Data.Data(), step.Uniforms.Data.Size());

// Advance to next PP texture if our output was sent there
if (step.Output.Type == PPTextureType::NextPipelineTexture)
@@ -415,41 +391,30 @@ void VkPostprocess::RenderEffect(const FString &name)
}
}

void VkPostprocess::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize)
void VkPostprocess::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferWidth, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize)
{
auto fb = GetVulkanFrameBuffer();
auto cmdbuffer = fb->GetDrawCommands();

RenderPassBegin beginInfo;
beginInfo.setRenderPass(passSetup->RenderPass.get());
beginInfo.setRenderArea(x, y, width, height);
beginInfo.setFramebuffer(framebuffer);
beginInfo.addClearColor(0.0f, 0.0f, 0.0f, 1.0f);

VkViewport viewport = { };
viewport.x = x;
viewport.y = framebufferHeight - y - height;
viewport.y = y;
viewport.width = width;
viewport.height = height;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;

VkRect2D scissor = { };
scissor.offset.x = x;
scissor.offset.y = framebufferHeight - y - height;
scissor.extent.width = width;
scissor.extent.height = height;
scissor.offset.x = 0;
scissor.offset.y = 0;
scissor.extent.width = framebufferWidth;
scissor.extent.height = framebufferHeight;

if (scissor.offset.x < 0)
{
scissor.extent.height += scissor.offset.x;
scissor.offset.x = 0;
}
if (scissor.offset.y < 0)
{
scissor.extent.height += scissor.offset.y;
scissor.offset.y = 0;
}
RenderPassBegin beginInfo;
beginInfo.setRenderPass(passSetup->RenderPass.get());
beginInfo.setRenderArea(0, 0, framebufferWidth, framebufferHeight);
beginInfo.setFramebuffer(framebuffer);
beginInfo.addClearColor(0.0f, 0.0f, 0.0f, 1.0f);

VkBuffer vertexBuffers[] = { static_cast<VKVertexBuffer*>(screen->mVertexData->GetBufferObjects().first)->mBuffer->buffer };
VkDeviceSize offsets[] = { 0 };
@@ -492,7 +457,7 @@ VulkanDescriptorSet *VkPostprocess::GetInput(VkPPRenderPassSetup *passSetup, con
return mFrameDescriptorSets.back().get();
}

VulkanFramebuffer *VkPostprocess::GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, int &framebufferHeight)
VulkanFramebuffer *VkPostprocess::GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, int &framebufferWidth, int &framebufferHeight)
{
auto fb = GetVulkanFrameBuffer();

@@ -528,6 +493,7 @@ VulkanFramebuffer *VkPostprocess::GetOutput(VkPPRenderPassSetup *passSetup, cons
framebuffer->SetDebugName(tex.debugname);
}

framebufferWidth = w;
framebufferHeight = h;
return framebuffer.get();
}
@@ -69,10 +69,10 @@ class VkPostprocess
FString LoadShaderCode(const FString &lumpname, const FString &defines, int version);
void RenderEffect(const FString &name);
void NextEye(int eyeCount);
void RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize);
void RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferWidth, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize);

VulkanDescriptorSet *GetInput(VkPPRenderPassSetup *passSetup, const TArray<PPTextureInput> &textures);
VulkanFramebuffer *GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, int &framebufferHeight);
VulkanFramebuffer *GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, int &framebufferWidth, int &framebufferHeight);
VulkanSampler *GetSampler(PPFilterMode filter, PPWrapMode wrap);

struct TextureImage
@@ -52,7 +52,7 @@ void VkRenderPassManager::BeginRenderPass(const VkRenderPassKey &key, VulkanComm
builder.setRenderPass(passSetup->RenderPass.get());
builder.setSize(mRenderTargetWidth, mRenderTargetHeight);
builder.addAttachment(mRenderTargetView->view);
if (key.DepthTest || key.DepthWrite || key.StencilTest)
if (key.UsesDepthStencil())
builder.addAttachment(buffers->SceneDepthStencilView.get());
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
framebuffer->SetDebugName("VkRenderPassSetup.Framebuffer");
@@ -62,6 +62,8 @@ void VkRenderPassManager::BeginRenderPass(const VkRenderPassKey &key, VulkanComm
beginInfo.setRenderPass(passSetup->RenderPass.get());
beginInfo.setRenderArea(0, 0, buffers->GetWidth(), buffers->GetHeight());
beginInfo.setFramebuffer(framebuffer.get());
beginInfo.addClearColor(screen->mSceneClearColor[0], screen->mSceneClearColor[1], screen->mSceneClearColor[2], screen->mSceneClearColor[3]);
beginInfo.addClearDepthStencil(1.0f, 0);
cmdbuffer->beginRenderPass(beginInfo);
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get());
}
@@ -182,19 +184,19 @@ void VkRenderPassSetup::CreateRenderPass(const VkRenderPassKey &key)
RenderPassBuilder builder;
builder.addAttachment(
VK_FORMAT_R16G16B16A16_SFLOAT, (VkSampleCountFlagBits)key.Samples,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
(key.ClearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (key.DepthTest || key.DepthWrite || key.StencilTest)
if (key.UsesDepthStencil())
{
builder.addDepthStencilAttachment(
buffers->SceneDepthStencilFormat, buffers->GetSceneSamples(),
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
(key.ClearTargets & CT_Depth) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
(key.ClearTargets & CT_Stencil) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
}
builder.addSubpass();
builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (key.DepthTest || key.DepthWrite || key.StencilTest)
if (key.UsesDepthStencil())
{
builder.addSubpassDepthStencilAttachmentRef(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
builder.addExternalSubpassDependency(
@@ -4,6 +4,7 @@
#include "vulkan/system/vk_objects.h"
#include "r_data/renderstyle.h"
#include "hwrenderer/data/buffers.h"
#include "hwrenderer/scene/hw_renderstate.h"
#include <string.h>
#include <map>

@@ -28,6 +29,9 @@ class VkRenderPassKey
int VertexFormat;
int DrawType;
int Samples;
int ClearTargets;

bool UsesDepthStencil() const { return DepthTest || DepthWrite || StencilTest || (ClearTargets & (CT_Depth | CT_Stencil)); }

bool operator<(const VkRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkRenderPassKey)) < 0; }
bool operator==(const VkRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkRenderPassKey)) == 0; }
Oops, something went wrong.

0 comments on commit dca0b75

Please sign in to comment.
You can’t perform that action at this time.