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