Add RenderPipelineLayout

This commit is contained in:
Lynix 2020-03-05 20:35:31 +01:00
parent 4941de61da
commit 2b3241f354
25 changed files with 330 additions and 126 deletions

View File

@ -66,24 +66,7 @@ int main()
{
std::cout << properties.layerName << ": \t" << properties.description << std::endl;
}
/*
std::vector<VkExtensionProperties> extensionProperties;
if (!Nz::Vk::Loader::EnumerateInstanceExtensionProperties(&extensionProperties))
{
NazaraError("Failed to enumerate instance extension properties");
return __LINE__;
}
for (const VkExtensionProperties& properties : extensionProperties)
std::cout << properties.extensionName << ": \t" << properties.specVersion << std::endl;
std::vector<VkPhysicalDevice> devices;
if (!instance.EnumeratePhysicalDevices(&devices))
{
NazaraError("Failed to enumerate physical devices");
return __LINE__;
}
*/
Nz::RenderWindow window;
Nz::MeshParams meshParams;
@ -113,22 +96,6 @@ int main()
return __LINE__;
}
Nz::VkRenderWindow& vulkanWindow = *static_cast<Nz::VkRenderWindow*>(window.GetImpl());
/*VkPhysicalDeviceFeatures features;
instance.GetPhysicalDeviceFeatures(physDevice, &features);
VkPhysicalDeviceMemoryProperties memoryProperties;
instance.GetPhysicalDeviceMemoryProperties(physDevice, &memoryProperties);
VkPhysicalDeviceProperties properties;
instance.GetPhysicalDeviceProperties(physDevice, &properties);
std::vector<VkQueueFamilyProperties> queues;
instance.GetPhysicalDeviceQueueFamilyProperties(physDevice, &queues);*/
Nz::VulkanDevice& vulkanDevice = vulkanWindow.GetDevice();
Nz::MeshRef drfreak = Nz::Mesh::LoadFromFile("resources/drfreak.md2", meshParams);
if (!drfreak)
@ -145,27 +112,9 @@ int main()
// Index buffer
std::cout << "Index count: " << drfreakIB->GetIndexCount() << std::endl;
Nz::RenderBuffer* renderBufferIB = static_cast<Nz::RenderBuffer*>(drfreakIB->GetBuffer()->GetImpl());
if (!renderBufferIB->Synchronize(&vulkanDevice))
{
NazaraError("Failed to synchronize render buffer");
return __LINE__;
}
Nz::VulkanBuffer* indexBufferImpl = static_cast<Nz::VulkanBuffer*>(renderBufferIB->GetHardwareBuffer(&vulkanDevice));
// Vertex buffer
std::cout << "Vertex count: " << drfreakVB->GetVertexCount() << std::endl;
Nz::RenderBuffer* renderBufferVB = static_cast<Nz::RenderBuffer*>(drfreakVB->GetBuffer()->GetImpl());
if (!renderBufferVB->Synchronize(&vulkanDevice))
{
NazaraError("Failed to synchronize render buffer");
return __LINE__;
}
Nz::VulkanBuffer* vertexBufferImpl = static_cast<Nz::VulkanBuffer*>(renderBufferVB->GetHardwareBuffer(&vulkanDevice));
struct
{
Nz::Matrix4f projectionMatrix;
@ -184,33 +133,26 @@ int main()
Nz::UniformBuffer uniformBuffer(uniformSize, Nz::DataStorage_Hardware, Nz::BufferUsage_Dynamic);
uniformBuffer.Fill(&ubo, 0, uniformSize);
Nz::RenderBuffer* renderBufferUB = static_cast<Nz::RenderBuffer*>(uniformBuffer.GetBuffer()->GetImpl());
if (!renderBufferUB->Synchronize(&vulkanDevice))
{
NazaraError("Failed to synchronize render buffer");
return __LINE__;
}
Nz::RenderPipelineLayoutInfo pipelineLayoutInfo;
auto& bindingInfo = pipelineLayoutInfo.bindings.emplace_back();
bindingInfo.index = 0;
bindingInfo.shaderStageFlags = Nz::ShaderStageType::Vertex;
bindingInfo.type = Nz::ShaderBindingType::UniformBuffer;
Nz::VulkanBuffer* uniformBufferImpl = static_cast<Nz::VulkanBuffer*>(renderBufferUB->GetHardwareBuffer(&vulkanDevice));
std::shared_ptr<Nz::RenderPipelineLayout> renderPipelineLayout = device->InstantiateRenderPipelineLayout(pipelineLayoutInfo);
VkDescriptorSetLayoutBinding layoutBinding = {};
layoutBinding.binding = 0;
layoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
layoutBinding.descriptorCount = 1;
layoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
layoutBinding.pImmutableSamplers = nullptr;
Nz::VulkanRenderPipelineLayout* vkPipelineLayout = static_cast<Nz::VulkanRenderPipelineLayout*>(renderPipelineLayout.get());
Nz::Vk::DescriptorSetLayout descriptorLayout;
if (!descriptorLayout.Create(vulkanDevice.shared_from_this(), layoutBinding))
{
NazaraError("Failed to create descriptor set layout");
return __LINE__;
}
VkDescriptorSetLayout descriptorLayout = vkPipelineLayout->GetDescriptorSetLayout();
VkPipelineLayout pipelineLayout = vkPipelineLayout->GetPipelineLayout();
VkDescriptorPoolSize poolSize;
poolSize.descriptorCount = 1;
poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
Nz::VkRenderWindow& vulkanWindow = *static_cast<Nz::VkRenderWindow*>(window.GetImpl());
Nz::VulkanDevice& vulkanDevice = vulkanWindow.GetDevice();
Nz::Vk::DescriptorPool descriptorPool;
if (!descriptorPool.Create(vulkanDevice.shared_from_this(), 1, poolSize, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT))
{
@ -220,9 +162,18 @@ int main()
Nz::Vk::DescriptorSet descriptorSet = descriptorPool.AllocateDescriptorSet(descriptorLayout);
Nz::RenderBuffer* renderBufferUB = static_cast<Nz::RenderBuffer*>(uniformBuffer.GetBuffer()->GetImpl());
if (!renderBufferUB->Synchronize(&vulkanDevice))
{
NazaraError("Failed to synchronize render buffer");
return __LINE__;
}
Nz::VulkanBuffer* uniformBufferImpl = static_cast<Nz::VulkanBuffer*>(renderBufferUB->GetHardwareBuffer(&vulkanDevice));
descriptorSet.WriteUniformDescriptor(0, uniformBufferImpl->GetBufferHandle(), 0, uniformSize);
Nz::RenderPipelineInfo pipelineInfo;
pipelineInfo.pipelineLayout = renderPipelineLayout;
pipelineInfo.depthBuffer = true;
pipelineInfo.shaderStages.emplace_back(fragmentShader);
pipelineInfo.shaderStages.emplace_back(vertexShader);
@ -231,35 +182,11 @@ int main()
vertexBuffer.binding = 0;
vertexBuffer.declaration = drfreakVB->GetVertexDeclaration();
//std::unique_ptr<Nz::RenderPipeline> pipeline = device->InstantiateRenderPipeline(pipelineInfo);
VkDescriptorSetLayout descriptorSetLayout = descriptorLayout;
VkPipelineLayoutCreateInfo layout_create_info = {
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineLayoutCreateFlags flags
1U, // uint32_t setLayoutCount
&descriptorSetLayout, // const VkDescriptorSetLayout *pSetLayouts
0, // uint32_t pushConstantRangeCount
nullptr // const VkPushConstantRange *pPushConstantRanges
};
Nz::Vk::PipelineLayout pipelineLayout;
pipelineLayout.Create(vulkanDevice.shared_from_this(), layout_create_info);
std::unique_ptr<Nz::RenderPipeline> pipeline = device->InstantiateRenderPipeline(pipelineInfo);
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(), pipelineCreateInfo.pipelineInfo))
{
NazaraError("Failed to create pipeline");
return __LINE__;
}
Nz::Vk::CommandPool cmdPool;
if (!cmdPool.Create(vulkanDevice.shared_from_this(), 0, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT))
{
@ -276,6 +203,26 @@ int main()
Nz::UInt32 imageCount = vulkanWindow.GetFramebufferCount();
std::vector<Nz::Vk::CommandBuffer> renderCmds = cmdPool.AllocateCommandBuffers(imageCount, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
Nz::RenderBuffer* renderBufferIB = static_cast<Nz::RenderBuffer*>(drfreakIB->GetBuffer()->GetImpl());
Nz::RenderBuffer* renderBufferVB = static_cast<Nz::RenderBuffer*>(drfreakVB->GetBuffer()->GetImpl());
if (!renderBufferIB->Synchronize(&vulkanDevice))
{
NazaraError("Failed to synchronize render buffer");
return __LINE__;
}
if (!renderBufferVB->Synchronize(&vulkanDevice))
{
NazaraError("Failed to synchronize render buffer");
return __LINE__;
}
Nz::VulkanBuffer* indexBufferImpl = static_cast<Nz::VulkanBuffer*>(renderBufferIB->GetHardwareBuffer(&vulkanDevice));
Nz::VulkanBuffer* vertexBufferImpl = static_cast<Nz::VulkanBuffer*>(renderBufferVB->GetHardwareBuffer(&vulkanDevice));
Nz::VulkanRenderPipeline* vkPipeline = static_cast<Nz::VulkanRenderPipeline*>(pipeline.get());
for (Nz::UInt32 i = 0; i < imageCount; ++i)
{
Nz::Vk::CommandBuffer& renderCmd = renderCmds[i];
@ -307,7 +254,7 @@ int main()
renderCmd.BindIndexBuffer(indexBufferImpl->GetBufferHandle(), 0, VK_INDEX_TYPE_UINT16);
renderCmd.BindVertexBuffer(0, vertexBufferImpl->GetBufferHandle(), 0);
renderCmd.BindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, descriptorSet);
renderCmd.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, vkPipeline);
renderCmd.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, vkPipeline->Get(vulkanWindow.GetRenderPass()));
renderCmd.SetScissor(Nz::Recti{0, 0, int(windowSize.x), int(windowSize.y)});
renderCmd.SetViewport({0.f, 0.f, float(windowSize.x), float(windowSize.y)}, 0.f, 1.f);
renderCmd.DrawIndexed(drfreakIB->GetIndexCount());
@ -352,6 +299,7 @@ int main()
Nz::Clock updateClock;
Nz::Clock secondClock;
unsigned int fps = 0;
while (window.IsOpen())
{
bool updateUniforms = false;
@ -410,8 +358,6 @@ int main()
ubo.viewMatrix = Nz::Matrix4f::ViewMatrix(viewerPos, camAngles);
uniformBuffer.Fill(&ubo, 0, uniformSize);
Nz::RenderBuffer* renderBufferUB = static_cast<Nz::RenderBuffer*>(uniformBuffer.GetBuffer()->GetImpl());
if (!renderBufferUB->Synchronize(&vulkanDevice))
{
NazaraError("Failed to synchronize render buffer");

View File

@ -30,7 +30,7 @@ namespace Nz
template<typename T> std::size_t CountOf(const T& c);
template<typename T> void HashCombine(std::size_t& seed, const T& v);
template<typename T> T ReverseBits(T integer);
template<typename T> auto UnderlyingCast(T value) -> std::underlying_type_t<T>;
template<typename T> constexpr auto UnderlyingCast(T value) -> std::underlying_type_t<T>;
template<typename T>
struct AlwaysFalse : std::false_type {};

View File

@ -196,7 +196,7 @@ namespace Nz
}
template<typename T>
auto UnderlyingCast(T value) -> std::underlying_type_t<T>
constexpr auto UnderlyingCast(T value) -> std::underlying_type_t<T>
{
return static_cast<std::underlying_type_t<T>>(value);
}

View File

@ -39,6 +39,7 @@
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/RendererImpl.hpp>
#include <Nazara/Renderer/RenderPipeline.hpp>
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/Renderer/RenderStates.hpp>
#include <Nazara/Renderer/RenderSurface.hpp>
#include <Nazara/Renderer/RenderWindow.hpp>

View File

@ -60,6 +60,7 @@ namespace Nz
Max = Vertex
};
template<>
struct EnumAsFlags<ShaderStageType>
{
static constexpr ShaderStageType max = ShaderStageType::Max;

View File

@ -11,6 +11,7 @@
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/RenderPipeline.hpp>
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/Utility/AbstractBuffer.hpp>
#include <memory>
#include <string>
@ -28,6 +29,7 @@ namespace Nz
virtual std::unique_ptr<AbstractBuffer> InstantiateBuffer(Buffer* parent, BufferType type) = 0;
virtual std::unique_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) = 0;
virtual std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) = 0;
virtual std::shared_ptr<ShaderStageImpl> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) = 0;
std::shared_ptr<ShaderStageImpl> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const std::filesystem::path& sourcePath);
};

