summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends
diff options
context:
space:
mode:
authorTellowKrinkle <tellowkrinkle@gmail.com>2023-06-27 23:50:16 -0500
committerTellowKrinkle <tellowkrinkle@gmail.com>2023-06-28 00:11:37 -0500
commitfc4036af809fcdfec64d8b8d24b8569ba21f4326 (patch)
tree293980619097346c2caf304665e04d3abb2e335f /Source/Core/VideoBackends
parent78f4a9189d2d3aa8a8428ac61cf02a6eb3db20c8 (diff)
VideoBackends:Metal: Multi render target support
Diffstat (limited to 'Source/Core/VideoBackends')
-rw-r--r--Source/Core/VideoBackends/Metal/MTLGfx.mm14
-rw-r--r--Source/Core/VideoBackends/Metal/MTLObjectCache.mm7
-rw-r--r--Source/Core/VideoBackends/Metal/MTLStateTracker.h1
-rw-r--r--Source/Core/VideoBackends/Metal/MTLStateTracker.mm35
-rw-r--r--Source/Core/VideoBackends/Metal/MTLTexture.h26
-rw-r--r--Source/Core/VideoBackends/Metal/MTLTexture.mm47
6 files changed, 82 insertions, 48 deletions
diff --git a/Source/Core/VideoBackends/Metal/MTLGfx.mm b/Source/Core/VideoBackends/Metal/MTLGfx.mm
index 1137c45e5f..cf3c134cdb 100644
--- a/Source/Core/VideoBackends/Metal/MTLGfx.mm
+++ b/Source/Core/VideoBackends/Metal/MTLGfx.mm
@@ -94,12 +94,12 @@ Metal::Gfx::CreateStagingTexture(StagingTextureType type, const TextureConfig& c
std::unique_ptr<AbstractFramebuffer>
Metal::Gfx::CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment,
- std::vector<AbstractTexture*>)
+ std::vector<AbstractTexture*> additional_color_attachments)
{
AbstractTexture* const either_attachment = color_attachment ? color_attachment : depth_attachment;
return std::make_unique<Framebuffer>(
- color_attachment, depth_attachment, either_attachment->GetWidth(),
- either_attachment->GetHeight(), either_attachment->GetLayers(),
+ color_attachment, depth_attachment, std::move(additional_color_attachments),
+ either_attachment->GetWidth(), either_attachment->GetHeight(), either_attachment->GetLayers(),
either_attachment->GetSamples());
}
@@ -437,7 +437,7 @@ void Metal::Gfx::BindBackbuffer(const ClearColor& clear_color)
CheckForSurfaceChange();
CheckForSurfaceResize();
m_drawable = MRCRetain([m_layer nextDrawable]);
- m_bb_texture->SetMTLTexture(MRCRetain([m_drawable texture]));
+ m_backbuffer->UpdateBackbufferTexture([m_drawable texture]);
SetAndClearFramebuffer(m_backbuffer.get(), clear_color);
}
}
@@ -460,7 +460,7 @@ void Metal::Gfx::PresentBackbuffer()
else
[g_state_tracker->GetRenderCmdBuf()
addScheduledHandler:[drawable = std::move(m_drawable)](id) { [drawable present]; }];
- m_bb_texture->SetMTLTexture(nullptr);
+ m_backbuffer->UpdateBackbufferTexture(nullptr);
m_drawable = nullptr;
}
g_state_tracker->FlushEncoders();
@@ -491,8 +491,8 @@ void Metal::Gfx::SetupSurface()
TextureConfig cfg(info.width, info.height, 1, 1, 1, info.format,
AbstractTextureFlag_RenderTarget);
m_bb_texture = std::make_unique<Texture>(nullptr, cfg);
- m_backbuffer = std::make_unique<Framebuffer>(m_bb_texture.get(), nullptr, //
- info.width, info.height, 1, 1);
+ m_backbuffer = std::make_unique<Framebuffer>(
+ m_bb_texture.get(), nullptr, std::vector<AbstractTexture*>{}, info.width, info.height, 1, 1);
if (g_presenter)
g_presenter->SetBackbuffer(info);
diff --git a/Source/Core/VideoBackends/Metal/MTLObjectCache.mm b/Source/Core/VideoBackends/Metal/MTLObjectCache.mm
index 2a9387edeb..5d29f06e88 100644
--- a/Source/Core/VideoBackends/Metal/MTLObjectCache.mm
+++ b/Source/Core/VideoBackends/Metal/MTLObjectCache.mm
@@ -313,6 +313,8 @@ public:
framebuffer.color_texture_format = cfg.framebuffer_state.color_texture_format.Value();
framebuffer.depth_texture_format = cfg.framebuffer_state.depth_texture_format.Value();
framebuffer.samples = cfg.framebuffer_state.samples.Value();
+ framebuffer.additional_color_attachment_count =
+ cfg.framebuffer_state.additional_color_attachment_count.Value();
blend.colorupdate = cfg.blending_state.colorupdate.Value();
blend.alphaupdate = cfg.blending_state.alphaupdate.Value();
if (cfg.blending_state.blendenable)
@@ -426,6 +428,11 @@ public:
}
[desc setRasterSampleCount:fs.samples];
[color0 setPixelFormat:Util::FromAbstract(fs.color_texture_format)];
+ if (u32 cnt = fs.additional_color_attachment_count)
+ {
+ for (u32 i = 0; i < cnt; i++)
+ [[desc colorAttachments] setObject:color0 atIndexedSubscript:i + 1];
+ }
[desc setDepthAttachmentPixelFormat:Util::FromAbstract(fs.depth_texture_format)];
if (Util::HasStencil(fs.depth_texture_format))
[desc setStencilAttachmentPixelFormat:Util::FromAbstract(fs.depth_texture_format)];
diff --git a/Source/Core/VideoBackends/Metal/MTLStateTracker.h b/Source/Core/VideoBackends/Metal/MTLStateTracker.h
index 54e16cac7e..f3fa306dd7 100644
--- a/Source/Core/VideoBackends/Metal/MTLStateTracker.h
+++ b/Source/Core/VideoBackends/Metal/MTLStateTracker.h
@@ -182,7 +182,6 @@ private:
MRCOwned<id<MTLCommandBuffer>> m_last_render_cmdbuf;
MRCOwned<id<MTLRenderCommandEncoder>> m_current_render_encoder;
MRCOwned<id<MTLComputeCommandEncoder>> m_current_compute_encoder;
- MRCOwned<MTLRenderPassDescriptor*> m_render_pass_desc[3];
MRCOwned<MTLRenderPassDescriptor*> m_resolve_pass_desc;
Framebuffer* m_current_framebuffer;
CPUBuffer m_texture_upload_buffer;
diff --git a/Source/Core/VideoBackends/Metal/MTLStateTracker.mm b/Source/Core/VideoBackends/Metal/MTLStateTracker.mm
index f699657ade..8546744a4d 100644
--- a/Source/Core/VideoBackends/Metal/MTLStateTracker.mm
+++ b/Source/Core/VideoBackends/Metal/MTLStateTracker.mm
@@ -107,12 +107,6 @@ Metal::StateTracker::StateTracker() : m_backref(std::make_shared<Backref>(this))
{
m_flags.should_apply_label = true;
m_fence = MRCTransfer([g_device newFence]);
- for (MRCOwned<MTLRenderPassDescriptor*>& rpdesc : m_render_pass_desc)
- {
- rpdesc = MRCTransfer([MTLRenderPassDescriptor new]);
- [[rpdesc depthAttachment] setStoreAction:MTLStoreActionStore];
- [[rpdesc stencilAttachment] setStoreAction:MTLStoreActionStore];
- }
m_resolve_pass_desc = MRCTransfer([MTLRenderPassDescriptor new]);
auto color0 = [[m_resolve_pass_desc colorAttachments] objectAtIndexedSubscript:0];
[color0 setLoadAction:MTLLoadActionLoad];
@@ -299,27 +293,8 @@ void Metal::StateTracker::SetCurrentFramebuffer(Framebuffer* framebuffer)
MTLRenderPassDescriptor* Metal::StateTracker::GetRenderPassDescriptor(Framebuffer* framebuffer,
MTLLoadAction load_action)
{
- const AbstractTextureFormat depth_fmt = framebuffer->GetDepthFormat();
- MTLRenderPassDescriptor* desc;
- if (depth_fmt == AbstractTextureFormat::Undefined)
- desc = m_render_pass_desc[0];
- else if (!Util::HasStencil(depth_fmt))
- desc = m_render_pass_desc[1];
- else
- desc = m_render_pass_desc[2];
- desc.colorAttachments[0].texture = framebuffer->GetColor();
- desc.colorAttachments[0].loadAction = load_action;
- if (depth_fmt != AbstractTextureFormat::Undefined)
- {
- desc.depthAttachment.texture = framebuffer->GetDepth();
- desc.depthAttachment.loadAction = load_action;
- if (Util::HasStencil(depth_fmt))
- {
- desc.stencilAttachment.texture = framebuffer->GetDepth();
- desc.stencilAttachment.loadAction = load_action;
- }
- }
- return desc;
+ framebuffer->SetLoadAction(load_action);
+ return framebuffer->PassDesc();
}
void Metal::StateTracker::BeginClearRenderPass(MTLClearColor color, float depth)
@@ -328,11 +303,9 @@ void Metal::StateTracker::BeginClearRenderPass(MTLClearColor color, float depth)
MTLRenderPassDescriptor* desc = GetRenderPassDescriptor(framebuffer, MTLLoadActionClear);
desc.colorAttachments[0].clearColor = color;
if (framebuffer->GetDepthFormat() != AbstractTextureFormat::Undefined)
- {
desc.depthAttachment.clearDepth = depth;
- if (Util::HasStencil(framebuffer->GetDepthFormat()))
- desc.stencilAttachment.clearStencil = 0;
- }
+ for (size_t i = 0; i < framebuffer->NumAdditionalColorTextures(); i++)
+ desc.colorAttachments[i + 1].clearColor = color;
BeginRenderPass(desc);
}
diff --git a/Source/Core/VideoBackends/Metal/MTLTexture.h b/Source/Core/VideoBackends/Metal/MTLTexture.h
index 0624661414..908f281e04 100644
--- a/Source/Core/VideoBackends/Metal/MTLTexture.h
+++ b/Source/Core/VideoBackends/Metal/MTLTexture.h
@@ -29,7 +29,6 @@ public:
u32 layer) override;
id<MTLTexture> GetMTLTexture() const { return m_tex; }
- void SetMTLTexture(MRCOwned<id<MTLTexture>> tex) { m_tex = std::move(tex); }
private:
MRCOwned<id<MTLTexture>> m_tex;
@@ -61,17 +60,30 @@ private:
class Framebuffer final : public AbstractFramebuffer
{
public:
- Framebuffer(AbstractTexture* color, AbstractTexture* depth, u32 width, u32 height, u32 layers,
- u32 samples);
+ Framebuffer(AbstractTexture* color, AbstractTexture* depth,
+ std::vector<AbstractTexture*> additonal_color_textures, //
+ u32 width, u32 height, u32 layers, u32 samples);
~Framebuffer();
- id<MTLTexture> GetColor() const
+ MTLRenderPassDescriptor* PassDesc() const { return m_pass_descriptor; }
+
+ size_t NumAdditionalColorTextures() const { return m_additional_color_textures.size(); }
+
+ void SetLoadAction(MTLLoadAction action)
{
- return static_cast<Texture*>(GetColorAttachment())->GetMTLTexture();
+ if (m_current_load_action != action)
+ ActualSetLoadAction(action);
}
- id<MTLTexture> GetDepth() const
+
+ void UpdateBackbufferTexture(id<MTLTexture> tex)
{
- return static_cast<Texture*>(GetDepthAttachment())->GetMTLTexture();
+ [m_pass_descriptor colorAttachments][0].texture = tex;
}
+
+private:
+ MRCOwned<MTLRenderPassDescriptor*> m_pass_descriptor;
+ std::vector<AbstractTexture*> m_additional_color_textures;
+ MTLLoadAction m_current_load_action = MTLLoadActionLoad;
+ void ActualSetLoadAction(MTLLoadAction action);
};
} // namespace Metal
diff --git a/Source/Core/VideoBackends/Metal/MTLTexture.mm b/Source/Core/VideoBackends/Metal/MTLTexture.mm
index c9750eb1a5..ea4c7fb5ab 100644
--- a/Source/Core/VideoBackends/Metal/MTLTexture.mm
+++ b/Source/Core/VideoBackends/Metal/MTLTexture.mm
@@ -189,13 +189,56 @@ void Metal::StagingTexture::Flush()
m_wait_buffer = nullptr;
}
-Metal::Framebuffer::Framebuffer(AbstractTexture* color, AbstractTexture* depth, //
+static void InitDesc(id desc, AbstractTexture* tex)
+{
+ [desc setTexture:static_cast<Metal::Texture*>(tex)->GetMTLTexture()];
+ [desc setLoadAction:MTLLoadActionLoad];
+ [desc setStoreAction:MTLStoreActionStore];
+}
+
+static void InitStencilDesc(MTLRenderPassStencilAttachmentDescriptor* desc, AbstractTexture* tex)
+{
+ InitDesc(desc, tex);
+ [desc setClearStencil:0];
+}
+
+Metal::Framebuffer::Framebuffer(AbstractTexture* color, AbstractTexture* depth,
+ std::vector<AbstractTexture*> additonal_color_textures, //
u32 width, u32 height, u32 layers, u32 samples)
: AbstractFramebuffer(color, depth, {},
color ? color->GetFormat() : AbstractTextureFormat::Undefined, //
depth ? depth->GetFormat() : AbstractTextureFormat::Undefined, //
- width, height, layers, samples)
+ width, height, layers, samples),
+ m_additional_color_textures(std::move(additonal_color_textures))
{
+ m_pass_descriptor = MRCTransfer([MTLRenderPassDescriptor new]);
+ MTLRenderPassDescriptor* desc = m_pass_descriptor;
+ if (color)
+ InitDesc(desc.colorAttachments[0], color);
+ if (depth)
+ {
+ InitDesc(desc.depthAttachment, depth);
+ if (Util::HasStencil(depth->GetFormat()))
+ InitStencilDesc(desc.stencilAttachment, depth);
+ }
+ for (size_t i = 0; i < m_additional_color_textures.size(); i++)
+ InitDesc(desc.colorAttachments[i + 1], m_additional_color_textures[i]);
}
Metal::Framebuffer::~Framebuffer() = default;
+
+void Metal::Framebuffer::ActualSetLoadAction(MTLLoadAction action)
+{
+ m_current_load_action = action;
+ AbstractTextureFormat depth_fmt = GetDepthFormat();
+ MTLRenderPassDescriptor* desc = m_pass_descriptor;
+ desc.colorAttachments[0].loadAction = action;
+ if (depth_fmt != AbstractTextureFormat::Undefined)
+ {
+ desc.depthAttachment.loadAction = action;
+ if (Util::HasStencil(depth_fmt))
+ desc.stencilAttachment.loadAction = action;
+ }
+ for (size_t i = 0; i < NumAdditionalColorTextures(); i++)
+ desc.colorAttachments[i + 1].loadAction = action;
+}