#include "iwa/pipeline.hpp" #include #include #include "iwa/device.hpp" #include "iwa/util/glsl_compiler.hpp" #include "iwa/util/next_chain.hpp" namespace iwa { PipelineLayout::PipelineLayout(ObjectPtr owner, const PipelineLayoutCreationArgs& args) : super_t(std::move(owner)) { std::vector setLayoutHandles; setLayoutHandles.reserve(args.setLayouts.size()); for (const ObjectPtr& setLayout : args.setLayouts) { setLayoutHandles.push_back(setLayout->getVkHandle()); } mHandle = getOwner()->getVkHandle().createPipelineLayout(vk::PipelineLayoutCreateInfo{ .flags = args.flags, .setLayoutCount = static_cast(setLayoutHandles.size()), .pSetLayouts = setLayoutHandles.data(), .pushConstantRangeCount = static_cast(args.pushConstantRanges.size()), .pPushConstantRanges = args.pushConstantRanges.data() }); } PipelineLayout::~PipelineLayout() noexcept { IWA_DELETE_DEVICE_OBJECT(getOwner(), mHandle, destroyPipelineLayout) } Pipeline::Pipeline(ObjectPtr owner) noexcept : super_t(std::move(owner)) { } Pipeline::~Pipeline() noexcept { IWA_DELETE_DEVICE_OBJECT(getOwner(), mHandle, destroyPipeline) } GraphicsPipeline::GraphicsPipeline(ObjectPtr owner, const GraphicsPipelineCreationArgs& args) noexcept : super_t(std::move(owner)) { std::vector vkStages; for (const PipelineStage& stage : args.stages) { vk::PipelineShaderStageCreateInfo& vkStage = vkStages.emplace_back(); vkStage.stage = stage.stage; vkStage.module = *stage.shader; vkStage.pName = stage.name.c_str(); } const vk::PipelineVertexInputStateCreateInfo vkVertexInput = { .vertexBindingDescriptionCount = static_cast(args.vertexInput.bindings.size()), .pVertexBindingDescriptions = args.vertexInput.bindings.data(), .vertexAttributeDescriptionCount = static_cast(args.vertexInput.attributes.size()), .pVertexAttributeDescriptions = args.vertexInput.attributes.data() }; const vk::PipelineColorBlendStateCreateInfo vkColorBlend = { .logicOpEnable = args.colorBlend.logicOp.has_value(), .logicOp = args.colorBlend.logicOp.has_value() ? *args.colorBlend.logicOp : vk::LogicOp(), .attachmentCount = static_cast(args.colorBlend.attachements.size()), .pAttachments = args.colorBlend.attachements.data() }; const vk::PipelineDynamicStateCreateInfo vkDynamic = { .dynamicStateCount = static_cast(args.dynamicState.size()), .pDynamicStates = args.dynamicState.data() }; NextChain nextChain; if (args.renderingInfo.has_value()) { const GraphicsPipelineRenderingInfo& rinfo = *args.renderingInfo; nextChain.append(vk::PipelineRenderingCreateInfo{ .viewMask = rinfo.viewMask, .colorAttachmentCount = static_cast(rinfo.colorAttachmentFormats.size()), .pColorAttachmentFormats = rinfo.colorAttachmentFormats.data(), .depthAttachmentFormat = rinfo.depthFormat, .stencilAttachmentFormat = rinfo.stencilFormat }); } const vk::GraphicsPipelineCreateInfo vkCreateInfo = { .pNext = nextChain.finalize(), .stageCount = static_cast(vkStages.size()), .pStages = vkStages.data(), .pVertexInputState = &vkVertexInput, .pInputAssemblyState = &args.inputAssembly, .pViewportState = &args.viewport, .pRasterizationState = &args.rasterization, .pMultisampleState = &args.multisample, .pDepthStencilState = &args.depthStencil, .pColorBlendState = &vkColorBlend, .pDynamicState = &vkDynamic, .layout = *args.layout, .renderPass = args.renderPass ? *args.renderPass : vk::RenderPass(), .subpass = args.subpass }; const auto result = getOwner()->getVkHandle().createGraphicsPipeline(VK_NULL_HANDLE, vkCreateInfo); MIJIN_ASSERT(result.result == vk::Result::eSuccess, "Graphics pipeline creation failed."); mHandle = result.value; } ComputePipeline::ComputePipeline(ObjectPtr owner, const ComputePipelineCreationArgs& args) noexcept : super_t(std::move(owner)) { const vk::ComputePipelineCreateInfo vkCreateInfo{ .stage = { .stage = vk::ShaderStageFlagBits::eCompute, .module = *args.stage.shader, .pName = args.stage.name.c_str() }, .layout = *args.layout }; const vk::ResultValue result = getOwner()->getVkHandle().createComputePipeline(VK_NULL_HANDLE, vkCreateInfo); MIJIN_ASSERT(result.result == vk::Result::eSuccess, "Compute pipeline creation failed."); mHandle = result.value; } RayTracingPipeline::RayTracingPipeline(ObjectPtr owner, const RayTracingPipelineCreationArgs& args) noexcept : super_t(std::move(owner)) { (void) args; } } // namespace iwa