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