View File

@ -8,6 +8,7 @@
#define NAZARA_RENDERPIPELINE_HPP
#include <Nazara/Utility/Enums.hpp>
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/Renderer/RenderStates.hpp>
//#include <Nazara/Renderer/Shader.hpp>
@ -15,7 +16,15 @@ namespace Nz
{
struct RenderPipelineInfo : RenderStates
{
/*ShaderConstRef shader;*/
struct VertexBufferData
{
std::size_t binding;
VertexDeclarationConstRef declaration;
};
std::shared_ptr<RenderPipelineLayout> pipelineLayout;
std::vector<std::shared_ptr<ShaderStageImpl>> shaderStages;
std::vector<VertexBufferData> vertexBuffers;
};
class NAZARA_RENDERER_API RenderPipeline

View File

@ -0,0 +1,40 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_RENDERPIPELINELAYOUT_HPP
#define NAZARA_RENDERPIPELINELAYOUT_HPP
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <string>
#include <vector>
namespace Nz
{
struct RenderPipelineLayoutInfo
{
struct Binding
{
std::string name; //< FIXME: wtf is this?
ShaderBindingType type;
ShaderStageTypeFlags shaderStageFlags;
unsigned int index;
};
std::vector<Binding> bindings;
};
class NAZARA_RENDERER_API RenderPipelineLayout
{
public:
RenderPipelineLayout() = default;
virtual ~RenderPipelineLayout();
};
}
#include <Nazara/Renderer/RenderPipelineLayout.inl>
#endif // NAZARA_RENDERPIPELINELAYOUT_HPP

View File

@ -0,0 +1,13 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Renderer/DebugOff.hpp>

View File

@ -37,15 +37,6 @@ namespace Nz
UInt32 writeMask = 0xFFFFFFFF;
} stencilBack, stencilFront;
struct VertexBufferData
{
std::size_t binding;
VertexDeclarationConstRef declaration;
};
std::vector<std::shared_ptr<ShaderStageImpl>> shaderStages;
std::vector<VertexBufferData> vertexBuffers;
bool blending = false;
bool colorWrite = true;
bool depthBuffer = false;

