xref: /aosp_15_r20/external/skia/src/gpu/graphite/RenderPassDesc.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2024 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/RenderPassDesc.h"
9 
10 #include "src/gpu/graphite/Caps.h"
11 
12 namespace skgpu::graphite {
13 
14 namespace {
15 
to_str(LoadOp op)16 const char* to_str(LoadOp op) {
17     switch (op) {
18         case LoadOp::kLoad:    return "load";
19         case LoadOp::kClear:   return "clear";
20         case LoadOp::kDiscard: return "discard";
21     }
22 
23     SkUNREACHABLE;
24 }
25 
to_str(StoreOp op)26 const char* to_str(StoreOp op) {
27     switch (op) {
28         case StoreOp::kStore:   return "store";
29         case StoreOp::kDiscard: return "discard";
30     }
31 
32     SkUNREACHABLE;
33 }
34 
35 } // anonymous namespace
36 
Make(const Caps * caps,const TextureInfo & targetInfo,LoadOp loadOp,StoreOp storeOp,SkEnumBitMask<DepthStencilFlags> depthStencilFlags,const std::array<float,4> & clearColor,bool requiresMSAA,Swizzle writeSwizzle)37 RenderPassDesc RenderPassDesc::Make(const Caps* caps,
38                                     const TextureInfo& targetInfo,
39                                     LoadOp loadOp,
40                                     StoreOp storeOp,
41                                     SkEnumBitMask<DepthStencilFlags> depthStencilFlags,
42                                     const std::array<float, 4>& clearColor,
43                                     bool requiresMSAA,
44                                     Swizzle writeSwizzle) {
45     RenderPassDesc desc;
46     desc.fWriteSwizzle = writeSwizzle;
47     desc.fSampleCount = 1;
48     // It doesn't make sense to have a storeOp for our main target not be store. Why are we doing
49     // this DrawPass then
50     SkASSERT(storeOp == StoreOp::kStore);
51     if (requiresMSAA) {
52         if (caps->msaaRenderToSingleSampledSupport()) {
53             desc.fColorAttachment.fTextureInfo = targetInfo;
54             desc.fColorAttachment.fLoadOp = loadOp;
55             desc.fColorAttachment.fStoreOp = storeOp;
56             desc.fSampleCount = caps->defaultMSAASamplesCount();
57         } else {
58             // TODO: If the resolve texture isn't readable, the MSAA color attachment will need to
59             // be persistently associated with the framebuffer, in which case it's not discardable.
60             auto msaaTextureInfo = caps->getDefaultMSAATextureInfo(targetInfo, Discardable::kYes);
61             if (msaaTextureInfo.isValid()) {
62                 desc.fColorAttachment.fTextureInfo = msaaTextureInfo;
63                 if (loadOp != LoadOp::kClear) {
64                     desc.fColorAttachment.fLoadOp = LoadOp::kDiscard;
65                 } else {
66                     desc.fColorAttachment.fLoadOp = LoadOp::kClear;
67                 }
68                 desc.fColorAttachment.fStoreOp = StoreOp::kDiscard;
69 
70                 desc.fColorResolveAttachment.fTextureInfo = targetInfo;
71                 if (loadOp != LoadOp::kLoad) {
72                     desc.fColorResolveAttachment.fLoadOp = LoadOp::kDiscard;
73                 } else {
74                     desc.fColorResolveAttachment.fLoadOp = LoadOp::kLoad;
75                 }
76                 desc.fColorResolveAttachment.fStoreOp = storeOp;
77 
78                 desc.fSampleCount = msaaTextureInfo.numSamples();
79             } else {
80                 // fall back to single sampled
81                 desc.fColorAttachment.fTextureInfo = targetInfo;
82                 desc.fColorAttachment.fLoadOp = loadOp;
83                 desc.fColorAttachment.fStoreOp = storeOp;
84             }
85         }
86     } else {
87         desc.fColorAttachment.fTextureInfo = targetInfo;
88         desc.fColorAttachment.fLoadOp = loadOp;
89         desc.fColorAttachment.fStoreOp = storeOp;
90     }
91     desc.fClearColor = clearColor;
92 
93     if (depthStencilFlags != DepthStencilFlags::kNone) {
94         desc.fDepthStencilAttachment.fTextureInfo = caps->getDefaultDepthStencilTextureInfo(
95                 depthStencilFlags, desc.fSampleCount, targetInfo.isProtected());
96         // Always clear the depth and stencil to 0 at the start of a DrawPass, but discard at the
97         // end since their contents do not affect the next frame.
98         desc.fDepthStencilAttachment.fLoadOp = LoadOp::kClear;
99         desc.fClearDepth = 0.f;
100         desc.fClearStencil = 0;
101         desc.fDepthStencilAttachment.fStoreOp = StoreOp::kDiscard;
102     }
103 
104     return desc;
105 }
106 
toString() const107 SkString RenderPassDesc::toString() const {
108     return SkStringPrintf("RP(color: %s, resolve: %s, ds: %s, samples: %u, swizzle: %s, "
109                           "clear: c(%f,%f,%f,%f), d(%f), s(0x%02x))",
110                           fColorAttachment.toString().c_str(),
111                           fColorResolveAttachment.toString().c_str(),
112                           fDepthStencilAttachment.toString().c_str(),
113                           fSampleCount,
114                           fWriteSwizzle.asString().c_str(),
115                           fClearColor[0], fClearColor[1], fClearColor[2], fClearColor[3],
116                           fClearDepth,
117                           fClearStencil);
118 }
119 
toPipelineLabel() const120 SkString RenderPassDesc::toPipelineLabel() const {
121     // This intentionally only includes the fixed state that impacts pipeline compilation.
122     // We include the load op of the color attachment when there is a resolve attachment because
123     // the load may trigger a different renderpass description.
124     const char* colorLoadStr = "";
125     if (fColorAttachment.fLoadOp == LoadOp::kLoad &&
126         (fColorResolveAttachment.fTextureInfo.isValid() || fSampleCount > 1)) {
127         colorLoadStr = " w/ msaa load";
128     }
129     // TODO: Remove `fSampleCount` in label when the Dawn backend manages its MSAA color attachments
130     // directly instead of relying on msaaRenderToSingleSampledSupport().
131     return SkStringPrintf("RP(color: %s%s, resolve: %s, ds: %s, samples: %u, swizzle: %s)",
132                           fColorAttachment.fTextureInfo.toRPAttachmentString().c_str(),
133                           colorLoadStr,
134                           fColorResolveAttachment.fTextureInfo.toRPAttachmentString().c_str(),
135                           fDepthStencilAttachment.fTextureInfo.toRPAttachmentString().c_str(),
136                           fSampleCount,
137                           fWriteSwizzle.asString().c_str());
138 }
139 
toString() const140 SkString AttachmentDesc::toString() const {
141     if (fTextureInfo.isValid()) {
142         return SkStringPrintf("info: %s loadOp: %s storeOp: %s",
143                               fTextureInfo.toString().c_str(),
144                               to_str(fLoadOp),
145                               to_str(fStoreOp));
146     } else {
147         return SkString("invalid attachment");
148     }
149 }
150 
151 } // namespace skgpu::graphite
152