• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/gpu/graphite/compute/ComputeStep.h"
9 
10 #include "include/private/base/SkAssert.h"
11 
12 #include <atomic>
13 #include <unordered_set>
14 
15 namespace skgpu::graphite {
16 namespace {
17 
next_id()18 static uint32_t next_id() {
19     static std::atomic<int32_t> nextId{0};
20     // Not worried about overflow since a Context isn't expected to have that many ComputeSteps.
21     // Even if this it wraps around to 0, that ComputeStep will not be in the same Context as the
22     // original 0.
23     return nextId.fetch_add(1, std::memory_order_relaxed);
24 }
25 
26 }  // namespace
27 
ComputeStep(std::string_view name,WorkgroupSize localDispatchSize,SkSpan<const ResourceDesc> resources)28 ComputeStep::ComputeStep(std::string_view name,
29                          WorkgroupSize localDispatchSize,
30                          SkSpan<const ResourceDesc> resources)
31         : fUniqueID(next_id())
32         , fFlags(Flags::kNone)
33         , fName(name)
34         , fResources(resources.begin(), resources.end())
35         , fLocalDispatchSize(localDispatchSize) {
36 #ifdef SK_DEBUG
37     std::unordered_set<int> slots;
38 #endif
39     for (const ResourceDesc& r : fResources) {
40 #ifdef SK_DEBUG
41         // Validate that slot assignments within a ComputeStep are unique.
42         if (r.fFlow == DataFlow::kShared) {
43             SkASSERT(r.fSlot > -1);
44             SkASSERT(r.fSlot < kMaxComputeDataFlowSlots);
45             auto [_, inserted] = slots.insert(r.fSlot);
46             SkASSERT(inserted);
47         }
48 #endif  // SK_DEBUG
49         switch (r.fFlow) {
50             case DataFlow::kVertexOutput:
51                 SkASSERT(r.fType == ResourceType::kStorageBuffer);
52                 SkASSERTF(!(fFlags & Flags::kOutputsVertexBuffer),
53                           "a ComputeStep cannot produce more than one vertex buffer");
54                 fFlags |= Flags::kOutputsVertexBuffer;
55                 break;
56             case DataFlow::kIndexOutput:
57                 SkASSERT(r.fType == ResourceType::kStorageBuffer);
58                 SkASSERTF(!(fFlags & Flags::kOutputsIndexBuffer),
59                           "a ComputeStep cannot produce more than one index buffer");
60                 fFlags |= Flags::kOutputsIndexBuffer;
61                 break;
62             case DataFlow::kInstanceOutput:
63                 SkASSERT(r.fType == ResourceType::kStorageBuffer);
64                 SkASSERTF(!(fFlags & Flags::kOutputsInstanceBuffer),
65                           "a ComputeStep cannot produce more than one instance buffer");
66                 fFlags |= Flags::kOutputsInstanceBuffer;
67                 break;
68             case DataFlow::kIndirectDrawOutput:
69                 // More than one indirect buffer output cannot be specified.
70                 SkASSERTF(!(fFlags & Flags::kOutputsIndirectDrawBuffer),
71                           "a ComputeStep cannot produce more than indirect buffer");
72                 fFlags |= Flags::kOutputsIndirectDrawBuffer;
73                 break;
74             default:
75                 break;
76         }
77     }
78 }
79 
prepareBuffer(const DrawParams &,int,int,const ResourceDesc &,void *,size_t) const80 void ComputeStep::prepareBuffer(
81         const DrawParams&, int, int, const ResourceDesc&, void*, size_t) const {
82     SK_ABORT("ComputeSteps using a mapped resource must override prepareBuffer()");
83 }
84 
85 }  // namespace skgpu::graphite
86