From db6a4781c8a0483f93c9de65ad23f785e34bf579 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 12 Mar 2019 16:17:26 +0100 Subject: [PATCH] - clip scissors (tired of my computer blue screening - thanks NVidia!) - wrap viewport --- .../vulkan/renderer/vk_postprocess.cpp | 25 ++++++++++++++----- .../vulkan/renderer/vk_postprocess.h | 4 +-- .../vulkan/renderer/vk_renderstate.cpp | 24 +++++++++++++++++- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/rendering/vulkan/renderer/vk_postprocess.cpp b/src/rendering/vulkan/renderer/vk_postprocess.cpp index 7b4d054a3..3823fa2bc 100644 --- a/src/rendering/vulkan/renderer/vk_postprocess.cpp +++ b/src/rendering/vulkan/renderer/vk_postprocess.cpp @@ -401,10 +401,11 @@ void VkPostprocess::RenderEffect(const FString &name) if (!passSetup) passSetup.reset(new VkPPRenderPassSetup(key)); + int framebufferHeight = 0; VulkanDescriptorSet *input = GetInput(passSetup.get(), step.Textures); - VulkanFramebuffer *output = GetOutput(passSetup.get(), step.Output); + VulkanFramebuffer *output = GetOutput(passSetup.get(), step.Output, framebufferHeight); - RenderScreenQuad(passSetup.get(), input, output, 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, 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) @@ -414,7 +415,7 @@ void VkPostprocess::RenderEffect(const FString &name) } } -void VkPostprocess::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize) +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) { auto fb = GetVulkanFrameBuffer(); auto cmdbuffer = fb->GetDrawCommands(); @@ -427,7 +428,7 @@ void VkPostprocess::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescr VkViewport viewport = { }; viewport.x = x; - viewport.y = y; + viewport.y = framebufferHeight - y - height; viewport.width = width; viewport.height = height; viewport.minDepth = 0.0f; @@ -435,10 +436,21 @@ void VkPostprocess::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescr VkRect2D scissor = { }; scissor.offset.x = x; - scissor.offset.y = y; + scissor.offset.y = framebufferHeight - y - height; scissor.extent.width = width; scissor.extent.height = height; + 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; + } + VkBuffer vertexBuffers[] = { static_cast(screen->mVertexData->GetBufferObjects().first)->mBuffer->buffer }; VkDeviceSize offsets[] = { 0 }; @@ -480,7 +492,7 @@ VulkanDescriptorSet *VkPostprocess::GetInput(VkPPRenderPassSetup *passSetup, con return mFrameDescriptorSets.back().get(); } -VulkanFramebuffer *VkPostprocess::GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output) +VulkanFramebuffer *VkPostprocess::GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, int &framebufferHeight) { auto fb = GetVulkanFrameBuffer(); @@ -516,6 +528,7 @@ VulkanFramebuffer *VkPostprocess::GetOutput(VkPPRenderPassSetup *passSetup, cons framebuffer->SetDebugName(tex.debugname); } + framebufferHeight = h; return framebuffer.get(); } diff --git a/src/rendering/vulkan/renderer/vk_postprocess.h b/src/rendering/vulkan/renderer/vk_postprocess.h index cf7cdc86e..e24b4a689 100644 --- a/src/rendering/vulkan/renderer/vk_postprocess.h +++ b/src/rendering/vulkan/renderer/vk_postprocess.h @@ -69,10 +69,10 @@ private: 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 x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize); + void RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize); VulkanDescriptorSet *GetInput(VkPPRenderPassSetup *passSetup, const TArray &textures); - VulkanFramebuffer *GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output); + VulkanFramebuffer *GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, int &framebufferHeight); VulkanSampler *GetSampler(PPFilterMode filter, PPWrapMode wrap); struct TextureImage diff --git a/src/rendering/vulkan/renderer/vk_renderstate.cpp b/src/rendering/vulkan/renderer/vk_renderstate.cpp index edaca5e2d..ae47bd641 100644 --- a/src/rendering/vulkan/renderer/vk_renderstate.cpp +++ b/src/rendering/vulkan/renderer/vk_renderstate.cpp @@ -139,9 +139,20 @@ void VkRenderState::Clear(int targets) if (mScissorWidth >= 0) { rects[0].rect.offset.x = mScissorX; - rects[0].rect.offset.y = mScissorY; + rects[0].rect.offset.y = GetVulkanFrameBuffer()->GetBuffers()->GetHeight() - mScissorY - mViewportHeight; rects[0].rect.extent.width = mScissorWidth; rects[0].rect.extent.height = mScissorHeight; + + if (rects[0].rect.offset.x < 0) + { + rects[0].rect.extent.height += rects[0].rect.offset.x; + rects[0].rect.offset.x = 0; + } + if (rects[0].rect.offset.y < 0) + { + rects[0].rect.extent.height += rects[0].rect.offset.y; + rects[0].rect.offset.y = 0; + } } else { @@ -320,6 +331,17 @@ void VkRenderState::ApplyScissor() scissor.offset.y = buffers->GetHeight() - mScissorY - mViewportHeight; scissor.extent.width = mScissorWidth; scissor.extent.height = mScissorHeight; + + 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; + } } else {