View File

@ -38,6 +38,7 @@
#include <Nazara/VulkanRenderer/VulkanDevice.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderer.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderPipeline.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderPipelineLayout.hpp>
#include <Nazara/VulkanRenderer/VulkanShaderStage.hpp>
#include <Nazara/VulkanRenderer/VulkanSurface.hpp>
#include <Nazara/VulkanRenderer/Wrapper.hpp>

View File

@ -20,7 +20,9 @@ namespace Nz
inline VkPolygonMode ToVulkan(FaceFilling faceFilling);
inline VkPrimitiveTopology ToVulkan(PrimitiveMode primitiveMode);
inline VkCompareOp ToVulkan(RendererComparison comparison);
inline VkDescriptorType ToVulkan(ShaderBindingType bindingType);
inline VkShaderStageFlagBits ToVulkan(ShaderStageType stageType);
inline VkShaderStageFlags ToVulkan(ShaderStageTypeFlags stageType);
inline VkStencilOp ToVulkan(StencilOperation stencilOp);
inline VkVertexInputRate ToVulkan(VertexInputRate inputRate);

View File

@ -95,6 +95,18 @@ namespace Nz
return VK_COMPARE_OP_NEVER;
}
VkDescriptorType ToVulkan(ShaderBindingType bindingType)
{
switch (bindingType)
{
case ShaderBindingType::Texture: return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
case ShaderBindingType::UniformBuffer: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
}
NazaraError("Unhandled ShaderBindingType 0x" + String::Number(UnderlyingCast(bindingType), 16));
return VK_DESCRIPTOR_TYPE_SAMPLER;
}
VkShaderStageFlagBits ToVulkan(ShaderStageType stageType)
{
switch (stageType)
@ -103,10 +115,25 @@ namespace Nz
case ShaderStageType::Vertex: return VK_SHADER_STAGE_VERTEX_BIT;
}
NazaraError("Unhandled ShaderStageType 0x" + String::Number(static_cast<std::size_t>(stageType), 16));
NazaraError("Unhandled ShaderStageType 0x" + String::Number(UnderlyingCast(stageType), 16));
return {};
}
VkShaderStageFlags ToVulkan(ShaderStageTypeFlags stageType)
{
VkShaderStageFlags shaderStageBits = 0;
if (stageType.Test(ShaderStageType::Fragment))
shaderStageBits |= VK_SHADER_STAGE_FRAGMENT_BIT;
if (stageType.Test(ShaderStageType::Vertex))
shaderStageBits |= VK_SHADER_STAGE_VERTEX_BIT;
static_assert(UnderlyingCast(ShaderStageType::Max) + 1 == 2);
return shaderStageBits;
}
VkStencilOp ToVulkan(StencilOperation stencilOp)
{
switch (stencilOp)

View File

@ -25,6 +25,7 @@ namespace Nz
std::unique_ptr<AbstractBuffer> InstantiateBuffer(Buffer* parent, BufferType type) override;
std::unique_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
std::shared_ptr<ShaderStageImpl> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) override;
VulkanDevice& operator=(const VulkanDevice&) = delete;

