diff --git a/src/rendering/vulkan/renderer/vk_renderpass.cpp b/src/rendering/vulkan/renderer/vk_renderpass.cpp index 4625114a56..1307a204ec 100644 --- a/src/rendering/vulkan/renderer/vk_renderpass.cpp +++ b/src/rendering/vulkan/renderer/vk_renderpass.cpp @@ -9,6 +9,10 @@ #include "rendering/2d/v_2ddrawer.h" VkRenderPassManager::VkRenderPassManager() +{ +} + +void VkRenderPassManager::Init() { CreateDynamicSetLayout(); CreateTextureSetLayout(); @@ -60,6 +64,37 @@ VkRenderPassSetup *VkRenderPassManager::GetRenderPass(const VkRenderPassKey &key return item.get(); } +int VkRenderPassManager::GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) +{ + for (size_t i = 0; i < VertexFormats.size(); i++) + { + const auto &f = VertexFormats[i]; + if (f.Attrs.size() == numAttributes && f.NumBindingPoints == numBindingPoints && f.Stride == stride) + { + bool matches = true; + for (int j = 0; j < numAttributes; j++) + { + if (memcmp(&f.Attrs[j], &attrs[j], sizeof(FVertexBufferAttribute)) != 0) + { + matches = false; + break; + } + } + + if (matches) + return (int)i; + } + } + + VkVertexFormat fmt; + fmt.NumBindingPoints = numBindingPoints; + fmt.Stride = stride; + for (int j = 0; j < numAttributes; j++) + fmt.Attrs.push_back(attrs[j]); + VertexFormats.push_back(fmt); + return (int)VertexFormats.size() - 1; +} + void VkRenderPassManager::CreateDynamicSetLayout() { DescriptorSetLayoutBuilder builder; @@ -151,24 +186,25 @@ void VkRenderPassSetup::CreatePipeline(const VkRenderPassKey &key) builder.addVertexShader(program->vert.get()); builder.addFragmentShader(program->frag.get()); - builder.addVertexBufferBinding(0, sizeof(F2DDrawer::TwoDVertex)); - builder.addVertexAttribute(0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(F2DDrawer::TwoDVertex, x)); - builder.addVertexAttribute(1, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(F2DDrawer::TwoDVertex, u)); - builder.addVertexAttribute(2, 0, VK_FORMAT_R8G8B8A8_UNORM, offsetof(F2DDrawer::TwoDVertex, color0)); - builder.addVertexAttribute(3, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(F2DDrawer::TwoDVertex, x)); - builder.addVertexAttribute(4, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(F2DDrawer::TwoDVertex, x)); - builder.addVertexAttribute(5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(F2DDrawer::TwoDVertex, x)); + const VkVertexFormat &vfmt = fb->GetRenderPassManager()->VertexFormats[key.VertexFormat]; -#if 0 - 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)); -#endif + for (int i = 0; i < vfmt.NumBindingPoints; i++) + builder.addVertexBufferBinding(i, vfmt.Stride); + + const static VkFormat vkfmts[] = { + VK_FORMAT_R32G32B32A32_SFLOAT, + VK_FORMAT_R32G32B32_SFLOAT, + VK_FORMAT_R32G32_SFLOAT, + VK_FORMAT_R32_SFLOAT, + VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_A2R10G10B10_SNORM_PACK32 + }; + + for (size_t i = 0; i < vfmt.Attrs.size(); i++) + { + const auto &attr = vfmt.Attrs[i]; + builder.addVertexAttribute(attr.location, attr.binding, vkfmts[attr.format], attr.offset); + } builder.addDynamicState(VK_DYNAMIC_STATE_VIEWPORT); builder.addDynamicState(VK_DYNAMIC_STATE_SCISSOR); diff --git a/src/rendering/vulkan/renderer/vk_renderpass.h b/src/rendering/vulkan/renderer/vk_renderpass.h index 0fd1c985b9..33c4b685f9 100644 --- a/src/rendering/vulkan/renderer/vk_renderpass.h +++ b/src/rendering/vulkan/renderer/vk_renderpass.h @@ -3,6 +3,7 @@ #include "vulkan/system/vk_objects.h" #include "r_data/renderstyle.h" +#include "hwrenderer/data/buffers.h" #include class VKDataBuffer; @@ -14,11 +15,12 @@ public: int SpecialEffect; int EffectState; bool AlphaTest; + int VertexFormat; bool operator<(const VkRenderPassKey &other) const { - uint64_t a = RenderStyle.AsDWORD | (static_cast(SpecialEffect) << 32) | (static_cast(EffectState) << 40) | (static_cast(AlphaTest) << 48); - uint64_t b = other.RenderStyle.AsDWORD | (static_cast(other.SpecialEffect) << 32) | (static_cast(other.EffectState) << 40) | (static_cast(other.AlphaTest) << 48); + uint64_t a = RenderStyle.AsDWORD | (static_cast(SpecialEffect) << 32) | (static_cast(EffectState) << 40) | (static_cast(AlphaTest) << 48) | (static_cast(VertexFormat) << 56); + uint64_t b = other.RenderStyle.AsDWORD | (static_cast(other.SpecialEffect) << 32) | (static_cast(other.EffectState) << 40) | (static_cast(other.AlphaTest) << 48) | (static_cast(other.VertexFormat) << 56); return a < b; } }; @@ -38,14 +40,25 @@ private: void CreateFramebuffer(); }; +class VkVertexFormat +{ +public: + int NumBindingPoints; + size_t Stride; + std::vector Attrs; +}; + class VkRenderPassManager { public: VkRenderPassManager(); + void Init(); void BeginFrame(); VkRenderPassSetup *GetRenderPass(const VkRenderPassKey &key); + int GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs); + std::unique_ptr DynamicSetLayout; std::unique_ptr TextureSetLayout; std::unique_ptr PipelineLayout; @@ -60,6 +73,8 @@ public: std::unique_ptr DynamicSet; + std::vector VertexFormats; + private: void CreateDynamicSetLayout(); void CreateTextureSetLayout(); diff --git a/src/rendering/vulkan/renderer/vk_renderstate.cpp b/src/rendering/vulkan/renderer/vk_renderstate.cpp index 8616085022..10bf944bd8 100644 --- a/src/rendering/vulkan/renderer/vk_renderstate.cpp +++ b/src/rendering/vulkan/renderer/vk_renderstate.cpp @@ -26,13 +26,7 @@ void VkRenderState::ClearScreen() screen->mViewpoints->Set2D(*this, SCREENWIDTH, SCREENHEIGHT); SetColor(0, 0, 0); Apply(DT_TriangleStrip); - - /* - glDisable(GL_MULTISAMPLE); - glDisable(GL_DEPTH_TEST); mCommandBuffer->draw(4, 1, FFlatVertexBuffer::FULLSCREEN_INDEX, 0); - glEnable(GL_DEPTH_TEST); - */ } void VkRenderState::Draw(int dt, int index, int count, bool apply) @@ -55,7 +49,6 @@ void VkRenderState::DrawIndexed(int dt, int index, int count, bool apply) BindDescriptorSets(); drawcalls.Clock(); - if (mMaterial.mMaterial) mCommandBuffer->drawIndexed(count, 1, index, 0, 0); drawcalls.Unclock(); } @@ -147,6 +140,7 @@ void VkRenderState::Apply(int dt) // Find a render pass that matches our state VkRenderPassKey passKey; + passKey.VertexFormat = static_cast(mVertexBuffer)->VertexFormat; passKey.RenderStyle = mRenderStyle; if (mSpecialEffect > EFF_NONE) { diff --git a/src/rendering/vulkan/system/vk_buffers.cpp b/src/rendering/vulkan/system/vk_buffers.cpp index 7bb17f40f6..661329508d 100644 --- a/src/rendering/vulkan/system/vk_buffers.cpp +++ b/src/rendering/vulkan/system/vk_buffers.cpp @@ -3,6 +3,7 @@ #include "vk_builders.h" #include "vk_framebuffer.h" #include "vulkan/renderer/vk_renderstate.h" +#include "vulkan/renderer/vk_renderpass.h" #include "doomerrors.h" VKBuffer::~VKBuffer() @@ -119,6 +120,7 @@ void VKBuffer::Unlock() void VKVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) { + VertexFormat = GetVulkanFrameBuffer()->GetRenderPassManager()->GetVertexFormat(numBindingPoints, numAttributes, stride, attrs); } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/rendering/vulkan/system/vk_buffers.h b/src/rendering/vulkan/system/vk_buffers.h index 72ea6a46a0..eb90f89351 100644 --- a/src/rendering/vulkan/system/vk_buffers.h +++ b/src/rendering/vulkan/system/vk_buffers.h @@ -35,6 +35,8 @@ class VKVertexBuffer : public IVertexBuffer, public VKBuffer public: VKVertexBuffer() { mBufferType = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; } void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) override; + + int VertexFormat = -1; }; class VKIndexBuffer : public IIndexBuffer, public VKBuffer diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index b1d2cbb9f1..0230fa1ef4 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -85,6 +85,8 @@ void VulkanFrameBuffer::InitializeState() mUploadSemaphore.reset(new VulkanSemaphore(device)); mGraphicsCommandPool.reset(new VulkanCommandPool(device, device->graphicsFamily)); + mRenderPassManager.reset(new VkRenderPassManager()); + mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight()); mSkyData = new FSkyVertexBuffer; mViewpoints = new GLViewpointBuffer; @@ -100,7 +102,7 @@ void VulkanFrameBuffer::InitializeState() mShaderManager.reset(new VkShaderManager(device)); mSamplerManager.reset(new VkSamplerManager(device)); - mRenderPassManager.reset(new VkRenderPassManager()); + mRenderPassManager->Init(); mRenderState.reset(new VkRenderState()); }