metal: do not begin render pass if already active

This commit is contained in:
Samuliak 2024-04-08 16:36:29 +02:00
parent 2c38fa1a35
commit 22ec7e72f0
No known key found for this signature in database
4 changed files with 19 additions and 12 deletions

View file

@ -10,11 +10,14 @@ CommandRecorder::CommandRecorder(const Device& device_) : device(device_) {}
CommandRecorder::~CommandRecorder() = default; CommandRecorder::~CommandRecorder() = default;
void CommandRecorder::BeginRenderPass(MTL::RenderPassDescriptor* render_pass) { void CommandRecorder::BeginOrContinueRenderPass(MTL::RenderPassDescriptor* render_pass) {
RequireCommandBuffer(); if (render_pass != bound_render_pass) {
EndEncoding(); RequireCommandBuffer();
encoder = command_buffer->renderCommandEncoder(render_pass); EndEncoding();
encoder_type = EncoderType::Render; encoder = command_buffer->renderCommandEncoder(render_pass);
encoder_type = EncoderType::Render;
bound_render_pass = render_pass;
}
} }
void CommandRecorder::RequireComputeEncoder() { void CommandRecorder::RequireComputeEncoder() {
@ -40,6 +43,7 @@ void CommandRecorder::EndEncoding() {
encoder->endEncoding(); encoder->endEncoding();
//[encoder release]; //[encoder release];
encoder = nullptr; encoder = nullptr;
bound_render_pass = nullptr;
} }
} }

View file

@ -20,7 +20,7 @@ public:
CommandRecorder(const Device& device_); CommandRecorder(const Device& device_);
~CommandRecorder(); ~CommandRecorder();
void BeginRenderPass(MTL::RenderPassDescriptor* render_pass); void BeginOrContinueRenderPass(MTL::RenderPassDescriptor* render_pass);
void CheckIfRenderPassIsActive() { void CheckIfRenderPassIsActive() {
if (!encoder || encoder_type != EncoderType::Render) { if (!encoder || encoder_type != EncoderType::Render) {
@ -66,11 +66,14 @@ private:
// HACK: Command buffers and encoders currently aren't released every frame due to Xcode // HACK: Command buffers and encoders currently aren't released every frame due to Xcode
// crashing in Debug mode. This leads to memory leaks // crashing in Debug mode. This leads to memory leaks
MTL::CommandBuffer* command_buffer = nil; MTL::CommandBuffer* command_buffer{nullptr};
MTL::CommandEncoder* encoder = nil; MTL::CommandEncoder* encoder{nullptr};
EncoderType encoder_type; EncoderType encoder_type;
// Keep track of last bound render pass
MTL::RenderPassDescriptor* bound_render_pass{nullptr};
void RequireCommandBuffer(); void RequireCommandBuffer();
}; };

View file

@ -96,7 +96,7 @@ void RasterizerMetal::Clear(u32 layer_count) {
} }
// Begin render pass // Begin render pass
command_recorder.BeginRenderPass(framebuffer->GetHandle()); command_recorder.BeginOrContinueRenderPass(framebuffer->GetHandle());
} }
void RasterizerMetal::DispatchCompute() { void RasterizerMetal::DispatchCompute() {

View file

@ -14,8 +14,8 @@ namespace Metal {
RendererMetal::RendererMetal(Core::Frontend::EmuWindow& emu_window, RendererMetal::RendererMetal(Core::Frontend::EmuWindow& emu_window,
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_, Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_,
std::unique_ptr<Core::Frontend::GraphicsContext> context_) std::unique_ptr<Core::Frontend::GraphicsContext> context_)
: RendererBase(emu_window, std::move(context_)), : RendererBase(emu_window, std::move(context_)), device_memory{device_memory_}, gpu{gpu_},
device_memory{device_memory_}, gpu{gpu_}, device{}, command_recorder(device), device{}, command_recorder(device),
swap_chain(device, command_recorder, swap_chain(device, command_recorder,
static_cast<CA::MetalLayer*>(render_window.GetWindowInfo().render_surface)), static_cast<CA::MetalLayer*>(render_window.GetWindowInfo().render_surface)),
rasterizer(gpu_, device_memory, device, command_recorder, swap_chain) { rasterizer(gpu_, device_memory, device, command_recorder, swap_chain) {
@ -42,7 +42,7 @@ void RendererMetal::Composite(std::span<const Tegra::FramebufferConfig> framebuf
render_pass_descriptor->colorAttachments()->object(0)->setTexture( render_pass_descriptor->colorAttachments()->object(0)->setTexture(
swap_chain.GetDrawableTexture()); swap_chain.GetDrawableTexture());
command_recorder.BeginRenderPass(render_pass_descriptor); command_recorder.BeginOrContinueRenderPass(render_pass_descriptor);
// Blit the framebuffer to the drawable texture // Blit the framebuffer to the drawable texture
// TODO: acquire the texture from @ref framebuffers // TODO: acquire the texture from @ref framebuffers