View File

@ -11,6 +11,8 @@
#include <Nazara/Renderer/RenderPipeline.hpp>
#include <Nazara/VulkanRenderer/Config.hpp>
#include <Nazara/VulkanRenderer/Wrapper/Device.hpp>
#include <Nazara/VulkanRenderer/Wrapper/Pipeline.hpp>
#include <Nazara/VulkanRenderer/Wrapper/RenderPass.hpp>
#include <vector>
namespace Nz
@ -23,6 +25,8 @@ namespace Nz
VulkanRenderPipeline(Vk::DeviceHandle device, RenderPipelineInfo pipelineInfo);
~VulkanRenderPipeline() = default;
VkPipeline Get(const Vk::RenderPass& renderPass);
static std::vector<VkPipelineColorBlendAttachmentState> BuildColorBlendAttachmentStateList(const RenderPipelineInfo& pipelineInfo);
static VkPipelineColorBlendStateCreateInfo BuildColorBlendInfo(const RenderPipelineInfo& pipelineInfo, const std::vector<VkPipelineColorBlendAttachmentState>& attachmentState);
static VkPipelineDepthStencilStateCreateInfo BuildDepthStencilInfo(const RenderPipelineInfo& pipelineInfo);
@ -64,9 +68,9 @@ namespace Nz
};
private:
std::unordered_map<VkRenderPass, Vk::Pipeline> m_pipelines;
Vk::DeviceHandle m_device;
CreateInfo m_pipelineCreateInfo;
RenderPipelineInfo m_pipelineInfo;
};
}

