From 7bf734cdd45d9aa75fc87455cd5cadd36544e2f5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 3 Mar 2020 22:26:57 +0100 Subject: [PATCH] Improve pipeline building --- examples/VulkanTest/main.cpp | 157 +----------- .../bin/resources/shaders/triangle.frag.spv | Bin 572 -> 572 bytes examples/bin/resources/shaders/triangle.vert | 4 +- .../bin/resources/shaders/triangle.vert.spv | Bin 1492 -> 1444 bytes include/Nazara/Core/Algorithm.hpp | 1 + include/Nazara/Core/Algorithm.inl | 6 + include/Nazara/Renderer/RenderStates.hpp | 8 + include/Nazara/Utility/VertexDeclaration.hpp | 2 +- include/Nazara/Utility/VertexDeclaration.inl | 17 +- include/Nazara/Utility/VertexMapper.hpp | 2 +- include/Nazara/Utility/VertexMapper.inl | 12 +- include/Nazara/VulkanRenderer/Utils.hpp | 3 + include/Nazara/VulkanRenderer/Utils.inl | 37 +++ .../VulkanRenderer/VulkanRenderPipeline.hpp | 17 +- src/Nazara/Utility/VertexDeclaration.cpp | 232 ++++++++++++++---- .../VulkanRenderer/VulkanRenderPipeline.cpp | 79 +++++- 16 files changed, 360 insertions(+), 217 deletions(-) diff --git a/examples/VulkanTest/main.cpp b/examples/VulkanTest/main.cpp index e731f04ed..811c8a21f 100644 --- a/examples/VulkanTest/main.cpp +++ b/examples/VulkanTest/main.cpp @@ -223,8 +223,15 @@ int main() descriptorSet.WriteUniformDescriptor(0, uniformBufferImpl->GetBufferHandle(), 0, uniformSize); Nz::RenderPipelineInfo pipelineInfo; + pipelineInfo.shaderStages.emplace_back(fragmentShader); + pipelineInfo.shaderStages.emplace_back(vertexShader); - std::unique_ptr pipeline = device->InstantiateRenderPipeline(pipelineInfo); + auto& vertexBuffer = pipelineInfo.vertexBuffers.emplace_back(); + vertexBuffer.binding = 0; + vertexBuffer.declaration = drfreakVB->GetVertexDeclaration(); + + + //std::unique_ptr pipeline = device->InstantiateRenderPipeline(pipelineInfo); VkDescriptorSetLayout descriptorSetLayout = descriptorLayout; @@ -241,150 +248,12 @@ int main() Nz::Vk::PipelineLayout pipelineLayout; pipelineLayout.Create(vulkanDevice.shared_from_this(), layout_create_info); - - std::array shaderStageCreateInfo = { - { - { - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - nullptr, - 0, - VK_SHADER_STAGE_VERTEX_BIT, - static_cast(vertexShader.get())->GetHandle(), - "main", - nullptr - }, - { - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - nullptr, - 0, - VK_SHADER_STAGE_FRAGMENT_BIT, - static_cast(fragmentShader.get())->GetHandle(), - "main", - nullptr - } - } - }; - - VkVertexInputBindingDescription bindingDescription = { - 0, - drfreakVB->GetStride(), - VK_VERTEX_INPUT_RATE_VERTEX - }; - - std::array attributeDescription = - { - { - { - 0, // uint32_t location - 0, // uint32_t binding; - VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format; - 0 // uint32_t offset; - }, - { - 1, // uint32_t location - 0, // uint32_t binding; - VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format; - sizeof(float) * 3 // uint32_t offset; - } - } - }; - - VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info = { - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType - nullptr, // const void *pNext - 0, // VkPipelineVertexInputStateCreateFlags flags; - 1, // uint32_t vertexBindingDescriptionCount - &bindingDescription, // const VkVertexInputBindingDescription *pVertexBindingDescriptions - Nz::UInt32(attributeDescription.size()), // uint32_t vertexAttributeDescriptionCount - attributeDescription.data() // const VkVertexInputAttributeDescription *pVertexAttributeDescriptions - }; - - VkPipelineViewportStateCreateInfo viewport_state_create_info = { - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType - nullptr, // const void *pNext - 0, // VkPipelineViewportStateCreateFlags flags - 1, // uint32_t viewportCount - nullptr, // const VkViewport *pViewports - 1, // uint32_t scissorCount - nullptr // const VkRect2D *pScissors - }; - - VkPipelineInputAssemblyStateCreateInfo input_assembly_state_create_info = Nz::VulkanRenderPipeline::BuildInputAssemblyInfo(pipelineInfo); - VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = Nz::VulkanRenderPipeline::BuildRasterizationInfo(pipelineInfo); - VkPipelineDepthStencilStateCreateInfo depthStencilInfo = Nz::VulkanRenderPipeline::BuildDepthStencilInfo(pipelineInfo); - - VkPipelineMultisampleStateCreateInfo multisample_state_create_info = { - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType - nullptr, // const void *pNext - 0, // VkPipelineMultisampleStateCreateFlags flags - VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples - VK_FALSE, // VkBool32 sampleShadingEnable - 1.0f, // float minSampleShading - nullptr, // const VkSampleMask *pSampleMask - VK_FALSE, // VkBool32 alphaToCoverageEnable - VK_FALSE // VkBool32 alphaToOneEnable - }; - - VkPipelineColorBlendAttachmentState color_blend_attachment_state = { - VK_FALSE, // VkBool32 blendEnable - VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor - VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor - VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp - VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor - VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor - VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp - VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT - }; - - VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = { - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType - nullptr, // const void *pNext - 0, // VkPipelineColorBlendStateCreateFlags flags - VK_FALSE, // VkBool32 logicOpEnable - VK_LOGIC_OP_COPY, // VkLogicOp logicOp - 1, // uint32_t attachmentCount - &color_blend_attachment_state, // const VkPipelineColorBlendAttachmentState *pAttachments - {0.0f, 0.0f, 0.0f, 0.0f} // float blendConstants[4] - }; - - std::array dynamicStates = { - VK_DYNAMIC_STATE_SCISSOR, - VK_DYNAMIC_STATE_VIEWPORT, - }; - - VkPipelineDynamicStateCreateInfo dynamicStateInfo = { - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType; - nullptr, // const void* pNext; - 0, // VkPipelineDynamicStateCreateFlags flags; - Nz::UInt32(dynamicStates.size()), // uint32_t dynamicStateCount; - dynamicStates.data() // const VkDynamicState* pDynamicStates; - }; - - VkGraphicsPipelineCreateInfo pipeline_create_info = { - VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType - nullptr, // const void *pNext - 0, // VkPipelineCreateFlags flags - static_cast(shaderStageCreateInfo.size()), // uint32_t stageCount - shaderStageCreateInfo.data(), // const VkPipelineShaderStageCreateInfo *pStages - &vertex_input_state_create_info, // const VkPipelineVertexInputStateCreateInfo *pVertexInputState; - &input_assembly_state_create_info, // const VkPipelineInputAssemblyStateCreateInfo *pInputAssemblyState - nullptr, // const VkPipelineTessellationStateCreateInfo *pTessellationState - &viewport_state_create_info, // const VkPipelineViewportStateCreateInfo *pViewportState - &rasterization_state_create_info, // const VkPipelineRasterizationStateCreateInfo *pRasterizationState - &multisample_state_create_info, // const VkPipelineMultisampleStateCreateInfo *pMultisampleState - &depthStencilInfo, // const VkPipelineDepthStencilStateCreateInfo *pDepthStencilState - &color_blend_state_create_info, // const VkPipelineColorBlendStateCreateInfo *pColorBlendState - &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo *pDynamicState - pipelineLayout, // VkPipelineLayout layout - vulkanWindow.GetRenderPass(), // VkRenderPass renderPass - 0, // uint32_t subpass - VK_NULL_HANDLE, // VkPipeline basePipelineHandle - -1 // int32_t basePipelineIndex - }; + Nz::VulkanRenderPipeline::CreateInfo pipelineCreateInfo = Nz::VulkanRenderPipeline::BuildCreateInfo(pipelineInfo); + pipelineCreateInfo.pipelineInfo.layout = pipelineLayout; + pipelineCreateInfo.pipelineInfo.renderPass = vulkanWindow.GetRenderPass(); Nz::Vk::Pipeline vkPipeline; - if (!vkPipeline.CreateGraphics(vulkanDevice.shared_from_this(), pipeline_create_info)) + if (!vkPipeline.CreateGraphics(vulkanDevice.shared_from_this(), pipelineCreateInfo.pipelineInfo)) { NazaraError("Failed to create pipeline"); return __LINE__; @@ -501,7 +370,7 @@ int main() // Gestion de la caméra free-fly (Rotation) float sensitivity = 0.3f; // Sensibilité de la souris - // On modifie l'angle de la caméra grâce au déplacement relatif sur X de la souris + // On modifie l'angle de la caméra grâce au déplacement relatif sur X de la souris camAngles.yaw = Nz::NormalizeAngle(camAngles.yaw - event.mouseMove.deltaX*sensitivity); // Idem, mais pour éviter les problèmes de calcul de la matrice de vue, on restreint les angles diff --git a/examples/bin/resources/shaders/triangle.frag.spv b/examples/bin/resources/shaders/triangle.frag.spv index 06ab7a2fc2398c7fe17c45bb65069587bc9af78c..3804e0ca05a6071d94591cb640444938edc1df7b 100644 GIT binary patch delta 18 ZcmdnPvWJC}nMs+Qfq{{MV3Y!EeG JiywY`Nxplb6Au6Y delta 293 zcmXwzOA5k35JYQ|_<=AWo std::size_t CountOf(const T& c); template void HashCombine(std::size_t& seed, const T& v); template T ReverseBits(T integer); + template auto UnderlyingCast(T value) -> std::underlying_type_t; template struct AlwaysFalse : std::false_type {}; diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index f21b0c36a..391e32326 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -195,6 +195,12 @@ namespace Nz return reversed; } + template + auto UnderlyingCast(T value) -> std::underlying_type_t + { + return static_cast>(value); + } + template struct PointedType { using type = T; }; template struct PointedType { using type = T; }; template struct PointedType { using type = T; }; diff --git a/include/Nazara/Renderer/RenderStates.hpp b/include/Nazara/Renderer/RenderStates.hpp index f4d4ea369..f1c0ff6cb 100644 --- a/include/Nazara/Renderer/RenderStates.hpp +++ b/include/Nazara/Renderer/RenderStates.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -36,7 +37,14 @@ namespace Nz UInt32 writeMask = 0xFFFFFFFF; } stencilBack, stencilFront; + struct VertexBufferData + { + std::size_t binding; + VertexDeclarationConstRef declaration; + }; + std::vector> shaderStages; + std::vector vertexBuffers; bool blending = false; bool colorWrite = true; diff --git a/include/Nazara/Utility/VertexDeclaration.hpp b/include/Nazara/Utility/VertexDeclaration.hpp index 649482e6b..a11b3b798 100644 --- a/include/Nazara/Utility/VertexDeclaration.hpp +++ b/include/Nazara/Utility/VertexDeclaration.hpp @@ -53,7 +53,7 @@ namespace Nz VertexDeclaration& operator=(const VertexDeclaration&) = delete; VertexDeclaration& operator=(VertexDeclaration&&) noexcept = default; - static const VertexDeclarationRef& Get(VertexLayout layout); + static inline const VertexDeclarationRef& Get(VertexLayout layout); static bool IsTypeSupported(ComponentType type); template static VertexDeclarationRef New(Args&&... args); diff --git a/include/Nazara/Utility/VertexDeclaration.inl b/include/Nazara/Utility/VertexDeclaration.inl index f1ee4c290..1e1462556 100644 --- a/include/Nazara/Utility/VertexDeclaration.inl +++ b/include/Nazara/Utility/VertexDeclaration.inl @@ -67,7 +67,7 @@ namespace Nz return GetComponentByType(vertexComponent, componentIndex) != nullptr; } - const VertexDeclarationRef& VertexDeclaration::Get(VertexLayout layout) + inline const VertexDeclarationRef& VertexDeclaration::Get(VertexLayout layout) { NazaraAssert(layout <= VertexLayout_Max, "Vertex layout out of enum"); @@ -84,4 +84,19 @@ namespace Nz } } +namespace std +{ + inline const Nz::VertexDeclaration::Component* begin(const Nz::VertexDeclaration& declaration) + { + assert(declaration.GetComponentCount() != 0); + return &declaration.GetComponent(0); + } + + inline const Nz::VertexDeclaration::Component* end(const Nz::VertexDeclaration& declaration) + { + assert(declaration.GetComponentCount() != 0); + return (&declaration.GetComponent(declaration.GetComponentCount() - 1) + 1); + } +} + #include diff --git a/include/Nazara/Utility/VertexMapper.hpp b/include/Nazara/Utility/VertexMapper.hpp index d76d830a6..80680a86d 100644 --- a/include/Nazara/Utility/VertexMapper.hpp +++ b/include/Nazara/Utility/VertexMapper.hpp @@ -26,7 +26,7 @@ namespace Nz VertexMapper(const VertexBuffer* vertexBuffer, BufferAccess access = BufferAccess_ReadOnly); ~VertexMapper(); - template SparsePtr GetComponentPtr(VertexComponent component); + template SparsePtr GetComponentPtr(VertexComponent component, std::size_t componentIndex = 0); inline const VertexBuffer* GetVertexBuffer() const; inline std::size_t GetVertexCount() const; diff --git a/include/Nazara/Utility/VertexMapper.inl b/include/Nazara/Utility/VertexMapper.inl index bdb1edfc2..736a51c35 100644 --- a/include/Nazara/Utility/VertexMapper.inl +++ b/include/Nazara/Utility/VertexMapper.inl @@ -10,19 +10,13 @@ namespace Nz { template - SparsePtr VertexMapper::GetComponentPtr(VertexComponent component) + SparsePtr VertexMapper::GetComponentPtr(VertexComponent component, std::size_t componentIndex) { // On récupère la déclaration depuis le buffer const VertexDeclaration* declaration = m_mapper.GetBuffer()->GetVertexDeclaration(); - // Ensuite le composant qui nous intéresse - bool enabled; - ComponentType type; - std::size_t offset; - declaration->GetComponent(component, &enabled, &type, &offset); - - if (enabled && GetComponentTypeOf() == type) - return SparsePtr(static_cast(m_mapper.GetPointer()) + offset, declaration->GetStride()); + if (const auto* componentData = declaration->GetComponentByType(component, componentIndex)) + return SparsePtr(static_cast(m_mapper.GetPointer()) + componentData->offset, declaration->GetStride()); else return SparsePtr(); } diff --git a/include/Nazara/VulkanRenderer/Utils.hpp b/include/Nazara/VulkanRenderer/Utils.hpp index 40e5009a9..1c1d6715e 100644 --- a/include/Nazara/VulkanRenderer/Utils.hpp +++ b/include/Nazara/VulkanRenderer/Utils.hpp @@ -15,12 +15,15 @@ namespace Nz { + inline VkFormat ToVulkan(ComponentType componentType); inline VkCullModeFlagBits ToVulkan(FaceSide faceSide); inline VkPolygonMode ToVulkan(FaceFilling faceFilling); inline VkPrimitiveTopology ToVulkan(PrimitiveMode primitiveMode); inline VkCompareOp ToVulkan(RendererComparison comparison); inline VkShaderStageFlagBits ToVulkan(ShaderStageType stageType); inline VkStencilOp ToVulkan(StencilOperation stencilOp); + inline VkVertexInputRate ToVulkan(VertexInputRate inputRate); + NAZARA_VULKANRENDERER_API String TranslateVulkanError(VkResult code); } diff --git a/include/Nazara/VulkanRenderer/Utils.inl b/include/Nazara/VulkanRenderer/Utils.inl index 1f806bc43..723483292 100644 --- a/include/Nazara/VulkanRenderer/Utils.inl +++ b/include/Nazara/VulkanRenderer/Utils.inl @@ -3,12 +3,37 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include namespace Nz { + VkFormat ToVulkan(ComponentType componentType) + { + switch (componentType) + { + case ComponentType_Color: return VK_FORMAT_R8G8B8A8_UINT; + case ComponentType_Double1: return VK_FORMAT_R64_SFLOAT; + case ComponentType_Double2: return VK_FORMAT_R64G64_SFLOAT; + case ComponentType_Double3: return VK_FORMAT_R64G64B64_SFLOAT; + case ComponentType_Double4: return VK_FORMAT_R64G64B64A64_SFLOAT; + case ComponentType_Float1: return VK_FORMAT_R32_SFLOAT; + case ComponentType_Float2: return VK_FORMAT_R32G32_SFLOAT; + case ComponentType_Float3: return VK_FORMAT_R32G32B32_SFLOAT; + case ComponentType_Float4: return VK_FORMAT_R32G32B32A32_SFLOAT; + case ComponentType_Int1: return VK_FORMAT_R32_SINT; + case ComponentType_Int2: return VK_FORMAT_R32G32_SINT; + case ComponentType_Int3: return VK_FORMAT_R32G32B32_SINT; + case ComponentType_Int4: return VK_FORMAT_R32G32B32A32_SINT; + case ComponentType_Quaternion: return VK_FORMAT_R32G32B32A32_SFLOAT; + } + + NazaraError("Unhandled ComponentType 0x" + String::Number(componentType, 16)); + return VK_FORMAT_UNDEFINED; + } + VkCullModeFlagBits ToVulkan(FaceSide faceSide) { switch (faceSide) @@ -99,6 +124,18 @@ namespace Nz NazaraError("Unhandled RendererComparison 0x" + String::Number(stencilOp, 16)); return VK_STENCIL_OP_KEEP; } + + VkVertexInputRate ToVulkan(VertexInputRate inputRate) + { + switch (inputRate) + { + case VertexInputRate::Instance: return VK_VERTEX_INPUT_RATE_INSTANCE; + case VertexInputRate::Vertex: return VK_VERTEX_INPUT_RATE_VERTEX; + } + + NazaraError("Unhandled VertexInputRate 0x" + String::Number(UnderlyingCast(inputRate), 16)); + return VK_VERTEX_INPUT_RATE_VERTEX; + } } #include diff --git a/include/Nazara/VulkanRenderer/VulkanRenderPipeline.hpp b/include/Nazara/VulkanRenderer/VulkanRenderPipeline.hpp index 76f73d224..5c292da04 100644 --- a/include/Nazara/VulkanRenderer/VulkanRenderPipeline.hpp +++ b/include/Nazara/VulkanRenderer/VulkanRenderPipeline.hpp @@ -29,10 +29,14 @@ namespace Nz static VkPipelineDynamicStateCreateInfo BuildDynamicStateInfo(const RenderPipelineInfo& pipelineInfo, const std::vector& dynamicStates); static std::vector BuildDynamicStateList(const RenderPipelineInfo& pipelineInfo); static VkPipelineInputAssemblyStateCreateInfo BuildInputAssemblyInfo(const RenderPipelineInfo& pipelineInfo); + static VkPipelineMultisampleStateCreateInfo BuildMultisampleInfo(const RenderPipelineInfo& pipelineInfo); static VkPipelineRasterizationStateCreateInfo BuildRasterizationInfo(const RenderPipelineInfo& pipelineInfo); static VkPipelineViewportStateCreateInfo BuildViewportInfo(const RenderPipelineInfo& pipelineInfo); static VkStencilOpState BuildStencilOp(const RenderPipelineInfo& pipelineInfo, bool front); static std::vector BuildShaderStageInfo(const RenderPipelineInfo& pipelineInfo); + static std::vector BuildVertexAttributeDescription(const RenderPipelineInfo& pipelineInfo); + static std::vector BuildVertexBindingDescription(const RenderPipelineInfo& pipelineInfo); + static VkPipelineVertexInputStateCreateInfo BuildVertexInputInfo(const RenderPipelineInfo& pipelineInfo, const std::vector& vertexAttributes, const std::vector& bindingDescription); static CreateInfo BuildCreateInfo(const RenderPipelineInfo& pipelineInfo); @@ -40,18 +44,21 @@ namespace Nz { struct StateData { - VkPipelineVertexInputStateCreateInfo vertexInputState; - VkPipelineInputAssemblyStateCreateInfo inputAssemblyState; - VkPipelineViewportStateCreateInfo viewportState; - VkPipelineRasterizationStateCreateInfo rasterizationState; - VkPipelineDepthStencilStateCreateInfo depthStencilState; VkPipelineColorBlendStateCreateInfo colorBlendState; + VkPipelineDepthStencilStateCreateInfo depthStencilState; VkPipelineDynamicStateCreateInfo dynamicState; + VkPipelineMultisampleStateCreateInfo multiSampleState; + VkPipelineInputAssemblyStateCreateInfo inputAssemblyState; + VkPipelineRasterizationStateCreateInfo rasterizationState; + VkPipelineVertexInputStateCreateInfo vertexInputState; + VkPipelineViewportStateCreateInfo viewportState; }; std::vector colorBlendAttachmentState; std::vector dynamicStates; std::vector shaderStages; + std::vector vertexAttributesDescription; + std::vector vertexBindingDescription; std::unique_ptr stateData; VkGraphicsPipelineCreateInfo pipelineInfo; }; diff --git a/src/Nazara/Utility/VertexDeclaration.cpp b/src/Nazara/Utility/VertexDeclaration.cpp index d44692e31..61c7f1d86 100644 --- a/src/Nazara/Utility/VertexDeclaration.cpp +++ b/src/Nazara/Utility/VertexDeclaration.cpp @@ -106,86 +106,216 @@ namespace Nz }); NazaraAssert(s_declarations[VertexLayout_XY_Color]->GetStride() == sizeof(VertexStruct_XY_Color), "Invalid stride for declaration VertexLayout_XY_Color"); - /* + // VertexLayout_XY_UV : VertexStruct_XY_UV - declaration = &s_declarations[VertexLayout_XY_UV]; - declaration->EnableComponent(VertexComponent_Position, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XY_UV, position)); - declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XY_UV, uv)); + s_declarations[VertexLayout_XY_UV] = NewDeclaration(VertexInputRate::Vertex, { + { + VertexComponent_Position, + ComponentType_Float2, + 0 + }, + { + VertexComponent_TexCoord, + ComponentType_Float2, + 0 + }, + }); - NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XY_UV), "Invalid stride for declaration VertexLayout_XY_UV"); + NazaraAssert(s_declarations[VertexLayout_XY_UV]->GetStride() == sizeof(VertexStruct_XY_UV), "Invalid stride for declaration VertexLayout_XY_UV"); // VertexLayout_XYZ : VertexStruct_XYZ - declaration = &s_declarations[VertexLayout_XYZ]; - declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ, position)); + s_declarations[VertexLayout_XYZ] = NewDeclaration(VertexInputRate::Vertex, { + { + VertexComponent_Position, + ComponentType_Float3, + 0 + }, + }); - NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ), "Invalid stride for declaration VertexLayout_XYZ"); + NazaraAssert(s_declarations[VertexLayout_XYZ]->GetStride() == sizeof(VertexStruct_XYZ), "Invalid stride for declaration VertexLayout_XYZ"); // VertexLayout_XYZ_Color : VertexStruct_XYZ_Color - declaration = &s_declarations[VertexLayout_XYZ_Color]; - declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Color, position)); - declaration->EnableComponent(VertexComponent_Color, ComponentType_Color, NazaraOffsetOf(VertexStruct_XYZ_Color, color)); + s_declarations[VertexLayout_XYZ_Color] = NewDeclaration(VertexInputRate::Vertex, { + { + VertexComponent_Position, + ComponentType_Float3, + 0 + }, + { + VertexComponent_Color, + ComponentType_Color, + 0 + } + }); - NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Color), "Invalid stride for declaration VertexLayout_XYZ_Color"); + NazaraAssert(s_declarations[VertexLayout_XYZ_Color]->GetStride() == sizeof(VertexStruct_XYZ_Color), "Invalid stride for declaration VertexLayout_XYZ_Color"); // VertexLayout_XYZ_Color_UV : VertexStruct_XYZ_Color_UV - declaration = &s_declarations[VertexLayout_XYZ_Color_UV]; - declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Color_UV, position)); - declaration->EnableComponent(VertexComponent_Color, ComponentType_Color, NazaraOffsetOf(VertexStruct_XYZ_Color_UV, color)); - declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XYZ_Color_UV, uv)); + s_declarations[VertexLayout_XYZ_Color_UV] = NewDeclaration(VertexInputRate::Vertex, { + { + VertexComponent_Position, + ComponentType_Float3, + 0 + }, + { + VertexComponent_Color, + ComponentType_Color, + 0 + }, + { + VertexComponent_TexCoord, + ComponentType_Float2, + 0 + }, + }); - NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Color_UV), "Invalid stride for declaration VertexLayout_XYZ_Color_UV"); + NazaraAssert(s_declarations[VertexLayout_XYZ_Color_UV]->GetStride() == sizeof(VertexStruct_XYZ_Color_UV), "Invalid stride for declaration VertexLayout_XYZ_Color_UV"); // VertexLayout_XYZ_Normal : VertexStruct_XYZ_Normal - declaration = &s_declarations[VertexLayout_XYZ_Normal]; - declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal, position)); - declaration->EnableComponent(VertexComponent_Normal, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal, normal)); + s_declarations[VertexLayout_XYZ_Normal] = NewDeclaration(VertexInputRate::Vertex, { + { + VertexComponent_Position, + ComponentType_Float3, + 0 + }, + { + VertexComponent_Normal, + ComponentType_Float3, + 0 + } + }); - NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Normal), "Invalid stride for declaration VertexLayout_XYZ_Normal"); + NazaraAssert(s_declarations[VertexLayout_XYZ_Normal]->GetStride() == sizeof(VertexStruct_XYZ_Normal), "Invalid stride for declaration VertexLayout_XYZ_Normal"); // VertexLayout_XYZ_Normal_UV : VertexStruct_XYZ_Normal_UV - declaration = &s_declarations[VertexLayout_XYZ_Normal_UV]; - declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV, position)); - declaration->EnableComponent(VertexComponent_Normal, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV, normal)); - declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV, uv)); + s_declarations[VertexLayout_XYZ_Normal_UV] = NewDeclaration(VertexInputRate::Vertex, { + { + VertexComponent_Position, + ComponentType_Float3, + 0 + }, + { + VertexComponent_Normal, + ComponentType_Float3, + 0 + }, + { + VertexComponent_TexCoord, + ComponentType_Float2, + 0 + } + }); - NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Normal_UV), "Invalid stride for declaration VertexLayout_XYZ_Normal_UV"); + NazaraAssert(s_declarations[VertexLayout_XYZ_Normal_UV]->GetStride() == sizeof(VertexStruct_XYZ_Normal_UV), "Invalid stride for declaration VertexLayout_XYZ_Normal_UV"); // VertexLayout_XYZ_Normal_UV_Tangent : VertexStruct_XYZ_Normal_UV_Tangent - declaration = &s_declarations[VertexLayout_XYZ_Normal_UV_Tangent]; - declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent, position)); - declaration->EnableComponent(VertexComponent_Normal, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent, normal)); - declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent, uv)); - declaration->EnableComponent(VertexComponent_Tangent, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent, tangent)); + s_declarations[VertexLayout_XYZ_Normal_UV_Tangent] = NewDeclaration(VertexInputRate::Vertex, { + { + VertexComponent_Position, + ComponentType_Float3, + 0 + }, + { + VertexComponent_Normal, + ComponentType_Float3, + 0 + }, + { + VertexComponent_TexCoord, + ComponentType_Float2, + 0 + }, + { + VertexComponent_Tangent, + ComponentType_Float3, + 0 + } + }); - NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Normal_UV_Tangent), "Invalid stride for declaration VertexLayout_XYZ_Normal_UV_Tangent"); + NazaraAssert(s_declarations[VertexLayout_XYZ_Normal_UV_Tangent]->GetStride() == sizeof(VertexStruct_XYZ_Normal_UV_Tangent), "Invalid stride for declaration VertexLayout_XYZ_Normal_UV_Tangent"); // VertexLayout_XYZ_Normal_UV_Tangent_Skinning : VertexStruct_XYZ_Normal_UV_Tangent_Skinning - declaration = &s_declarations[VertexLayout_XYZ_Normal_UV_Tangent_Skinning]; - declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, position)); - declaration->EnableComponent(VertexComponent_Normal, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, normal)); - declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, uv)); - declaration->EnableComponent(VertexComponent_Tangent, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, tangent)); - declaration->EnableComponent(VertexComponent_Unused, ComponentType_Int1, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, weightCount)); - declaration->EnableComponent(VertexComponent_Userdata0, ComponentType_Float4, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, weights)); - declaration->EnableComponent(VertexComponent_Userdata1, ComponentType_Int4, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, jointIndexes)); + s_declarations[VertexLayout_XYZ_Normal_UV_Tangent_Skinning] = NewDeclaration(VertexInputRate::Vertex, { + { + VertexComponent_Position, + ComponentType_Float3, + 0 + }, + { + VertexComponent_Normal, + ComponentType_Float3, + 0 + }, + { + VertexComponent_TexCoord, + ComponentType_Float2, + 0 + }, + { + VertexComponent_Tangent, + ComponentType_Float3, + 0 + }, + { + VertexComponent_Userdata, + ComponentType_Int1, + 0 // Weight count + }, + { + VertexComponent_Userdata, + ComponentType_Float4, + 1 // Weights + }, + { + VertexComponent_Userdata, + ComponentType_Int4, + 2 // Joint indexes + }, + }); - NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Normal_UV_Tangent_Skinning), "Invalid stride for declaration VertexLayout_XYZ_Normal_UV_Tangent_Skinning"); + NazaraAssert(s_declarations[VertexLayout_XYZ_Normal_UV_Tangent_Skinning]->GetStride() == sizeof(VertexStruct_XYZ_Normal_UV_Tangent_Skinning), "Invalid stride for declaration VertexLayout_XYZ_Normal_UV_Tangent_Skinning"); // VertexLayout_XYZ_UV : VertexStruct_XYZ_UV - declaration = &s_declarations[VertexLayout_XYZ_UV]; - declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_UV, position)); - declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XYZ_UV, uv)); + s_declarations[VertexLayout_XYZ_UV] = NewDeclaration(VertexInputRate::Vertex, { + { + VertexComponent_Position, + ComponentType_Float3, + 0 + }, + { + VertexComponent_TexCoord, + ComponentType_Float2, + 0 + } + }); - NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_UV), "Invalid stride for declaration VertexLayout_XYZ_UV"); + NazaraAssert(s_declarations[VertexLayout_XYZ_UV]->GetStride() == sizeof(VertexStruct_XYZ_UV), "Invalid stride for declaration VertexLayout_XYZ_UV"); // VertexLayout_Matrix4 : Matrix4f - declaration = &s_declarations[VertexLayout_Matrix4]; - declaration->EnableComponent(VertexComponent_InstanceData0, ComponentType_Float4, NazaraOffsetOf(Matrix4f, m11)); - declaration->EnableComponent(VertexComponent_InstanceData1, ComponentType_Float4, NazaraOffsetOf(Matrix4f, m21)); - declaration->EnableComponent(VertexComponent_InstanceData2, ComponentType_Float4, NazaraOffsetOf(Matrix4f, m31)); - declaration->EnableComponent(VertexComponent_InstanceData3, ComponentType_Float4, NazaraOffsetOf(Matrix4f, m41)); + s_declarations[VertexLayout_Matrix4] = NewDeclaration(VertexInputRate::Vertex, { + { + VertexComponent_Userdata, + ComponentType_Float4, + 0 + }, + { + VertexComponent_Userdata, + ComponentType_Float4, + 1 + }, + { + VertexComponent_Userdata, + ComponentType_Float4, + 2 + }, + { + VertexComponent_Userdata, + ComponentType_Float4, + 3 + } + }); - NazaraAssert(declaration->GetStride() == sizeof(Matrix4f), "Invalid stride for declaration VertexLayout_Matrix4");*/ + NazaraAssert(s_declarations[VertexLayout_Matrix4]->GetStride() == sizeof(Matrix4f), "Invalid stride for declaration VertexLayout_Matrix4"); } catch (const std::exception& e) { diff --git a/src/Nazara/VulkanRenderer/VulkanRenderPipeline.cpp b/src/Nazara/VulkanRenderer/VulkanRenderPipeline.cpp index 99a185107..fca5229c1 100644 --- a/src/Nazara/VulkanRenderer/VulkanRenderPipeline.cpp +++ b/src/Nazara/VulkanRenderer/VulkanRenderPipeline.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace Nz @@ -21,7 +22,7 @@ namespace Nz { std::vector colorBlendStates; - VkPipelineColorBlendAttachmentState colorBlendState = colorBlendStates.emplace_back(); + VkPipelineColorBlendAttachmentState& colorBlendState = colorBlendStates.emplace_back(); colorBlendState.blendEnable = pipelineInfo.blending; colorBlendState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; //< TODO @@ -94,6 +95,16 @@ namespace Nz return createInfo; } + VkPipelineMultisampleStateCreateInfo VulkanRenderPipeline::BuildMultisampleInfo(const RenderPipelineInfo& pipelineInfo) + { + VkPipelineMultisampleStateCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + createInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + createInfo.minSampleShading = 1.0f; //< TODO: Remove + + return createInfo; + } + VkPipelineRasterizationStateCreateInfo VulkanRenderPipeline::BuildRasterizationInfo(const RenderPipelineInfo& pipelineInfo) { VkPipelineRasterizationStateCreateInfo createInfo = {}; @@ -149,6 +160,58 @@ namespace Nz return shaderStageCreateInfos; } + std::vector VulkanRenderPipeline::BuildVertexAttributeDescription(const RenderPipelineInfo& pipelineInfo) + { + std::vector vertexAttributes; + + std::uint32_t locationIndex = 0; + + for (const auto& bufferData : pipelineInfo.vertexBuffers) + { + std::uint32_t binding = std::uint32_t(bufferData.binding); + + for (const auto& componentInfo : *bufferData.declaration) + { + auto& bufferAttribute = vertexAttributes.emplace_back(); + bufferAttribute.binding = binding; + bufferAttribute.location = locationIndex++; + bufferAttribute.offset = std::uint32_t(componentInfo.offset); + bufferAttribute.format = ToVulkan(componentInfo.type); + } + } + + return vertexAttributes; + } + + std::vector VulkanRenderPipeline::BuildVertexBindingDescription(const RenderPipelineInfo& pipelineInfo) + { + std::vector vertexBindings; + + for (const auto& bufferData : pipelineInfo.vertexBuffers) + { + auto& bufferBinding = vertexBindings.emplace_back(); + bufferBinding.binding = std::uint32_t(bufferData.binding); + bufferBinding.stride = std::uint32_t(bufferData.declaration->GetStride()); + bufferBinding.inputRate = ToVulkan(bufferData.declaration->GetInputRate()); + } + + return vertexBindings; + } + + VkPipelineVertexInputStateCreateInfo VulkanRenderPipeline::BuildVertexInputInfo(const RenderPipelineInfo& pipelineInfo, const std::vector& vertexAttributes, const std::vector& bindingDescriptions) + { + VkPipelineVertexInputStateCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + + createInfo.vertexAttributeDescriptionCount = std::uint32_t(vertexAttributes.size()); + createInfo.pVertexAttributeDescriptions = vertexAttributes.data(); + + createInfo.vertexBindingDescriptionCount = std::uint32_t(bindingDescriptions.size()); + createInfo.pVertexBindingDescriptions = bindingDescriptions.data(); + + return createInfo; + } + auto VulkanRenderPipeline::BuildCreateInfo(const RenderPipelineInfo& pipelineInfo) -> CreateInfo { CreateInfo createInfo = {}; @@ -157,20 +220,30 @@ namespace Nz createInfo.colorBlendAttachmentState = BuildColorBlendAttachmentStateList(pipelineInfo); createInfo.dynamicStates = BuildDynamicStateList(pipelineInfo); createInfo.shaderStages = BuildShaderStageInfo(pipelineInfo); + createInfo.vertexAttributesDescription = BuildVertexAttributeDescription(pipelineInfo); + createInfo.vertexBindingDescription = BuildVertexBindingDescription(pipelineInfo); createInfo.stateData->colorBlendState = BuildColorBlendInfo(pipelineInfo, createInfo.colorBlendAttachmentState); createInfo.stateData->depthStencilState = BuildDepthStencilInfo(pipelineInfo); createInfo.stateData->dynamicState = BuildDynamicStateInfo(pipelineInfo, createInfo.dynamicStates); createInfo.stateData->inputAssemblyState = BuildInputAssemblyInfo(pipelineInfo); + createInfo.stateData->multiSampleState = BuildMultisampleInfo(pipelineInfo); createInfo.stateData->rasterizationState = BuildRasterizationInfo(pipelineInfo); createInfo.stateData->viewportState = BuildViewportInfo(pipelineInfo); + createInfo.stateData->vertexInputState = BuildVertexInputInfo(pipelineInfo, createInfo.vertexAttributesDescription, createInfo.vertexBindingDescription); createInfo.pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; createInfo.pipelineInfo.stageCount = std::uint32_t(createInfo.shaderStages.size()); createInfo.pipelineInfo.pStages = createInfo.shaderStages.data(); - createInfo.pipelineInfo.pColorBlendState = createInfo.colorBlendAttachmentState.data(); - createInfo.pipelineInfo. + createInfo.pipelineInfo.pColorBlendState = &createInfo.stateData->colorBlendState; + createInfo.pipelineInfo.pDepthStencilState = &createInfo.stateData->depthStencilState; + createInfo.pipelineInfo.pDynamicState = &createInfo.stateData->dynamicState; + createInfo.pipelineInfo.pInputAssemblyState = &createInfo.stateData->inputAssemblyState; + createInfo.pipelineInfo.pMultisampleState = &createInfo.stateData->multiSampleState; + createInfo.pipelineInfo.pRasterizationState = &createInfo.stateData->rasterizationState; + createInfo.pipelineInfo.pVertexInputState = &createInfo.stateData->vertexInputState; + createInfo.pipelineInfo.pViewportState = &createInfo.stateData->viewportState; return createInfo; }