MetalDevice: Drop feedback loop path

I could never test this since I don't have a non-Apple GPU, and I don't
think it ever worked properly anyway.
This commit is contained in:
Stenzek
2026-09-28 00:29:50 +10:00
parent a2edf2d0f0
commit 0619481dcb
3 changed files with 6 additions and 141 deletions
-5
View File
@@ -308,10 +308,6 @@ public:
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
void DrawIndexedWithPushConstants(u32 index_count, u32 base_index, u32 base_vertex, const void* push_constants,
u32 push_constants_size) override;
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
void DrawIndexedWithBarrierWithPushConstants(u32 index_count, u32 base_index, u32 base_vertex,
const void* push_constants, u32 push_constants_size,
DrawBarrier type) override;
void Dispatch(u32 threads_x, u32 threads_y, u32 threads_z, u32 group_size_x, u32 group_size_y,
u32 group_size_z) override;
void DispatchWithPushConstants(u32 threads_x, u32 threads_y, u32 threads_z, u32 group_size_x, u32 group_size_y,
@@ -402,7 +398,6 @@ private:
void PreDrawCheck();
void SetInitialEncoderState();
void PushRenderUniformBuffer(const void* data, u32 data_size);
void SubmitDrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type);
void SetViewportInRenderEncoder();
void SetScissorInRenderEncoder();
void CommitRenderTargetClears();
+3 -115
View File
@@ -402,7 +402,7 @@ void MetalDevice::SetFeatures(CreateFlags create_flags)
m_features.texture_copy_to_self = !HasCreateFlag(create_flags, CreateFlags::DisableTextureCopyToSelf);
m_features.texture_buffers = !HasCreateFlag(create_flags, CreateFlags::DisableTextureBuffers);
m_features.texture_buffers_emulated_with_ssbo = true;
m_features.feedback_loops = (m_features.framebuffer_fetch || supports_barriers);
m_features.feedback_loops = false;
m_features.geometry_shaders = false;
m_features.partial_msaa_resolve = false;
m_features.memory_import = true;
@@ -422,9 +422,8 @@ void MetalDevice::SetFeatures(CreateFlags create_flags)
u16 MetalDevice::GetShaderCacheVersion() const
{
// Incorporate feature bits into the archive version so that device capability changes don't load the wrong shaders.
const bool barriers = (!m_features.framebuffer_fetch && m_features.feedback_loops);
return (BoolToUInt16(m_features.dual_source_blend) << 15) | (BoolToUInt16(m_features.framebuffer_fetch) << 14) |
(BoolToUInt16(m_features.texture_buffers) << 13) | (BoolToUInt16(barriers) << 12);
(BoolToUInt16(m_features.texture_buffers) << 13);
}
bool MetalDevice::LoadShaders(Error* error)
@@ -1906,9 +1905,7 @@ void MetalDevice::SetRenderTargets(GPUTexture* const* rts, u32 num_rts, GPUTextu
{
bool changed = (m_num_current_render_targets != num_rts || m_current_depth_target != ds ||
((flags & GPUPipeline::BindRenderTargetsAsImages) !=
(m_current_render_pass_flags & GPUPipeline::BindRenderTargetsAsImages)) ||
(!m_features.framebuffer_fetch && ((flags & GPUPipeline::ColorFeedbackLoop) !=
(m_current_render_pass_flags & GPUPipeline::ColorFeedbackLoop))));
(m_current_render_pass_flags & GPUPipeline::BindRenderTargetsAsImages)));
bool needs_ds_clear = (ds && ds->IsClearedOrInvalidated());
bool needs_rt_clear = false;
@@ -2300,12 +2297,6 @@ void MetalDevice::SetInitialEncoderState()
[m_render_encoder setFragmentTextures:m_current_textures.data() withRange:NSMakeRange(0, MAX_TEXTURE_SAMPLERS)];
[m_render_encoder setFragmentSamplerStates:m_current_samplers.data() withRange:NSMakeRange(0, MAX_TEXTURE_SAMPLERS)];
if (!m_features.framebuffer_fetch && (m_current_render_pass_flags & GPUPipeline::ColorFeedbackLoop))
{
DebugAssert(m_current_render_targets[0]);
[m_render_encoder setFragmentTexture:m_current_render_targets[0]->GetMTLTexture() atIndex:MAX_TEXTURE_SAMPLERS];
}
SetViewportInRenderEncoder();
SetScissorInRenderEncoder();
}
@@ -2400,109 +2391,6 @@ void MetalDevice::DrawIndexedWithPushConstants(u32 index_count, u32 base_index,
baseInstance:0];
}
void MetalDevice::DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type)
{
PreDrawCheck();
SubmitDrawIndexedWithBarrier(index_count, base_index, base_vertex, type);
}
void MetalDevice::DrawIndexedWithBarrierWithPushConstants(u32 index_count, u32 base_index, u32 base_vertex,
const void* push_constants, u32 push_constants_size,
DrawBarrier type)
{
PreDrawCheck();
PushRenderUniformBuffer(push_constants, push_constants_size);
SubmitDrawIndexedWithBarrier(index_count, base_index, base_vertex, type);
}
void MetalDevice::SubmitDrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type)
{
// Shouldn't be using this with framebuffer fetch.
DebugAssert(!m_features.framebuffer_fetch);
const MTLPrimitiveType primitive = m_current_pipeline->GetPrimitive();
const id<MTLBuffer> index_buffer = m_index_buffer.GetBuffer();
u32 index_offset = base_index * sizeof(u16);
switch (type)
{
case GPUDevice::DrawBarrier::None:
{
s_stats.num_draws++;
[m_render_encoder drawIndexedPrimitives:primitive
indexCount:index_count
indexType:MTLIndexTypeUInt16
indexBuffer:index_buffer
indexBufferOffset:index_offset
instanceCount:1
baseVertex:base_vertex
baseInstance:0];
}
break;
case GPUDevice::DrawBarrier::One:
{
DebugAssert(m_num_current_render_targets == 1);
s_stats.num_draws++;
s_stats.num_barriers++;
[m_render_encoder memoryBarrierWithScope:MTLBarrierScopeRenderTargets
afterStages:MTLRenderStageFragment
beforeStages:MTLRenderStageFragment];
[m_render_encoder drawIndexedPrimitives:primitive
indexCount:index_count
indexType:MTLIndexTypeUInt16
indexBuffer:index_buffer
indexBufferOffset:index_offset
instanceCount:1
baseVertex:base_vertex
baseInstance:0];
}
break;
case GPUDevice::DrawBarrier::Full:
{
DebugAssert(m_num_current_render_targets == 1);
static constexpr const u8 vertices_per_primitive[][2] = {
{1, 1}, // MTLPrimitiveTypePoint
{2, 2}, // MTLPrimitiveTypeLine
{2, 1}, // MTLPrimitiveTypeLineStrip
{3, 3}, // MTLPrimitiveTypeTriangle
{3, 1}, // MTLPrimitiveTypeTriangleStrip
};
const u32 index_step = vertices_per_primitive[static_cast<size_t>(primitive)][1] * sizeof(u16);
const u32 end_offset = (base_index + index_count) * sizeof(u16);
for (; index_offset < end_offset; index_offset += index_step)
{
s_stats.num_barriers++;
s_stats.num_draws++;
[m_render_encoder memoryBarrierWithScope:MTLBarrierScopeRenderTargets
afterStages:MTLRenderStageFragment
beforeStages:MTLRenderStageFragment];
[m_render_encoder drawIndexedPrimitives:primitive
indexCount:vertices_per_primitive[static_cast<size_t>(primitive)][0]
indexType:MTLIndexTypeUInt16
indexBuffer:index_buffer
indexBufferOffset:index_offset
instanceCount:1
baseVertex:base_vertex
baseInstance:0];
}
}
break;
DefaultCaseIsUnreachable();
}
}
void MetalDevice::Dispatch(u32 threads_x, u32 threads_y, u32 threads_z, u32 group_size_x, u32 group_size_y,
u32 group_size_z)
{
+3 -21
View File
@@ -719,33 +719,15 @@ void ShaderGen::DeclareFragmentEntryPoint(
}
}
#endif
#ifdef ENABLE_VULKAN
if (m_render_api == RenderAPI::Vulkan)
#if defined(ENABLE_VULKAN) || defined(__APPLE__)
if (m_render_api == RenderAPI::Vulkan || (m_render_api == RenderAPI::Metal && m_supports_framebuffer_fetch))
{
// Set doesn't matter for Metal, because it's transformed to color0.
ss << "layout(input_attachment_index = 0, set = 2, binding = 0) uniform "
<< (msaa ? "subpassInputMS" : "subpassInput") << " u_input_rt; \n";
ss << "#define LAST_FRAG_COLOR " << (msaa ? "subpassLoad(u_input_rt, gl_SampleID)" : "subpassLoad(u_input_rt)")
<< "\n";
}
#endif
#ifdef __APPLE__
if (m_render_api == RenderAPI::Metal)
{
if (m_supports_framebuffer_fetch)
{
// Set doesn't matter, because it's transformed to color0.
ss << "layout(input_attachment_index = 0, set = 2, binding = 0) uniform "
<< (msaa ? "subpassInputMS" : "subpassInput") << " u_input_rt; \n";
ss << "#define LAST_FRAG_COLOR "
<< (msaa ? "subpassLoad(u_input_rt, gl_SampleID)" : "subpassLoad(u_input_rt)") << "\n";
}
else
{
ss << "layout(set = 2, binding = 0) uniform " << (msaa ? "texture2DMS" : "texture2D") << " u_input_rt;\n";
ss << "#define LAST_FRAG_COLOR texelFetch(u_input_rt, int2(gl_FragCoord.xy), " << (msaa ? "gl_SampleID" : "0")
<< ")\n";
}
}
#endif
}
else if (rov)