View File

@ -0,0 +1,41 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_VULKANRENDERER_VULKANRENDERPIPELINELAYOUT_HPP
#define NAZARA_VULKANRENDERER_VULKANRENDERPIPELINELAYOUT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/VulkanRenderer/Config.hpp>
#include <Nazara/VulkanRenderer/Wrapper/DescriptorSetLayout.hpp>
#include <Nazara/VulkanRenderer/Wrapper/PipelineLayout.hpp>
#include <Nazara/VulkanRenderer/Wrapper/Device.hpp>
#include <vector>
namespace Nz
{
class NAZARA_VULKANRENDERER_API VulkanRenderPipelineLayout : public RenderPipelineLayout
{
public:
VulkanRenderPipelineLayout() = default;
~VulkanRenderPipelineLayout() = default;
bool Create(Vk::DeviceHandle device, RenderPipelineLayoutInfo layoutInfo);
inline const Vk::DescriptorSetLayout& GetDescriptorSetLayout() const;
inline const Vk::PipelineLayout& GetPipelineLayout() const;
private:
Vk::DeviceHandle m_device;
Vk::DescriptorSetLayout m_descriptorSetLayout;
Vk::PipelineLayout m_pipelineLayout;
RenderPipelineLayoutInfo m_layoutInfo;
};
}
#include <Nazara/VulkanRenderer/VulkanRenderPipelineLayout.inl>
#endif // NAZARA_VULKANRENDERER_VULKANRENDERPIPELINE_HPP

View File

@ -0,0 +1,21 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Vulkan Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/VulkanRenderer/VulkanRenderPipelineLayout.hpp>
#include <Nazara/VulkanRenderer/Debug.hpp>
namespace Nz
{
inline const Vk::DescriptorSetLayout& VulkanRenderPipelineLayout::GetDescriptorSetLayout() const
{
return m_descriptorSetLayout;
}
inline const Vk::PipelineLayout& VulkanRenderPipelineLayout::GetPipelineLayout() const
{
return m_pipelineLayout;
}
}
#include <Nazara/VulkanRenderer/DebugOff.hpp>

