From e6eeb6f09ff592f5b27e115d1817654de7568757 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 27 Jun 2018 23:55:08 -0300 Subject: 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 --- Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'Ryujinx.HLE/Gpu') 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); -- cgit v1.2.3