From f09bba82b9366e5912b639a610ae89cbb1cf352c Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Tue, 29 Aug 2023 21:10:34 -0300
Subject: Geometry shader emulation for macOS (#5551)

* Implement vertex and geometry shader conversion to compute

* Call InitializeReservedCounts for compute too

* PR feedback

* Set clip distance mask for geometry and tessellation shaders too

* Transform feedback emulation only for vertex
---
 .../Shader/DiskCache/ParallelDiskCacheLoader.cs          | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

(limited to 'src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs')

diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs
index 8c2108bf..153fc442 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs
@@ -595,6 +595,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
 
             ResourceCounts counts = new();
 
+            DiskCacheGpuAccessor[] gpuAccessors = new DiskCacheGpuAccessor[Constants.ShaderStages];
             TranslatorContext[] translatorContexts = new TranslatorContext[Constants.ShaderStages + 1];
             TranslatorContext nextStage = null;
 
@@ -626,14 +627,22 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
                         translatorContexts[0] = DecodeGraphicsShader(gpuAccessorA, api, DefaultFlags | TranslationFlags.VertexA, 0);
                     }
 
+                    gpuAccessors[stageIndex] = gpuAccessor;
                     translatorContexts[stageIndex + 1] = currentStage;
                     nextStage = currentStage;
                 }
             }
 
-            if (!_context.Capabilities.SupportsGeometryShader)
+            bool hasGeometryShader = translatorContexts[4] != null;
+            bool vertexHasStore = translatorContexts[1] != null && translatorContexts[1].HasStore;
+            bool geometryHasStore = hasGeometryShader && translatorContexts[4].HasStore;
+            bool vertexToCompute = ShouldConvertVertexToCompute(_context, vertexHasStore, geometryHasStore, hasGeometryShader);
+
+            // We don't support caching shader stages that have been converted to compute currently,
+            // so just eliminate them if they exist in the cache.
+            if (vertexToCompute)
             {
-                ShaderCache.TryRemoveGeometryStage(translatorContexts);
+                return;
             }
 
             CachedShaderStage[] shaders = new CachedShaderStage[guestShaders.Length];
@@ -647,6 +656,8 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
 
                 if (currentStage != null)
                 {
+                    gpuAccessors[stageIndex].InitializeReservedCounts(specState.TransformFeedbackDescriptors != null, vertexToCompute);
+
                     ShaderProgram program;
 
                     byte[] guestCode = guestShaders[stageIndex + 1].Value.Code;
@@ -701,6 +712,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
             ResourceCounts counts = new();
             ShaderSpecializationState newSpecState = new(ref specState.ComputeState);
             DiskCacheGpuAccessor gpuAccessor = new(_context, shader.Code, shader.Cb1Data, specState, newSpecState, counts, 0);
+            gpuAccessor.InitializeReservedCounts(tfEnabled: false, vertexAsCompute: false);
 
             TranslatorContext translatorContext = DecodeComputeShader(gpuAccessor, _context.Capabilities.Api, 0);
 
-- 
cgit v1.2.3-70-g09d2