10#include "spdlog/spdlog.h"
16 MTL::Texture* createMultisampledTexture(
MetalGraphicsDevice* device,
const MTL::PixelFormat format,
17 const int width,
const int height,
const int samples)
19 auto* descriptor = MTL::TextureDescriptor::alloc()->init();
20 descriptor->setTextureType(MTL::TextureType2DMultisample);
21 descriptor->setWidth(width);
22 descriptor->setHeight(height);
23 descriptor->setPixelFormat(format);
24 descriptor->setSampleCount(samples);
25 descriptor->setStorageMode(MTL::StorageModePrivate);
26 descriptor->setUsage(MTL::TextureUsageRenderTarget);
27 auto* texture = device->raw()->newTexture(descriptor);
28 descriptor->release();
32 MTL::Texture* createInternalDepthTexture(
MetalGraphicsDevice* device,
const MTL::PixelFormat format,
33 const int width,
const int height)
35 auto* descriptor = MTL::TextureDescriptor::alloc()->init();
36 descriptor->setTextureType(MTL::TextureType2D);
37 descriptor->setWidth(width);
38 descriptor->setHeight(height);
39 descriptor->setPixelFormat(format);
40 descriptor->setStorageMode(MTL::StorageModePrivate);
41 descriptor->setUsage(MTL::TextureUsageRenderTarget | MTL::TextureUsageShaderRead);
42 auto* texture = device->raw()->newTexture(descriptor);
43 descriptor->release();
101 if (!
colorBuffer || i >=
static_cast<int>(_colorAttachments.size()) || !_colorAttachments[i])
continue;
103 if (hwTexture && hwTexture->raw() && _colorAttachments[i]->texture != hwTexture->raw()) {
104 _colorAttachments[i]->texture = hwTexture->raw();
105 _colorAttachments[i]->pixelFormat = hwTexture->raw()->pixelFormat();
109 if (
hasDepth() && !_depthAttachment) {
116 for (
const auto& colorAttachment : _colorAttachments) {
117 if (colorAttachment) {
118 colorAttachment->destroy();
121 _colorAttachments.clear();
123 if (_depthAttachment) {
124 auto* metalDevice =
dynamic_cast<MetalGraphicsDevice*
>(
device());
125 _depthAttachment->destroy(metalDevice);
126 _depthAttachment.reset();
132 auto* metalDevice =
dynamic_cast<MetalGraphicsDevice*
>(
device());
134 spdlog::error(
"MetalRenderTarget requires MetalGraphicsDevice");
149 auto* hwTexture =
dynamic_cast<gpu::MetalTexture*
>(
colorBuffer->impl());
150 if (!hwTexture || !hwTexture->raw()) {
151 spdlog::warn(
"MetalRenderTarget color buffer {} has no Metal texture", i);
155 auto colorAttachment = std::make_shared<ColorAttachment>();
156 colorAttachment->texture = hwTexture->raw();
157 colorAttachment->pixelFormat = colorAttachment->texture->pixelFormat();
160 colorAttachment->multisampledBuffer = createMultisampledTexture(
165 _colorAttachments[i] = colorAttachment;
169 depthTexture->upload();
170 auto* hwTexture =
dynamic_cast<gpu::MetalTexture*
>(depthTexture->impl());
171 if (hwTexture && hwTexture->raw()) {
172 const auto depthFormat = hwTexture->raw()->pixelFormat();
173 const bool hasStencil = depthFormat == MTL::PixelFormatDepth32Float_Stencil8;
174 _depthAttachment = std::make_shared<DepthAttachment>(depthFormat,
hasStencil);
175 _depthAttachment->depthTexture = hwTexture->raw();
178 _depthAttachment->multisampledDepthBuffer = createMultisampledTexture(
183 spdlog::warn(
"MetalRenderTarget depth buffer has no Metal texture");
186 const MTL::PixelFormat depthFormat =
hasStencil() ? MTL::PixelFormatDepth32Float_Stencil8 : MTL::PixelFormatDepth32Float;
187 _depthAttachment = std::make_shared<DepthAttachment>(depthFormat,
hasStencil());
188 _depthAttachment->depthTexture = createInternalDepthTexture(metalDevice, depthFormat,
width(),
height());
189 _depthAttachment->depthTextureInternal =
true;
192 _depthAttachment->multisampledDepthBuffer = createMultisampledTexture(
MTL::Texture * multisampledBuffer
MTL::PixelFormat pixelFormat
MTL::Texture * depthTexture
bool depthTextureInternal
MTL::Texture * multisampledDepthBuffer
DepthAttachment(MTL::PixelFormat format, bool hasStencil)
void destroy(MetalGraphicsDevice *device)
Texture * getColorBuffer(size_t index) const
GraphicsDevice * device() const
virtual void destroyFrameBuffers()=0
int colorBufferCount() const
RenderTarget(const RenderTargetOptions &options={})
Texture * depthBuffer() const
virtual void createFrameBuffers()=0
Texture * colorBuffer() const