View File

@ -24,6 +24,10 @@ namespace Nz
PipelineLayout(PipelineLayout&&) = default;
~PipelineLayout() = default;
using DeviceObject::Create;
bool Create(DeviceHandle device, VkDescriptorSetLayout layout, VkPipelineLayoutCreateFlags flags = 0);
bool Create(DeviceHandle device, UInt32 layoutCount, const VkDescriptorSetLayout* layouts, VkPipelineLayoutCreateFlags flags = 0);
PipelineLayout& operator=(const PipelineLayout&) = delete;
PipelineLayout& operator=(PipelineLayout&&) = delete;

View File

@ -9,6 +9,26 @@ namespace Nz
{
namespace Vk
{
inline bool PipelineLayout::Create(DeviceHandle device, VkDescriptorSetLayout layout, VkPipelineLayoutCreateFlags flags)
{
return Create(std::move(device), 1U, &layout, flags);
}
inline bool PipelineLayout::Create(DeviceHandle device, UInt32 layoutCount, const VkDescriptorSetLayout* layouts, VkPipelineLayoutCreateFlags flags)
{
VkPipelineLayoutCreateInfo createInfo = {
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
nullptr,
flags,
layoutCount,
layouts,
0U,
nullptr
};
return Create(std::move(device), createInfo);
}
inline VkResult PipelineLayout::CreateHelper(const DeviceHandle& device, const VkPipelineLayoutCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkPipelineLayout* handle)
{
return device->vkCreatePipelineLayout(*device, createInfo, allocator, handle);

View File

@ -0,0 +1,11 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
RenderPipelineLayout::~RenderPipelineLayout() = default;
}

View File

@ -137,7 +137,7 @@ namespace Nz
return false;
}
if (!SetupRenderPass(size))
if (!SetupRenderPass())
{
NazaraError("Failed to create render pass");
return false;
@ -245,8 +245,8 @@ namespace Nz
return true;
}
bool VkRenderWindow::SetupRenderPass(const Vector2ui& size)
{
bool VkRenderWindow::SetupRenderPass()
{
std::array<VkAttachmentDescription, 2> attachments = {
{
{

View File

@ -4,6 +4,7 @@
#include <Nazara/VulkanRenderer/VulkanDevice.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderPipeline.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderPipelineLayout.hpp>
#include <Nazara/VulkanRenderer/VulkanShaderStage.hpp>
#include <Nazara/VulkanRenderer/Debug.hpp>
@ -21,6 +22,15 @@ namespace Nz
return std::make_unique<VulkanRenderPipeline>(shared_from_this(), std::move(pipelineInfo));
}
std::shared_ptr<RenderPipelineLayout> VulkanDevice::InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo)
{
auto pipelineLayout = std::make_shared<VulkanRenderPipelineLayout>();
if (!pipelineLayout->Create(shared_from_this(), std::move(pipelineLayoutInfo)))
return {};
return pipelineLayout;
}
std::shared_ptr<ShaderStageImpl> VulkanDevice::InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
{
auto stage = std::make_shared<VulkanShaderStage>();

View File

@ -4,10 +4,10 @@
#include <Nazara/VulkanRenderer/VulkanRenderPipeline.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/VulkanRenderer/VulkanShaderStage.hpp>
#include <Nazara/VulkanRenderer/Utils.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderPipelineLayout.hpp>
#include <Nazara/VulkanRenderer/VulkanShaderStage.hpp>
#include <cassert>
#include <iostream>
#include <Nazara/VulkanRenderer/Debug.hpp>
namespace Nz
@ -16,6 +16,24 @@ namespace Nz
m_device(std::move(device)),
m_pipelineInfo(std::move(pipelineInfo))
{
m_pipelineCreateInfo = BuildCreateInfo(m_pipelineInfo);
}
VkPipeline VulkanRenderPipeline::Get(const Vk::RenderPass& renderPass)
{
if (auto it = m_pipelines.find(renderPass); it != m_pipelines.end())
return it->second;
// Copy create info to make Get re-entrant
VkGraphicsPipelineCreateInfo pipelineCreateInfo = m_pipelineCreateInfo.pipelineInfo;
pipelineCreateInfo.renderPass = renderPass;
Vk::Pipeline newPipeline;
if (!newPipeline.CreateGraphics(m_device, pipelineCreateInfo))
return VK_NULL_HANDLE;
auto it = m_pipelines.emplace(renderPass, std::move(newPipeline)).first;
return it->second;
}
std::vector<VkPipelineColorBlendAttachmentState> VulkanRenderPipeline::BuildColorBlendAttachmentStateList(const RenderPipelineInfo& pipelineInfo)
@ -235,7 +253,6 @@ namespace Nz
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.stateData->colorBlendState;
createInfo.pipelineInfo.pDepthStencilState = &createInfo.stateData->depthStencilState;
createInfo.pipelineInfo.pDynamicState = &createInfo.stateData->dynamicState;
@ -245,6 +262,9 @@ namespace Nz
createInfo.pipelineInfo.pVertexInputState = &createInfo.stateData->vertexInputState;
createInfo.pipelineInfo.pViewportState = &createInfo.stateData->viewportState;
VulkanRenderPipelineLayout& pipelineLayout = *static_cast<VulkanRenderPipelineLayout*>(pipelineInfo.pipelineLayout.get());
createInfo.pipelineInfo.layout = pipelineLayout.GetPipelineLayout();
return createInfo;
}
}

View File

@ -0,0 +1,39 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Vulkan Renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/VulkanRenderer/VulkanRenderPipelineLayout.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/StackVector.hpp>
#include <Nazara/VulkanRenderer/Utils.hpp>
#include <cassert>
#include <stdexcept>
#include <Nazara/VulkanRenderer/Debug.hpp>
namespace Nz
{
bool VulkanRenderPipelineLayout::Create(Vk::DeviceHandle device, RenderPipelineLayoutInfo layoutInfo)
{
m_device = std::move(device);
m_layoutInfo = std::move(layoutInfo);
StackVector<VkDescriptorSetLayoutBinding> layoutBindings = NazaraStackVector(VkDescriptorSetLayoutBinding, m_layoutInfo.bindings.size());
for (const auto& bindingInfo : m_layoutInfo.bindings)
{
VkDescriptorSetLayoutBinding& layoutBinding = layoutBindings.emplace_back();
layoutBinding.binding = bindingInfo.index;
layoutBinding.descriptorCount = 1U;
layoutBinding.descriptorType = ToVulkan(bindingInfo.type);
layoutBinding.stageFlags = ToVulkan(bindingInfo.shaderStageFlags);
}
if (!m_descriptorSetLayout.Create(m_device, layoutBindings.size(), layoutBindings.data()))
return false;
if (!m_pipelineLayout.Create(m_device, m_descriptorSetLayout))
return false;
return true;
}
}

View File

@ -37,7 +37,7 @@ namespace Nz
bool VulkanRenderer::IsBetterThan(const RendererImpl* other) const
{
if (other->QueryAPI() == RenderAPI_Vulkan && QueryAPIVersion() < other->QueryAPIVersion())
if (other->QueryAPI() == RenderAPI::Vulkan && QueryAPIVersion() < other->QueryAPIVersion())
return false;
return true; //< Vulkan FTW
@ -50,7 +50,7 @@ namespace Nz
RenderAPI VulkanRenderer::QueryAPI() const
{
return RenderAPI_Vulkan;
return RenderAPI::Vulkan;
}
String VulkanRenderer::QueryAPIString() const
@ -79,25 +79,25 @@ namespace Nz
switch (physDevice.properties.deviceType)
{
case VK_PHYSICAL_DEVICE_TYPE_CPU:
device.type = RenderDeviceType_Software;
device.type = RenderDeviceType::Software;
break;
case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
device.type = RenderDeviceType_Dedicated;
device.type = RenderDeviceType::Dedicated;
break;
case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
device.type = RenderDeviceType_Integrated;
device.type = RenderDeviceType::Integrated;
break;
case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
device.type = RenderDeviceType_Virtual;
device.type = RenderDeviceType::Virtual;
break;
default:
NazaraWarning("Device " + device.name + " has handled device type (0x" + String::Number(physDevice.properties.deviceType, 16) + ')');
case VK_PHYSICAL_DEVICE_TYPE_OTHER:
device.type = RenderDeviceType_Unknown;
device.type = RenderDeviceType::Unknown;
break;
}