Flutter Impeller
pipeline_vk.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include "flutter/fml/make_copyable.h"
8 #include "flutter/fml/status_or.h"
9 #include "flutter/fml/trace_event.h"
10 #include "impeller/base/strings.h"
11 #include "impeller/base/timing.h"
19 
20 namespace impeller {
21 
22 static vk::PipelineCreationFeedbackEXT EmptyFeedback() {
23  vk::PipelineCreationFeedbackEXT feedback;
24  // If the VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT is not set in flags, an
25  // implementation must not set any other bits in flags, and the values of all
26  // other VkPipelineCreationFeedback data members are undefined.
27  feedback.flags = vk::PipelineCreationFeedbackFlagBits::eValid;
28  return feedback;
29 }
30 
31 constexpr vk::FrontFace ToVKFrontFace(WindingOrder order) {
32  switch (order) {
34  return vk::FrontFace::eClockwise;
36  return vk::FrontFace::eCounterClockwise;
37  }
38  FML_UNREACHABLE();
39 }
40 
42  std::stringstream& stream,
43  const vk::PipelineCreationFeedbackEXT& feedback) {
44  const auto pipeline_cache_hit =
45  feedback.flags &
46  vk::PipelineCreationFeedbackFlagBits::eApplicationPipelineCacheHit;
47  const auto base_pipeline_accl =
48  feedback.flags &
49  vk::PipelineCreationFeedbackFlagBits::eBasePipelineAcceleration;
50  auto duration = std::chrono::duration_cast<MillisecondsF>(
51  std::chrono::nanoseconds{feedback.duration});
52  stream << "Time: " << duration.count() << "ms"
53  << " Cache Hit: " << static_cast<bool>(pipeline_cache_hit)
54  << " Base Accel: " << static_cast<bool>(base_pipeline_accl)
55  << " Thread: " << std::this_thread::get_id();
56 }
57 
59  const PipelineDescriptor& desc,
60  const vk::PipelineCreationFeedbackCreateInfoEXT& feedback) {
61  std::stringstream stream;
62  stream << std::fixed << std::showpoint << std::setprecision(2);
63  stream << std::endl << ">>>>>>" << std::endl;
64  stream << "Pipeline '" << desc.GetLabel() << "' ";
66  *feedback.pPipelineCreationFeedback);
67  if (feedback.pipelineStageCreationFeedbackCount != 0) {
68  stream << std::endl;
69  }
70  for (size_t i = 0, count = feedback.pipelineStageCreationFeedbackCount;
71  i < count; i++) {
72  stream << "\tStage " << i + 1 << ": ";
74  stream, feedback.pPipelineStageCreationFeedbacks[i]);
75  if (i != count - 1) {
76  stream << std::endl;
77  }
78  }
79  stream << std::endl << "<<<<<<" << std::endl;
80  FML_LOG(ERROR) << stream.str();
81 }
82 
84  const PipelineDescriptor& desc,
85  const vk::PipelineCreationFeedbackCreateInfoEXT& feedback) {
86  static int64_t gPipelineCacheHits = 0;
87  static int64_t gPipelineCacheMisses = 0;
88  static int64_t gPipelines = 0;
89  if (feedback.pPipelineCreationFeedback->flags &
90  vk::PipelineCreationFeedbackFlagBits::eApplicationPipelineCacheHit) {
91  gPipelineCacheHits++;
92  } else {
93  gPipelineCacheMisses++;
94  }
95  gPipelines++;
96  static constexpr int64_t kImpellerPipelineTraceID = 1988;
97  FML_TRACE_COUNTER("impeller", //
98  "PipelineCache", // series name
99  kImpellerPipelineTraceID, // series ID
100  "PipelineCacheHits", gPipelineCacheHits, //
101  "PipelineCacheMisses", gPipelineCacheMisses, //
102  "TotalPipelines", gPipelines //
103  );
104 }
105 
107  const PipelineDescriptor& desc,
108  const vk::PipelineCreationFeedbackCreateInfoEXT& feedback) {
109  constexpr bool kReportPipelineCreationFeedbackToLogs = false;
110  constexpr bool kReportPipelineCreationFeedbackToTraces = true;
111  if (kReportPipelineCreationFeedbackToLogs) {
112  ReportPipelineCreationFeedbackToLog(desc, feedback);
113  }
114  if (kReportPipelineCreationFeedbackToTraces) {
116  }
117 }
118 
119 //----------------------------------------------------------------------------
120 /// Render Pass
121 /// We are NOT going to use the same render pass with the framebuffer (later)
122 /// and the graphics pipeline (here). Instead, we are going to ensure that the
123 /// sub-passes are compatible. To see the compatibility rules, see the Vulkan
124 /// spec:
125 /// https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/chap8.html#renderpass-compatibility
126 ///
127 static vk::UniqueRenderPass CreateCompatRenderPassForPipeline(
128  const vk::Device& device,
129  const PipelineDescriptor& desc) {
130  RenderPassBuilderVK builder;
131 
132  for (const auto& [bind_point, color] : desc.GetColorAttachmentDescriptors()) {
133  builder.SetColorAttachment(bind_point, //
134  color.format, //
135  desc.GetSampleCount(), //
138  );
139  }
140 
141  if (auto depth = desc.GetDepthStencilAttachmentDescriptor();
142  depth.has_value()) {
144  desc.GetSampleCount(), //
147  );
148  } else if (desc.HasStencilAttachmentDescriptors()) {
150  desc.GetSampleCount(), //
153  );
154  }
155 
156  auto pass = builder.Build(device);
157  if (!pass) {
158  VALIDATION_LOG << "Failed to create render pass for pipeline: "
159  << desc.GetLabel();
160  return {};
161  }
162 
163 #ifdef IMPELLER_DEBUG
165  device, pass.get(),
166  SPrintF("Compat Render Pass: %s", desc.GetLabel().data()));
167 #endif // IMPELLER_DEBUG
168 
169  return pass;
170 }
171 
172 namespace {
173 fml::StatusOr<vk::UniqueDescriptorSetLayout> MakeDescriptorSetLayout(
174  const PipelineDescriptor& desc,
175  const std::shared_ptr<DeviceHolderVK>& device_holder,
176  const std::shared_ptr<SamplerVK>& immutable_sampler) {
177  std::vector<vk::DescriptorSetLayoutBinding> set_bindings;
178 
179  vk::Sampler vk_immutable_sampler =
180  immutable_sampler ? immutable_sampler->GetSampler()
181  : static_cast<vk::Sampler>(VK_NULL_HANDLE);
182 
183  for (auto layout : desc.GetVertexDescriptor()->GetDescriptorSetLayouts()) {
184  vk::DescriptorSetLayoutBinding set_binding;
185  set_binding.binding = layout.binding;
186  set_binding.descriptorCount = 1u;
187  set_binding.descriptorType = ToVKDescriptorType(layout.descriptor_type);
188  set_binding.stageFlags = ToVkShaderStage(layout.shader_stage);
189  // TODO(143719): This specifies the immutable sampler for all sampled
190  // images. This is incorrect. In cases where the shader samples from the
191  // multiple images, there is currently no way to tell which sampler needs to
192  // be immutable and which one needs a binding set in the render pass. Expect
193  // errors if the shader has more than on sampled image. The sampling from
194  // the one that is expected to be non-immutable will be incorrect.
195  if (vk_immutable_sampler &&
196  layout.descriptor_type == DescriptorType::kSampledImage) {
197  set_binding.setImmutableSamplers(vk_immutable_sampler);
198  }
199  set_bindings.push_back(set_binding);
200  }
201 
202  vk::DescriptorSetLayoutCreateInfo desc_set_layout_info;
203  desc_set_layout_info.setBindings(set_bindings);
204 
205  auto [descs_result, descs_layout] =
206  device_holder->GetDevice().createDescriptorSetLayoutUnique(
207  desc_set_layout_info);
208  if (descs_result != vk::Result::eSuccess) {
209  VALIDATION_LOG << "unable to create uniform descriptors";
210  return {fml::Status(fml::StatusCode::kUnknown,
211  "unable to create uniform descriptors")};
212  }
213 
214 #ifdef IMPELLER_DEBUG
216  device_holder->GetDevice(), descs_layout.get(),
217  SPrintF("Descriptor Set Layout: %s", desc.GetLabel().data()));
218 #endif // IMPELLER_DEBUG
219 
220  return fml::StatusOr<vk::UniqueDescriptorSetLayout>(std::move(descs_layout));
221 }
222 
223 fml::StatusOr<vk::UniquePipelineLayout> MakePipelineLayout(
224  const PipelineDescriptor& desc,
225  const std::shared_ptr<DeviceHolderVK>& device_holder,
226  const vk::DescriptorSetLayout& descs_layout) {
227  vk::PipelineLayoutCreateInfo pipeline_layout_info;
228  pipeline_layout_info.setSetLayouts(descs_layout);
229  auto pipeline_layout = device_holder->GetDevice().createPipelineLayoutUnique(
230  pipeline_layout_info);
231  if (pipeline_layout.result != vk::Result::eSuccess) {
232  VALIDATION_LOG << "Could not create pipeline layout for pipeline "
233  << desc.GetLabel() << ": "
234  << vk::to_string(pipeline_layout.result);
235  return {fml::Status(fml::StatusCode::kUnknown,
236  "Could not create pipeline layout for pipeline.")};
237  }
238 
239 #ifdef IMPELLER_DEBUG
241  device_holder->GetDevice(), *pipeline_layout.value,
242  SPrintF("Pipeline Layout %s", desc.GetLabel().data()));
243 #endif // IMPELLER_DEBUG
244 
245  return std::move(pipeline_layout.value);
246 }
247 
248 fml::StatusOr<vk::UniquePipeline> MakePipeline(
249  const PipelineDescriptor& desc,
250  const std::shared_ptr<DeviceHolderVK>& device_holder,
251  const std::shared_ptr<PipelineCacheVK>& pso_cache,
252  const vk::PipelineLayout& pipeline_layout,
253  const vk::RenderPass& render_pass) {
254  vk::StructureChain<vk::GraphicsPipelineCreateInfo,
255  vk::PipelineCreationFeedbackCreateInfoEXT>
256  chain;
257 
258  const auto* caps = pso_cache->GetCapabilities();
259 
260  const auto supports_pipeline_creation_feedback = caps->HasExtension(
262  if (!supports_pipeline_creation_feedback) {
263  chain.unlink<vk::PipelineCreationFeedbackCreateInfoEXT>();
264  }
265 
266  auto& pipeline_info = chain.get<vk::GraphicsPipelineCreateInfo>();
267  pipeline_info.setLayout(pipeline_layout);
268 
269  //----------------------------------------------------------------------------
270  /// Dynamic States
271  ///
272  vk::PipelineDynamicStateCreateInfo dynamic_create_state_info;
273  std::vector<vk::DynamicState> dynamic_states = {
274  vk::DynamicState::eViewport,
275  vk::DynamicState::eScissor,
276  vk::DynamicState::eStencilReference,
277  };
278  dynamic_create_state_info.setDynamicStates(dynamic_states);
279  pipeline_info.setPDynamicState(&dynamic_create_state_info);
280 
281  //----------------------------------------------------------------------------
282  /// Viewport State
283  ///
284  vk::PipelineViewportStateCreateInfo viewport_state;
285  viewport_state.setViewportCount(1u);
286  viewport_state.setScissorCount(1u);
287  // The actual viewport and scissor rects are not set here since they are
288  // dynamic as mentioned above in the dynamic state info.
289  pipeline_info.setPViewportState(&viewport_state);
290 
291  //----------------------------------------------------------------------------
292  /// Shader Stages
293  ///
294  const auto& constants = desc.GetSpecializationConstants();
295 
296  std::vector<std::vector<vk::SpecializationMapEntry>> map_entries(
297  desc.GetStageEntrypoints().size());
298  std::vector<vk::SpecializationInfo> specialization_infos(
299  desc.GetStageEntrypoints().size());
300  std::vector<vk::PipelineShaderStageCreateInfo> shader_stages;
301 
302  size_t entrypoint_count = 0;
303  for (const auto& entrypoint : desc.GetStageEntrypoints()) {
304  auto stage = ToVKShaderStageFlagBits(entrypoint.first);
305  if (!stage.has_value()) {
306  VALIDATION_LOG << "Unsupported shader type in pipeline: "
307  << desc.GetLabel();
308  return {fml::Status(fml::StatusCode::kUnknown,
309  "Unsupported shader type in pipeline.")};
310  }
311 
312  std::vector<vk::SpecializationMapEntry>& entries =
313  map_entries[entrypoint_count];
314  for (auto i = 0u; i < constants.size(); i++) {
315  vk::SpecializationMapEntry entry;
316  entry.offset = (i * sizeof(Scalar));
317  entry.size = sizeof(Scalar);
318  entry.constantID = i;
319  entries.emplace_back(entry);
320  }
321 
322  vk::SpecializationInfo& specialization_info =
323  specialization_infos[entrypoint_count];
324  specialization_info.setMapEntries(map_entries[entrypoint_count]);
325  specialization_info.setPData(constants.data());
326  specialization_info.setDataSize(sizeof(Scalar) * constants.size());
327 
328  vk::PipelineShaderStageCreateInfo info;
329  info.setStage(stage.value());
330  info.setPName("main");
331  info.setModule(
332  ShaderFunctionVK::Cast(entrypoint.second.get())->GetModule());
333  info.setPSpecializationInfo(&specialization_info);
334  shader_stages.push_back(info);
335  entrypoint_count++;
336  }
337  pipeline_info.setStages(shader_stages);
338 
339  //----------------------------------------------------------------------------
340  /// Rasterization State
341  ///
342  vk::PipelineRasterizationStateCreateInfo rasterization_state;
343  rasterization_state.setFrontFace(ToVKFrontFace(desc.GetWindingOrder()));
344  rasterization_state.setCullMode(ToVKCullModeFlags(desc.GetCullMode()));
345  rasterization_state.setPolygonMode(ToVKPolygonMode(desc.GetPolygonMode()));
346  rasterization_state.setLineWidth(1.0f);
347  rasterization_state.setDepthClampEnable(false);
348  rasterization_state.setRasterizerDiscardEnable(false);
349  pipeline_info.setPRasterizationState(&rasterization_state);
350 
351  //----------------------------------------------------------------------------
352  /// Multi-sample State
353  ///
354  vk::PipelineMultisampleStateCreateInfo multisample_state;
355  multisample_state.setRasterizationSamples(
356  ToVKSampleCountFlagBits(desc.GetSampleCount()));
357  pipeline_info.setPMultisampleState(&multisample_state);
358 
359  //----------------------------------------------------------------------------
360  /// Primitive Input Assembly State
361  vk::PipelineInputAssemblyStateCreateInfo input_assembly;
362  const auto topology = ToVKPrimitiveTopology(desc.GetPrimitiveType());
363  input_assembly.setTopology(topology);
364  input_assembly.setPrimitiveRestartEnable(
365  caps->SupportsPrimitiveRestart() &&
366  PrimitiveTopologySupportsPrimitiveRestart(desc.GetPrimitiveType()));
367  pipeline_info.setPInputAssemblyState(&input_assembly);
368 
369  //----------------------------------------------------------------------------
370  /// Color Blend State
371  std::vector<vk::PipelineColorBlendAttachmentState> attachment_blend_state;
372  for (const auto& color_desc : desc.GetColorAttachmentDescriptors()) {
373  // TODO(csg): The blend states are per color attachment. But it isn't clear
374  // how the color attachment indices are specified in the pipeline create
375  // info. But, this should always work for one color attachment.
376  attachment_blend_state.push_back(
377  ToVKPipelineColorBlendAttachmentState(color_desc.second));
378  }
379  vk::PipelineColorBlendStateCreateInfo blend_state;
380  blend_state.setAttachments(attachment_blend_state);
381  pipeline_info.setPColorBlendState(&blend_state);
382 
383  // Convention wisdom says that the base acceleration pipelines are never used
384  // by drivers for cache hits. Instead, the PSO cache is the preferred
385  // mechanism.
386  pipeline_info.setBasePipelineHandle(VK_NULL_HANDLE);
387  pipeline_info.setSubpass(0u);
388  pipeline_info.setRenderPass(render_pass);
389 
390  //----------------------------------------------------------------------------
391  /// Vertex Input Setup
392  ///
393  std::vector<vk::VertexInputAttributeDescription> attr_descs;
394  std::vector<vk::VertexInputBindingDescription> buffer_descs;
395 
396  const auto& stage_inputs = desc.GetVertexDescriptor()->GetStageInputs();
397  const auto& stage_buffer_layouts =
398  desc.GetVertexDescriptor()->GetStageLayouts();
399  for (const ShaderStageIOSlot& stage_in : stage_inputs) {
400  vk::VertexInputAttributeDescription attr_desc;
401  attr_desc.setBinding(stage_in.binding);
402  attr_desc.setLocation(stage_in.location);
403  attr_desc.setFormat(ToVertexDescriptorFormat(stage_in));
404  attr_desc.setOffset(stage_in.offset);
405  attr_descs.push_back(attr_desc);
406  }
407  for (const ShaderStageBufferLayout& layout : stage_buffer_layouts) {
408  vk::VertexInputBindingDescription binding_description;
409  binding_description.setBinding(layout.binding);
410  binding_description.setInputRate(vk::VertexInputRate::eVertex);
411  binding_description.setStride(layout.stride);
412  buffer_descs.push_back(binding_description);
413  }
414 
415  vk::PipelineVertexInputStateCreateInfo vertex_input_state;
416  vertex_input_state.setVertexAttributeDescriptions(attr_descs);
417  vertex_input_state.setVertexBindingDescriptions(buffer_descs);
418 
419  pipeline_info.setPVertexInputState(&vertex_input_state);
420 
421  //----------------------------------------------------------------------------
422  /// Create the depth stencil state.
423  ///
424  auto depth_stencil_state = ToVKPipelineDepthStencilStateCreateInfo(
425  desc.GetDepthStencilAttachmentDescriptor(),
426  desc.GetFrontStencilAttachmentDescriptor(),
427  desc.GetBackStencilAttachmentDescriptor());
428  pipeline_info.setPDepthStencilState(&depth_stencil_state);
429 
430  //----------------------------------------------------------------------------
431  /// Setup the optional pipeline creation feedback struct so we can understand
432  /// how Vulkan created the PSO.
433  ///
434  auto& feedback = chain.get<vk::PipelineCreationFeedbackCreateInfoEXT>();
435  auto pipeline_feedback = EmptyFeedback();
436  std::vector<vk::PipelineCreationFeedbackEXT> stage_feedbacks(
437  pipeline_info.stageCount, EmptyFeedback());
438  feedback.setPPipelineCreationFeedback(&pipeline_feedback);
439  feedback.setPipelineStageCreationFeedbacks(stage_feedbacks);
440 
441  //----------------------------------------------------------------------------
442  /// Finally, all done with the setup info. Create the pipeline itself.
443  ///
444  auto pipeline = pso_cache->CreatePipeline(pipeline_info);
445  if (!pipeline) {
446  VALIDATION_LOG << "Could not create graphics pipeline: " << desc.GetLabel();
447  return {fml::Status(fml::StatusCode::kUnknown,
448  "Could not create graphics pipeline.")};
449  }
450 
451  if (supports_pipeline_creation_feedback) {
452  ReportPipelineCreationFeedback(desc, feedback);
453  }
454 
455 #ifdef IMPELLER_DEBUG
456  ContextVK::SetDebugName(device_holder->GetDevice(), *pipeline,
457  SPrintF("Pipeline %s", desc.GetLabel().data()));
458 #endif // IMPELLER_DEBUG
459 
460  return std::move(pipeline);
461 }
462 } // namespace
463 
464 std::unique_ptr<PipelineVK> PipelineVK::Create(
465  const PipelineDescriptor& desc,
466  const std::shared_ptr<DeviceHolderVK>& device_holder,
467  const std::weak_ptr<PipelineLibrary>& weak_library,
468  PipelineKey pipeline_key,
469  std::shared_ptr<SamplerVK> immutable_sampler) {
470  TRACE_EVENT1("flutter", "PipelineVK::Create", "Name", desc.GetLabel().data());
471 
472  auto library = weak_library.lock();
473 
474  if (!device_holder || !library) {
475  return nullptr;
476  }
477 
478  const auto& pso_cache = PipelineLibraryVK::Cast(*library).GetPSOCache();
479 
480  fml::StatusOr<vk::UniqueDescriptorSetLayout> descs_layout =
481  MakeDescriptorSetLayout(desc, device_holder, immutable_sampler);
482  if (!descs_layout.ok()) {
483  return nullptr;
484  }
485 
486  fml::StatusOr<vk::UniquePipelineLayout> pipeline_layout =
487  MakePipelineLayout(desc, device_holder, descs_layout.value().get());
488  if (!pipeline_layout.ok()) {
489  return nullptr;
490  }
491 
492  vk::UniqueRenderPass render_pass =
493  CreateCompatRenderPassForPipeline(device_holder->GetDevice(), desc);
494  if (!render_pass) {
495  VALIDATION_LOG << "Could not create render pass for pipeline.";
496  return nullptr;
497  }
498 
499  fml::StatusOr<vk::UniquePipeline> pipeline =
500  MakePipeline(desc, device_holder, pso_cache,
501  pipeline_layout.value().get(), render_pass.get());
502  if (!pipeline.ok()) {
503  return nullptr;
504  }
505 
506  // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
507  auto pipeline_vk = std::unique_ptr<PipelineVK>(new PipelineVK(
508  device_holder, //
509  library, //
510  desc, //
511  std::move(pipeline.value()), //
512  std::move(render_pass), //
513  std::move(pipeline_layout.value()), //
514  std::move(descs_layout.value()), //
515  pipeline_key, //
516  std::move(immutable_sampler) //
517  ));
518  if (!pipeline_vk->IsValid()) {
519  VALIDATION_LOG << "Could not create a valid pipeline.";
520  return nullptr;
521  }
522  return pipeline_vk;
523 }
524 
525 PipelineVK::PipelineVK(std::weak_ptr<DeviceHolderVK> device_holder,
526  std::weak_ptr<PipelineLibrary> library,
527  const PipelineDescriptor& desc,
528  vk::UniquePipeline pipeline,
529  vk::UniqueRenderPass render_pass,
530  vk::UniquePipelineLayout layout,
531  vk::UniqueDescriptorSetLayout descriptor_set_layout,
532  PipelineKey pipeline_key,
533  std::shared_ptr<SamplerVK> immutable_sampler)
534  : Pipeline(std::move(library), desc),
535  device_holder_(std::move(device_holder)),
536  pipeline_(std::move(pipeline)),
537  render_pass_(std::move(render_pass)),
538  layout_(std::move(layout)),
539  descriptor_set_layout_(std::move(descriptor_set_layout)),
540  immutable_sampler_(std::move(immutable_sampler)),
541  pipeline_key_(pipeline_key) {
542  is_valid_ = pipeline_ && render_pass_ && layout_ && descriptor_set_layout_;
543 }
544 
546  if (auto device = device_holder_.lock(); !device) {
547  descriptor_set_layout_.release();
548  layout_.release();
549  render_pass_.release();
550  pipeline_.release();
551  }
552 }
553 
554 bool PipelineVK::IsValid() const {
555  return is_valid_;
556 }
557 
558 vk::Pipeline PipelineVK::GetPipeline() const {
559  return *pipeline_;
560 }
561 
562 const vk::PipelineLayout& PipelineVK::GetPipelineLayout() const {
563  return *layout_;
564 }
565 
566 const vk::DescriptorSetLayout& PipelineVK::GetDescriptorSetLayout() const {
567  return *descriptor_set_layout_;
568 }
569 
571  const std::shared_ptr<SamplerVK>& immutable_sampler) const {
572  if (!immutable_sampler) {
573  return nullptr;
574  }
575  auto cache_key = ImmutableSamplerKeyVK{*immutable_sampler};
576  Lock lock(immutable_sampler_variants_mutex_);
577  auto found = immutable_sampler_variants_.find(cache_key);
578  if (found != immutable_sampler_variants_.end()) {
579  return found->second;
580  }
581  auto device_holder = device_holder_.lock();
582  if (!device_holder) {
583  return nullptr;
584  }
585  // Note: immutable sampler variant of a pipeline is the negation of the
586  // existing pipeline key. This keeps the descriptors separate.
587  return (immutable_sampler_variants_[cache_key] =
588  Create(desc_, device_holder, library_, -1 * pipeline_key_,
589  immutable_sampler));
590 }
591 
592 } // namespace impeller
static ShaderFunctionVK & Cast(ShaderFunction &base)
Definition: backend_cast.h:13
bool SetDebugName(T handle, std::string_view label) const
Definition: context_vk.h:151
std::string_view GetLabel() const
PixelFormat GetDepthPixelFormat() const
std::optional< DepthAttachmentDescriptor > GetDepthStencilAttachmentDescriptor() const
PixelFormat GetStencilPixelFormat() const
const std::map< size_t, ColorAttachmentDescriptor > & GetColorAttachmentDescriptors() const
SampleCount GetSampleCount() const
Describes the fixed function and programmable aspects of rendering and compute operations performed b...
Definition: pipeline.h:52
const std::weak_ptr< PipelineLibrary > library_
Definition: pipeline.h:72
const PipelineDescriptor desc_
Definition: pipeline.h:74
const std::shared_ptr< PipelineCacheVK > & GetPSOCache() const
std::shared_ptr< PipelineVK > CreateVariantForImmutableSamplers(const std::shared_ptr< SamplerVK > &immutable_sampler) const
Definition: pipeline_vk.cc:570
~PipelineVK() override
Definition: pipeline_vk.cc:545
const vk::PipelineLayout & GetPipelineLayout() const
Definition: pipeline_vk.cc:562
const vk::DescriptorSetLayout & GetDescriptorSetLayout() const
Definition: pipeline_vk.cc:566
vk::Pipeline GetPipeline() const
Definition: pipeline_vk.cc:558
static std::unique_ptr< PipelineVK > Create(const PipelineDescriptor &desc, const std::shared_ptr< DeviceHolderVK > &device_holder, const std::weak_ptr< PipelineLibrary > &weak_library, PipelineKey pipeline_key, std::shared_ptr< SamplerVK > immutable_sampler={})
Definition: pipeline_vk.cc:464
RenderPassBuilderVK & SetDepthStencilAttachment(PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action)
RenderPassBuilderVK & SetStencilAttachment(PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action)
RenderPassBuilderVK & SetColorAttachment(size_t index, PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action, vk::ImageLayout current_layout=vk::ImageLayout::eUndefined, bool is_swapchain=false)
vk::UniqueRenderPass Build(const vk::Device &device) const
float Scalar
Definition: scalar.h:19
vk::Format ToVertexDescriptorFormat(const ShaderStageIOSlot &input)
static void ReportPipelineCreationFeedback(const PipelineDescriptor &desc, const vk::PipelineCreationFeedbackCreateInfoEXT &feedback)
Definition: pipeline_vk.cc:106
constexpr vk::PipelineColorBlendAttachmentState ToVKPipelineColorBlendAttachmentState(const ColorAttachmentDescriptor &desc)
Definition: formats_vk.h:113
static vk::PipelineCreationFeedbackEXT EmptyFeedback()
Definition: pipeline_vk.cc:22
int64_t PipelineKey
Definition: pipeline.h:21
constexpr vk::SampleCountFlagBits ToVKSampleCountFlagBits(SampleCount count)
Definition: formats_vk.h:32
constexpr std::optional< vk::ShaderStageFlagBits > ToVKShaderStageFlagBits(ShaderStage stage)
Definition: formats_vk.h:131
constexpr vk::DescriptorType ToVKDescriptorType(DescriptorType type)
Definition: formats_vk.h:292
constexpr vk::PolygonMode ToVKPolygonMode(PolygonMode mode)
Definition: formats_vk.h:370
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
constexpr vk::CullModeFlags ToVKCullModeFlags(CullMode mode)
Definition: formats_vk.h:441
static void ReportPipelineCreationFeedbackToLog(std::stringstream &stream, const vk::PipelineCreationFeedbackEXT &feedback)
Definition: pipeline_vk.cc:41
vk::PipelineDepthStencilStateCreateInfo ToVKPipelineDepthStencilStateCreateInfo(std::optional< DepthAttachmentDescriptor > depth, std::optional< StencilAttachmentDescriptor > front, std::optional< StencilAttachmentDescriptor > back)
Definition: formats_vk.cc:9
constexpr bool PrimitiveTopologySupportsPrimitiveRestart(PrimitiveType primitive)
Definition: formats_vk.h:380
WindingOrder
Definition: formats.h:22
constexpr vk::FrontFace ToVKFrontFace(WindingOrder order)
Definition: pipeline_vk.cc:31
constexpr vk::ShaderStageFlags ToVkShaderStage(ShaderStage stage)
Definition: formats_vk.h:264
constexpr vk::PrimitiveTopology ToVKPrimitiveTopology(PrimitiveType primitive)
Definition: formats_vk.h:395
static void ReportPipelineCreationFeedbackToTrace(const PipelineDescriptor &desc, const vk::PipelineCreationFeedbackCreateInfoEXT &feedback)
Definition: pipeline_vk.cc:83
static vk::UniqueRenderPass CreateCompatRenderPassForPipeline(const vk::Device &device, const PipelineDescriptor &desc)
Definition: pipeline_vk.cc:127
Definition: comparable.h:95
#define VALIDATION_LOG
Definition: validation.h:91