From 9ed1c7f40bc7d34751ccbc63abebcdbae860bf7c Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 26 Feb 2019 11:27:29 +0100 Subject: [PATCH] - add render pass manager and setup a pipeline for VkRenderState --- src/CMakeLists.txt | 1 + .../vulkan/renderer/vk_renderpass.cpp | 157 ++++++++++++++++++ src/rendering/vulkan/renderer/vk_renderpass.h | 50 ++++++ .../vulkan/renderer/vk_renderstate.cpp | 72 ++++++-- .../vulkan/renderer/vk_renderstate.h | 10 ++ src/rendering/vulkan/shaders/vk_shader.cpp | 28 ++-- src/rendering/vulkan/shaders/vk_shader.h | 13 +- src/rendering/vulkan/system/vk_buffers.cpp | 3 + src/rendering/vulkan/system/vk_builders.cpp | 2 +- src/rendering/vulkan/system/vk_builders.h | 41 +---- src/rendering/vulkan/system/vk_device.cpp | 35 ++-- src/rendering/vulkan/system/vk_device.h | 2 +- .../vulkan/system/vk_framebuffer.cpp | 18 +- src/rendering/vulkan/system/vk_framebuffer.h | 9 + src/rendering/vulkan/system/vk_objects.h | 6 +- 15 files changed, 360 insertions(+), 87 deletions(-) create mode 100644 src/rendering/vulkan/renderer/vk_renderpass.cpp create mode 100644 src/rendering/vulkan/renderer/vk_renderpass.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47c586417..06f411a1d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -900,6 +900,7 @@ set( FASTMATH_SOURCES rendering/vulkan/system/vk_framebuffer.cpp rendering/vulkan/system/vk_buffers.cpp rendering/vulkan/renderer/vk_renderstate.cpp + rendering/vulkan/renderer/vk_renderpass.cpp rendering/vulkan/shaders/vk_shader.cpp rendering/vulkan/textures/vk_samplers.cpp rendering/vulkan/textures/vk_hwtexture.cpp diff --git a/src/rendering/vulkan/renderer/vk_renderpass.cpp b/src/rendering/vulkan/renderer/vk_renderpass.cpp new file mode 100644 index 000000000..8adfbe2ce --- /dev/null +++ b/src/rendering/vulkan/renderer/vk_renderpass.cpp @@ -0,0 +1,157 @@ + +#include "vk_renderpass.h" +#include "vulkan/shaders/vk_shader.h" +#include "vulkan/system/vk_builders.h" +#include "vulkan/system/vk_framebuffer.h" +#include "vulkan/system/vk_buffers.h" +#include "hwrenderer/data/flatvertices.h" +#include "hwrenderer/scene/hw_viewpointuniforms.h" + +VkRenderPassManager::VkRenderPassManager() +{ + CreateDynamicSetLayout(); + CreateTextureSetLayout(); + CreatePipelineLayout(); + CreateDescriptorPool(); + CreateDynamicSet(); +} + +void VkRenderPassManager::BeginFrame() +{ + if (!SceneColor || SceneColor->width != SCREENWIDTH || SceneColor->height != SCREENHEIGHT) + { + auto fb = GetVulkanFrameBuffer(); + + RenderPassSetup.reset(); + SceneColorView.reset(); + SceneDepthStencilView.reset(); + SceneDepthView.reset(); + SceneColor.reset(); + SceneDepthStencil.reset(); + + ImageBuilder builder; + builder.setSize(SCREENWIDTH, SCREENHEIGHT); + builder.setFormat(VK_FORMAT_R16G16B16A16_SFLOAT); + builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + SceneColor = builder.create(fb->device); + + builder.setFormat(VK_FORMAT_D24_UNORM_S8_UINT); + builder.setUsage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + SceneDepthStencil = builder.create(fb->device); + + ImageViewBuilder viewbuilder; + viewbuilder.setImage(SceneColor.get(), VK_FORMAT_R16G16B16A16_SFLOAT); + SceneColorView = viewbuilder.create(fb->device); + + viewbuilder.setImage(SceneDepthStencil.get(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + SceneDepthStencilView = viewbuilder.create(fb->device); + + viewbuilder.setImage(SceneDepthStencil.get(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT); + SceneDepthView = viewbuilder.create(fb->device); + + RenderPassSetup.reset(new VkRenderPassSetup()); + } +} + +void VkRenderPassManager::CreateDynamicSetLayout() +{ + DescriptorSetLayoutBuilder builder; + builder.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); + builder.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT); + DynamicSetLayout = builder.create(GetVulkanFrameBuffer()->device); +} + +void VkRenderPassManager::CreateTextureSetLayout() +{ + DescriptorSetLayoutBuilder builder; + builder.addBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT); + /* + for (int i = 0; i < 6; i++) + { + 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); +} + +void VkRenderPassManager::CreatePipelineLayout() +{ + PipelineLayoutBuilder builder; + builder.addSetLayout(DynamicSetLayout.get()); + builder.addSetLayout(TextureSetLayout.get()); + builder.addPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants)); + PipelineLayout = builder.create(GetVulkanFrameBuffer()->device); +} + +void VkRenderPassManager::CreateDescriptorPool() +{ + DescriptorPoolBuilder builder; + builder.addPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1); + builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1); + builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 512 * 6); + builder.setMaxSets(512); + DescriptorPool = builder.create(GetVulkanFrameBuffer()->device); +} + +void VkRenderPassManager::CreateDynamicSet() +{ + DynamicSet = DescriptorPool->allocate(DynamicSetLayout.get()); + + 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, 4096); + update.updateSets(fb->device); +} + +///////////////////////////////////////////////////////////////////////////// + +VkRenderPassSetup::VkRenderPassSetup() +{ + CreateRenderPass(); + CreatePipeline(); + CreateFramebuffer(); +} + +void VkRenderPassSetup::CreateRenderPass() +{ + RenderPassBuilder builder; + builder.addRgba16fAttachment(false, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + builder.addSubpass(); + builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + builder.addExternalSubpassDependency(); + RenderPass = builder.create(GetVulkanFrameBuffer()->device); +} + +void VkRenderPassSetup::CreatePipeline() +{ + auto fb = GetVulkanFrameBuffer(); + GraphicsPipelineBuilder builder; + builder.addVertexShader(fb->GetShaderManager()->vert.get()); + builder.addFragmentShader(fb->GetShaderManager()->frag.get()); + builder.addVertexBufferBinding(0, sizeof(FFlatVertex)); + builder.addVertexAttribute(0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(FFlatVertex, x)); + builder.addVertexAttribute(1, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(FFlatVertex, u)); + // To do: not all vertex formats has all the data.. + //builder.addVertexAttribute(2, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(FFlatVertex, x)); + //builder.addVertexAttribute(3, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(FFlatVertex, x)); + //builder.addVertexAttribute(4, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(FFlatVertex, x)); + //builder.addVertexAttribute(5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(FFlatVertex, x)); + builder.setViewport(0.0f, 0.0f, (float)SCREENWIDTH, (float)SCREENHEIGHT); + builder.setScissor(0, 0, SCREENWIDTH, SCREENHEIGHT); + builder.setAlphaBlendMode(); + builder.setLayout(fb->GetRenderPassManager()->PipelineLayout.get()); + builder.setRenderPass(RenderPass.get()); + Pipeline = builder.create(fb->device); +} + +void VkRenderPassSetup::CreateFramebuffer() +{ + auto fb = GetVulkanFrameBuffer(); + FramebufferBuilder builder; + builder.setRenderPass(RenderPass.get()); + builder.setSize(SCREENWIDTH, SCREENHEIGHT); + builder.addAttachment(fb->GetRenderPassManager()->SceneColorView.get()); + Framebuffer = builder.create(GetVulkanFrameBuffer()->device); +} diff --git a/src/rendering/vulkan/renderer/vk_renderpass.h b/src/rendering/vulkan/renderer/vk_renderpass.h new file mode 100644 index 000000000..2ec1c0321 --- /dev/null +++ b/src/rendering/vulkan/renderer/vk_renderpass.h @@ -0,0 +1,50 @@ + +#pragma once + +#include "vulkan/system/vk_objects.h" + +class VKDataBuffer; + +class VkRenderPassSetup +{ +public: + VkRenderPassSetup(); + + std::unique_ptr RenderPass; + std::unique_ptr Pipeline; + std::unique_ptr Framebuffer; + +private: + void CreatePipeline(); + void CreateRenderPass(); + void CreateFramebuffer(); +}; + +class VkRenderPassManager +{ +public: + VkRenderPassManager(); + + void BeginFrame(); + + std::unique_ptr DynamicSetLayout; + std::unique_ptr TextureSetLayout; + std::unique_ptr PipelineLayout; + std::unique_ptr DescriptorPool; + std::unique_ptr RenderPassSetup; + + std::unique_ptr SceneColor; + std::unique_ptr SceneDepthStencil; + std::unique_ptr SceneColorView; + std::unique_ptr SceneDepthStencilView; + std::unique_ptr SceneDepthView; + + std::unique_ptr DynamicSet; + +private: + void CreateDynamicSetLayout(); + void CreateTextureSetLayout(); + void CreatePipelineLayout(); + void CreateDescriptorPool(); + void CreateDynamicSet(); +}; diff --git a/src/rendering/vulkan/renderer/vk_renderstate.cpp b/src/rendering/vulkan/renderer/vk_renderstate.cpp index 5837a7455..b3a641823 100644 --- a/src/rendering/vulkan/renderer/vk_renderstate.cpp +++ b/src/rendering/vulkan/renderer/vk_renderstate.cpp @@ -1,15 +1,23 @@ #include "vk_renderstate.h" #include "vulkan/system/vk_framebuffer.h" +#include "vulkan/system/vk_builders.h" +#include "vulkan/renderer/vk_renderpass.h" #include "templates.h" #include "doomstat.h" #include "r_data/colormaps.h" #include "hwrenderer/scene/hw_skydome.h" +#include "hwrenderer/scene/hw_viewpointuniforms.h" #include "hwrenderer/dynlights/hw_lightbuffer.h" #include "hwrenderer/utility/hw_cvars.h" #include "hwrenderer/utility/hw_clock.h" #include "hwrenderer/data/flatvertices.h" #include "hwrenderer/data/hw_viewpointbuffer.h" +#include "hwrenderer/data/shaderuniforms.h" + +VkRenderState::VkRenderState() +{ +} void VkRenderState::ClearScreen() { @@ -28,9 +36,10 @@ void VkRenderState::ClearScreen() void VkRenderState::Draw(int dt, int index, int count, bool apply) { if (apply) - { Apply(dt); - } + else if (mDescriptorsChanged) + BindDescriptorSets(); + drawcalls.Clock(); //mCommandBuffer->draw(count, 1, index, 0); drawcalls.Unclock(); @@ -39,9 +48,10 @@ void VkRenderState::Draw(int dt, int index, int count, bool apply) void VkRenderState::DrawIndexed(int dt, int index, int count, bool apply) { if (apply) - { Apply(dt); - } + else if (mDescriptorsChanged) + BindDescriptorSets(); + drawcalls.Clock(); //mCommandBuffer->drawIndexed(count, 1, 0, index * (int)sizeof(uint32_t), 0); drawcalls.Unclock(); @@ -116,8 +126,9 @@ void VkRenderState::EnableLineSmooth(bool on) void VkRenderState::Apply(int dt) { -#if 0 auto fb = GetVulkanFrameBuffer(); + auto passManager = fb->GetRenderPassManager(); + auto passSetup = passManager->RenderPassSetup.get(); bool changingRenderPass = false; // To do: decide if the state matches current bound renderpass @@ -134,16 +145,57 @@ void VkRenderState::Apply(int dt) if (changingRenderPass) { RenderPassBegin beginInfo; - beginInfo.setRenderPass(renderPass); + beginInfo.setRenderPass(passSetup->RenderPass.get()); beginInfo.setRenderArea(0, 0, SCREENWIDTH, SCREENHEIGHT); - beginInfo.setFramebuffer(framebuffer); + beginInfo.setFramebuffer(passSetup->Framebuffer.get()); beginInfo.addClearColor(0.0f, 0.0f, 0.0f, 1.0f); beginInfo.addClearDepthStencil(0.0f, 0); mCommandBuffer->beginRenderPass(beginInfo); - mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get()); } // To do: maybe only push the subset that changed? - mCommandBuffer->pushConstants(pipelineLayout, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants); -#endif + static_assert(sizeof(PushConstants) % 16 == 0, "std140 layouts must be 16 byte aligned"); + //mCommandBuffer->pushConstants(passManager->PipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants); + + VkBuffer vertexBuffers[] = { static_cast(mVertexBuffer)->mBuffer->buffer }; + VkDeviceSize offsets[] = { 0 }; + mCommandBuffer->bindVertexBuffers(0, 1, vertexBuffers, offsets); + + mCommandBuffer->bindIndexBuffer(static_cast(mIndexBuffer)->mBuffer->buffer, 0, VK_INDEX_TYPE_UINT32); + + BindDescriptorSets(); +} + +void VkRenderState::Bind(int bindingpoint, uint32_t offset) +{ + if (bindingpoint == VIEWPOINT_BINDINGPOINT) + { + mViewpointOffset = offset; + } + else if (bindingpoint == LIGHTBUF_BINDINGPOINT) + { + mLightBufferOffset = offset; + } + + mDescriptorsChanged = true; +} + +void VkRenderState::BindDescriptorSets() +{ + auto fb = GetVulkanFrameBuffer(); + auto passManager = fb->GetRenderPassManager(); + + uint32_t offsets[2] = { mViewpointOffset, mLightBufferOffset }; + mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->PipelineLayout.get(), 0, passManager->DynamicSet.get(), 2, offsets); + mDescriptorsChanged = false; +} + +void VkRenderState::EndRenderPass() +{ + if (mCommandBuffer) + { + mCommandBuffer->endRenderPass(); + mCommandBuffer = nullptr; + } } diff --git a/src/rendering/vulkan/renderer/vk_renderstate.h b/src/rendering/vulkan/renderer/vk_renderstate.h index 4e14bffe3..982b6d63a 100644 --- a/src/rendering/vulkan/renderer/vk_renderstate.h +++ b/src/rendering/vulkan/renderer/vk_renderstate.h @@ -13,6 +13,8 @@ class VkRenderState : public FRenderState { public: + VkRenderState(); + // Draw commands void ClearScreen() override; void Draw(int dt, int index, int count, bool apply = true) override; @@ -36,10 +38,18 @@ public: void EnableMultisampling(bool on) override; void EnableLineSmooth(bool on) override; + void Bind(int bindingpoint, uint32_t offset); + void EndRenderPass(); + private: void Apply(int dt); + void BindDescriptorSets(); bool mLastDepthClamp = true; VulkanCommandBuffer *mCommandBuffer = nullptr; PushConstants mPushConstants; + bool mDescriptorsChanged = true; + + uint32_t mViewpointOffset = 0, mLastViewpointOffset = 0; + uint32_t mLightBufferOffset = 0, mLastLightBufferOffset = 0; }; diff --git a/src/rendering/vulkan/shaders/vk_shader.cpp b/src/rendering/vulkan/shaders/vk_shader.cpp index c5e7e9756..34fad3e6d 100644 --- a/src/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/rendering/vulkan/shaders/vk_shader.cpp @@ -48,19 +48,24 @@ static const char *shaderBindings = R"( // textures layout(set = 1, binding = 0) uniform sampler2D tex; - layout(set = 1, binding = 1) uniform sampler2D texture2; - layout(set = 1, binding = 2) uniform sampler2D texture3; - 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; + // layout(set = 1, binding = 1) uniform sampler2D texture2; + // layout(set = 1, binding = 2) uniform sampler2D texture3; + // 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, std140) uniform PushConstants { + // matrices + mat4 ModelMatrix; + mat4 NormalModelMatrix; + mat4 TextureMatrix; + int uTextureMode; - vec2 uClipSplit; float uAlphaThreshold; + vec2 uClipSplit; // colors vec4 uObjectColor; @@ -70,6 +75,7 @@ static const char *shaderBindings = R"( vec4 uFogColor; float uDesaturationFactor; float uInterpolationFactor; + float padding0, padding1; // Glowing walls stuff vec4 uGlowTopPlane; @@ -95,11 +101,6 @@ static const char *shaderBindings = R"( // Blinn glossiness and specular level vec2 uSpecularMaterial; - - // matrices - mat4 ModelMatrix; - mat4 NormalModelMatrix; - mat4 TextureMatrix; }; // material types @@ -117,10 +118,9 @@ static const char *shaderBindings = R"( #define brighttexture texture2 #endif - #define SUPPORTS_SHADOWMAPS + // #define SUPPORTS_SHADOWMAPS )"; - std::unique_ptr VkShaderManager::LoadVertShader(const char *vert_lump, const char *defines) { FString code = GetTargetGlslVersion(); diff --git a/src/rendering/vulkan/shaders/vk_shader.h b/src/rendering/vulkan/shaders/vk_shader.h index 2d1e8b530..89877aab0 100644 --- a/src/rendering/vulkan/shaders/vk_shader.h +++ b/src/rendering/vulkan/shaders/vk_shader.h @@ -10,9 +10,14 @@ class VulkanShader; struct PushConstants { + // matrices + VSMatrix ModelMatrix; + VSMatrix NormalModelMatrix; + VSMatrix TextureMatrix; + int uTextureMode; - FVector2 uClipSplit; float uAlphaThreshold; + FVector2 uClipSplit; // colors FVector4 uObjectColor; @@ -22,6 +27,7 @@ struct PushConstants FVector4 uFogColor; float uDesaturationFactor; float uInterpolationFactor; + float padding0, padding1; // Glowing walls stuff FVector4 uGlowTopPlane; @@ -47,11 +53,6 @@ struct PushConstants // Blinn glossiness and specular level FVector2 uSpecularMaterial; - - // matrices - VSMatrix ModelMatrix; - VSMatrix NormalModelMatrix; - VSMatrix TextureMatrix; }; class VkShaderManager diff --git a/src/rendering/vulkan/system/vk_buffers.cpp b/src/rendering/vulkan/system/vk_buffers.cpp index 6726ff326..ef5cc9348 100644 --- a/src/rendering/vulkan/system/vk_buffers.cpp +++ b/src/rendering/vulkan/system/vk_buffers.cpp @@ -2,6 +2,7 @@ #include "vk_buffers.h" #include "vk_builders.h" #include "vk_framebuffer.h" +#include "vulkan/renderer/vk_renderstate.h" #include "doomerrors.h" void VKBuffer::SetData(size_t size, const void *data, bool staticdata) @@ -112,8 +113,10 @@ void VKVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t s void VKDataBuffer::BindRange(size_t start, size_t length) { + GetVulkanFrameBuffer()->GetRenderState()->Bind(bindingpoint, (uint32_t)start); } void VKDataBuffer::BindBase() { + GetVulkanFrameBuffer()->GetRenderState()->Bind(bindingpoint, 0); } diff --git a/src/rendering/vulkan/system/vk_builders.cpp b/src/rendering/vulkan/system/vk_builders.cpp index eb0f3ca57..839b1b356 100644 --- a/src/rendering/vulkan/system/vk_builders.cpp +++ b/src/rendering/vulkan/system/vk_builders.cpp @@ -170,7 +170,7 @@ std::unique_ptr ShaderBuilder::create(VulkanDevice *device) VkShaderModuleCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - createInfo.codeSize = spirv.size(); + createInfo.codeSize = spirv.size() * sizeof(unsigned int); createInfo.pCode = spirv.data(); VkShaderModule shaderModule; diff --git a/src/rendering/vulkan/system/vk_builders.h b/src/rendering/vulkan/system/vk_builders.h index 89f2e98ed..d50caaf2c 100644 --- a/src/rendering/vulkan/system/vk_builders.h +++ b/src/rendering/vulkan/system/vk_builders.h @@ -285,10 +285,8 @@ private: class WriteDescriptors { public: - void addUniformBuffer(VulkanDescriptorSet *descriptorSet, int binding, VulkanBuffer *buffer); - void addUniformBuffer(VulkanDescriptorSet *descriptorSet, int binding, VulkanBuffer *buffer, size_t offset, size_t range); - void addStorageBuffer(VulkanDescriptorSet *descriptorSet, int binding, VulkanBuffer *buffer); - void addStorageBuffer(VulkanDescriptorSet *descriptorSet, int binding, VulkanBuffer *buffer, size_t offset, size_t range); + void addBuffer(VulkanDescriptorSet *descriptorSet, int binding, VkDescriptorType type, VulkanBuffer *buffer); + void addBuffer(VulkanDescriptorSet *descriptorSet, int binding, VkDescriptorType type, VulkanBuffer *buffer, size_t offset, size_t range); void addStorageImage(VulkanDescriptorSet *descriptorSet, int binding, VulkanImageView *view, VkImageLayout imageLayout); void addCombinedImageSampler(VulkanDescriptorSet *descriptorSet, int binding, VulkanImageView *view, VulkanSampler *sampler, VkImageLayout imageLayout); @@ -1041,12 +1039,12 @@ inline void PipelineBarrier::execute(VulkanCommandBuffer *commandBuffer, VkPipel ///////////////////////////////////////////////////////////////////////////// -inline void WriteDescriptors::addUniformBuffer(VulkanDescriptorSet *descriptorSet, int binding, VulkanBuffer *buffer) +inline void WriteDescriptors::addBuffer(VulkanDescriptorSet *descriptorSet, int binding, VkDescriptorType type, VulkanBuffer *buffer) { - addUniformBuffer(descriptorSet, binding, buffer, 0, buffer->size); + addBuffer(descriptorSet, binding, type, buffer, 0, buffer->size); } -inline void WriteDescriptors::addUniformBuffer(VulkanDescriptorSet *descriptorSet, int binding, VulkanBuffer *buffer, size_t offset, size_t range) +inline void WriteDescriptors::addBuffer(VulkanDescriptorSet *descriptorSet, int binding, VkDescriptorType type, VulkanBuffer *buffer, size_t offset, size_t range) { VkDescriptorBufferInfo bufferInfo = {}; bufferInfo.buffer = buffer->buffer; @@ -1061,34 +1059,7 @@ inline void WriteDescriptors::addUniformBuffer(VulkanDescriptorSet *descriptorSe descriptorWrite.dstSet = descriptorSet->set; descriptorWrite.dstBinding = binding; descriptorWrite.dstArrayElement = 0; - descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptorWrite.descriptorCount = 1; - descriptorWrite.pBufferInfo = &extra->bufferInfo; - writes.push_back(descriptorWrite); - writeExtras.push_back(std::move(extra)); -} - -inline void WriteDescriptors::addStorageBuffer(VulkanDescriptorSet *descriptorSet, int binding, VulkanBuffer *buffer) -{ - addStorageBuffer(descriptorSet, binding, buffer, 0, buffer->size); -} - -inline void WriteDescriptors::addStorageBuffer(VulkanDescriptorSet *descriptorSet, int binding, VulkanBuffer *buffer, size_t offset, size_t range) -{ - VkDescriptorBufferInfo bufferInfo = {}; - bufferInfo.buffer = buffer->buffer; - bufferInfo.offset = offset; - bufferInfo.range = range; - - auto extra = std::make_unique(); - extra->bufferInfo = bufferInfo; - - VkWriteDescriptorSet descriptorWrite = {}; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.dstSet = descriptorSet->set; - descriptorWrite.dstBinding = binding; - descriptorWrite.dstArrayElement = 0; - descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + descriptorWrite.descriptorType = type; descriptorWrite.descriptorCount = 1; descriptorWrite.pBufferInfo = &extra->bufferInfo; writes.push_back(descriptorWrite); diff --git a/src/rendering/vulkan/system/vk_device.cpp b/src/rendering/vulkan/system/vk_device.cpp index 1ded967de..29d4c15de 100644 --- a/src/rendering/vulkan/system/vk_device.cpp +++ b/src/rendering/vulkan/system/vk_device.cpp @@ -127,6 +127,8 @@ void VulkanDevice::presentFrame() vkQueuePresentKHR(presentQueue, &presentInfo); } +//FString allVulkanOutput; + VkBool32 VulkanDevice::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* callbackData, void* userData) { VulkanDevice *device = (VulkanDevice*)userData; @@ -143,6 +145,8 @@ VkBool32 VulkanDevice::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT mess Printf("Vulkan validation layer %s: %s\n", prefix, callbackData->pMessage); + //allVulkanOutput.AppendFormat("Vulkan validation layer %s: %s\n", prefix, callbackData->pMessage); + return VK_FALSE; } @@ -178,7 +182,6 @@ void VulkanDevice::createInstance() if (layer.layerName == debugLayer) { validationLayers.push_back(debugLayer.c_str()); - //enabledExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); enabledExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); debugLayerFound = true; } @@ -203,23 +206,20 @@ void VulkanDevice::createInstance() { VkDebugUtilsMessengerCreateInfoEXT createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; - createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + createInfo.messageSeverity = + //VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | + //VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + createInfo.messageType = + VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; createInfo.pfnUserCallback = debugCallback; createInfo.pUserData = this; result = vkCreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger); if (result != VK_SUCCESS) throw std::runtime_error("vkCreateDebugUtilsMessengerEXT failed"); - - /* - VkDebugReportCallbackCreateInfoEXT createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; - createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; - createInfo.pfnCallback = debugCallback; - result = vkCreateDebugReportCallbackEXT(instance, &createInfo, nullptr, &vkCallback); - if (result != VK_SUCCESS) - throw std::runtime_error("vkCreateDebugReportCallbackEXT failed"); - */ } } @@ -397,15 +397,15 @@ void VulkanDevice::releaseResources() if (device) vkDeviceWaitIdle(device); - if (!imageAvailableSemaphore) + if (imageAvailableSemaphore) vkDestroySemaphore(device, imageAvailableSemaphore, nullptr); imageAvailableSemaphore = 0; - if (!renderFinishedSemaphore) + if (renderFinishedSemaphore) vkDestroySemaphore(device, renderFinishedSemaphore, nullptr); renderFinishedSemaphore = 0; - if (!renderFinishedFence) + if (renderFinishedFence) vkDestroyFence(device, renderFinishedFence, nullptr); renderFinishedFence = 0; @@ -419,6 +419,9 @@ void VulkanDevice::releaseResources() vkDestroySurfaceKHR(instance, surface, nullptr); surface = 0; + if (debugMessenger) + vkDestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr); + if (instance) vkDestroyInstance(instance, nullptr); instance = nullptr; diff --git a/src/rendering/vulkan/system/vk_device.h b/src/rendering/vulkan/system/vk_device.h index b659dfb68..fd90febd0 100644 --- a/src/rendering/vulkan/system/vk_device.h +++ b/src/rendering/vulkan/system/vk_device.h @@ -54,7 +54,7 @@ private: void createSemaphores(); void releaseResources(); - VkDebugUtilsMessengerEXT debugMessenger; + VkDebugUtilsMessengerEXT debugMessenger = VK_NULL_HANDLE; static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData); std::vector requiredExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index ff0f52617..de71fbfdb 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -34,11 +34,13 @@ #include "hwrenderer/scene/hw_skydome.h" #include "hwrenderer/data/hw_viewpointbuffer.h" #include "hwrenderer/data/flatvertices.h" +#include "hwrenderer/data/shaderuniforms.h" #include "hwrenderer/dynlights/hw_lightbuffer.h" #include "vk_framebuffer.h" #include "vk_buffers.h" #include "vulkan/renderer/vk_renderstate.h" +#include "vulkan/renderer/vk_renderpass.h" #include "vulkan/shaders/vk_shader.h" #include "vulkan/textures/vk_samplers.h" #include "vulkan/system/vk_builders.h" @@ -73,6 +75,7 @@ void VulkanFrameBuffer::InitializeState() mShaderManager.reset(new VkShaderManager(device)); mSamplerManager.reset(new VkSamplerManager(device)); + mRenderPassManager.reset(new VkRenderPassManager()); mRenderState.reset(new VkRenderState()); } @@ -99,6 +102,9 @@ void VulkanFrameBuffer::Update() Draw2D(); Clear2D(); + + mRenderState->EndRenderPass(); + //DrawPresentTexture(mOutputLetterbox, true); mPresentCommands->end(); @@ -194,7 +200,16 @@ IIndexBuffer *VulkanFrameBuffer::CreateIndexBuffer() IDataBuffer *VulkanFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo) { - return new VKDataBuffer(bindingpoint, ssbo); + auto buffer = new VKDataBuffer(bindingpoint, ssbo); + if (bindingpoint == VIEWPOINT_BINDINGPOINT) + { + ViewpointUBO = buffer; + } + else if (bindingpoint == LIGHTBUF_BINDINGPOINT) + { + LightBufferSSO = buffer; + } + return buffer; } void VulkanFrameBuffer::UnbindTexUnit(int no) @@ -215,6 +230,7 @@ void VulkanFrameBuffer::UpdatePalette() void VulkanFrameBuffer::BeginFrame() { + mRenderPassManager->BeginFrame(); } void VulkanFrameBuffer::Draw2D() diff --git a/src/rendering/vulkan/system/vk_framebuffer.h b/src/rendering/vulkan/system/vk_framebuffer.h index 118d894b4..8780fdb86 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.h +++ b/src/rendering/vulkan/system/vk_framebuffer.h @@ -6,7 +6,9 @@ class VkSamplerManager; class VkShaderManager; +class VkRenderPassManager; class VkRenderState; +class VKDataBuffer; class VulkanFrameBuffer : public SystemBaseFrameBuffer { @@ -18,6 +20,12 @@ public: VulkanCommandBuffer *GetUploadCommands(); VulkanCommandBuffer *GetDrawCommands(); + VkShaderManager *GetShaderManager() { return mShaderManager.get(); } + VkRenderPassManager *GetRenderPassManager() { return mRenderPassManager.get(); } + VkRenderState *GetRenderState() { return mRenderState.get(); } + + VKDataBuffer *ViewpointUBO = nullptr; + VKDataBuffer *LightBufferSSO = nullptr; VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevice *dev); ~VulkanFrameBuffer(); @@ -56,6 +64,7 @@ public: private: std::unique_ptr mShaderManager; std::unique_ptr mSamplerManager; + std::unique_ptr mRenderPassManager; std::unique_ptr mGraphicsCommandPool; std::unique_ptr mUploadCommands; std::unique_ptr mPresentCommands; diff --git a/src/rendering/vulkan/system/vk_objects.h b/src/rendering/vulkan/system/vk_objects.h index 22422aa7f..9492fe1ed 100644 --- a/src/rendering/vulkan/system/vk_objects.h +++ b/src/rendering/vulkan/system/vk_objects.h @@ -229,7 +229,7 @@ public: void setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask); void setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask); void setStencilReference(VkStencilFaceFlags faceMask, uint32_t reference); - void bindDescriptorSet(VkPipelineBindPoint pipelineBindPoint, VulkanPipelineLayout *layout, VulkanDescriptorSet *descriptorSet, uint32_t dynamicOffsetCount = 0, const uint32_t* pDynamicOffsets = nullptr); + void bindDescriptorSet(VkPipelineBindPoint pipelineBindPoint, VulkanPipelineLayout *layout, uint32_t setIndex, VulkanDescriptorSet *descriptorSet, uint32_t dynamicOffsetCount = 0, const uint32_t* pDynamicOffsets = nullptr); void bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets); void bindIndexBuffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); void bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets); @@ -545,9 +545,9 @@ inline void VulkanCommandBuffer::setStencilReference(VkStencilFaceFlags faceMask vkCmdSetStencilReference(buffer, faceMask, reference); } -inline void VulkanCommandBuffer::bindDescriptorSet(VkPipelineBindPoint pipelineBindPoint, VulkanPipelineLayout *layout, VulkanDescriptorSet *descriptorSet, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets) +inline void VulkanCommandBuffer::bindDescriptorSet(VkPipelineBindPoint pipelineBindPoint, VulkanPipelineLayout *layout, uint32_t setIndex, VulkanDescriptorSet *descriptorSet, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets) { - bindDescriptorSets(pipelineBindPoint, layout->layout, 0, 1, &descriptorSet->set, dynamicOffsetCount, pDynamicOffsets); + bindDescriptorSets(pipelineBindPoint, layout->layout, setIndex, 1, &descriptorSet->set, dynamicOffsetCount, pDynamicOffsets); } inline void VulkanCommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)