• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright 2021 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 "experimental/graphite/src/mtl/MtlTexture.h"
9
10#include "experimental/graphite/include/mtl/MtlTypes.h"
11#include "experimental/graphite/include/private/MtlTypesPriv.h"
12#include "experimental/graphite/src/mtl/MtlCaps.h"
13#include "experimental/graphite/src/mtl/MtlGpu.h"
14#include "experimental/graphite/src/mtl/MtlUtils.h"
15
16namespace skgpu::mtl {
17
18sk_cfp<id<MTLTexture>> Texture::MakeMtlTexture(const Gpu* gpu,
19                                               SkISize dimensions,
20                                               const skgpu::TextureInfo& info) {
21    const skgpu::Caps* caps = gpu->caps();
22    if (dimensions.width() > caps->maxTextureSize() ||
23        dimensions.height() > caps->maxTextureSize()) {
24        return nullptr;
25    }
26
27    const TextureSpec& mtlSpec = info.mtlTextureSpec();
28    SkASSERT(!mtlSpec.fFramebufferOnly);
29
30    if (mtlSpec.fUsage & MTLTextureUsageShaderRead && !caps->isTexturable(info)) {
31        return nullptr;
32    }
33
34    if (mtlSpec.fUsage & MTLTextureUsageRenderTarget &&
35        !(caps->isRenderable(info) || FormatIsDepthOrStencil((MTLPixelFormat)mtlSpec.fFormat))) {
36        return nullptr;
37    }
38
39    sk_cfp<MTLTextureDescriptor*> desc([[MTLTextureDescriptor alloc] init]);
40    (*desc).textureType = (info.numSamples() > 1) ? MTLTextureType2DMultisample : MTLTextureType2D;
41    (*desc).pixelFormat = (MTLPixelFormat)mtlSpec.fFormat;
42    (*desc).width = dimensions.width();
43    (*desc).height = dimensions.height();
44    (*desc).depth = 1;
45    (*desc).mipmapLevelCount = info.numMipLevels();
46    (*desc).sampleCount = info.numSamples();
47    (*desc).arrayLength = 1;
48    (*desc).usage = mtlSpec.fUsage;
49    (*desc).storageMode = (MTLStorageMode)mtlSpec.fStorageMode;
50
51    sk_cfp<id<MTLTexture>> texture([gpu->device() newTextureWithDescriptor:desc.get()]);
52#ifdef SK_ENABLE_MTL_DEBUG_INFO
53    if (mtlSpec.fUsage & MTLTextureUsageRenderTarget) {
54        if (FormatIsDepthOrStencil((MTLPixelFormat)mtlSpec.fFormat)) {
55            (*texture).label = @"DepthStencil";
56        } else {
57            if (info.numSamples() > 1) {
58                if (mtlSpec.fUsage & MTLTextureUsageShaderRead) {
59                    (*texture).label = @"MSAA SampledTexture-ColorAttachment";
60                } else {
61                    (*texture).label = @"MSAA ColorAttachment";
62                }
63            } else {
64                if (mtlSpec.fUsage & MTLTextureUsageShaderRead) {
65                    (*texture).label = @"SampledTexture-ColorAttachment";
66                } else {
67                    (*texture).label = @"ColorAttachment";
68                }
69            }
70        }
71    } else {
72        SkASSERT(mtlSpec.fUsage & MTLTextureUsageShaderRead);
73        (*texture).label = @"SampledTexture";
74    }
75#endif
76
77    return texture;
78}
79
80Texture::Texture(const Gpu* gpu,
81                 SkISize dimensions,
82                 const skgpu::TextureInfo& info,
83                 sk_cfp<id<MTLTexture>> texture,
84                 Ownership ownership)
85        : skgpu::Texture(gpu, dimensions, info, ownership)
86        , fTexture(std::move(texture)) {}
87
88sk_sp<Texture> Texture::Make(const Gpu* gpu,
89                             SkISize dimensions,
90                             const skgpu::TextureInfo& info) {
91    sk_cfp<id<MTLTexture>> texture = MakeMtlTexture(gpu, dimensions, info);
92    if (!texture) {
93        return nullptr;
94    }
95    return sk_sp<Texture>(new Texture(gpu,
96                                      dimensions,
97                                      info,
98                                      std::move(texture),
99                                      Ownership::kOwned));
100}
101
102sk_sp<Texture> Texture::MakeWrapped(const Gpu* gpu,
103                                    SkISize dimensions,
104                                    const skgpu::TextureInfo& info,
105                                    sk_cfp<id<MTLTexture>> texture) {
106    return sk_sp<Texture>(new Texture(gpu,
107                                      dimensions,
108                                      info,
109                                      std::move(texture),
110                                      Ownership::kWrapped));
111}
112
113void Texture::onFreeGpuData() {
114    fTexture.reset();
115}
116
117} // namespace skgpu::mtl
118
119