From 788ca6a411762035a6a7a88100c4b582b47ee82d Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 15 Jul 2020 00:01:10 -0300 Subject: Initial transform feedback support (#1370) * Initial transform feedback support * Some nits and fixes * Update ReportCounterType and Write method * Can't change shader or TFB bindings while TFB is active * Fix geometry shader input names with new naming --- Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | 36 ++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'Ryujinx.Graphics.Gpu/Shader') diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 8a1abe32..d16f1057 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -82,7 +82,7 @@ namespace Ryujinx.Graphics.Gpu.Shader shader.HostShader = _context.Renderer.CompileShader(shader.Program); - IProgram hostProgram = _context.Renderer.CreateProgram(new IShader[] { shader.HostShader }); + IProgram hostProgram = _context.Renderer.CreateProgram(new IShader[] { shader.HostShader }, null); ShaderBundle cpShader = new ShaderBundle(hostProgram, shader); @@ -150,6 +150,8 @@ namespace Ryujinx.Graphics.Gpu.Shader continue; } + var tfd = GetTransformFeedbackDescriptors(state); + IShader hostShader = _context.Renderer.CompileShader(program); shaders[stage].HostShader = hostShader; @@ -157,7 +159,7 @@ namespace Ryujinx.Graphics.Gpu.Shader hostShaders.Add(hostShader); } - IProgram hostProgram = _context.Renderer.CreateProgram(hostShaders.ToArray()); + IProgram hostProgram = _context.Renderer.CreateProgram(hostShaders.ToArray(), GetTransformFeedbackDescriptors(state)); ShaderBundle gpShaders = new ShaderBundle(hostProgram, shaders); @@ -173,6 +175,36 @@ namespace Ryujinx.Graphics.Gpu.Shader return gpShaders; } + /// + /// Gets transform feedback state from the current GPU state. + /// + /// Current GPU state + /// Four transform feedback descriptors for the enabled TFBs, or null if TFB is disabled + private TransformFeedbackDescriptor[] GetTransformFeedbackDescriptors(GpuState state) + { + bool tfEnable = state.Get(MethodOffset.TfEnable); + + if (!tfEnable) + { + return null; + } + + TransformFeedbackDescriptor[] descs = new TransformFeedbackDescriptor[Constants.TotalTransformFeedbackBuffers]; + + for (int i = 0; i < Constants.TotalTransformFeedbackBuffers; i++) + { + var tf = state.Get(MethodOffset.TfState, i); + + int length = (int)Math.Min((uint)tf.VaryingsCount, 0x80); + + var varyingLocations = state.GetSpan(MethodOffset.TfVaryingLocations + i * 0x80, length).ToArray(); + + descs[i] = new TransformFeedbackDescriptor(tf.BufferIndex, tf.Stride, varyingLocations); + } + + return descs; + } + /// /// Checks if compute shader code in memory is equal to the cached shader. /// -- cgit v1.2.3