32 std::vector<uint32_t> shaderCode{};
46 if (!graphicsPipelineBuilder.setShaderFromData(VK_SHADER_STAGE_VERTEX_BIT,
"main", shaderCode)) {
47 LUG_LOG.error(
"Vulkan::Render::Pipeline: Can't create vertex shader.");
54 std::vector<uint32_t> shaderCode{};
68 if (!graphicsPipelineBuilder.setShaderFromData(VK_SHADER_STAGE_FRAGMENT_BIT,
"main", shaderCode)) {
69 LUG_LOG.error(
"Vulkan::Render::Pipeline: Can't create fragment shader.");
78 auto positionBinding = graphicsPipelineBuilder.addInputBinding(
sizeof(Math::Vec3f), VK_VERTEX_INPUT_RATE_VERTEX);
79 positionBinding.addAttributes(VK_FORMAT_R32G32B32_SFLOAT, 0);
82 auto normalBinding = graphicsPipelineBuilder.addInputBinding(
sizeof(Math::Vec3f), VK_VERTEX_INPUT_RATE_VERTEX);
83 normalBinding.addAttributes(VK_FORMAT_R32G32B32_SFLOAT, 0);
87 auto tangentBinding = graphicsPipelineBuilder.addInputBinding(
sizeof(Math::Vec4f), VK_VERTEX_INPUT_RATE_VERTEX);
88 tangentBinding.addAttributes(VK_FORMAT_R32G32B32A32_SFLOAT, 0);
92 auto uvBinding = graphicsPipelineBuilder.addInputBinding(
sizeof(Math::Vec2f), VK_VERTEX_INPUT_RATE_VERTEX);
93 uvBinding.addAttributes(VK_FORMAT_R32G32_SFLOAT, 0);
96 for (uint8_t i = 0; i < primitivePart.
countColor; ++i) {
97 auto uvBinding = graphicsPipelineBuilder.addInputBinding(
sizeof(Math::Vec4f), VK_VERTEX_INPUT_RATE_VERTEX);
98 uvBinding.addAttributes(VK_FORMAT_R32G32B32A32_SFLOAT, 0);
103 switch(static_cast<Render::Mesh::PrimitiveSet::Mode>(primitivePart.
primitiveMode)) {
105 graphicsPipelineBuilder.setInputAssemblyInfo(VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
false);
108 graphicsPipelineBuilder.setInputAssemblyInfo(VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
false);
111 graphicsPipelineBuilder.setInputAssemblyInfo(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
false);
114 graphicsPipelineBuilder.setInputAssemblyInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
false);
117 graphicsPipelineBuilder.setInputAssemblyInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
false);
120 graphicsPipelineBuilder.setInputAssemblyInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
false);
125 const VkViewport viewport{
134 const VkRect2D scissor{
139 auto viewportState = graphicsPipelineBuilder.getViewportState();
140 viewportState.addViewport(viewport);
141 viewportState.addScissor(scissor);
144 auto depthStencilState = graphicsPipelineBuilder.getDepthStencilState();
145 depthStencilState.enableDepthTest(VK_COMPARE_OP_LESS_OR_EQUAL);
146 depthStencilState.enableDepthWrite();
149 const VkPipelineColorBlendAttachmentState colorBlendAttachment{
152 VK_BLEND_FACTOR_CONSTANT_COLOR,
155 VK_BLEND_FACTOR_CONSTANT_COLOR,
157 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
160 auto colorBlendState = graphicsPipelineBuilder.getColorBlendState();
161 colorBlendState.addAttachment(colorBlendAttachment);
164 graphicsPipelineBuilder.setDynamicStates({
165 VK_DYNAMIC_STATE_VIEWPORT,
166 VK_DYNAMIC_STATE_SCISSOR,
167 VK_DYNAMIC_STATE_BLEND_CONSTANTS
172 VkResult result{VK_SUCCESS};
173 std::vector<API::DescriptorSetLayout> descriptorSetLayouts(3);
179 const VkDescriptorSetLayoutBinding binding{
181 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
183 VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
188 if (!descriptorSetLayoutBuilder.build(descriptorSetLayouts[0], &result)) {
189 LUG_LOG.error(
"Vulkan::Render::Pipeline: Can't create pipeline descriptor sets layout 0: {}", result);
196 const std::vector<VkDescriptorSetLayoutBinding> bindings{
200 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
202 VK_SHADER_STAGE_FRAGMENT_BIT,
207 descriptorSetLayoutBuilder.setBindings(bindings);
208 if (!descriptorSetLayoutBuilder.build(descriptorSetLayouts[1], &result)) {
209 LUG_LOG.error(
"Vulkan::Render::Pipeline: Can't create pipeline descriptor sets layout 1: {}", result);
216 const VkDescriptorSetLayoutBinding materialBinding{
218 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
220 VK_SHADER_STAGE_FRAGMENT_BIT,
224 descriptorSetLayoutBuilder.setBindings({materialBinding});
225 if (!descriptorSetLayoutBuilder.build(descriptorSetLayouts[2], &result)) {
226 LUG_LOG.error(
"Vulkan::Render::Pipeline: Can't create pipeline descriptor sets layout 2: {}", result);
233 std::vector<VkDescriptorSetLayoutBinding> bindings = {};
239 const VkDescriptorSetLayoutBinding textureBinding = {
241 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
243 VK_SHADER_STAGE_FRAGMENT_BIT,
247 bindings.push_back(std::move(textureBinding));
251 const VkDescriptorSetLayoutBinding textureBinding = {
253 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
255 VK_SHADER_STAGE_FRAGMENT_BIT,
259 bindings.push_back(std::move(textureBinding));
263 const VkDescriptorSetLayoutBinding textureBinding = {
265 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
267 VK_SHADER_STAGE_FRAGMENT_BIT,
271 bindings.push_back(std::move(textureBinding));
275 const VkDescriptorSetLayoutBinding textureBinding = {
277 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
279 VK_SHADER_STAGE_FRAGMENT_BIT,
283 bindings.push_back(std::move(textureBinding));
287 const VkDescriptorSetLayoutBinding textureBinding = {
289 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
291 VK_SHADER_STAGE_FRAGMENT_BIT,
295 bindings.push_back(std::move(textureBinding));
299 const VkDescriptorSetLayoutBinding textureBinding = {
301 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
303 VK_SHADER_STAGE_FRAGMENT_BIT,
307 bindings.push_back(std::move(textureBinding));
313 const VkDescriptorSetLayoutBinding textureBinding = {
315 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
317 VK_SHADER_STAGE_FRAGMENT_BIT,
321 bindings.push_back(std::move(textureBinding));
326 const VkDescriptorSetLayoutBinding textureBinding = {
328 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
330 VK_SHADER_STAGE_FRAGMENT_BIT,
334 bindings.push_back(std::move(textureBinding));
338 if (bindings.size() > 0) {
339 descriptorSetLayouts.resize(4);
341 descriptorSetLayoutBuilder.setBindings(bindings);
342 if (!descriptorSetLayoutBuilder.build(descriptorSetLayouts[3], &result)) {
343 LUG_LOG.error(
"Vulkan::Render::Pipeline: Can't create pipeline descriptor sets layout 3: {}", result);
350 const VkPushConstantRange pushConstant{
351 VK_SHADER_STAGE_VERTEX_BIT,
353 sizeof(Math::Mat4x4f)
359 pipelineLayoutBuilder.setDescriptorSetLayouts(std::move(descriptorSetLayouts));
362 if (!pipelineLayoutBuilder.build(pipelineLayout, &result)) {
363 LUG_LOG.error(
"Vulkan::Render::Pipeline: Can't create pipeline layout: {}", result);
367 graphicsPipelineBuilder.setPipelineLayout(std::move(pipelineLayout));
374 const VkAttachmentDescription colorAttachment{
377 VK_SAMPLE_COUNT_1_BIT,
378 VK_ATTACHMENT_LOAD_OP_CLEAR,
379 VK_ATTACHMENT_STORE_OP_STORE,
380 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
381 VK_ATTACHMENT_STORE_OP_DONT_CARE,
382 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
383 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
386 auto colorAttachmentIndex = renderPassBuilder.addAttachment(colorAttachment);
390 {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT},
391 VK_IMAGE_TILING_OPTIMAL,
392 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
395 const VkAttachmentDescription depthAttachment{
398 VK_SAMPLE_COUNT_1_BIT,
399 VK_ATTACHMENT_LOAD_OP_CLEAR,
400 VK_ATTACHMENT_STORE_OP_STORE,
401 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
402 VK_ATTACHMENT_STORE_OP_DONT_CARE,
403 VK_IMAGE_LAYOUT_UNDEFINED,
404 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
407 auto depthAttachmentIndex = renderPassBuilder.addAttachment(depthAttachment);
410 VK_PIPELINE_BIND_POINT_GRAPHICS,
412 {{colorAttachmentIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}},
414 {depthAttachmentIndex, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL},
418 renderPassBuilder.addSubpass(subpassDescription);
420 VkResult result{VK_SUCCESS};
422 if (!renderPassBuilder.build(renderPass, &result)) {
423 LUG_LOG.error(
"Vulkan::Render::Pipeline: Can't create render pass: {}", result);
427 graphicsPipelineBuilder.setRenderPass(std::move(renderPass), 0);
430 VkResult result{VK_SUCCESS};
431 if (!graphicsPipelineBuilder.build(
_pipeline, &result)) {
432 LUG_LOG.error(
"Vulkan::Render::Pipeline: Can't create pipeline: {}", result);
444 std::unique_ptr<Resource> resource{
new Pipeline(renderer,
id)};
447 if (!pipeline->
init()) {
454 return sharedPtrPipeline;
Id of the Pipeline. It's a concatenation of three parts: PrimitivePart, MaterialPart and PipelinePart...
Describes the material. How is the material composed, with textures, no textures, etc...
uint32_t occlusionInfo
0b00 texture with UV0, 0b01 texture with UV1, 0b10 texture with UV2, 0b11 no texture.
uint32_t countColor
The number of colors (maximum 3).
uint32_t baseColorInfo
0b00 texture with UV0, 0b01 texture with UV1, 0b10 texture with UV2, 0b11 no texture.
Pipeline(Renderer &renderer, Id id)
void setBindings(const std::vector< VkDescriptorSetLayoutBinding > &bindings)
Resource::SharedPtr< T > add(std::unique_ptr< Resource > resource)
Add a resource to the ResourceManager.
const char * what() const noexcept override
Return the full formated exception.
Resource::SharedPtr< Render::Pipeline > getPipeline(Render::Pipeline::Id id)
The first two vertices define the first segment, with subsequent pairs of vertices each defining one ...
Dummy class for a shared pointer.
bool containsPipeline(Render::Pipeline::Id id) const
uint32_t primitiveMode
The primitive mode.
const API::Swapchain & getSwapchain() const
const VkSurfaceFormatKHR & getFormat() const
PrimitivePart getPrimitivePart()
void addPipeline(Resource::SharedPtr< Render::Pipeline > pipeline)
Render::Technique::Type renderTechnique
static std::vector< uint32_t > buildShader(std::string shaderRoot, ::lug::Graphics::Render::Technique::Type technique, Type type, Pipeline::Id id)
static VkFormat findSupportedFormat(const Device &device, const std::set< VkFormat > &formats, VkImageTiling tiling, VkFormatFeatureFlags features)
uint32_t emissiveInfo
0b00 texture with UV0, 0b01 texture with UV1, 0b10 texture with UV2, 0b11 no texture.
Render::Window * getRenderWindow() const
API::GraphicsPipeline _pipeline
const InitInfo & getInfo() const
void setPushConstants(const std::vector< VkPushConstantRange > &pushConstants)
uint32_t metallicRoughnessInfo
0b00 texture with UV0, 0b01 texture with UV1, 0b10 texture with UV2, 0b11 no texture.
MaterialPart getMaterialPart()
API::Device & getDevice()
The first vertex specifies the first segment’s start point while the second vertex specifies the fir...
static Resource::SharedPtr< Pipeline > create(Renderer &renderer, Id id)
Type
Type of the resource.
Each vertex defines a separate point.
uint32_t normalInfo
0b00 texture with UV0, 0b01 texture with UV1, 0b10 texture with UV2, 0b11 no texture.
uint32_t tangentVertexData
0 if no attribute tangeant.
ResourceManager * getResourceManager() const
Class for the Vulkan pipeline, Render side.
uint32_t countTexCoord
The number of texcoord (maximum 3).