xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrAttachment.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2011 Google Inc.
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/ganesh/GrAttachment.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/DataUtils.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ResourceKey.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrBackendUtils.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGpu.h"
18*c8dee2aaSAndroid Build Coastguard Worker 
19*c8dee2aaSAndroid Build Coastguard Worker enum class SkTextureCompressionType;
20*c8dee2aaSAndroid Build Coastguard Worker 
onGpuMemorySize() const21*c8dee2aaSAndroid Build Coastguard Worker size_t GrAttachment::onGpuMemorySize() const {
22*c8dee2aaSAndroid Build Coastguard Worker     // The GrTexture[RenderTarget] is built up by a bunch of attachments each of which are their
23*c8dee2aaSAndroid Build Coastguard Worker     // own GrGpuResource. Ideally the GrRenderTarget would not be a GrGpuResource and the GrTexture
24*c8dee2aaSAndroid Build Coastguard Worker     // would just merge with the new GrSurface/Attachment world. Then we could just depend on each
25*c8dee2aaSAndroid Build Coastguard Worker     // attachment to give its own size since we don't have GrGpuResources owning other
26*c8dee2aaSAndroid Build Coastguard Worker     // GrGpuResources. Until we get to that point we need to live in some hybrid world. We will let
27*c8dee2aaSAndroid Build Coastguard Worker     // the msaa and stencil attachments track their own size because they do get cached separately.
28*c8dee2aaSAndroid Build Coastguard Worker     // For all GrTexture* based things we will continue to to use the GrTexture* to report size and
29*c8dee2aaSAndroid Build Coastguard Worker     // the owned attachments will have no size and be uncached.
30*c8dee2aaSAndroid Build Coastguard Worker     if (!(fSupportedUsages & UsageFlags::kTexture) && fMemoryless == GrMemoryless::kNo) {
31*c8dee2aaSAndroid Build Coastguard Worker         GrBackendFormat format = this->backendFormat();
32*c8dee2aaSAndroid Build Coastguard Worker         SkTextureCompressionType compression = GrBackendFormatToCompressionType(format);
33*c8dee2aaSAndroid Build Coastguard Worker 
34*c8dee2aaSAndroid Build Coastguard Worker         uint64_t size = skgpu::NumCompressedBlocks(compression, this->dimensions());
35*c8dee2aaSAndroid Build Coastguard Worker         size *= GrBackendFormatBytesPerBlock(this->backendFormat());
36*c8dee2aaSAndroid Build Coastguard Worker         size *= this->numSamples();
37*c8dee2aaSAndroid Build Coastguard Worker         return size;
38*c8dee2aaSAndroid Build Coastguard Worker     }
39*c8dee2aaSAndroid Build Coastguard Worker     return 0;
40*c8dee2aaSAndroid Build Coastguard Worker }
41*c8dee2aaSAndroid Build Coastguard Worker 
build_key(skgpu::ResourceKey::Builder * builder,const GrCaps & caps,const GrBackendFormat & format,SkISize dimensions,GrAttachment::UsageFlags requiredUsage,int sampleCnt,skgpu::Mipmapped mipmapped,GrProtected isProtected,GrMemoryless memoryless)42*c8dee2aaSAndroid Build Coastguard Worker static void build_key(skgpu::ResourceKey::Builder* builder,
43*c8dee2aaSAndroid Build Coastguard Worker                       const GrCaps& caps,
44*c8dee2aaSAndroid Build Coastguard Worker                       const GrBackendFormat& format,
45*c8dee2aaSAndroid Build Coastguard Worker                       SkISize dimensions,
46*c8dee2aaSAndroid Build Coastguard Worker                       GrAttachment::UsageFlags requiredUsage,
47*c8dee2aaSAndroid Build Coastguard Worker                       int sampleCnt,
48*c8dee2aaSAndroid Build Coastguard Worker                       skgpu::Mipmapped mipmapped,
49*c8dee2aaSAndroid Build Coastguard Worker                       GrProtected isProtected,
50*c8dee2aaSAndroid Build Coastguard Worker                       GrMemoryless memoryless) {
51*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!dimensions.isEmpty());
52*c8dee2aaSAndroid Build Coastguard Worker 
53*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(static_cast<uint32_t>(isProtected) <= 1);
54*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(static_cast<uint32_t>(memoryless) <= 1);
55*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(static_cast<uint32_t>(requiredUsage) < (1u << 8));
56*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(static_cast<uint32_t>(sampleCnt) < (1u << (32 - 10)));
57*c8dee2aaSAndroid Build Coastguard Worker 
58*c8dee2aaSAndroid Build Coastguard Worker     uint64_t formatKey = caps.computeFormatKey(format);
59*c8dee2aaSAndroid Build Coastguard Worker     (*builder)[0] = dimensions.width();
60*c8dee2aaSAndroid Build Coastguard Worker     (*builder)[1] = dimensions.height();
61*c8dee2aaSAndroid Build Coastguard Worker     (*builder)[2] = formatKey & 0xFFFFFFFF;
62*c8dee2aaSAndroid Build Coastguard Worker     (*builder)[3] = (formatKey >> 32) & 0xFFFFFFFF;
63*c8dee2aaSAndroid Build Coastguard Worker     (*builder)[4] = (static_cast<uint32_t>(isProtected) << 0) |
64*c8dee2aaSAndroid Build Coastguard Worker                     (static_cast<uint32_t>(memoryless) << 1) |
65*c8dee2aaSAndroid Build Coastguard Worker                     (static_cast<uint32_t>(requiredUsage) << 2) |
66*c8dee2aaSAndroid Build Coastguard Worker                     (static_cast<uint32_t>(sampleCnt) << 10);
67*c8dee2aaSAndroid Build Coastguard Worker }
68*c8dee2aaSAndroid Build Coastguard Worker 
ComputeSharedAttachmentUniqueKey(const GrCaps & caps,const GrBackendFormat & format,SkISize dimensions,UsageFlags requiredUsage,int sampleCnt,skgpu::Mipmapped mipmapped,GrProtected isProtected,GrMemoryless memoryless,skgpu::UniqueKey * key)69*c8dee2aaSAndroid Build Coastguard Worker void GrAttachment::ComputeSharedAttachmentUniqueKey(const GrCaps& caps,
70*c8dee2aaSAndroid Build Coastguard Worker                                                     const GrBackendFormat& format,
71*c8dee2aaSAndroid Build Coastguard Worker                                                     SkISize dimensions,
72*c8dee2aaSAndroid Build Coastguard Worker                                                     UsageFlags requiredUsage,
73*c8dee2aaSAndroid Build Coastguard Worker                                                     int sampleCnt,
74*c8dee2aaSAndroid Build Coastguard Worker                                                     skgpu::Mipmapped mipmapped,
75*c8dee2aaSAndroid Build Coastguard Worker                                                     GrProtected isProtected,
76*c8dee2aaSAndroid Build Coastguard Worker                                                     GrMemoryless memoryless,
77*c8dee2aaSAndroid Build Coastguard Worker                                                     skgpu::UniqueKey* key) {
78*c8dee2aaSAndroid Build Coastguard Worker     static const skgpu::UniqueKey::Domain kDomain = skgpu::UniqueKey::GenerateDomain();
79*c8dee2aaSAndroid Build Coastguard Worker 
80*c8dee2aaSAndroid Build Coastguard Worker     skgpu::UniqueKey::Builder builder(key, kDomain, 5);
81*c8dee2aaSAndroid Build Coastguard Worker     build_key(&builder, caps, format, dimensions, requiredUsage, sampleCnt, mipmapped, isProtected,
82*c8dee2aaSAndroid Build Coastguard Worker               memoryless);
83*c8dee2aaSAndroid Build Coastguard Worker }
84*c8dee2aaSAndroid Build Coastguard Worker 
ComputeScratchKey(const GrCaps & caps,const GrBackendFormat & format,SkISize dimensions,UsageFlags requiredUsage,int sampleCnt,skgpu::Mipmapped mipmapped,GrProtected isProtected,GrMemoryless memoryless,skgpu::ScratchKey * key)85*c8dee2aaSAndroid Build Coastguard Worker void GrAttachment::ComputeScratchKey(const GrCaps& caps,
86*c8dee2aaSAndroid Build Coastguard Worker                                      const GrBackendFormat& format,
87*c8dee2aaSAndroid Build Coastguard Worker                                      SkISize dimensions,
88*c8dee2aaSAndroid Build Coastguard Worker                                      UsageFlags requiredUsage,
89*c8dee2aaSAndroid Build Coastguard Worker                                      int sampleCnt,
90*c8dee2aaSAndroid Build Coastguard Worker                                      skgpu::Mipmapped mipmapped,
91*c8dee2aaSAndroid Build Coastguard Worker                                      GrProtected isProtected,
92*c8dee2aaSAndroid Build Coastguard Worker                                      GrMemoryless memoryless,
93*c8dee2aaSAndroid Build Coastguard Worker                                      skgpu::ScratchKey* key) {
94*c8dee2aaSAndroid Build Coastguard Worker     static const skgpu::ScratchKey::ResourceType kType = skgpu::ScratchKey::GenerateResourceType();
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker     skgpu::ScratchKey::Builder builder(key, kType, 5);
97*c8dee2aaSAndroid Build Coastguard Worker     build_key(&builder, caps, format, dimensions, requiredUsage, sampleCnt, mipmapped, isProtected,
98*c8dee2aaSAndroid Build Coastguard Worker               memoryless);
99*c8dee2aaSAndroid Build Coastguard Worker }
100*c8dee2aaSAndroid Build Coastguard Worker 
computeScratchKey(skgpu::ScratchKey * key) const101*c8dee2aaSAndroid Build Coastguard Worker void GrAttachment::computeScratchKey(skgpu::ScratchKey* key) const {
102*c8dee2aaSAndroid Build Coastguard Worker     // We do don't cache GrAttachments as scratch resources when used for stencils or textures. For
103*c8dee2aaSAndroid Build Coastguard Worker     // stencils we share/cache them with unique keys so that they can be shared. Textures are in a
104*c8dee2aaSAndroid Build Coastguard Worker     // weird place on the Vulkan backend. Currently, GrVkTexture contains a GrAttachment (GrVkImage)
105*c8dee2aaSAndroid Build Coastguard Worker     // that actually holds the VkImage. The GrVkTexture is cached as a scratch resource and is
106*c8dee2aaSAndroid Build Coastguard Worker     // responsible for tracking the gpuMemorySize. Thus we set the size of the texture GrVkImage,
107*c8dee2aaSAndroid Build Coastguard Worker     // above in onGpuMemorySize, to be zero. Therefore, we can't have the GrVkImage getting cached
108*c8dee2aaSAndroid Build Coastguard Worker     // separately on its own in the GrResourceCache or we may grow forever adding them thinking they
109*c8dee2aaSAndroid Build Coastguard Worker     // contatin a memory that's size 0 and never freeing the actual VkImages.
110*c8dee2aaSAndroid Build Coastguard Worker     if (!SkToBool(fSupportedUsages & UsageFlags::kStencilAttachment) &&
111*c8dee2aaSAndroid Build Coastguard Worker         !SkToBool(fSupportedUsages & UsageFlags::kTexture)) {
112*c8dee2aaSAndroid Build Coastguard Worker         auto isProtected = this->isProtected() ? GrProtected::kYes : GrProtected::kNo;
113*c8dee2aaSAndroid Build Coastguard Worker         ComputeScratchKey(*this->getGpu()->caps(),
114*c8dee2aaSAndroid Build Coastguard Worker                           this->backendFormat(),
115*c8dee2aaSAndroid Build Coastguard Worker                           this->dimensions(),
116*c8dee2aaSAndroid Build Coastguard Worker                           fSupportedUsages,
117*c8dee2aaSAndroid Build Coastguard Worker                           this->numSamples(),
118*c8dee2aaSAndroid Build Coastguard Worker                           this->mipmapped(),
119*c8dee2aaSAndroid Build Coastguard Worker                           isProtected,
120*c8dee2aaSAndroid Build Coastguard Worker                           fMemoryless,
121*c8dee2aaSAndroid Build Coastguard Worker                           key);
122*c8dee2aaSAndroid Build Coastguard Worker     }
123*c8dee2aaSAndroid Build Coastguard Worker }
124