xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/metal/RenderBufferMtl.mm (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker//
2*8975f5c5SAndroid Build Coastguard Worker// Copyright 2019 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker// found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker//
6*8975f5c5SAndroid Build Coastguard Worker// RenderBufferMtl.mm:
7*8975f5c5SAndroid Build Coastguard Worker//    Implements the class methods for RenderBufferMtl.
8*8975f5c5SAndroid Build Coastguard Worker//
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/RenderBufferMtl.h"
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/ContextMtl.h"
13*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/ImageMtl.h"
14*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/mtl_format_utils.h"
15*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/mtl_utils.h"
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Workernamespace rx
18*8975f5c5SAndroid Build Coastguard Worker{
19*8975f5c5SAndroid Build Coastguard Worker
20*8975f5c5SAndroid Build Coastguard WorkerRenderbufferMtl::RenderbufferMtl(const gl::RenderbufferState &state) : RenderbufferImpl(state) {}
21*8975f5c5SAndroid Build Coastguard Worker
22*8975f5c5SAndroid Build Coastguard WorkerRenderbufferMtl::~RenderbufferMtl() {}
23*8975f5c5SAndroid Build Coastguard Worker
24*8975f5c5SAndroid Build Coastguard Workervoid RenderbufferMtl::onDestroy(const gl::Context *context)
25*8975f5c5SAndroid Build Coastguard Worker{
26*8975f5c5SAndroid Build Coastguard Worker    releaseTexture();
27*8975f5c5SAndroid Build Coastguard Worker}
28*8975f5c5SAndroid Build Coastguard Worker
29*8975f5c5SAndroid Build Coastguard Workervoid RenderbufferMtl::releaseTexture()
30*8975f5c5SAndroid Build Coastguard Worker{
31*8975f5c5SAndroid Build Coastguard Worker    mTexture           = nullptr;
32*8975f5c5SAndroid Build Coastguard Worker    mImplicitMSTexture = nullptr;
33*8975f5c5SAndroid Build Coastguard Worker}
34*8975f5c5SAndroid Build Coastguard Worker
35*8975f5c5SAndroid Build Coastguard Workerangle::Result RenderbufferMtl::setStorageImpl(const gl::Context *context,
36*8975f5c5SAndroid Build Coastguard Worker                                              GLsizei samples,
37*8975f5c5SAndroid Build Coastguard Worker                                              GLenum internalformat,
38*8975f5c5SAndroid Build Coastguard Worker                                              GLsizei width,
39*8975f5c5SAndroid Build Coastguard Worker                                              GLsizei height,
40*8975f5c5SAndroid Build Coastguard Worker                                              gl::MultisamplingMode mode)
41*8975f5c5SAndroid Build Coastguard Worker{
42*8975f5c5SAndroid Build Coastguard Worker    ContextMtl *contextMtl = mtl::GetImpl(context);
43*8975f5c5SAndroid Build Coastguard Worker
44*8975f5c5SAndroid Build Coastguard Worker    if (mTexture != nullptr && mTexture->valid())
45*8975f5c5SAndroid Build Coastguard Worker    {
46*8975f5c5SAndroid Build Coastguard Worker        // Check against the state if we need to recreate the storage.
47*8975f5c5SAndroid Build Coastguard Worker        if (internalformat != mState.getFormat().info->internalFormat ||
48*8975f5c5SAndroid Build Coastguard Worker            width != mState.getWidth() || height != mState.getHeight() ||
49*8975f5c5SAndroid Build Coastguard Worker            samples != mState.getSamples())
50*8975f5c5SAndroid Build Coastguard Worker        {
51*8975f5c5SAndroid Build Coastguard Worker            releaseTexture();
52*8975f5c5SAndroid Build Coastguard Worker        }
53*8975f5c5SAndroid Build Coastguard Worker    }
54*8975f5c5SAndroid Build Coastguard Worker
55*8975f5c5SAndroid Build Coastguard Worker    const gl::InternalFormat &internalFormat = gl::GetSizedInternalFormatInfo(internalformat);
56*8975f5c5SAndroid Build Coastguard Worker    angle::FormatID angleFormatId =
57*8975f5c5SAndroid Build Coastguard Worker        angle::Format::InternalFormatToID(internalFormat.sizedInternalFormat);
58*8975f5c5SAndroid Build Coastguard Worker    mFormat = contextMtl->getPixelFormat(angleFormatId);
59*8975f5c5SAndroid Build Coastguard Worker
60*8975f5c5SAndroid Build Coastguard Worker    uint32_t actualSamples;
61*8975f5c5SAndroid Build Coastguard Worker    if (samples == 0)
62*8975f5c5SAndroid Build Coastguard Worker    {
63*8975f5c5SAndroid Build Coastguard Worker        actualSamples = 1;
64*8975f5c5SAndroid Build Coastguard Worker    }
65*8975f5c5SAndroid Build Coastguard Worker    else
66*8975f5c5SAndroid Build Coastguard Worker    {
67*8975f5c5SAndroid Build Coastguard Worker        // We always start at at least 2 samples
68*8975f5c5SAndroid Build Coastguard Worker        actualSamples = static_cast<uint32_t>(std::max<size_t>(2, samples));
69*8975f5c5SAndroid Build Coastguard Worker
70*8975f5c5SAndroid Build Coastguard Worker        const gl::TextureCaps &textureCaps =
71*8975f5c5SAndroid Build Coastguard Worker            contextMtl->getTextureCaps().get(mFormat.intendedFormatId);
72*8975f5c5SAndroid Build Coastguard Worker        actualSamples = textureCaps.getNearestSamples(actualSamples);
73*8975f5c5SAndroid Build Coastguard Worker        ANGLE_MTL_CHECK(contextMtl, actualSamples != 0, GL_INVALID_VALUE);
74*8975f5c5SAndroid Build Coastguard Worker    }
75*8975f5c5SAndroid Build Coastguard Worker
76*8975f5c5SAndroid Build Coastguard Worker    if ((mTexture == nullptr || !mTexture->valid()) && (width != 0 && height != 0))
77*8975f5c5SAndroid Build Coastguard Worker    {
78*8975f5c5SAndroid Build Coastguard Worker        if (actualSamples == 1 || mode == gl::MultisamplingMode::MultisampledRenderToTexture)
79*8975f5c5SAndroid Build Coastguard Worker        {
80*8975f5c5SAndroid Build Coastguard Worker            ANGLE_TRY(mtl::Texture::Make2DTexture(
81*8975f5c5SAndroid Build Coastguard Worker                contextMtl, mFormat, static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1,
82*8975f5c5SAndroid Build Coastguard Worker                /* renderTargetOnly */ false,
83*8975f5c5SAndroid Build Coastguard Worker                /* allowFormatView */ mFormat.hasDepthAndStencilBits(), &mTexture));
84*8975f5c5SAndroid Build Coastguard Worker
85*8975f5c5SAndroid Build Coastguard Worker            if (mode == gl::MultisamplingMode::MultisampledRenderToTexture)
86*8975f5c5SAndroid Build Coastguard Worker            {
87*8975f5c5SAndroid Build Coastguard Worker                // This format must supports implicit resolve
88*8975f5c5SAndroid Build Coastguard Worker                ASSERT(mFormat.getCaps().resolve);
89*8975f5c5SAndroid Build Coastguard Worker
90*8975f5c5SAndroid Build Coastguard Worker                ANGLE_TRY(mtl::Texture::MakeMemoryLess2DMSTexture(
91*8975f5c5SAndroid Build Coastguard Worker                    contextMtl, mFormat, static_cast<uint32_t>(width),
92*8975f5c5SAndroid Build Coastguard Worker                    static_cast<uint32_t>(height), actualSamples, &mImplicitMSTexture));
93*8975f5c5SAndroid Build Coastguard Worker            }
94*8975f5c5SAndroid Build Coastguard Worker        }
95*8975f5c5SAndroid Build Coastguard Worker        else
96*8975f5c5SAndroid Build Coastguard Worker        {
97*8975f5c5SAndroid Build Coastguard Worker            ANGLE_TRY(mtl::Texture::Make2DMSTexture(
98*8975f5c5SAndroid Build Coastguard Worker                contextMtl, mFormat, static_cast<uint32_t>(width), static_cast<uint32_t>(height),
99*8975f5c5SAndroid Build Coastguard Worker                actualSamples,
100*8975f5c5SAndroid Build Coastguard Worker                /* renderTargetOnly */ false,
101*8975f5c5SAndroid Build Coastguard Worker                /* allowFormatView */ mFormat.hasDepthAndStencilBits(), &mTexture));
102*8975f5c5SAndroid Build Coastguard Worker        }
103*8975f5c5SAndroid Build Coastguard Worker
104*8975f5c5SAndroid Build Coastguard Worker        mRenderTarget.setWithImplicitMSTexture(mTexture, mImplicitMSTexture,
105*8975f5c5SAndroid Build Coastguard Worker                                               mtl::kZeroNativeMipLevel, 0, mFormat);
106*8975f5c5SAndroid Build Coastguard Worker
107*8975f5c5SAndroid Build Coastguard Worker        // For emulated channels that GL texture intends to not have,
108*8975f5c5SAndroid Build Coastguard Worker        // we need to initialize their content.
109*8975f5c5SAndroid Build Coastguard Worker        bool emulatedChannels = mtl::IsFormatEmulated(mFormat);
110*8975f5c5SAndroid Build Coastguard Worker        if (emulatedChannels)
111*8975f5c5SAndroid Build Coastguard Worker        {
112*8975f5c5SAndroid Build Coastguard Worker            gl::ImageIndex index;
113*8975f5c5SAndroid Build Coastguard Worker
114*8975f5c5SAndroid Build Coastguard Worker            if (mTexture->samples() > 1)
115*8975f5c5SAndroid Build Coastguard Worker            {
116*8975f5c5SAndroid Build Coastguard Worker                index = gl::ImageIndex::Make2DMultisample();
117*8975f5c5SAndroid Build Coastguard Worker            }
118*8975f5c5SAndroid Build Coastguard Worker            else
119*8975f5c5SAndroid Build Coastguard Worker            {
120*8975f5c5SAndroid Build Coastguard Worker                index = gl::ImageIndex::Make2D(0);
121*8975f5c5SAndroid Build Coastguard Worker            }
122*8975f5c5SAndroid Build Coastguard Worker
123*8975f5c5SAndroid Build Coastguard Worker            ANGLE_TRY(mtl::InitializeTextureContents(context, mTexture, mFormat,
124*8975f5c5SAndroid Build Coastguard Worker                                                     mtl::ImageNativeIndex(index, 0)));
125*8975f5c5SAndroid Build Coastguard Worker        }  // if (emulatedChannels)
126*8975f5c5SAndroid Build Coastguard Worker        bool isDepthStencil = mFormat.hasDepthOrStencilBits();
127*8975f5c5SAndroid Build Coastguard Worker        if (isDepthStencil)
128*8975f5c5SAndroid Build Coastguard Worker        {
129*8975f5c5SAndroid Build Coastguard Worker            gl::ImageIndex index;
130*8975f5c5SAndroid Build Coastguard Worker            if (mTexture->samples() > 1)
131*8975f5c5SAndroid Build Coastguard Worker            {
132*8975f5c5SAndroid Build Coastguard Worker                index = gl::ImageIndex::Make2DMultisample();
133*8975f5c5SAndroid Build Coastguard Worker            }
134*8975f5c5SAndroid Build Coastguard Worker            else
135*8975f5c5SAndroid Build Coastguard Worker            {
136*8975f5c5SAndroid Build Coastguard Worker                index = gl::ImageIndex::Make2D(0);
137*8975f5c5SAndroid Build Coastguard Worker            }
138*8975f5c5SAndroid Build Coastguard Worker            ANGLE_TRY(mtl::InitializeDepthStencilTextureContentsGPU(
139*8975f5c5SAndroid Build Coastguard Worker                context, mTexture, mFormat, mtl::ImageNativeIndex(index, 0)));
140*8975f5c5SAndroid Build Coastguard Worker        }
141*8975f5c5SAndroid Build Coastguard Worker    }
142*8975f5c5SAndroid Build Coastguard Worker
143*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
144*8975f5c5SAndroid Build Coastguard Worker}
145*8975f5c5SAndroid Build Coastguard Worker
146*8975f5c5SAndroid Build Coastguard Workerangle::Result RenderbufferMtl::setStorage(const gl::Context *context,
147*8975f5c5SAndroid Build Coastguard Worker                                          GLenum internalformat,
148*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei width,
149*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei height)
150*8975f5c5SAndroid Build Coastguard Worker{
151*8975f5c5SAndroid Build Coastguard Worker    return setStorageImpl(context, 0, internalformat, width, height,
152*8975f5c5SAndroid Build Coastguard Worker                          gl::MultisamplingMode::Regular);
153*8975f5c5SAndroid Build Coastguard Worker}
154*8975f5c5SAndroid Build Coastguard Worker
155*8975f5c5SAndroid Build Coastguard Workerangle::Result RenderbufferMtl::setStorageMultisample(const gl::Context *context,
156*8975f5c5SAndroid Build Coastguard Worker                                                     GLsizei samples,
157*8975f5c5SAndroid Build Coastguard Worker                                                     GLenum internalformat,
158*8975f5c5SAndroid Build Coastguard Worker                                                     GLsizei width,
159*8975f5c5SAndroid Build Coastguard Worker                                                     GLsizei height,
160*8975f5c5SAndroid Build Coastguard Worker                                                     gl::MultisamplingMode mode)
161*8975f5c5SAndroid Build Coastguard Worker{
162*8975f5c5SAndroid Build Coastguard Worker    return setStorageImpl(context, samples, internalformat, width, height, mode);
163*8975f5c5SAndroid Build Coastguard Worker}
164*8975f5c5SAndroid Build Coastguard Worker
165*8975f5c5SAndroid Build Coastguard Workerangle::Result RenderbufferMtl::setStorageEGLImageTarget(const gl::Context *context,
166*8975f5c5SAndroid Build Coastguard Worker                                                        egl::Image *image)
167*8975f5c5SAndroid Build Coastguard Worker{
168*8975f5c5SAndroid Build Coastguard Worker    releaseTexture();
169*8975f5c5SAndroid Build Coastguard Worker
170*8975f5c5SAndroid Build Coastguard Worker    ContextMtl *contextMtl = mtl::GetImpl(context);
171*8975f5c5SAndroid Build Coastguard Worker
172*8975f5c5SAndroid Build Coastguard Worker    ImageMtl *imageMtl = mtl::GetImpl(image);
173*8975f5c5SAndroid Build Coastguard Worker    mTexture           = imageMtl->getTexture();
174*8975f5c5SAndroid Build Coastguard Worker
175*8975f5c5SAndroid Build Coastguard Worker    const angle::FormatID angleFormatId =
176*8975f5c5SAndroid Build Coastguard Worker        angle::Format::InternalFormatToID(image->getFormat().info->sizedInternalFormat);
177*8975f5c5SAndroid Build Coastguard Worker    mFormat = contextMtl->getPixelFormat(angleFormatId);
178*8975f5c5SAndroid Build Coastguard Worker
179*8975f5c5SAndroid Build Coastguard Worker    mRenderTarget.set(mTexture, mtl::kZeroNativeMipLevel, 0, mFormat);
180*8975f5c5SAndroid Build Coastguard Worker
181*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
182*8975f5c5SAndroid Build Coastguard Worker}
183*8975f5c5SAndroid Build Coastguard Worker
184*8975f5c5SAndroid Build Coastguard Workerangle::Result RenderbufferMtl::getAttachmentRenderTarget(const gl::Context *context,
185*8975f5c5SAndroid Build Coastguard Worker                                                         GLenum binding,
186*8975f5c5SAndroid Build Coastguard Worker                                                         const gl::ImageIndex &imageIndex,
187*8975f5c5SAndroid Build Coastguard Worker                                                         GLsizei samples,
188*8975f5c5SAndroid Build Coastguard Worker                                                         FramebufferAttachmentRenderTarget **rtOut)
189*8975f5c5SAndroid Build Coastguard Worker{
190*8975f5c5SAndroid Build Coastguard Worker    ASSERT(mTexture && mTexture->valid());
191*8975f5c5SAndroid Build Coastguard Worker    *rtOut = &mRenderTarget;
192*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
193*8975f5c5SAndroid Build Coastguard Worker}
194*8975f5c5SAndroid Build Coastguard Worker
195*8975f5c5SAndroid Build Coastguard Workerangle::Result RenderbufferMtl::initializeContents(const gl::Context *context,
196*8975f5c5SAndroid Build Coastguard Worker                                                  GLenum binding,
197*8975f5c5SAndroid Build Coastguard Worker                                                  const gl::ImageIndex &imageIndex)
198*8975f5c5SAndroid Build Coastguard Worker{
199*8975f5c5SAndroid Build Coastguard Worker    if (imageIndex.valid())
200*8975f5c5SAndroid Build Coastguard Worker        return mtl::InitializeTextureContents(
201*8975f5c5SAndroid Build Coastguard Worker            context, mTexture, mFormat, mtl::ImageNativeIndex::FromBaseZeroGLIndex(imageIndex));
202*8975f5c5SAndroid Build Coastguard Worker    else
203*8975f5c5SAndroid Build Coastguard Worker        return mtl::InitializeTextureContents(
204*8975f5c5SAndroid Build Coastguard Worker            context, mTexture, mFormat,
205*8975f5c5SAndroid Build Coastguard Worker            mtl::ImageNativeIndex::FromBaseZeroGLIndex(gl::ImageIndex::Make2D(0)));
206*8975f5c5SAndroid Build Coastguard Worker}
207*8975f5c5SAndroid Build Coastguard Worker}  // namespace rx
208