12#include "vulkan/vulkan_structs.hpp"
16ComputePassVK::ComputePassVK(std::shared_ptr<const Context>
context,
23ComputePassVK::~ComputePassVK() =
default;
25bool ComputePassVK::IsValid()
const {
29void ComputePassVK::OnSetLabel(
const std::string& label) {
37void ComputePassVK::SetCommandLabel(std::string_view label) {
39 command_buffer_->PushDebugGroup(label);
45void ComputePassVK::SetPipeline(
46 const std::shared_ptr<Pipeline<ComputePipelineDescriptor>>&
pipeline) {
47 const auto& pipeline_vk = ComputePipelineVK::Cast(*
pipeline);
48 const vk::CommandBuffer& command_buffer_vk =
49 command_buffer_->GetCommandBuffer();
50 command_buffer_vk.bindPipeline(vk::PipelineBindPoint::eCompute,
51 pipeline_vk.GetPipeline());
52 pipeline_layout_ = pipeline_vk.GetPipelineLayout();
54 auto descriptor_result = command_buffer_->AllocateDescriptorSets(
55 pipeline_vk.GetDescriptorSetLayout(), pipeline_vk.GetPipelineKey(),
56 ContextVK::Cast(*context_));
57 if (!descriptor_result.ok()) {
60 descriptor_set_ = descriptor_result.value();
61 pipeline_valid_ =
true;
65fml::Status ComputePassVK::Compute(std::array<uint32_t, 3> workgroup_count) {
66 if (workgroup_count[0] == 0u || workgroup_count[1] == 0u ||
67 workgroup_count[2] == 0u || !pipeline_valid_) {
68 bound_image_offset_ = 0u;
69 bound_buffer_offset_ = 0u;
70 descriptor_write_offset_ = 0u;
72 pipeline_valid_ =
false;
74 "Invalid pipeline or empty workgroup count.");
77 const ContextVK& context_vk = ContextVK::Cast(*context_);
78 for (
auto i = 0u;
i < descriptor_write_offset_;
i++) {
79 write_workspace_[
i].dstSet = descriptor_set_;
82 context_vk.GetDevice().updateDescriptorSets(descriptor_write_offset_,
83 write_workspace_.data(), 0u, {});
84 const vk::CommandBuffer& command_buffer_vk =
85 command_buffer_->GetCommandBuffer();
87 command_buffer_vk.bindDescriptorSets(
88 vk::PipelineBindPoint::eCompute,
100 command_buffer_vk.dispatch(workgroup_count[0], workgroup_count[1],
105 command_buffer_->PopDebugGroup();
110 bound_image_offset_ = 0u;
111 bound_buffer_offset_ = 0u;
112 descriptor_write_offset_ = 0u;
114 pipeline_valid_ =
false;
120bool ComputePassVK::BindResource(ShaderStage stage,
122 const ShaderUniformSlot& slot,
123 const ShaderMetadata* metadata,
125 return BindResource(slot.binding,
type, view);
129bool ComputePassVK::BindResource(ShaderStage stage,
131 const SampledImageSlot& slot,
132 const ShaderMetadata* metadata,
133 std::shared_ptr<const Texture>
texture,
134 raw_ptr<const Sampler> sampler) {
135 if (bound_image_offset_ >= kMaxBindings) {
138 if (!
texture->IsValid() || !sampler) {
141 const TextureVK& texture_vk = TextureVK::Cast(*
texture);
142 const SamplerVK& sampler_vk = SamplerVK::Cast(*sampler);
144 if (!command_buffer_->Track(
texture)) {
148 vk::DescriptorImageInfo image_info;
149 image_info.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
150 image_info.sampler = sampler_vk.GetSampler();
151 image_info.imageView = texture_vk.GetImageView();
152 image_workspace_[bound_image_offset_++] = image_info;
154 vk::WriteDescriptorSet write_set;
155 write_set.dstBinding = slot.binding;
156 write_set.descriptorCount = 1u;
158 write_set.pImageInfo = &image_workspace_[bound_image_offset_ - 1];
160 write_workspace_[descriptor_write_offset_++] = write_set;
164bool ComputePassVK::BindResource(
size_t binding,
167 if (bound_buffer_offset_ >= kMaxBindings) {
171 auto buffer = DeviceBufferVK::Cast(*
view.GetBuffer()).GetBuffer();
176 std::shared_ptr<const DeviceBuffer> device_buffer =
view.TakeBuffer();
177 if (device_buffer && !command_buffer_->Track(device_buffer)) {
181 uint32_t offset =
view.GetRange().offset;
183 vk::DescriptorBufferInfo buffer_info;
184 buffer_info.buffer =
buffer;
185 buffer_info.offset = offset;
186 buffer_info.range =
view.GetRange().length;
187 buffer_workspace_[bound_buffer_offset_++] = buffer_info;
189 vk::WriteDescriptorSet write_set;
190 write_set.dstBinding = binding;
191 write_set.descriptorCount = 1u;
193 write_set.pBufferInfo = &buffer_workspace_[bound_buffer_offset_ - 1];
195 write_workspace_[descriptor_write_offset_++] = write_set;
206void ComputePassVK::AddBufferMemoryBarrier() {
207 vk::MemoryBarrier barrier;
208 barrier.srcAccessMask = vk::AccessFlagBits::eShaderWrite;
209 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
211 command_buffer_->GetCommandBuffer().pipelineBarrier(
212 vk::PipelineStageFlagBits::eComputeShader,
213 vk::PipelineStageFlagBits::eComputeShader, {}, 1, &barrier, 0, {}, 0, {});
217void ComputePassVK::AddTextureMemoryBarrier() {
218 vk::MemoryBarrier barrier;
219 barrier.srcAccessMask = vk::AccessFlagBits::eShaderWrite;
220 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
222 command_buffer_->GetCommandBuffer().pipelineBarrier(
223 vk::PipelineStageFlagBits::eComputeShader,
224 vk::PipelineStageFlagBits::eComputeShader, {}, 1, &barrier, 0, {}, 0, {});
228bool ComputePassVK::EncodeCommands()
const {
237 vk::MemoryBarrier barrier;
238 barrier.srcAccessMask = vk::AccessFlagBits::eShaderWrite;
239 barrier.dstAccessMask =
240 vk::AccessFlagBits::eIndexRead | vk::AccessFlagBits::eVertexAttributeRead;
242 command_buffer_->GetCommandBuffer().pipelineBarrier(
243 vk::PipelineStageFlagBits::eComputeShader,
244 vk::PipelineStageFlagBits::eVertexInput, {}, 1, &barrier, 0, {}, 0, {});
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
constexpr vk::DescriptorType ToVKDescriptorType(DescriptorType type)
std::shared_ptr< ContextGLES > context
std::shared_ptr< PipelineGLES > pipeline
std::shared_ptr< CommandBuffer > command_buffer
impeller::ShaderType type