@@ -20,26 +20,31 @@ std::vector<char> Pipeline::readFile(const std::string &filename) const {
2020
2121Pipeline::Pipeline (vk::Device device, vk::Format colorAttachmentFormat,
2222 const std::string &vertShaderPath, const std::string &fragShaderPath,
23- const std::vector<vk::DescriptorSetLayout> &setLayouts, uint32_t samples)
23+ const std::vector<vk::DescriptorSetLayout> &setLayouts, uint32_t samples,
24+ vk::Format depthAttachmentFormat, bool depthWriteEnable)
2425 : m_device(device) {
2526 // 1. Read shader code from files
2627 auto vertShaderCode = readFile (vertShaderPath);
27- auto fragShaderCode = readFile (fragShaderPath);
28-
2928 auto vertShaderModule = ShaderModule (m_device, vertShaderCode);
30- auto fragShaderModule = ShaderModule (m_device, fragShaderCode);
3129
3230 vk::PipelineShaderStageCreateInfo vertStageInfo{};
3331 vertStageInfo.stage = vk::ShaderStageFlagBits::eVertex;
3432 vertStageInfo.module = vertShaderModule.getHandle ();
3533 vertStageInfo.pName = " main" ;
3634
37- vk::PipelineShaderStageCreateInfo fragStageInfo{};
38- fragStageInfo.stage = vk::ShaderStageFlagBits::eFragment;
39- fragStageInfo.module = fragShaderModule.getHandle ();
40- fragStageInfo.pName = " main" ;
35+ std::vector<vk::PipelineShaderStageCreateInfo> shaderStages = {vertStageInfo};
36+
37+ std::unique_ptr<ShaderModule> fragShaderModule;
38+ if (!fragShaderPath.empty ()) {
39+ auto fragShaderCode = readFile (fragShaderPath);
40+ fragShaderModule = std::make_unique<ShaderModule>(m_device, fragShaderCode);
4141
42- vk::PipelineShaderStageCreateInfo shaderStages[] = {vertStageInfo, fragStageInfo};
42+ vk::PipelineShaderStageCreateInfo fragStageInfo{};
43+ fragStageInfo.stage = vk::ShaderStageFlagBits::eFragment;
44+ fragStageInfo.module = fragShaderModule->getHandle ();
45+ fragStageInfo.pName = " main" ;
46+ shaderStages.push_back (fragStageInfo);
47+ }
4348
4449 // 3. Vertex input (empty, for a basic triangle with no vertex buffer)
4550 vk::PipelineVertexInputStateCreateInfo vertexInputInfo{};
@@ -67,19 +72,28 @@ Pipeline::Pipeline(vk::Device device, vk::Format colorAttachmentFormat,
6772 // 7. Multisampling (disabled)
6873 vk::PipelineMultisampleStateCreateInfo multisampling{};
6974 multisampling.sampleShadingEnable = VK_FALSE;
70-
7175 multisampling.rasterizationSamples = utils::mapSampleCountFlag (samples);
7276
77+ vk::PipelineDepthStencilStateCreateInfo depthStencil{};
78+ if (depthAttachmentFormat != vk::Format::eUndefined) {
79+ depthStencil.depthTestEnable = VK_TRUE;
80+ depthStencil.depthWriteEnable = depthWriteEnable ? VK_TRUE : VK_FALSE;
81+ depthStencil.depthCompareOp = vk::CompareOp::eLess;
82+ depthStencil.depthBoundsTestEnable = VK_FALSE;
83+ depthStencil.stencilTestEnable = VK_FALSE;
84+ }
85+
7386 // 8. Color blending
7487 vk::PipelineColorBlendAttachmentState colorBlendAttachment{};
7588 colorBlendAttachment.colorWriteMask =
7689 vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
7790 vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA;
7891 colorBlendAttachment.blendEnable = VK_FALSE;
92+
7993 vk::PipelineColorBlendStateCreateInfo colorBlending{};
8094 colorBlending.logicOpEnable = VK_FALSE;
81- colorBlending.attachmentCount = 1 ;
82- colorBlending.pAttachments = &colorBlendAttachment;
95+ colorBlending.attachmentCount = (colorAttachmentFormat != vk::Format::eUndefined) ? 1 : 0 ;
96+ colorBlending.pAttachments = (colorAttachmentFormat != vk::Format::eUndefined) ? &colorBlendAttachment : nullptr ;
8397
8498 // 9. Pipeline layout
8599 vk::PipelineLayoutCreateInfo pipelineLayoutInfo{};
@@ -97,16 +111,16 @@ Pipeline::Pipeline(vk::Device device, vk::Format colorAttachmentFormat,
97111
98112 // 11. Dynamic rendering
99113 vk::PipelineRenderingCreateInfo renderingInfo{};
100- renderingInfo.colorAttachmentCount = 1 ;
101- renderingInfo.pColorAttachmentFormats = &colorAttachmentFormat;
114+ renderingInfo.colorAttachmentCount = (colorAttachmentFormat != vk::Format::eUndefined) ? 1 : 0 ;
115+ renderingInfo.pColorAttachmentFormats = (colorAttachmentFormat != vk::Format::eUndefined) ? &colorAttachmentFormat : nullptr ;
102116 renderingInfo.viewMask = 0 ;
103- renderingInfo.depthAttachmentFormat = vk::Format::eUndefined ;
117+ renderingInfo.depthAttachmentFormat = depthAttachmentFormat ;
104118 renderingInfo.stencilAttachmentFormat = vk::Format::eUndefined;
105119
106120 // 11. Create graphics pipeline
107121 vk::GraphicsPipelineCreateInfo pipelineInfo{};
108- pipelineInfo.stageCount = 2 ;
109- pipelineInfo.pStages = shaderStages;
122+ pipelineInfo.stageCount = static_cast < uint32_t >(shaderStages. size ()) ;
123+ pipelineInfo.pStages = shaderStages. data () ;
110124 pipelineInfo.pVertexInputState = &vertexInputInfo;
111125 pipelineInfo.pInputAssemblyState = &inputAssembly;
112126 pipelineInfo.pViewportState = &viewportState;
@@ -129,10 +143,42 @@ Pipeline::Pipeline(vk::Device device, vk::Format colorAttachmentFormat,
129143}
130144
131145Pipeline::~Pipeline () {
132- if (m_pipeline)
146+ if (m_pipeline) {
133147 m_device.destroyPipeline (m_pipeline);
134- if (m_pipelineLayout)
148+ }
149+ if (m_pipelineLayout) {
135150 m_device.destroyPipelineLayout (m_pipelineLayout);
136151}
152+ }
153+
154+ Pipeline::Pipeline (Pipeline&& other) noexcept
155+ : m_device(other.m_device),
156+ m_pipelineLayout (other.m_pipelineLayout),
157+ m_pipeline(other.m_pipeline)
158+ {
159+ other.m_pipelineLayout = nullptr ;
160+ other.m_pipeline = nullptr ;
161+ }
162+
163+ Pipeline& Pipeline::operator =(Pipeline&& other) noexcept
164+ {
165+ if (this != &other) {
166+ // Destroy our own Vulkan objects first
167+ if (m_pipeline) {
168+ m_device.destroyPipeline (m_pipeline);
169+ }
170+ if (m_pipelineLayout) {
171+ m_device.destroyPipelineLayout (m_pipelineLayout);
172+ }
173+ m_device = other.m_device ;
174+ m_pipelineLayout = other.m_pipelineLayout ;
175+ m_pipeline = other.m_pipeline ;
176+
177+ other.m_pipelineLayout = nullptr ;
178+ other.m_pipeline = nullptr ;
179+ }
180+ return *this ;
181+ }
182+
137183
138184} // namespace reactor
0 commit comments