2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali/graphics/vulkan/vulkan-pipeline.h>
19 #include <dali/graphics/vulkan/vulkan-graphics.h>
20 #include <dali/graphics/vulkan/vulkan-surface.h>
30 * Class Pipeline::Impl
31 * Internal implementation of the pipeline
35 Impl( Vulkan::Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info ) :
46 mGraphics.GetDevice().destroyPipelineLayout( mPipelineLayout, mGraphics.GetAllocator() );
50 mGraphics.GetDevice().destroyPipeline( mPipeline, mGraphics.GetAllocator() );
58 vk::Pipeline GetVkPipeline() const
63 vk::Result Initialise()
65 if( !ValidateShaderModules() )
67 return vk::Result::eErrorInitializationFailed;
70 CreatePipelineLayout();
72 // use default render pass for default framebuffer
73 // TODO: swapchain/surface should use vulkan-framebuffer object
74 // in place of swapchain structures!
75 if( !mInfo.renderPass )
77 SetRenderPass( mGraphics.GetSurface( 0 ).GetRenderPass() );
80 SetRasterizationState();
82 SetDepthStencilState();
84 SetMultisampleState();
88 mInfo.setFlags( vk::PipelineCreateFlagBits::eAllowDerivatives );
90 mPipeline = VkAssert( mGraphics.GetDevice().createGraphicsPipeline( nullptr, mInfo, mGraphics.GetAllocator() ) );
93 return vk::Result::eSuccess;
95 return vk::Result::eErrorInitializationFailed;
98 void SetRenderPass( vk::RenderPass renderpass )
100 mInfo.setRenderPass( renderpass );
103 void SetDepthStencilState()
105 mDepthStencilState = vk::PipelineDepthStencilStateCreateInfo{};
106 mDepthStencilState.setDepthBoundsTestEnable( false );
107 mDepthStencilState.setStencilTestEnable( false );
108 mInfo.setPDepthStencilState( & mDepthStencilState );
111 void SetMultisampleState()
113 mMultisampleState = vk::PipelineMultisampleStateCreateInfo{};
114 mMultisampleState.setSampleShadingEnable( false );
115 mMultisampleState.setRasterizationSamples( vk::SampleCountFlagBits::e1);
116 mMultisampleState.setAlphaToCoverageEnable( false );
117 mMultisampleState.setMinSampleShading( 1.0f );
118 mMultisampleState.setPSampleMask( nullptr );
119 mInfo.setPMultisampleState( &mMultisampleState );
122 void SetVertexInputState(
123 std::vector<vk::VertexInputAttributeDescription> attrDesc,
124 std::vector<vk::VertexInputBindingDescription> bindingDesc)
126 mBindingDesc.clear();
128 mVertexInputState = vk::PipelineVertexInputStateCreateInfo{};
129 mVertexInputState.setPVertexAttributeDescriptions( (mAttrDesc = attrDesc).data() );
130 mVertexInputState.setPVertexBindingDescriptions( (mBindingDesc = bindingDesc).data() );
131 mVertexInputState.setVertexAttributeDescriptionCount( U32(mAttrDesc.size()) );
132 mVertexInputState.setVertexBindingDescriptionCount( U32(mBindingDesc.size()) );
133 mInfo.setPVertexInputState( &mVertexInputState );
137 * Sets the viewport on uncompiled pipeline
140 void SetViewport( float x, float y, float width, float height )
142 assert( !mPipeline && "Pipeline cannot be changed anymore!");
144 // AB: add scissor, read data from graphics for fullscreen viewport
145 // simplified mode for the demo purposes
146 mViewports.emplace_back( x, y, width, height );
147 mViewports[0].setMinDepth( 0.0f );
148 mViewports[0].setMaxDepth( 1.0f );
149 mScissors = vk::Rect2D( { static_cast<int32_t>(x), static_cast<int32_t>(y) },
150 { U32(width), U32(height) });
151 mViewportState = vk::PipelineViewportStateCreateInfo{}.
152 setViewportCount( U32(mViewports.size()) ).
153 setPViewports( mViewports.data() ).
154 setPScissors( &mScissors ).
155 setScissorCount( 1 );
157 // replace viewport state
158 mInfo.setPViewportState( &mViewportState );
164 * @param restartEnable
166 void SetInputAssemblyState( vk::PrimitiveTopology topology, bool restartEnable )
168 mInputAssemblyState = vk::PipelineInputAssemblyStateCreateInfo{};
169 mInputAssemblyState.setPrimitiveRestartEnable( restartEnable );
170 mInputAssemblyState.setTopology( topology );
171 mInfo.setPInputAssemblyState( &mInputAssemblyState );
174 void SetRasterizationState()
176 mRasterizationState = vk::PipelineRasterizationStateCreateInfo{};
177 mRasterizationState.setCullMode( vk::CullModeFlagBits::eNone );
178 mRasterizationState.setDepthBiasClamp( 0.0f );
179 mRasterizationState.setDepthBiasEnable( false );
180 mRasterizationState.setDepthClampEnable( false );
181 mRasterizationState.setFrontFace( vk::FrontFace::eCounterClockwise );
182 mRasterizationState.setPolygonMode( vk::PolygonMode::eFill );
183 mRasterizationState.setRasterizerDiscardEnable( false );
184 mRasterizationState.setLineWidth( 1.0f );
185 mInfo.setPRasterizationState( & mRasterizationState );
188 void SetColorBlendState()
190 mAttachementNoBlendState = vk::PipelineColorBlendAttachmentState{};
191 //mAttachementNoBlendState.setBlendEnable( true );
192 mAttachementNoBlendState.setColorWriteMask( vk::ColorComponentFlagBits::eR |
193 vk::ColorComponentFlagBits::eG |
194 vk::ColorComponentFlagBits::eB |
195 vk::ColorComponentFlagBits::eA );
197 mColorBlendState.setBlendConstants( { 1.0f, 1.0f, 1.0f, 1.0f });
198 mColorBlendState = vk::PipelineColorBlendStateCreateInfo{};
199 mColorBlendState.setAttachmentCount( 1 );
200 mColorBlendState.setPAttachments( &mAttachementNoBlendState );
201 mInfo.setPColorBlendState(&mColorBlendState);
205 * Sets the shader. Must be set before compiling the pipeline, compiled pipeline
211 bool SetShader( ShaderRef shader, Shader::Type stage )
213 assert( !mPipeline && "Pipeline cannot be changed anymore!");
215 // check if shader isn't orphaned for some reason
216 if( !mGraphics.FindShader( *shader ) )
221 auto info = vk::PipelineShaderStageCreateInfo{}.
222 setModule( *shader ).
223 setStage( static_cast<vk::ShaderStageFlagBits>( stage ) ).
226 mShaderStageCreateInfo.push_back( info );
227 mShaderResources.push_back( shader );
229 mInfo.setPStages( mShaderStageCreateInfo.data() );
230 mInfo.setStageCount( static_cast<uint32_t>(mShaderStageCreateInfo.size()) );
238 void CreatePipelineLayout()
240 // pull desciptor set layouts from shaders
241 auto layoutInfo = vk::PipelineLayoutCreateInfo{};
243 //info.setPSetLayouts( vk::DescriptorSetLayout )
245 std::vector<vk::DescriptorSetLayout> allLayouts{};
246 for( auto&& shader : mShaderResources )
248 auto& layouts = shader->GetDescriptorSetLayouts();
251 allLayouts.resize(layouts.size());
252 for (auto i = 0u; i < layouts.size(); ++i)
256 allLayouts[i] = layouts[i];
262 layoutInfo.setPSetLayouts( allLayouts.data() );
263 layoutInfo.setSetLayoutCount( static_cast<uint32_t>(allLayouts.size()) );
265 mPipelineLayout = VkAssert( mGraphics.GetDevice().createPipelineLayout( layoutInfo, mGraphics.GetAllocator() ) );
267 mInfo.setLayout( mPipelineLayout );
273 return Initialise() == vk::Result::eSuccess;
276 bool ValidateShaderModules()
278 for( auto i = 0u; i < mInfo.stageCount; ++i )
280 const auto& stage = mInfo.pStages[i];
281 auto shaderHandle = mGraphics.FindShader( stage.module );
284 mShaderResources.push_back( shaderHandle );
288 return false; // invalid shader! Can't track it
295 vk::GraphicsPipelineCreateInfo mInfo { };
296 vk::Pipeline mPipeline { nullptr };
297 uint32_t mModified { 0u };
301 std::vector<Handle<Shader>> mShaderResources;
303 vk::PipelineViewportStateCreateInfo mViewportState {};
304 std::vector<vk::Viewport> mViewports {};
305 vk::Rect2D mScissors {};
307 std::vector<vk::PipelineShaderStageCreateInfo> mShaderStageCreateInfo;
308 vk::PipelineLayout mPipelineLayout{};
310 // vertex input state
311 vk::PipelineVertexInputStateCreateInfo mVertexInputState {};
312 std::vector<vk::VertexInputAttributeDescription> mAttrDesc;
313 std::vector<vk::VertexInputBindingDescription> mBindingDesc;
315 // vertex input assembly state
316 vk::PipelineInputAssemblyStateCreateInfo mInputAssemblyState {};
318 // rasterization state
319 vk::PipelineRasterizationStateCreateInfo mRasterizationState {};
321 // Dpeth/stencil state
322 vk::PipelineDepthStencilStateCreateInfo mDepthStencilState {};
325 vk::PipelineMultisampleStateCreateInfo mMultisampleState {};
328 vk::PipelineColorBlendStateCreateInfo mColorBlendState {};
329 vk::PipelineColorBlendAttachmentState mAttachementNoBlendState {};
332 /*********************************************************************
337 PipelineRef Pipeline::New( Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info )
339 auto pipeline = Handle<Pipeline>( new Pipeline(graphics, info) );
340 graphics.AddPipeline(pipeline);
344 Pipeline::~Pipeline() = default;
346 Pipeline::Pipeline( Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info )
348 mImpl = MakeUnique<Pipeline::Impl>( graphics, info );
351 vk::Pipeline Pipeline::GetVkPipeline() const
353 return mImpl->GetVkPipeline();
356 bool Pipeline::OnDestroy()
361 void Pipeline::SetViewport( float x, float y, float width, float height )
363 mImpl->SetViewport( x, y, width, height );
366 bool Pipeline::SetShader( ShaderRef shader, Shader::Type stage )
368 return mImpl->SetShader( shader, stage );
371 void Pipeline::SetVertexInputState(std::vector<vk::VertexInputAttributeDescription> attrDesc,
372 std::vector<vk::VertexInputBindingDescription> bindingDesc)
374 mImpl->SetVertexInputState( attrDesc, bindingDesc );
377 void Pipeline::SetInputAssemblyState( vk::PrimitiveTopology topology, bool restartEnable )
379 mImpl->SetInputAssemblyState( topology, restartEnable );
382 bool Pipeline::Compile()
384 return mImpl->Compile();
387 vk::PipelineLayout Pipeline::GetVkPipelineLayout() const
389 return mImpl->mPipelineLayout;
392 } // namespace Vulkan
394 } // namespace Graphics