mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- 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
This commit is contained in:
parent
0620041228
commit
dca0b75038
14 changed files with 74 additions and 165 deletions
|
@ -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->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->Scale = { screen->mScreenViewport.width / (float)mBuffers->GetWidth(), screen->mScreenViewport.height / (float)mBuffers->GetHeight() };
|
||||||
|
mPresentShader->Uniforms->Offset = { 0.0f, 0.0f };
|
||||||
mPresentShader->Uniforms.Set();
|
mPresentShader->Uniforms.Set();
|
||||||
RenderScreenQuad();
|
RenderScreenQuad();
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,6 +173,7 @@ void FGLRenderer::prepareInterleavedPresent(FPresentShaderBase& shader)
|
||||||
screen->mScreenViewport.width / (float)mBuffers->GetWidth(),
|
screen->mScreenViewport.width / (float)mBuffers->GetWidth(),
|
||||||
screen->mScreenViewport.height / (float)mBuffers->GetHeight()
|
screen->mScreenViewport.height / (float)mBuffers->GetHeight()
|
||||||
};
|
};
|
||||||
|
shader.Uniforms->Offset = { 0.0f, 0.0f };
|
||||||
shader.Uniforms.Set();
|
shader.Uniforms.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -613,8 +613,9 @@ struct PresentUniforms
|
||||||
int GrayFormula;
|
int GrayFormula;
|
||||||
int WindowPositionParity; // top-of-window might not be top-of-screen
|
int WindowPositionParity; // top-of-window might not be top-of-screen
|
||||||
FVector2 Scale;
|
FVector2 Scale;
|
||||||
|
FVector2 Offset;
|
||||||
float ColorScale;
|
float ColorScale;
|
||||||
float Padding1, Padding2, Padding3;
|
float Padding;
|
||||||
|
|
||||||
static std::vector<UniformFieldDesc> Desc()
|
static std::vector<UniformFieldDesc> Desc()
|
||||||
{
|
{
|
||||||
|
@ -627,6 +628,7 @@ struct PresentUniforms
|
||||||
{ "GrayFormula", UniformType::Int, offsetof(PresentUniforms, GrayFormula) },
|
{ "GrayFormula", UniformType::Int, offsetof(PresentUniforms, GrayFormula) },
|
||||||
{ "WindowPositionParity", UniformType::Int, offsetof(PresentUniforms, WindowPositionParity) },
|
{ "WindowPositionParity", UniformType::Int, offsetof(PresentUniforms, WindowPositionParity) },
|
||||||
{ "UVScale", UniformType::Vec2, offsetof(PresentUniforms, Scale) },
|
{ "UVScale", UniformType::Vec2, offsetof(PresentUniforms, Scale) },
|
||||||
|
{ "UVOffset", UniformType::Vec2, offsetof(PresentUniforms, Offset) },
|
||||||
{ "ColorScale", UniformType::Float, offsetof(PresentUniforms, ColorScale) },
|
{ "ColorScale", UniformType::Float, offsetof(PresentUniforms, ColorScale) },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,15 +43,6 @@ void VkPostprocess::PostProcessScene(int fixedcm, const std::function<void()> &a
|
||||||
auto fb = GetVulkanFrameBuffer();
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
|
||||||
hw_postprocess.fixedcm = fixedcm;
|
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");
|
RenderEffect("UpdateCameraExposure");
|
||||||
//mCustomPostProcessShaders->Run("beforebloom");
|
//mCustomPostProcessShaders->Run("beforebloom");
|
||||||
|
@ -133,12 +124,6 @@ void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool
|
||||||
{
|
{
|
||||||
auto fb = GetVulkanFrameBuffer();
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
|
||||||
hw_postprocess.DeclareShaders();
|
|
||||||
hw_postprocess.UpdateTextures();
|
|
||||||
hw_postprocess.UpdateSteps();
|
|
||||||
CompileEffectShaders();
|
|
||||||
UpdateEffectTextures();
|
|
||||||
|
|
||||||
PresentUniforms uniforms;
|
PresentUniforms uniforms;
|
||||||
if (!applyGamma /*|| framebuffer->IsHWGammaActive()*/)
|
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.GrayFormula = static_cast<int>(gl_satformula);
|
||||||
}
|
}
|
||||||
uniforms.ColorScale = (gl_dither_bpc == -1) ? 255.0f : (float)((1 << gl_dither_bpc) - 1);
|
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;
|
PPStep step;
|
||||||
step.ShaderName = "Present";
|
step.ShaderName = "Present";
|
||||||
|
@ -177,36 +163,15 @@ void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool
|
||||||
|
|
||||||
void VkPostprocess::AmbientOccludeScene(float m5)
|
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.m5 = m5;
|
||||||
|
|
||||||
hw_postprocess.DeclareShaders();
|
|
||||||
hw_postprocess.UpdateTextures();
|
|
||||||
hw_postprocess.UpdateSteps();
|
|
||||||
|
|
||||||
CompileEffectShaders();
|
|
||||||
UpdateEffectTextures();
|
|
||||||
|
|
||||||
RenderEffect("AmbientOccludeScene");
|
RenderEffect("AmbientOccludeScene");
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkPostprocess::BlurScene(float gameinfobluramount)
|
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.gameinfobluramount = gameinfobluramount;
|
||||||
|
|
||||||
hw_postprocess.DeclareShaders();
|
|
||||||
hw_postprocess.UpdateTextures();
|
|
||||||
hw_postprocess.UpdateSteps();
|
|
||||||
|
|
||||||
CompileEffectShaders();
|
|
||||||
UpdateEffectTextures();
|
|
||||||
|
|
||||||
auto vrmode = VRMode::GetVRMode(true);
|
auto vrmode = VRMode::GetVRMode(true);
|
||||||
int eyeCount = vrmode->mEyeCount;
|
int eyeCount = vrmode->mEyeCount;
|
||||||
for (int i = 0; i < eyeCount; ++i)
|
for (int i = 0; i < eyeCount; ++i)
|
||||||
|
@ -233,6 +198,17 @@ void VkPostprocess::BeginFrame()
|
||||||
mDescriptorPool = builder.create(GetVulkanFrameBuffer()->device);
|
mDescriptorPool = builder.create(GetVulkanFrameBuffer()->device);
|
||||||
mDescriptorPool->SetDebugName("VkPostprocess.mDescriptorPool");
|
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()
|
void VkPostprocess::RenderBuffersReset()
|
||||||
|
@ -401,11 +377,11 @@ void VkPostprocess::RenderEffect(const FString &name)
|
||||||
if (!passSetup)
|
if (!passSetup)
|
||||||
passSetup.reset(new VkPPRenderPassSetup(key));
|
passSetup.reset(new VkPPRenderPassSetup(key));
|
||||||
|
|
||||||
int framebufferHeight = 0;
|
int framebufferWidth = 0, framebufferHeight = 0;
|
||||||
VulkanDescriptorSet *input = GetInput(passSetup.get(), step.Textures);
|
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
|
// Advance to next PP texture if our output was sent there
|
||||||
if (step.Output.Type == PPTextureType::NextPipelineTexture)
|
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 fb = GetVulkanFrameBuffer();
|
||||||
auto cmdbuffer = fb->GetDrawCommands();
|
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 = { };
|
VkViewport viewport = { };
|
||||||
viewport.x = x;
|
viewport.x = x;
|
||||||
viewport.y = framebufferHeight - y - height;
|
viewport.y = y;
|
||||||
viewport.width = width;
|
viewport.width = width;
|
||||||
viewport.height = height;
|
viewport.height = height;
|
||||||
viewport.minDepth = 0.0f;
|
viewport.minDepth = 0.0f;
|
||||||
viewport.maxDepth = 1.0f;
|
viewport.maxDepth = 1.0f;
|
||||||
|
|
||||||
VkRect2D scissor = { };
|
VkRect2D scissor = { };
|
||||||
scissor.offset.x = x;
|
scissor.offset.x = 0;
|
||||||
scissor.offset.y = framebufferHeight - y - height;
|
scissor.offset.y = 0;
|
||||||
scissor.extent.width = width;
|
scissor.extent.width = framebufferWidth;
|
||||||
scissor.extent.height = height;
|
scissor.extent.height = framebufferHeight;
|
||||||
|
|
||||||
if (scissor.offset.x < 0)
|
RenderPassBegin beginInfo;
|
||||||
{
|
beginInfo.setRenderPass(passSetup->RenderPass.get());
|
||||||
scissor.extent.height += scissor.offset.x;
|
beginInfo.setRenderArea(0, 0, framebufferWidth, framebufferHeight);
|
||||||
scissor.offset.x = 0;
|
beginInfo.setFramebuffer(framebuffer);
|
||||||
}
|
beginInfo.addClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
if (scissor.offset.y < 0)
|
|
||||||
{
|
|
||||||
scissor.extent.height += scissor.offset.y;
|
|
||||||
scissor.offset.y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkBuffer vertexBuffers[] = { static_cast<VKVertexBuffer*>(screen->mVertexData->GetBufferObjects().first)->mBuffer->buffer };
|
VkBuffer vertexBuffers[] = { static_cast<VKVertexBuffer*>(screen->mVertexData->GetBufferObjects().first)->mBuffer->buffer };
|
||||||
VkDeviceSize offsets[] = { 0 };
|
VkDeviceSize offsets[] = { 0 };
|
||||||
|
@ -492,7 +457,7 @@ VulkanDescriptorSet *VkPostprocess::GetInput(VkPPRenderPassSetup *passSetup, con
|
||||||
return mFrameDescriptorSets.back().get();
|
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();
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
|
||||||
|
@ -528,6 +493,7 @@ VulkanFramebuffer *VkPostprocess::GetOutput(VkPPRenderPassSetup *passSetup, cons
|
||||||
framebuffer->SetDebugName(tex.debugname);
|
framebuffer->SetDebugName(tex.debugname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
framebufferWidth = w;
|
||||||
framebufferHeight = h;
|
framebufferHeight = h;
|
||||||
return framebuffer.get();
|
return framebuffer.get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,10 +69,10 @@ private:
|
||||||
FString LoadShaderCode(const FString &lumpname, const FString &defines, int version);
|
FString LoadShaderCode(const FString &lumpname, const FString &defines, int version);
|
||||||
void RenderEffect(const FString &name);
|
void RenderEffect(const FString &name);
|
||||||
void NextEye(int eyeCount);
|
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);
|
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);
|
VulkanSampler *GetSampler(PPFilterMode filter, PPWrapMode wrap);
|
||||||
|
|
||||||
struct TextureImage
|
struct TextureImage
|
||||||
|
|
|
@ -52,7 +52,7 @@ void VkRenderPassManager::BeginRenderPass(const VkRenderPassKey &key, VulkanComm
|
||||||
builder.setRenderPass(passSetup->RenderPass.get());
|
builder.setRenderPass(passSetup->RenderPass.get());
|
||||||
builder.setSize(mRenderTargetWidth, mRenderTargetHeight);
|
builder.setSize(mRenderTargetWidth, mRenderTargetHeight);
|
||||||
builder.addAttachment(mRenderTargetView->view);
|
builder.addAttachment(mRenderTargetView->view);
|
||||||
if (key.DepthTest || key.DepthWrite || key.StencilTest)
|
if (key.UsesDepthStencil())
|
||||||
builder.addAttachment(buffers->SceneDepthStencilView.get());
|
builder.addAttachment(buffers->SceneDepthStencilView.get());
|
||||||
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
|
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
|
||||||
framebuffer->SetDebugName("VkRenderPassSetup.Framebuffer");
|
framebuffer->SetDebugName("VkRenderPassSetup.Framebuffer");
|
||||||
|
@ -62,6 +62,8 @@ void VkRenderPassManager::BeginRenderPass(const VkRenderPassKey &key, VulkanComm
|
||||||
beginInfo.setRenderPass(passSetup->RenderPass.get());
|
beginInfo.setRenderPass(passSetup->RenderPass.get());
|
||||||
beginInfo.setRenderArea(0, 0, buffers->GetWidth(), buffers->GetHeight());
|
beginInfo.setRenderArea(0, 0, buffers->GetWidth(), buffers->GetHeight());
|
||||||
beginInfo.setFramebuffer(framebuffer.get());
|
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->beginRenderPass(beginInfo);
|
||||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get());
|
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get());
|
||||||
}
|
}
|
||||||
|
@ -182,19 +184,19 @@ void VkRenderPassSetup::CreateRenderPass(const VkRenderPassKey &key)
|
||||||
RenderPassBuilder builder;
|
RenderPassBuilder builder;
|
||||||
builder.addAttachment(
|
builder.addAttachment(
|
||||||
VK_FORMAT_R16G16B16A16_SFLOAT, (VkSampleCountFlagBits)key.Samples,
|
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);
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
if (key.DepthTest || key.DepthWrite || key.StencilTest)
|
if (key.UsesDepthStencil())
|
||||||
{
|
{
|
||||||
builder.addDepthStencilAttachment(
|
builder.addDepthStencilAttachment(
|
||||||
buffers->SceneDepthStencilFormat, buffers->GetSceneSamples(),
|
buffers->SceneDepthStencilFormat, buffers->GetSceneSamples(),
|
||||||
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,
|
||||||
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);
|
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
}
|
}
|
||||||
builder.addSubpass();
|
builder.addSubpass();
|
||||||
builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
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.addSubpassDepthStencilAttachmentRef(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
builder.addExternalSubpassDependency(
|
builder.addExternalSubpassDependency(
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "vulkan/system/vk_objects.h"
|
#include "vulkan/system/vk_objects.h"
|
||||||
#include "r_data/renderstyle.h"
|
#include "r_data/renderstyle.h"
|
||||||
#include "hwrenderer/data/buffers.h"
|
#include "hwrenderer/data/buffers.h"
|
||||||
|
#include "hwrenderer/scene/hw_renderstate.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -28,6 +29,9 @@ public:
|
||||||
int VertexFormat;
|
int VertexFormat;
|
||||||
int DrawType;
|
int DrawType;
|
||||||
int Samples;
|
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; }
|
||||||
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; }
|
||||||
|
|
|
@ -118,74 +118,8 @@ void VkRenderState::EnableClipDistance(int num, bool state)
|
||||||
|
|
||||||
void VkRenderState::Clear(int targets)
|
void VkRenderState::Clear(int targets)
|
||||||
{
|
{
|
||||||
// We need an active render pass, and it must have a depth attachment..
|
mClearTargets = targets;
|
||||||
bool lastDepthTest = mDepthTest;
|
EndRenderPass();
|
||||||
bool lastDepthWrite = mDepthWrite;
|
|
||||||
if (targets & (CT_Depth | CT_Stencil))
|
|
||||||
{
|
|
||||||
mDepthTest = true;
|
|
||||||
mDepthWrite = true;
|
|
||||||
}
|
|
||||||
Apply(DT_TriangleStrip);
|
|
||||||
mDepthTest = lastDepthTest;
|
|
||||||
mDepthWrite = lastDepthWrite;
|
|
||||||
|
|
||||||
VkClearAttachment attachments[2] = { };
|
|
||||||
VkClearRect rects[2] = { };
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
rects[i].layerCount = 1;
|
|
||||||
if (mScissorWidth >= 0)
|
|
||||||
{
|
|
||||||
rects[0].rect.offset.x = mScissorX;
|
|
||||||
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
|
|
||||||
{
|
|
||||||
rects[0].rect.offset.x = 0;
|
|
||||||
rects[0].rect.offset.y = 0;
|
|
||||||
rects[0].rect.extent.width = SCREENWIDTH;
|
|
||||||
rects[0].rect.extent.height = SCREENHEIGHT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targets & CT_Depth)
|
|
||||||
{
|
|
||||||
attachments[1].aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
||||||
attachments[1].clearValue.depthStencil.depth = 1.0f;
|
|
||||||
}
|
|
||||||
if (targets & CT_Stencil)
|
|
||||||
{
|
|
||||||
attachments[1].aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
|
||||||
attachments[1].clearValue.depthStencil.stencil = 0;
|
|
||||||
}
|
|
||||||
if (targets & CT_Color)
|
|
||||||
{
|
|
||||||
attachments[0].aspectMask |= VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
attachments[0].clearValue.color.float32[i] = screen->mSceneClearColor[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((targets & CT_Color) && (targets & CT_Stencil) && (targets & CT_Depth))
|
|
||||||
mCommandBuffer->clearAttachments(2, attachments, 2, rects);
|
|
||||||
else if (targets & (CT_Stencil | CT_Depth))
|
|
||||||
mCommandBuffer->clearAttachments(1, attachments + 1, 1, rects + 1);
|
|
||||||
else if (targets & CT_Color)
|
|
||||||
mCommandBuffer->clearAttachments(1, attachments, 1, rects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkRenderState::EnableStencil(bool on)
|
void VkRenderState::EnableStencil(bool on)
|
||||||
|
@ -259,6 +193,7 @@ void VkRenderState::ApplyRenderPass(int dt)
|
||||||
|
|
||||||
// Find a render pass that matches our state
|
// Find a render pass that matches our state
|
||||||
VkRenderPassKey passKey;
|
VkRenderPassKey passKey;
|
||||||
|
passKey.ClearTargets = mRenderPassKey.ClearTargets | mClearTargets;
|
||||||
passKey.DrawType = dt;
|
passKey.DrawType = dt;
|
||||||
passKey.VertexFormat = static_cast<VKVertexBuffer*>(mVertexBuffer)->VertexFormat;
|
passKey.VertexFormat = static_cast<VKVertexBuffer*>(mVertexBuffer)->VertexFormat;
|
||||||
passKey.RenderStyle = mRenderStyle;
|
passKey.RenderStyle = mRenderStyle;
|
||||||
|
@ -305,8 +240,10 @@ void VkRenderState::ApplyRenderPass(int dt)
|
||||||
|
|
||||||
if (changingRenderPass)
|
if (changingRenderPass)
|
||||||
{
|
{
|
||||||
|
passKey.ClearTargets = mClearTargets;
|
||||||
passManager->BeginRenderPass(passKey, mCommandBuffer);
|
passManager->BeginRenderPass(passKey, mCommandBuffer);
|
||||||
mRenderPassKey = passKey;
|
mRenderPassKey = passKey;
|
||||||
|
mClearTargets = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,30 +262,26 @@ void VkRenderState::ApplyScissor()
|
||||||
{
|
{
|
||||||
VkRect2D scissor;
|
VkRect2D scissor;
|
||||||
auto buffers = GetVulkanFrameBuffer()->GetBuffers();
|
auto buffers = GetVulkanFrameBuffer()->GetBuffers();
|
||||||
|
int targetWidth = buffers->GetWidth();
|
||||||
|
int targetHeight = buffers->GetHeight();
|
||||||
if (mScissorWidth >= 0)
|
if (mScissorWidth >= 0)
|
||||||
{
|
{
|
||||||
scissor.offset.x = mScissorX;
|
int x0 = clamp(mScissorX, 0, targetWidth);
|
||||||
scissor.offset.y = buffers->GetHeight() - mScissorY - mViewportHeight;
|
int y0 = clamp(mScissorY, 0, targetHeight);
|
||||||
scissor.extent.width = mScissorWidth;
|
int x1 = clamp(mScissorX + mScissorWidth, 0, targetWidth);
|
||||||
scissor.extent.height = mScissorHeight;
|
int y1 = clamp(mScissorY + mScissorHeight, 0, targetHeight);
|
||||||
|
|
||||||
if (scissor.offset.x < 0)
|
scissor.offset.x = x0;
|
||||||
{
|
scissor.offset.y = y0;
|
||||||
scissor.extent.height += scissor.offset.x;
|
scissor.extent.width = x1 - x0;
|
||||||
scissor.offset.x = 0;
|
scissor.extent.height = y1 - y0;
|
||||||
}
|
|
||||||
if (scissor.offset.y < 0)
|
|
||||||
{
|
|
||||||
scissor.extent.height += scissor.offset.y;
|
|
||||||
scissor.offset.y = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scissor.offset.x = 0;
|
scissor.offset.x = 0;
|
||||||
scissor.offset.y = 0;
|
scissor.offset.y = 0;
|
||||||
scissor.extent.width = buffers->GetWidth();
|
scissor.extent.width = targetWidth;
|
||||||
scissor.extent.height = buffers->GetHeight();
|
scissor.extent.height = targetHeight;
|
||||||
}
|
}
|
||||||
mCommandBuffer->setScissor(0, 1, &scissor);
|
mCommandBuffer->setScissor(0, 1, &scissor);
|
||||||
mScissorChanged = false;
|
mScissorChanged = false;
|
||||||
|
@ -364,7 +297,7 @@ void VkRenderState::ApplyViewport()
|
||||||
if (mViewportWidth >= 0)
|
if (mViewportWidth >= 0)
|
||||||
{
|
{
|
||||||
viewport.x = (float)mViewportX;
|
viewport.x = (float)mViewportX;
|
||||||
viewport.y = (float)buffers->GetHeight() - mViewportY - mViewportHeight;
|
viewport.y = (float)mViewportY;
|
||||||
viewport.width = (float)mViewportWidth;
|
viewport.width = (float)mViewportWidth;
|
||||||
viewport.height = (float)mViewportHeight;
|
viewport.height = (float)mViewportHeight;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ protected:
|
||||||
bool mDepthClamp = true;
|
bool mDepthClamp = true;
|
||||||
VulkanCommandBuffer *mCommandBuffer = nullptr;
|
VulkanCommandBuffer *mCommandBuffer = nullptr;
|
||||||
VkRenderPassKey mRenderPassKey = {};
|
VkRenderPassKey mRenderPassKey = {};
|
||||||
|
int mClearTargets = 0;
|
||||||
bool mNeedApply = true;
|
bool mNeedApply = true;
|
||||||
|
|
||||||
int mScissorX = 0, mScissorY = 0, mScissorWidth = -1, mScissorHeight = -1;
|
int mScissorX = 0, mScissorY = 0, mScissorWidth = -1, mScissorHeight = -1;
|
||||||
|
|
|
@ -97,7 +97,6 @@ void main()
|
||||||
|
|
||||||
#ifdef VULKAN_COORDINATE_SYSTEM
|
#ifdef VULKAN_COORDINATE_SYSTEM
|
||||||
gl_Position.z = (gl_Position.z + gl_Position.w) / 2.0;
|
gl_Position.z = (gl_Position.z + gl_Position.w) / 2.0;
|
||||||
gl_Position.y = -gl_Position.y;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (uClipHeightDirection != 0.0) // clip planes used for reflective flats
|
if (uClipHeightDirection != 0.0) // clip planes used for reflective flats
|
||||||
|
|
|
@ -29,5 +29,5 @@ vec4 Dither(vec4 c)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
FragColor = Dither(ApplyGamma(texture(InputTexture, TexCoord * UVScale)));
|
FragColor = Dither(ApplyGamma(texture(InputTexture, UVOffset + TexCoord * UVScale)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,11 @@ void main()
|
||||||
) % 2 == 0;
|
) % 2 == 0;
|
||||||
vec4 inputColor;
|
vec4 inputColor;
|
||||||
if (isLeftEye) {
|
if (isLeftEye) {
|
||||||
inputColor = texture(LeftEyeTexture, TexCoord * UVScale);
|
inputColor = texture(LeftEyeTexture, UVOffset + TexCoord * UVScale);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// inputColor = vec4(0, 1, 0, 1);
|
// inputColor = vec4(0, 1, 0, 1);
|
||||||
inputColor = texture(RightEyeTexture, TexCoord * UVScale);
|
inputColor = texture(RightEyeTexture, UVOffset + TexCoord * UVScale);
|
||||||
}
|
}
|
||||||
FragColor = ApplyGamma(inputColor);
|
FragColor = ApplyGamma(inputColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,11 @@ void main()
|
||||||
) % 2 == 0;
|
) % 2 == 0;
|
||||||
vec4 inputColor;
|
vec4 inputColor;
|
||||||
if (isLeftEye) {
|
if (isLeftEye) {
|
||||||
inputColor = texture(LeftEyeTexture, TexCoord * UVScale);
|
inputColor = texture(LeftEyeTexture, UVOffset + TexCoord * UVScale);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// inputColor = vec4(0, 1, 0, 1);
|
// inputColor = vec4(0, 1, 0, 1);
|
||||||
inputColor = texture(RightEyeTexture, TexCoord * UVScale);
|
inputColor = texture(RightEyeTexture, UVOffset + TexCoord * UVScale);
|
||||||
}
|
}
|
||||||
FragColor = ApplyGamma(inputColor);
|
FragColor = ApplyGamma(inputColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,11 @@ void main()
|
||||||
) % 2 == 0;
|
) % 2 == 0;
|
||||||
vec4 inputColor;
|
vec4 inputColor;
|
||||||
if (isLeftEye) {
|
if (isLeftEye) {
|
||||||
inputColor = texture(LeftEyeTexture, TexCoord * UVScale);
|
inputColor = texture(LeftEyeTexture, UVOffset + TexCoord * UVScale);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// inputColor = vec4(0, 1, 0, 1);
|
// inputColor = vec4(0, 1, 0, 1);
|
||||||
inputColor = texture(RightEyeTexture, TexCoord * UVScale);
|
inputColor = texture(RightEyeTexture, UVOffset + TexCoord * UVScale);
|
||||||
}
|
}
|
||||||
FragColor = ApplyGamma(inputColor);
|
FragColor = ApplyGamma(inputColor);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue