aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-06-27 23:55:08 -0300
committerGitHub <noreply@github.com>2018-06-27 23:55:08 -0300
commite6eeb6f09ff592f5b27e115d1817654de7568757 (patch)
tree0c6b7528dc907779fa8e0199822d9f20896752d2 /Ryujinx.HLE
parent900a84ae0a90ae13c8c3f5158eff85c68a953362 (diff)
Add support for Vertex Program A and other small shader improvements (#192)
* Add WIP support for Vertex Program A, add the FADD_I32 shader instruction, small fix on FFMA_I encoding, nits * Add separate subroutines for program A/B, and copy attributes to a temp * Move finalization code to main * Add new line after flip uniform on the shader * Handle possible case where VPB uses an output attribute written by VPA but not available on the vbo * Address PR feedback
Diffstat (limited to 'Ryujinx.HLE')
-rw-r--r--Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs28
1 files changed, 27 insertions, 1 deletions
diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs
index 1663d4c5..380082b3 100644
--- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs
+++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs
@@ -126,7 +126,33 @@ namespace Ryujinx.HLE.Gpu.Engines
long BasePosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress);
- for (int Index = 0; Index < 6; Index++)
+ int Index = 1;
+
+ int VpAControl = ReadRegister(NvGpuEngine3dReg.ShaderNControl);
+
+ bool VpAEnable = (VpAControl & 1) != 0;
+
+ if (VpAEnable)
+ {
+ //Note: The maxwell supports 2 vertex programs, usually
+ //only VP B is used, but in some cases VP A is also used.
+ //In this case, it seems to function as an extra vertex
+ //shader stage.
+ //The graphics abstraction layer has a special overload for this
+ //case, which should merge the two shaders into one vertex shader.
+ int VpAOffset = ReadRegister(NvGpuEngine3dReg.ShaderNOffset);
+ int VpBOffset = ReadRegister(NvGpuEngine3dReg.ShaderNOffset + 0x10);
+
+ long VpAPos = BasePosition + (uint)VpAOffset;
+ long VpBPos = BasePosition + (uint)VpBOffset;
+
+ Gpu.Renderer.Shader.Create(Vmm, VpAPos, VpBPos, GalShaderType.Vertex);
+ Gpu.Renderer.Shader.Bind(VpBPos);
+
+ Index = 2;
+ }
+
+ for (; Index < 6; Index++)
{
int Control = ReadRegister(NvGpuEngine3dReg.ShaderNControl + Index * 0x10);
int Offset = ReadRegister(NvGpuEngine3dReg.ShaderNOffset + Index * 0x10);