diff options
author | gdkchan <gab.dark.100@gmail.com> | 2023-06-10 18:31:38 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-10 18:31:38 -0300 |
commit | eb0bb36bbfc3a4f5f2ac1c8721e192239f899a1d (patch) | |
tree | e43650855d28e8d49d7ad2d82466647263c3fe16 /src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs | |
parent | 0e95a8271ac96b2c54907858140e2511a25a2b10 (diff) |
Implement transform feedback emulation for hardware without native support (#5080)1.1.882
* Implement transform feedback emulation for hardware without native support
* Stop doing some useless buffer updates and account for non-zero base instance
* Reduce redundant updates even more
* Update descriptor init logic to account for ResourceLayout
* Fix transform feedback and storage buffers not being updated in some cases
* Shader cache version bump
* PR feedback
* SetInstancedDrawVertexCount must be always called after UpdateState
* Minor typo
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs b/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs index 6ca74a37..87e5457f 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs @@ -234,6 +234,45 @@ namespace Ryujinx.Graphics.Shader.Translation public void PrepareForVertexReturn() { + if (!Config.GpuAccessor.QueryHostSupportsTransformFeedback() && Config.GpuAccessor.QueryTransformFeedbackEnabled()) + { + Operand vertexCount = this.Load(StorageKind.StorageBuffer, Constants.TfeInfoBinding, Const(1)); + + for (int tfbIndex = 0; tfbIndex < Constants.TfeBuffersCount; tfbIndex++) + { + var locations = Config.GpuAccessor.QueryTransformFeedbackVaryingLocations(tfbIndex); + var stride = Config.GpuAccessor.QueryTransformFeedbackStride(tfbIndex); + + Operand baseOffset = this.Load(StorageKind.StorageBuffer, Constants.TfeInfoBinding, Const(0), Const(tfbIndex)); + Operand baseVertex = this.Load(StorageKind.Input, IoVariable.BaseVertex); + Operand baseInstance = this.Load(StorageKind.Input, IoVariable.BaseInstance); + Operand vertexIndex = this.Load(StorageKind.Input, IoVariable.VertexIndex); + Operand instanceIndex = this.Load(StorageKind.Input, IoVariable.InstanceIndex); + + Operand outputVertexOffset = this.ISubtract(vertexIndex, baseVertex); + Operand outputInstanceOffset = this.ISubtract(instanceIndex, baseInstance); + + Operand outputBaseVertex = this.IMultiply(outputInstanceOffset, vertexCount); + + Operand vertexOffset = this.IMultiply(this.IAdd(outputBaseVertex, outputVertexOffset), Const(stride / 4)); + baseOffset = this.IAdd(baseOffset, vertexOffset); + + for (int j = 0; j < locations.Length; j++) + { + byte location = locations[j]; + if (location == 0xff) + { + continue; + } + + Operand offset = this.IAdd(baseOffset, Const(j)); + Operand value = Instructions.AttributeMap.GenerateAttributeLoad(this, null, location * 4, isOutput: true, isPerPatch: false); + + this.Store(StorageKind.StorageBuffer, Constants.TfeBufferBaseBinding + tfbIndex, Const(0), offset, value); + } + } + } + if (Config.GpuAccessor.QueryViewportTransformDisable()) { Operand x = this.Load(StorageKind.Output, IoVariable.Position, null, Const(0)); |