mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
GS:MTL: Faster fbfetch depth feedback
This commit is contained in:
committed by
lightningterror
parent
8f23e31ae4
commit
af81d8b7da
@@ -1073,7 +1073,7 @@ public:
|
||||
|
||||
bool IsDSInRTActive() const { return m_ds_as_rt; }
|
||||
/// Create a temporary color clone of depth for depth feedback
|
||||
void BeginDSAsRT(GSTexture* ds, const GSVector4i& drawarea);
|
||||
virtual void BeginDSAsRT(GSTexture* ds, const GSVector4i& drawarea);
|
||||
void EndDSAsRT();
|
||||
|
||||
/// Returns a string representing the specified API.
|
||||
|
||||
@@ -318,6 +318,8 @@ public:
|
||||
MRCOwned<id<MTLBlitCommandEncoder>> m_late_texture_upload_encoder;
|
||||
MRCOwned<id<MTLCommandBuffer>> m_vertex_upload_cmdbuf;
|
||||
MRCOwned<id<MTLBlitCommandEncoder>> m_vertex_upload_encoder;
|
||||
id<MTLTexture> m_ds_as_rt_texture = nil;
|
||||
GSTexture* m_ds_as_rt_gstexture = nullptr;
|
||||
|
||||
struct DebugEntry
|
||||
{
|
||||
@@ -417,6 +419,7 @@ public:
|
||||
void UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) override;
|
||||
void ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM) override;
|
||||
void FilteredDownsampleTexture(GSTexture* sTex, GSTexture* dTex, u32 downsample_factor, const GSVector2i& clamp_min, const GSVector4& dRect) override;
|
||||
void BeginDSAsRT(GSTexture* ds, const GSVector4i& drawarea) override;
|
||||
|
||||
void FlushClears(GSTexture* tex);
|
||||
|
||||
|
||||
@@ -95,6 +95,11 @@ GSDeviceMTL::GSDeviceMTL()
|
||||
|
||||
GSDeviceMTL::~GSDeviceMTL()
|
||||
{
|
||||
// m_ds_as_rt_texture is owned if the device has memoryless textures
|
||||
if (m_dev.features.memoryless_textures)
|
||||
[m_ds_as_rt_texture release];
|
||||
else if (m_ds_as_rt_gstexture)
|
||||
delete m_ds_as_rt_gstexture;
|
||||
}
|
||||
|
||||
GSDeviceMTL::Map GSDeviceMTL::Allocate(UploadBuffer& buffer, size_t amt)
|
||||
@@ -247,7 +252,10 @@ id<MTLFence> GSDeviceMTL::GetSpinFence()
|
||||
|
||||
id<MTLTexture> GSDeviceMTL::GetRT1DepthTexture(GSTextureMTL* depth)
|
||||
{
|
||||
return static_cast<GSTextureMTL*>(m_ds_as_rt)->GetTexture();
|
||||
if (m_dev.features.framebuffer_fetch)
|
||||
return m_ds_as_rt_texture;
|
||||
else
|
||||
return static_cast<GSTextureMTL*>(m_ds_as_rt)->GetTexture();
|
||||
}
|
||||
|
||||
void GSDeviceMTL::DrawCommandBufferFinished(u64 draw, id<MTLCommandBuffer> buffer)
|
||||
@@ -1023,7 +1031,15 @@ bool GSDeviceMTL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
|
||||
{
|
||||
MTLRenderPassColorAttachmentDescriptor* color1 = [[desc colorAttachments] objectAtIndexedSubscript:1];
|
||||
[color1 setStoreAction:MTLStoreActionDontCare];
|
||||
[color1 setLoadAction:MTLLoadActionLoad];
|
||||
if (m_features.framebuffer_fetch)
|
||||
{
|
||||
[color1 setLoadAction:MTLLoadActionClear];
|
||||
[color1 setClearColor:MTLClearColorMake(-1, 0, 0, 0)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[color1 setLoadAction:MTLLoadActionLoad];
|
||||
}
|
||||
}
|
||||
m_render_pass_desc[i] = desc;
|
||||
}
|
||||
@@ -1311,12 +1327,13 @@ bool GSDeviceMTL::SupportsExclusiveFullscreen() const { return false; }
|
||||
std::string GSDeviceMTL::GetDriverInfo() const
|
||||
{ @autoreleasepool {
|
||||
std::string desc([[m_dev.dev description] UTF8String]);
|
||||
desc += "\n Texture Swizzle: " + std::string(m_dev.features.texture_swizzle ? "Supported" : "Unsupported");
|
||||
desc += "\n Unified Memory: " + std::string(m_dev.features.unified_memory ? "Supported" : "Unsupported");
|
||||
desc += "\n Framebuffer Fetch: " + std::string(m_dev.features.framebuffer_fetch ? "Supported" : "Unsupported");
|
||||
desc += "\n Primitive ID: " + std::string(m_dev.features.primid ? "Supported" : "Unsupported");
|
||||
desc += "\n Shader Version: " + std::string(to_string(m_dev.features.shader_version));
|
||||
desc += "\n Max Texture Size: " + std::to_string(m_dev.features.max_texsize);
|
||||
desc += "\n Texture Swizzle: " + std::string(m_dev.features.texture_swizzle ? "Supported" : "Unsupported");
|
||||
desc += "\n Unified Memory: " + std::string(m_dev.features.unified_memory ? "Supported" : "Unsupported");
|
||||
desc += "\n Framebuffer Fetch: " + std::string(m_dev.features.framebuffer_fetch ? "Supported" : "Unsupported");
|
||||
desc += "\n Memoryless Textures: " + std::string(m_dev.features.memoryless_textures ? "Supported" : "Unsupported");
|
||||
desc += "\n Primitive ID: " + std::string(m_dev.features.primid ? "Supported" : "Unsupported");
|
||||
desc += "\n Shader Version: " + std::string(to_string(m_dev.features.shader_version));
|
||||
desc += "\n Max Texture Size: " + std::to_string(m_dev.features.max_texsize);
|
||||
return desc;
|
||||
}}
|
||||
|
||||
@@ -1802,6 +1819,50 @@ void GSDeviceMTL::FilteredDownsampleTexture(GSTexture* sTex, GSTexture* dTex, u3
|
||||
DoStretchRect(sTex, GSVector4::zero(), dTex, dRect, pipeline, false, LoadAction::DontCareIfFull, &uniform, sizeof(uniform));
|
||||
}}
|
||||
|
||||
static id<MTLTexture> CreateDSAsRTTexture(id<MTLDevice> dev, NSUInteger width, NSUInteger height, MTLStorageMode storage, NSString* name)
|
||||
{
|
||||
MTLTextureDescriptor *desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatR32Float width:width height:height mipmapped:false];
|
||||
[desc setUsage:MTLTextureUsageRenderTarget];
|
||||
[desc setStorageMode:storage];
|
||||
id<MTLTexture> result = [dev newTextureWithDescriptor:desc];
|
||||
[result setLabel:name];
|
||||
return result;
|
||||
}
|
||||
|
||||
void GSDeviceMTL::BeginDSAsRT(GSTexture* ds, const GSVector4i& drawarea)
|
||||
{
|
||||
if (!m_features.framebuffer_fetch)
|
||||
return GSDevice::BeginDSAsRT(ds, drawarea);
|
||||
u32 needed_width = ds->GetWidth();
|
||||
u32 needed_height = ds->GetHeight();
|
||||
u32 current_width = static_cast<u32>([m_ds_as_rt_texture width]);
|
||||
u32 current_height = static_cast<u32>([m_ds_as_rt_texture height]);
|
||||
if (m_dev.features.memoryless_textures)
|
||||
{
|
||||
if (needed_width > current_width || needed_height > current_height) [[unlikely]] @autoreleasepool
|
||||
{
|
||||
u32 width = std::max(needed_width, current_width);
|
||||
u32 height = std::max(needed_height, current_height);
|
||||
[m_ds_as_rt_texture release];
|
||||
m_ds_as_rt_texture = CreateDSAsRTTexture(m_dev.dev, width, height, MTLStorageModeMemoryless, @"DS as RT");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (needed_width == current_width && needed_height == current_height)
|
||||
return;
|
||||
if (m_ds_as_rt_gstexture)
|
||||
Recycle(m_ds_as_rt_gstexture);
|
||||
m_ds_as_rt_gstexture = CreateRenderTarget(needed_width, needed_height, GSTexture::Format::Float32, false, true);
|
||||
m_ds_as_rt_texture = static_cast<GSTextureMTL*>(m_ds_as_rt_gstexture)->GetTexture();
|
||||
@autoreleasepool
|
||||
{
|
||||
NSString* name = [NSString stringWithFormat:@"DS as RT %dx%d", needed_width, needed_height];
|
||||
[m_ds_as_rt_texture setLabel:name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GSDeviceMTL::FlushClears(GSTexture* tex)
|
||||
{
|
||||
if (tex)
|
||||
@@ -2328,10 +2389,10 @@ void GSDeviceMTL::RenderHW(GSHWDrawConfig& config)
|
||||
MREInitHWDraw(config, allocation);
|
||||
if (config.require_one_barrier || config.require_full_barrier)
|
||||
MRESetTexture(rt, GSMTLTextureIndexRenderTarget);
|
||||
if (feedback_depth && !m_features.framebuffer_fetch)
|
||||
if (feedback_depth)
|
||||
{
|
||||
bool depth_as_rt = m_features.depth_feedback == GSDevice::DepthFeedbackSupport::DepthAsRT;
|
||||
GSTexture* tex = depth_as_rt ? m_ds_as_rt : config.ds;
|
||||
GSTexture* tex = depth_as_rt && !m_features.framebuffer_fetch ? m_ds_as_rt : config.ds;
|
||||
MRESetTexture(tex, GSMTLTextureIndexDepthTarget);
|
||||
}
|
||||
if (primid_tex)
|
||||
@@ -2366,7 +2427,7 @@ void GSDeviceMTL::RenderHW(GSHWDrawConfig& config)
|
||||
|
||||
Recycle(colclip_rt);
|
||||
|
||||
g_gs_device->SetColorClipTexture(nullptr);
|
||||
SetColorClipTexture(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ struct GSMTLDevice
|
||||
bool primid : 1;
|
||||
bool slow_color_compression : 1; ///< Color compression seems to slow down rt read on AMD
|
||||
bool has_fast_half : 1;
|
||||
bool memoryless_textures : 1;
|
||||
MetalVersion shader_version;
|
||||
DepthFeedbackSupport preferred_depth_feedback : 8;
|
||||
int max_texsize;
|
||||
|
||||
@@ -147,7 +147,7 @@ GSMTLDevice::GSMTLDevice(MRCOwned<id<MTLDevice>> dev)
|
||||
|
||||
if (@available(macOS 11.0, iOS 13.0, *))
|
||||
if ([dev supportsFamily:MTLGPUFamilyApple1])
|
||||
features.framebuffer_fetch = true;
|
||||
features.framebuffer_fetch = features.memoryless_textures = true;
|
||||
|
||||
if (@available(macOS 10.15, iOS 13.0, *))
|
||||
if ([dev supportsFamily:MTLGPUFamilyMac2] || [dev supportsFamily:MTLGPUFamilyApple1])
|
||||
|
||||
@@ -1413,7 +1413,7 @@ constant bool NEEDS_DS_FBF = false;
|
||||
constant float ds_fbf = 0;
|
||||
#endif
|
||||
constant bool NEEDS_DS_TEX = SW_DEPTH && DEPTH_FEEDBACK == DepthFeedbackSupport::DepthAsRT && !NEEDS_DS_FBF;
|
||||
constant bool NEEDS_DS_DEPTH = SW_DEPTH && DEPTH_FEEDBACK == DepthFeedbackSupport::Depth;
|
||||
constant bool NEEDS_DS_DEPTH = SW_DEPTH && DEPTH_FEEDBACK == DepthFeedbackSupport::Depth || NEEDS_DS_FBF;
|
||||
|
||||
fragment MainPSOut ps_main(
|
||||
MainPSIn in [[stage_in]],
|
||||
@@ -1459,7 +1459,10 @@ fragment MainPSOut ps_main(
|
||||
main.current_depth = ds_depth.read(coord);
|
||||
break;
|
||||
case DepthFeedbackSupport::DepthAsRT:
|
||||
main.current_depth = HAS_FBFETCH ? ds_fbf : ds_tex.read(coord).x;
|
||||
if (NEEDS_DS_FBF)
|
||||
main.current_depth = ds_fbf < 0 ? ds_depth.read(coord) : ds_fbf;
|
||||
else
|
||||
main.current_depth = ds_tex.read(coord).x;
|
||||
break;
|
||||
case DepthFeedbackSupport::None:
|
||||
// Should never happen
|
||||
|
||||
Reference in New Issue
Block a user