| /* |
| * Copyright 2023 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "src/gpu/graphite/compute/ComputeStep.h" |
| |
| #include "include/private/base/SkAssert.h" |
| |
| #include <atomic> |
| #include <unordered_set> |
| |
| namespace skgpu::graphite { |
| namespace { |
| |
| static uint32_t next_id() { |
| static std::atomic<int32_t> nextId{0}; |
| // Not worried about overflow since a Context isn't expected to have that many ComputeSteps. |
| // Even if this it wraps around to 0, that ComputeStep will not be in the same Context as the |
| // original 0. |
| return nextId.fetch_add(1, std::memory_order_relaxed); |
| } |
| |
| } // namespace |
| |
| ComputeStep::ComputeStep(std::string_view name, |
| WorkgroupSize localDispatchSize, |
| SkSpan<const ResourceDesc> resources) |
| : fUniqueID(next_id()) |
| , fFlags(Flags::kNone) |
| , fName(name) |
| , fResources(resources.begin(), resources.end()) |
| , fLocalDispatchSize(localDispatchSize) { |
| #ifdef SK_DEBUG |
| std::unordered_set<int> slots; |
| #endif |
| for (const ResourceDesc& r : fResources) { |
| #ifdef SK_DEBUG |
| // Validate that slot assignments within a ComputeStep are unique. |
| if (r.fFlow == DataFlow::kShared) { |
| SkASSERT(r.fSlot > -1); |
| SkASSERT(r.fSlot < kMaxComputeDataFlowSlots); |
| auto [_, inserted] = slots.insert(r.fSlot); |
| SkASSERT(inserted); |
| } |
| #endif // SK_DEBUG |
| switch (r.fFlow) { |
| case DataFlow::kVertexOutput: |
| SkASSERT(r.fType == ResourceType::kStorageBuffer); |
| SkASSERTF(!(fFlags & Flags::kOutputsVertexBuffer), |
| "a ComputeStep cannot produce more than one vertex buffer"); |
| fFlags |= Flags::kOutputsVertexBuffer; |
| break; |
| case DataFlow::kIndexOutput: |
| SkASSERT(r.fType == ResourceType::kStorageBuffer); |
| SkASSERTF(!(fFlags & Flags::kOutputsIndexBuffer), |
| "a ComputeStep cannot produce more than one index buffer"); |
| fFlags |= Flags::kOutputsIndexBuffer; |
| break; |
| case DataFlow::kInstanceOutput: |
| SkASSERT(r.fType == ResourceType::kStorageBuffer); |
| SkASSERTF(!(fFlags & Flags::kOutputsInstanceBuffer), |
| "a ComputeStep cannot produce more than one instance buffer"); |
| fFlags |= Flags::kOutputsInstanceBuffer; |
| break; |
| case DataFlow::kIndirectDrawOutput: |
| // More than one indirect buffer output cannot be specified. |
| SkASSERTF(!(fFlags & Flags::kOutputsIndirectDrawBuffer), |
| "a ComputeStep cannot produce more than indirect buffer"); |
| fFlags |= Flags::kOutputsIndirectDrawBuffer; |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| |
| void ComputeStep::prepareBuffer( |
| const DrawParams&, int, int, const ResourceDesc&, void*, size_t) const { |
| SK_ABORT("ComputeSteps using a mapped resource must override prepareBuffer()"); |
| } |
| |
| } // namespace skgpu::graphite |