mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
- implement shadow maps
This commit is contained in:
parent
836938440c
commit
cce96ca87a
16 changed files with 200 additions and 26 deletions
|
@ -91,6 +91,7 @@ OpenGLFrameBuffer::~OpenGLFrameBuffer()
|
|||
if (mSkyData != nullptr) delete mSkyData;
|
||||
if (mViewpoints != nullptr) delete mViewpoints;
|
||||
if (mLights != nullptr) delete mLights;
|
||||
mShadowMap.Reset();
|
||||
|
||||
if (GLRenderer)
|
||||
{
|
||||
|
|
|
@ -8,7 +8,10 @@ enum
|
|||
{
|
||||
LIGHTBUF_BINDINGPOINT = 1,
|
||||
POSTPROCESS_BINDINGPOINT = 2,
|
||||
VIEWPOINT_BINDINGPOINT = 3
|
||||
VIEWPOINT_BINDINGPOINT = 3,
|
||||
LIGHTNODES_BINDINGPOINT = 4,
|
||||
LIGHTLINES_BINDINGPOINT = 5,
|
||||
LIGHTLIST_BINDINGPOINT = 6
|
||||
};
|
||||
|
||||
enum class UniformType
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
||||
#include "hwrenderer/data/buffers.h"
|
||||
#include "hwrenderer/data/shaderuniforms.h"
|
||||
#include "stats.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "v_video.h"
|
||||
|
@ -188,7 +189,7 @@ void IShadowMap::UploadLights()
|
|||
CollectLights();
|
||||
|
||||
if (mLightList == nullptr)
|
||||
mLightList = screen->CreateDataBuffer(4, true);
|
||||
mLightList = screen->CreateDataBuffer(LIGHTLIST_BINDINGPOINT, true);
|
||||
|
||||
mLightList->SetData(sizeof(float) * mLights.Size(), &mLights[0]);
|
||||
}
|
||||
|
@ -199,11 +200,11 @@ void IShadowMap::UploadAABBTree()
|
|||
if (!ValidateAABBTree(&level))
|
||||
{
|
||||
if (!mNodesBuffer)
|
||||
mNodesBuffer = screen->CreateDataBuffer(2, true);
|
||||
mNodesBuffer = screen->CreateDataBuffer(LIGHTNODES_BINDINGPOINT, true);
|
||||
mNodesBuffer->SetData(mAABBTree->NodesSize(), mAABBTree->Nodes());
|
||||
|
||||
if (!mLinesBuffer)
|
||||
mLinesBuffer = screen->CreateDataBuffer(3, true);
|
||||
mLinesBuffer = screen->CreateDataBuffer(LIGHTLINES_BINDINGPOINT, true);
|
||||
mLinesBuffer->SetData(mAABBTree->LinesSize(), mAABBTree->Lines());
|
||||
}
|
||||
else if (mAABBTree->Update())
|
||||
|
@ -213,10 +214,15 @@ void IShadowMap::UploadAABBTree()
|
|||
}
|
||||
}
|
||||
|
||||
IShadowMap::~IShadowMap()
|
||||
void IShadowMap::Reset()
|
||||
{
|
||||
if (mLightList) delete mLightList;
|
||||
if (mNodesBuffer) delete mNodesBuffer;
|
||||
if (mLinesBuffer) delete mLinesBuffer;
|
||||
delete mLightList; mLightList = nullptr;
|
||||
delete mNodesBuffer; mNodesBuffer = nullptr;
|
||||
delete mLinesBuffer; mLinesBuffer = nullptr;
|
||||
}
|
||||
|
||||
IShadowMap::~IShadowMap()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ public:
|
|||
IShadowMap() { }
|
||||
virtual ~IShadowMap();
|
||||
|
||||
void Reset();
|
||||
|
||||
// Test if a world position is in shadow relative to the specified light and returns false if it is
|
||||
bool ShadowTest(FDynamicLight *light, const DVector3 &pos);
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ Postprocess::Postprocess()
|
|||
Managers.Push(new PPTonemap());
|
||||
Managers.Push(new PPAmbientOcclusion());
|
||||
Managers.Push(new PPPresent());
|
||||
Managers.Push(new PPShadowMap());
|
||||
}
|
||||
|
||||
Postprocess::~Postprocess()
|
||||
|
@ -892,3 +893,32 @@ void PPPresent::UpdateTextures()
|
|||
void PPPresent::UpdateSteps()
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PPShadowMap::DeclareShaders()
|
||||
{
|
||||
hw_postprocess.Shaders["ShadowMap"] = { "shaders/glsl/shadowmap.fp", "", ShadowMapUniforms::Desc() };
|
||||
}
|
||||
|
||||
void PPShadowMap::UpdateTextures()
|
||||
{
|
||||
}
|
||||
|
||||
void PPShadowMap::UpdateSteps()
|
||||
{
|
||||
ShadowMapUniforms uniforms;
|
||||
uniforms.ShadowmapQuality = (float)gl_shadowmap_quality;
|
||||
|
||||
PPStep step;
|
||||
step.ShaderName = "ShadowMap";
|
||||
step.Uniforms.Set(uniforms);
|
||||
step.Viewport = { 0, 0, gl_shadowmap_quality, 1024 };
|
||||
step.SetShadowMapBuffers(true);
|
||||
step.SetOutputShadowMap();
|
||||
step.SetNoBlend();
|
||||
|
||||
TArray<PPStep> steps;
|
||||
steps.Push(step);
|
||||
hw_postprocess.Effects["UpdateShadowMap"] = steps;
|
||||
}
|
||||
|
|
|
@ -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, SwapChain };
|
||||
enum class PPTextureType { CurrentPipelineTexture, NextPipelineTexture, PPTexture, SceneColor, SceneFog, SceneNormal, SceneDepth, SwapChain, ShadowMap };
|
||||
|
||||
class PPTextureInput
|
||||
{
|
||||
|
@ -120,6 +120,11 @@ public:
|
|||
tex.Texture = "";
|
||||
}
|
||||
|
||||
void SetShadowMapBuffers(bool enable)
|
||||
{
|
||||
ShadowMapBuffers = enable;
|
||||
}
|
||||
|
||||
void SetOutputTexture(PPTextureName texture)
|
||||
{
|
||||
Output.Type = PPTextureType::PPTexture;
|
||||
|
@ -150,6 +155,12 @@ public:
|
|||
Output.Texture = "";
|
||||
}
|
||||
|
||||
void SetOutputShadowMap()
|
||||
{
|
||||
Output.Type = PPTextureType::ShadowMap;
|
||||
Output.Texture = "";
|
||||
}
|
||||
|
||||
void SetNoBlend()
|
||||
{
|
||||
BlendMode.BlendOp = STYLEOP_Add;
|
||||
|
@ -180,6 +191,7 @@ public:
|
|||
PPViewport Viewport;
|
||||
PPBlendMode BlendMode;
|
||||
PPOutput Output;
|
||||
bool ShadowMapBuffers = false;
|
||||
};
|
||||
|
||||
enum class PixelFormat
|
||||
|
@ -658,3 +670,11 @@ struct ShadowMapUniforms
|
|||
};
|
||||
}
|
||||
};
|
||||
|
||||
class PPShadowMap : public PPEffectManager
|
||||
{
|
||||
public:
|
||||
void DeclareShaders() override;
|
||||
void UpdateTextures() override;
|
||||
void UpdateSteps() override;
|
||||
};
|
||||
|
|
|
@ -225,6 +225,23 @@ void VkPostprocess::ClearTonemapPalette()
|
|||
hw_postprocess.Textures.Remove("Tonemap.Palette");
|
||||
}
|
||||
|
||||
void VkPostprocess::UpdateShadowMap()
|
||||
{
|
||||
if (screen->mShadowMap.PerformUpdate())
|
||||
{
|
||||
RenderEffect("UpdateShadowMap");
|
||||
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
auto buffers = fb->GetBuffers();
|
||||
|
||||
VkPPImageTransition imageTransition;
|
||||
imageTransition.addImage(buffers->Shadowmap.get(), &buffers->ShadowmapLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false);
|
||||
imageTransition.execute(fb->GetDrawCommands());
|
||||
|
||||
screen->mShadowMap.FinishUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void VkPostprocess::BeginFrame()
|
||||
{
|
||||
mFrameDescriptorSets.clear();
|
||||
|
@ -233,6 +250,7 @@ void VkPostprocess::BeginFrame()
|
|||
{
|
||||
DescriptorPoolBuilder builder;
|
||||
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 100);
|
||||
builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 4);
|
||||
builder.setMaxSets(100);
|
||||
mDescriptorPool = builder.create(GetVulkanFrameBuffer()->device);
|
||||
mDescriptorPool->SetDebugName("VkPostprocess.mDescriptorPool");
|
||||
|
@ -405,10 +423,13 @@ void VkPostprocess::RenderEffect(const FString &name)
|
|||
key.Uniforms = step.Uniforms.Data.Size();
|
||||
key.Shader = mShaders[step.ShaderName].get();
|
||||
key.SwapChain = (step.Output.Type == PPTextureType::SwapChain);
|
||||
key.ShadowMapBuffers = step.ShadowMapBuffers;
|
||||
if (step.Output.Type == PPTextureType::PPTexture)
|
||||
key.OutputFormat = mTextures[step.Output.Texture]->Format;
|
||||
else if (step.Output.Type == PPTextureType::SwapChain)
|
||||
key.OutputFormat = GetVulkanFrameBuffer()->swapChain->swapChainFormat.format;
|
||||
else if (step.Output.Type == PPTextureType::ShadowMap)
|
||||
key.OutputFormat = VK_FORMAT_R32_SFLOAT;
|
||||
else
|
||||
key.OutputFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
|
||||
|
@ -417,7 +438,7 @@ void VkPostprocess::RenderEffect(const FString &name)
|
|||
passSetup.reset(new VkPPRenderPassSetup(key));
|
||||
|
||||
int framebufferWidth = 0, framebufferHeight = 0;
|
||||
VulkanDescriptorSet *input = GetInput(passSetup.get(), step.Textures);
|
||||
VulkanDescriptorSet *input = GetInput(passSetup.get(), step.Textures, step.ShadowMapBuffers);
|
||||
VulkanFramebuffer *output = GetOutput(passSetup.get(), step.Output, framebufferWidth, framebufferHeight);
|
||||
|
||||
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());
|
||||
|
@ -470,7 +491,7 @@ void VkPostprocess::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescr
|
|||
cmdbuffer->endRenderPass();
|
||||
}
|
||||
|
||||
VulkanDescriptorSet *VkPostprocess::GetInput(VkPPRenderPassSetup *passSetup, const TArray<PPTextureInput> &textures)
|
||||
VulkanDescriptorSet *VkPostprocess::GetInput(VkPPRenderPassSetup *passSetup, const TArray<PPTextureInput> &textures, bool bindShadowMapBuffers)
|
||||
{
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
auto descriptors = mDescriptorPool->allocate(passSetup->DescriptorLayout.get());
|
||||
|
@ -489,6 +510,13 @@ VulkanDescriptorSet *VkPostprocess::GetInput(VkPPRenderPassSetup *passSetup, con
|
|||
imageTransition.addImage(tex.image, tex.layout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
}
|
||||
|
||||
if (bindShadowMapBuffers)
|
||||
{
|
||||
write.addBuffer(descriptors.get(), LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightNodes->mBuffer.get());
|
||||
write.addBuffer(descriptors.get(), LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightLines->mBuffer.get());
|
||||
write.addBuffer(descriptors.get(), LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightList->mBuffer.get());
|
||||
}
|
||||
|
||||
write.updateSets(fb->device);
|
||||
imageTransition.execute(fb->GetDrawCommands());
|
||||
|
||||
|
@ -588,6 +616,13 @@ VkPostprocess::TextureImage VkPostprocess::GetTexture(const PPTextureType &type,
|
|||
tex.layout = &fb->GetBuffers()->SceneDepthStencilLayout;
|
||||
tex.debugname = "SceneDepth";
|
||||
}
|
||||
else if (type == PPTextureType::ShadowMap)
|
||||
{
|
||||
tex.image = fb->GetBuffers()->Shadowmap.get();
|
||||
tex.view = fb->GetBuffers()->ShadowmapView.get();
|
||||
tex.layout = &fb->GetBuffers()->ShadowmapLayout;
|
||||
tex.debugname = "Shadowmap";
|
||||
}
|
||||
else if (type == PPTextureType::SwapChain)
|
||||
{
|
||||
tex.image = nullptr;
|
||||
|
@ -639,6 +674,12 @@ void VkPPRenderPassSetup::CreateDescriptorLayout(const VkPPRenderPassKey &key)
|
|||
DescriptorSetLayoutBuilder builder;
|
||||
for (int i = 0; i < key.InputTextures; i++)
|
||||
builder.addBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
if (key.ShadowMapBuffers)
|
||||
{
|
||||
builder.addBinding(LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.addBinding(LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.addBinding(LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
}
|
||||
DescriptorLayout = builder.create(GetVulkanFrameBuffer()->device);
|
||||
DescriptorLayout->SetDebugName("VkPPRenderPassSetup.DescriptorLayout");
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
PPBlendMode BlendMode;
|
||||
VkFormat OutputFormat;
|
||||
int SwapChain;
|
||||
int ShadowMapBuffers;
|
||||
|
||||
bool operator<(const VkPPRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) < 0; }
|
||||
bool operator==(const VkPPRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) == 0; }
|
||||
|
@ -60,6 +61,8 @@ public:
|
|||
void BlurScene(float gameinfobluramount);
|
||||
void ClearTonemapPalette();
|
||||
|
||||
void UpdateShadowMap();
|
||||
|
||||
void BlitSceneToTexture();
|
||||
void BlitCurrentToImage(VulkanImage *image, VkImageLayout *layout, VkImageLayout finallayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
void DrawPresentTexture(const IntRect &box, bool applyGamma, bool clearBorders);
|
||||
|
@ -72,7 +75,7 @@ private:
|
|||
void NextEye(int eyeCount);
|
||||
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, bool bindShadowMapBuffers);
|
||||
VulkanFramebuffer *GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, int &framebufferWidth, int &framebufferHeight);
|
||||
VulkanSampler *GetSampler(PPFilterMode filter, PPWrapMode wrap);
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ void VkRenderBuffers::BeginFrame(int width, int height, int sceneWidth, int scen
|
|||
if (width != mWidth || height != mHeight || mSamples != samples)
|
||||
CreateScene(width, height, samples);
|
||||
|
||||
CreateShadowmap();
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mSamples = samples;
|
||||
|
@ -206,3 +208,41 @@ void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlag
|
|||
SceneNormalView = viewbuilder.create(fb->device);
|
||||
SceneNormalView->SetDebugName("VkRenderBuffers.SceneNormalView");
|
||||
}
|
||||
|
||||
void VkRenderBuffers::CreateShadowmap()
|
||||
{
|
||||
if (Shadowmap && Shadowmap->width == gl_shadowmap_quality)
|
||||
return;
|
||||
|
||||
Shadowmap.reset();
|
||||
ShadowmapView.reset();
|
||||
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
|
||||
ImageBuilder builder;
|
||||
builder.setSize(gl_shadowmap_quality, 1024);
|
||||
builder.setFormat(VK_FORMAT_R32_SFLOAT);
|
||||
builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
Shadowmap = builder.create(fb->device);
|
||||
Shadowmap->SetDebugName("VkRenderBuffers.Shadowmap");
|
||||
|
||||
ImageViewBuilder viewbuilder;
|
||||
viewbuilder.setImage(Shadowmap.get(), VK_FORMAT_R32_SFLOAT);
|
||||
ShadowmapView = viewbuilder.create(fb->device);
|
||||
ShadowmapView->SetDebugName("VkRenderBuffers.ShadowmapView");
|
||||
|
||||
PipelineBarrier barrier;
|
||||
barrier.addImage(Shadowmap.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
||||
barrier.execute(fb->GetDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
|
||||
if (!ShadowmapSampler)
|
||||
{
|
||||
SamplerBuilder builder;
|
||||
builder.setMipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST);
|
||||
builder.setMinFilter(VK_FILTER_NEAREST);
|
||||
builder.setMagFilter(VK_FILTER_NEAREST);
|
||||
builder.setAddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
|
||||
ShadowmapSampler = builder.create(fb->device);
|
||||
ShadowmapSampler->SetDebugName("VkRenderBuffers.ShadowmapSampler");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,11 @@ public:
|
|||
std::unique_ptr<VulkanImageView> PipelineView[NumPipelineImages];
|
||||
VkImageLayout PipelineLayout[NumPipelineImages];
|
||||
|
||||
std::unique_ptr<VulkanImage> Shadowmap;
|
||||
std::unique_ptr<VulkanImageView> ShadowmapView;
|
||||
std::unique_ptr<VulkanSampler> ShadowmapSampler;
|
||||
VkImageLayout ShadowmapLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
private:
|
||||
void CreatePipeline(int width, int height);
|
||||
void CreateScene(int width, int height, VkSampleCountFlagBits samples);
|
||||
|
@ -44,6 +49,7 @@ private:
|
|||
void CreateSceneDepthStencil(int width, int height, VkSampleCountFlagBits samples);
|
||||
void CreateSceneFog(int width, int height, VkSampleCountFlagBits samples);
|
||||
void CreateSceneNormal(int width, int height, VkSampleCountFlagBits samples);
|
||||
void CreateShadowmap();
|
||||
VkSampleCountFlagBits GetBestSampleCount();
|
||||
|
||||
int mWidth = 0;
|
||||
|
|
|
@ -79,6 +79,7 @@ void VkRenderPassManager::CreateDynamicSetLayout()
|
|||
builder.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.addBinding(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.addBinding(3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
builder.addBinding(4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
DynamicSetLayout = builder.create(GetVulkanFrameBuffer()->device);
|
||||
DynamicSetLayout->SetDebugName("VkRenderPassManager.DynamicSetLayout");
|
||||
}
|
||||
|
@ -90,7 +91,6 @@ void VkRenderPassManager::CreateTextureSetLayout()
|
|||
{
|
||||
builder.addBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
}
|
||||
builder.addBinding(16, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
TextureSetLayout = builder.create(GetVulkanFrameBuffer()->device);
|
||||
TextureSetLayout->SetDebugName("VkRenderPassManager.TextureSetLayout");
|
||||
}
|
||||
|
@ -119,13 +119,18 @@ void VkRenderPassManager::CreateDescriptorPool()
|
|||
void VkRenderPassManager::CreateDynamicSet()
|
||||
{
|
||||
DynamicSet = DescriptorPool->allocate(DynamicSetLayout.get());
|
||||
}
|
||||
|
||||
void VkRenderPassManager::UpdateDynamicSet()
|
||||
{
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
|
||||
WriteDescriptors update;
|
||||
update.addBuffer(DynamicSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->ViewpointUBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms));
|
||||
update.addBuffer(DynamicSet.get(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, fb->LightBufferSSO->mBuffer.get(), 0, fb->GetLightBufferBlockSize());
|
||||
update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->MatricesUBO->mBuffer.get(), 0, sizeof(MatricesUBO));
|
||||
update.addBuffer(DynamicSet.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->StreamUBO->mBuffer.get(), 0, sizeof(StreamUBO));
|
||||
update.addCombinedImageSampler(DynamicSet.get(), 4, fb->GetBuffers()->ShadowmapView.get(), fb->GetBuffers()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
update.updateSets(fb->device);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
|
||||
void Init();
|
||||
void RenderBuffersReset();
|
||||
void UpdateDynamicSet();
|
||||
|
||||
VkRenderPassSetup *GetRenderPass(const VkRenderPassKey &key);
|
||||
int GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs);
|
||||
|
|
|
@ -139,6 +139,8 @@ static const char *shaderBindings = R"(
|
|||
StreamData data[256];
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 4) uniform sampler2D ShadowMap;
|
||||
|
||||
// textures
|
||||
layout(set = 1, binding = 0) uniform sampler2D tex;
|
||||
layout(set = 1, binding = 1) uniform sampler2D texture2;
|
||||
|
@ -146,7 +148,6 @@ static const char *shaderBindings = R"(
|
|||
layout(set = 1, binding = 3) uniform sampler2D texture4;
|
||||
layout(set = 1, binding = 4) uniform sampler2D texture5;
|
||||
layout(set = 1, binding = 5) uniform sampler2D texture6;
|
||||
layout(set = 1, binding = 16) uniform sampler2D ShadowMap;
|
||||
|
||||
// This must match the PushConstants struct
|
||||
layout(push_constant) uniform PushConstants
|
||||
|
@ -207,7 +208,7 @@ static const char *shaderBindings = R"(
|
|||
#define uSplitTopPlane data[uDataIndex].uSplitTopPlane
|
||||
#define uSplitBottomPlane data[uDataIndex].uSplitBottomPlane
|
||||
|
||||
// #define SUPPORTS_SHADOWMAPS
|
||||
#define SUPPORTS_SHADOWMAPS
|
||||
#define VULKAN_COORDINATE_SYSTEM
|
||||
#define HAS_UNIFORM_VERTEX_DATA
|
||||
)";
|
||||
|
|
|
@ -95,6 +95,7 @@ VulkanFrameBuffer::~VulkanFrameBuffer()
|
|||
delete mSkyData;
|
||||
delete mViewpoints;
|
||||
delete mLights;
|
||||
mShadowMap.Reset();
|
||||
}
|
||||
|
||||
void VulkanFrameBuffer::InitializeState()
|
||||
|
@ -390,10 +391,8 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor *
|
|||
|
||||
R_SetupFrame(mainvp, r_viewwindow, camera);
|
||||
|
||||
#if 0
|
||||
if (mainview && toscreen)
|
||||
UpdateShadowMap();
|
||||
#endif
|
||||
|
||||
// Update the attenuation flag of all light defaults for each viewpoint.
|
||||
// This function will only do something if the setting differs.
|
||||
|
@ -629,14 +628,19 @@ IIndexBuffer *VulkanFrameBuffer::CreateIndexBuffer()
|
|||
IDataBuffer *VulkanFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo)
|
||||
{
|
||||
auto buffer = new VKDataBuffer(bindingpoint, ssbo);
|
||||
if (bindingpoint == VIEWPOINT_BINDINGPOINT)
|
||||
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
switch (bindingpoint)
|
||||
{
|
||||
ViewpointUBO = buffer;
|
||||
}
|
||||
else if (bindingpoint == LIGHTBUF_BINDINGPOINT)
|
||||
{
|
||||
LightBufferSSO = buffer;
|
||||
case LIGHTBUF_BINDINGPOINT: LightBufferSSO = buffer; break;
|
||||
case VIEWPOINT_BINDINGPOINT: ViewpointUBO = buffer; break;
|
||||
case LIGHTNODES_BINDINGPOINT: LightNodes = buffer; break;
|
||||
case LIGHTLINES_BINDINGPOINT: LightLines = buffer; break;
|
||||
case LIGHTLIST_BINDINGPOINT: LightList = buffer; break;
|
||||
case POSTPROCESS_BINDINGPOINT: break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -758,6 +762,7 @@ void VulkanFrameBuffer::BeginFrame()
|
|||
mScreenBuffers->BeginFrame(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
|
||||
mSaveBuffers->BeginFrame(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT);
|
||||
mPostprocess->BeginFrame();
|
||||
mRenderPassManager->UpdateDynamicSet();
|
||||
}
|
||||
|
||||
void VulkanFrameBuffer::Draw2D()
|
||||
|
@ -841,3 +846,8 @@ void VulkanFrameBuffer::CreateFanToTrisIndexBuffer()
|
|||
FanToTrisIndexBuffer.reset(CreateIndexBuffer());
|
||||
FanToTrisIndexBuffer->SetData(sizeof(uint32_t) * data.Size(), data.Data());
|
||||
}
|
||||
|
||||
void VulkanFrameBuffer::UpdateShadowMap()
|
||||
{
|
||||
mPostprocess->UpdateShadowMap();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,10 @@ public:
|
|||
VKDataBuffer *MatricesUBO = nullptr;
|
||||
VKDataBuffer *StreamUBO = nullptr;
|
||||
|
||||
VKDataBuffer *LightNodes = nullptr;
|
||||
VKDataBuffer *LightLines = nullptr;
|
||||
VKDataBuffer *LightList = nullptr;
|
||||
|
||||
std::unique_ptr<IIndexBuffer> FanToTrisIndexBuffer;
|
||||
|
||||
std::vector<std::unique_ptr<VulkanBuffer>> mFrameDeleteList;
|
||||
|
@ -90,6 +94,7 @@ private:
|
|||
void CreateFanToTrisIndexBuffer();
|
||||
void SubmitCommands(bool finish);
|
||||
void CopyScreenToBuffer(int w, int h, void *data);
|
||||
void UpdateShadowMap();
|
||||
|
||||
std::unique_ptr<VkShaderManager> mShaderManager;
|
||||
std::unique_ptr<VkSamplerManager> mSamplerManager;
|
||||
|
|
|
@ -20,17 +20,17 @@ struct GPULine
|
|||
vec2 delta; // Line end position - line start position
|
||||
};
|
||||
|
||||
layout(std430, binding = 2) buffer LightNodes
|
||||
layout(std430, binding = 4) buffer LightNodes
|
||||
{
|
||||
GPUNode nodes[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 3) buffer LightLines
|
||||
layout(std430, binding = 5) buffer LightLines
|
||||
{
|
||||
GPULine lines[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 4) buffer LightList
|
||||
layout(std430, binding = 6) buffer LightList
|
||||
{
|
||||
vec4 lights[];
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue