Flutter Engine
 
Loading...
Searching...
No Matches
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 <format>
8
20
21namespace impeller {
22
23static vk::PipelineCreationFeedbackEXT EmptyFeedback() {
24 vk::PipelineCreationFeedbackEXT feedback;
25 // If the VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT is not set in flags, an
26 // implementation must not set any other bits in flags, and the values of all
27 // other VkPipelineCreationFeedback data members are undefined.
28 feedback.flags = vk::PipelineCreationFeedbackFlagBits::eValid;
29 return feedback;
30}
31
32constexpr vk::FrontFace ToVKFrontFace(WindingOrder order) {
33 switch (order) {
35 return vk::FrontFace::eClockwise;
37 return vk::FrontFace::eCounterClockwise;
38 }
40}
41
43 std::stringstream& stream,
44 const vk::PipelineCreationFeedbackEXT& feedback) {
45 const auto pipeline_cache_hit =
46 feedback.flags &
47 vk::PipelineCreationFeedbackFlagBits::eApplicationPipelineCacheHit;
48 const auto base_pipeline_accl =
49 feedback.flags &
50 vk::PipelineCreationFeedbackFlagBits::eBasePipelineAcceleration;
51 auto duration = std::chrono::duration_cast<MillisecondsF>(
52 std::chrono::nanoseconds{feedback.duration});
53 stream << "Time: " << duration.count() << "ms"
54 << " Cache Hit: " << static_cast<bool>(pipeline_cache_hit)
55 << " Base Accel: " << static_cast<bool>(base_pipeline_accl)
56 << " Thread: " << std::this_thread::get_id();
57}
58
60 const PipelineDescriptor& desc,
61 const vk::PipelineCreationFeedbackCreateInfoEXT& feedback) {
62 std::stringstream stream;
63 stream << std::fixed << std::showpoint << std::setprecision(2);
64 stream << std::endl << ">>>>>>" << std::endl;
65 stream << "Pipeline '" << desc.GetLabel() << "' ";
67 *feedback.pPipelineCreationFeedback);
68 if (feedback.pipelineStageCreationFeedbackCount != 0) {
69 stream << std::endl;
70 }
71 for (size_t i = 0, count = feedback.pipelineStageCreationFeedbackCount;
72 i < count; i++) {
73 stream << "\tStage " << i + 1 << ": ";
75 stream, feedback.pPipelineStageCreationFeedbacks[i]);
76 if (i != count - 1) {
77 stream << std::endl;
78 }
79 }
80 stream << std::endl << "<<<<<<" << std::endl;
81 FML_LOG(ERROR) << stream.str();
82}
83
85 const PipelineDescriptor& desc,
86 const vk::PipelineCreationFeedbackCreateInfoEXT& feedback) {
87 static int64_t gPipelineCacheHits = 0;
88 static int64_t gPipelineCacheMisses = 0;
89 static int64_t gPipelines = 0;
90 if (feedback.pPipelineCreationFeedback->flags &
91 vk::PipelineCreationFeedbackFlagBits::eApplicationPipelineCacheHit) {
92 gPipelineCacheHits++;
93 } else {
94 gPipelineCacheMisses++;
95 }
96 gPipelines++;
97 static constexpr int64_t kImpellerPipelineTraceID = 1988;
98 FML_TRACE_COUNTER("impeller", //
99 "PipelineCache", // series name
100 kImpellerPipelineTraceID, // series ID
101 "PipelineCacheHits", gPipelineCacheHits, //
102 "PipelineCacheMisses", gPipelineCacheMisses, //
103 "TotalPipelines", gPipelines //
104 );
105}
106
108 const PipelineDescriptor& desc,
109 const vk::PipelineCreationFeedbackCreateInfoEXT& feedback) {
110 constexpr bool kReportPipelineCreationFeedbackToLogs = false;
111 constexpr bool kReportPipelineCreationFeedbackToTraces = true;
112 if (kReportPipelineCreationFeedbackToLogs) {
114 }
115 if (kReportPipelineCreationFeedbackToTraces) {
117 }
118}
119
120//----------------------------------------------------------------------------
121/// Render Pass
122/// We are NOT going to use the same render pass with the framebuffer (later)
123/// and the graphics pipeline (here). Instead, we are going to ensure that the
124/// sub-passes are compatible. To see the compatibility rules, see the Vulkan
125/// spec:
126/// https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/chap8.html#renderpass-compatibility
127///
128static vk::UniqueRenderPass CreateCompatRenderPassForPipeline(
129 const vk::Device& device,
130 const PipelineDescriptor& desc) {
131 RenderPassBuilderVK builder;
132
133 for (const auto& [bind_point, color] : desc.GetColorAttachmentDescriptors()) {
134 builder.SetColorAttachment(bind_point, //
135 color.format, //
136 desc.GetSampleCount(), //
139 );
140 }
141
142 if (auto depth = desc.GetDepthStencilAttachmentDescriptor();
143 depth.has_value()) {
145 desc.GetSampleCount(), //
148 );
149 } else if (desc.HasStencilAttachmentDescriptors()) {
151 desc.GetSampleCount(), //
154 );
155 }
156
157 auto pass = builder.Build(device);
158 if (!pass) {
159 VALIDATION_LOG << "Failed to create render pass for pipeline: "
160 << desc.GetLabel();
161 return {};
162 }
163
164#ifdef IMPELLER_DEBUG
166 device, pass.get(),
167 std::format("Compat Render Pass: {}", desc.GetLabel()));
168#endif // IMPELLER_DEBUG
169
170 return pass;
171}
172
173namespace {
175 const PipelineDescriptor& desc,
176 const std::shared_ptr<DeviceHolderVK>& device_holder,
177 const std::shared_ptr<SamplerVK>& immutable_sampler) {
178 std::vector<vk::DescriptorSetLayoutBinding> set_bindings;
179
180 vk::Sampler vk_immutable_sampler =
181 immutable_sampler ? immutable_sampler->GetSampler()
182 : static_cast<vk::Sampler>(VK_NULL_HANDLE);
183
184 for (auto layout : desc.GetVertexDescriptor()->GetDescriptorSetLayouts()) {
185 vk::DescriptorSetLayoutBinding set_binding;
186 set_binding.binding = layout.binding;
187 set_binding.descriptorCount = 1u;
188 set_binding.descriptorType = ToVKDescriptorType(layout.descriptor_type);
189 set_binding.stageFlags = ToVkShaderStage(layout.shader_stage);
190 // TODO(143719): This specifies the immutable sampler for all sampled
191 // images. This is incorrect. In cases where the shader samples from the
192 // multiple images, there is currently no way to tell which sampler needs to
193 // be immutable and which one needs a binding set in the render pass. Expect
194 // errors if the shader has more than on sampled image. The sampling from
195 // the one that is expected to be non-immutable will be incorrect.
196 if (vk_immutable_sampler &&
197 layout.descriptor_type == DescriptorType::kSampledImage) {
198 set_binding.setImmutableSamplers(vk_immutable_sampler);
199 }
200 set_bindings.push_back(set_binding);
201 }
202
203 vk::DescriptorSetLayoutCreateInfo desc_set_layout_info;
204 desc_set_layout_info.setBindings(set_bindings);
205
206 auto [descs_result, descs_layout] =
207 device_holder->GetDevice().createDescriptorSetLayoutUnique(
208 desc_set_layout_info);
209 if (descs_result != vk::Result::eSuccess) {
210 VALIDATION_LOG << "unable to create uniform descriptors";
212 "unable to create uniform descriptors")};
213 }
214
215#ifdef IMPELLER_DEBUG
217 device_holder->GetDevice(), descs_layout.get(),
218 std::format("Descriptor Set Layout: {}", desc.GetLabel()));
219#endif // IMPELLER_DEBUG
220
221 return fml::StatusOr<vk::UniqueDescriptorSetLayout>(std::move(descs_layout));
222}
223
225 const PipelineDescriptor& desc,
226 const std::shared_ptr<DeviceHolderVK>& device_holder,
227 const vk::DescriptorSetLayout& descs_layout) {
228 vk::PipelineLayoutCreateInfo pipeline_layout_info;
229 pipeline_layout_info.setSetLayouts(descs_layout);
230 auto pipeline_layout = device_holder->GetDevice().createPipelineLayoutUnique(
231 pipeline_layout_info);
232 if (pipeline_layout.result != vk::Result::eSuccess) {
233 VALIDATION_LOG << "Could not create pipeline layout for pipeline "
234 << desc.GetLabel() << ": "
235 << vk::to_string(pipeline_layout.result);
237 "Could not create pipeline layout for pipeline.")};
238 }
239
240#ifdef IMPELLER_DEBUG
241 ContextVK::SetDebugName(device_holder->GetDevice(), *pipeline_layout.value,
242 std::format("Pipeline Layout {}", desc.GetLabel()));
243#endif // IMPELLER_DEBUG
244
245 return std::move(pipeline_layout.value);
246}
247
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();
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();
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 std::format("Pipeline {}", desc.GetLabel()));
458#endif // IMPELLER_DEBUG
459
460 return std::move(pipeline);
461}
462} // namespace
463
464std::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
481 MakeDescriptorSetLayout(desc, device_holder, immutable_sampler);
482 if (!descs_layout.ok()) {
483 return nullptr;
484 }
485
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
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
525PipelineVK::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
554bool PipelineVK::IsValid() const {
555 return is_valid_;
556}
557
558vk::Pipeline PipelineVK::GetPipeline() const {
559 return *pipeline_;
560}
561
562const vk::PipelineLayout& PipelineVK::GetPipelineLayout() const {
563 return *layout_;
564}
565
566const 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
const T & value() const
Definition status_or.h:77
bool ok() const
Definition status_or.h:75
static ShaderFunctionVK & Cast(ShaderFunction &base)
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
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
const vk::PipelineLayout & GetPipelineLayout() const
const vk::DescriptorSetLayout & GetDescriptorSetLayout() const
vk::Pipeline GetPipeline() const
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={})
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
VkDevice device
Definition main.cc:69
#define FML_LOG(severity)
Definition logging.h:101
#define FML_UNREACHABLE()
Definition logging.h:128
float Scalar
Definition scalar.h:19
vk::Format ToVertexDescriptorFormat(const ShaderStageIOSlot &input)
static void ReportPipelineCreationFeedback(const PipelineDescriptor &desc, const vk::PipelineCreationFeedbackCreateInfoEXT &feedback)
constexpr vk::PipelineColorBlendAttachmentState ToVKPipelineColorBlendAttachmentState(const ColorAttachmentDescriptor &desc)
Definition formats_vk.h:113
static vk::PipelineCreationFeedbackEXT EmptyFeedback()
int64_t PipelineKey
Definition pipeline.h:21
constexpr vk::SampleCountFlagBits ToVKSampleCountFlagBits(SampleCount count)
Definition formats_vk.h:32
constexpr vk::DescriptorType ToVKDescriptorType(DescriptorType type)
Definition formats_vk.h:292
constexpr vk::PolygonMode ToVKPolygonMode(PolygonMode mode)
Definition formats_vk.h:370
constexpr vk::CullModeFlags ToVKCullModeFlags(CullMode mode)
Definition formats_vk.h:441
static void ReportPipelineCreationFeedbackToLog(std::stringstream &stream, const vk::PipelineCreationFeedbackEXT &feedback)
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 std::optional< vk::ShaderStageFlagBits > ToVKShaderStageFlagBits(ShaderStage stage)
Definition formats_vk.h:131
constexpr vk::FrontFace ToVKFrontFace(WindingOrder order)
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)
static vk::UniqueRenderPass CreateCompatRenderPassForPipeline(const vk::Device &device, const PipelineDescriptor &desc)
Definition ref_ptr.h:261
fuchsia::ui::composition::LayoutInfo layout_
#define FML_TRACE_COUNTER(category_group, name, counter_id, arg1,...)
Definition trace_event.h:85
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
#define VALIDATION_LOG
Definition validation.h:91