private void UploadTextures(NvGpuVmm vmm, GalPipelineState state, long[] keys) { Profile.Begin(Profiles.GPU.Engine3d.UploadTextures); long baseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress); int textureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex); List <(long, GalImage, GalTextureSampler)> unboundTextures = new List <(long, GalImage, GalTextureSampler)>(); for (int index = 0; index < keys.Length; index++) { foreach (TextureDescriptor desc in _gpu.Renderer.Shader.GetTextureUsage(keys[index])) { int textureHandle; if (desc.IsBindless) { long position = _constBuffers[index][desc.CbufSlot].Position; textureHandle = vmm.ReadInt32(position + desc.CbufOffset * 4); } else { long position = _constBuffers[index][textureCbIndex].Position; textureHandle = vmm.ReadInt32(position + desc.HandleIndex * 4); } unboundTextures.Add(UploadTexture(vmm, textureHandle)); } } for (int index = 0; index < unboundTextures.Count; index++) { (long key, GalImage image, GalTextureSampler sampler) = unboundTextures[index]; if (key == 0) { continue; } _gpu.Renderer.Texture.Bind(key, index, image); _gpu.Renderer.Texture.SetSampler(image, sampler); } Profile.End(Profiles.GPU.Engine3d.UploadTextures); }
private void UploadTextures(NvGpuVmm Vmm, GalPipelineState State, long[] Keys) { long BaseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress); int TextureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex); int TexIndex = 0; for (int Index = 0; Index < Keys.Length; Index++) { foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.Shader.GetTextureUsage(Keys[Index])) { long Position; if (DeclInfo.IsCb) { Position = ConstBuffers[Index][DeclInfo.Cbuf].Position; } else { Position = ConstBuffers[Index][TextureCbIndex].Position; } int TextureHandle = Vmm.ReadInt32(Position + DeclInfo.Index * 4); UploadTexture(Vmm, TexIndex, TextureHandle); TexIndex++; } } }
private static long GetShaderSize(NvGpuVmm Vmm, long Position) { const int NopInst = 0x50b0; long Offset = 0x50; ulong OpCode = 0; do { uint Word0 = (uint)Vmm.ReadInt32(Position + Offset + 0); uint Word1 = (uint)Vmm.ReadInt32(Position + Offset + 4); OpCode = Word0 | (ulong)Word1 << 32; Offset += 8; }while ((OpCode >> 52 & 0xfff8) != NopInst && OpCode != 0); return(Offset - 8); }
private static int[] ReadWords(NvGpuVmm Vmm, long Position, int Count) { int[] Words = new int[Count]; for (int Index = 0; Index < Count; Index++, Position += 4) { Words[Index] = Vmm.ReadInt32(Position); } return(Words); }
private static int[] ReadWords(NvGpuVmm vmm, long position, int count) { int[] words = new int[count]; for (int index = 0; index < count; index++, position += 4) { words[index] = vmm.ReadInt32(position); } return(words); }
private void UploadTextures(NvGpuVmm Vmm, GalPipelineState State, long[] Keys) { long BaseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress); int TextureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex); List <(long, GalImage, GalTextureSampler)> UnboundTextures = new List <(long, GalImage, GalTextureSampler)>(); for (int Index = 0; Index < Keys.Length; Index++) { foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.Shader.GetTextureUsage(Keys[Index])) { long Position; if (DeclInfo.IsCb) { Position = ConstBuffers[Index][DeclInfo.Cbuf].Position; } else { Position = ConstBuffers[Index][TextureCbIndex].Position; } int TextureHandle = Vmm.ReadInt32(Position + DeclInfo.Index * 4); UnboundTextures.Add(UploadTexture(Vmm, TextureHandle)); } } for (int Index = 0; Index < UnboundTextures.Count; Index++) { (long Key, GalImage Image, GalTextureSampler Sampler) = UnboundTextures[Index]; if (Key == 0) { continue; } Gpu.Renderer.Texture.Bind(Key, Index, Image); Gpu.Renderer.Texture.SetSampler(Sampler); } }
private void UploadTextures(NvGpuVmm vmm, GalPipelineState state, long[] keys) { long baseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress); int textureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex); List <(long, GalImage, GalTextureSampler)> unboundTextures = new List <(long, GalImage, GalTextureSampler)>(); for (int index = 0; index < keys.Length; index++) { foreach (ShaderDeclInfo declInfo in _gpu.Renderer.Shader.GetTextureUsage(keys[index])) { long position; if (declInfo.IsCb) { position = _constBuffers[index][declInfo.Cbuf].Position; } else { position = _constBuffers[index][textureCbIndex].Position; } int textureHandle = vmm.ReadInt32(position + declInfo.Index * 4); unboundTextures.Add(UploadTexture(vmm, textureHandle)); } } for (int index = 0; index < unboundTextures.Count; index++) { (long key, GalImage image, GalTextureSampler sampler) = unboundTextures[index]; if (key == 0) { continue; } _gpu.Renderer.Texture.Bind(key, index, image); _gpu.Renderer.Texture.SetSampler(image, sampler); } }
private void UploadTexture(NvGpuVmm Vmm, long BasePosition, int TexIndex, int HndIndex) { long Position = BasePosition + HndIndex * 4; int TextureHandle = Vmm.ReadInt32(Position); if (TextureHandle == 0) { //TODO: Is this correct? //Some games like puyo puyo will have 0 handles. //It may be just normal behaviour or a bug caused by sync issues. //The game does initialize the value properly after through. return; } int TicIndex = (TextureHandle >> 0) & 0xfffff; int TscIndex = (TextureHandle >> 20) & 0xfff; long TicPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexHeaderPoolOffset); long TscPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexSamplerPoolOffset); TicPosition += TicIndex * 0x20; TscPosition += TscIndex * 0x20; GalTextureSampler Sampler = TextureFactory.MakeSampler(Gpu, Vmm, TscPosition); long Key = Vmm.ReadInt64(TicPosition + 4) & 0xffffffffffff; Key = Vmm.GetPhysicalAddress(Key); if (IsFrameBufferPosition(Key)) { //This texture is a frame buffer texture, //we shouldn't read anything from memory and bind //the frame buffer texture instead, since we're not //really writing anything to memory. Gpu.Renderer.FrameBuffer.BindTexture(Key, TexIndex); } else { GalTexture NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition); long Size = (uint)TextureHelper.GetTextureSize(NewTexture); bool HasCachedTexture = false; if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalTexture Texture)) { if (NewTexture.Equals(Texture) && !Vmm.IsRegionModified(Key, Size, NvGpuBufferType.Texture)) { Gpu.Renderer.Texture.Bind(Key, TexIndex); HasCachedTexture = true; } } if (!HasCachedTexture) { byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition); Gpu.Renderer.Texture.Create(Key, Data, NewTexture); } Gpu.Renderer.Texture.Bind(Key, TexIndex); } Gpu.Renderer.Texture.SetSampler(Sampler); }
private void Execute(NvGpuVmm vmm, int[] arguments) { if (_currentVideoCodec == VideoCodec.H264) { int frameDataSize = vmm.ReadInt32(_decoderContextAddress + 0x48); H264ParameterSets Params = MemoryHelper.Read <H264ParameterSets>(vmm.Memory, vmm.GetPhysicalAddress(_decoderContextAddress + 0x58)); H264Matrices matrices = new H264Matrices() { ScalingMatrix4 = vmm.ReadBytes(_decoderContextAddress + 0x1c0, 6 * 16), ScalingMatrix8 = vmm.ReadBytes(_decoderContextAddress + 0x220, 2 * 64) }; byte[] frameData = vmm.ReadBytes(_frameDataAddress, frameDataSize); _h264Decoder.Decode(Params, matrices, frameData); } else if (_currentVideoCodec == VideoCodec.Vp9) { int frameDataSize = vmm.ReadInt32(_decoderContextAddress + 0x30); Vp9FrameKeys keys = new Vp9FrameKeys() { CurrKey = vmm.GetPhysicalAddress(_vpxCurrLumaAddress), Ref0Key = vmm.GetPhysicalAddress(_vpxRef0LumaAddress), Ref1Key = vmm.GetPhysicalAddress(_vpxRef1LumaAddress), Ref2Key = vmm.GetPhysicalAddress(_vpxRef2LumaAddress) }; Vp9FrameHeader header = MemoryHelper.Read <Vp9FrameHeader>(vmm.Memory, vmm.GetPhysicalAddress(_decoderContextAddress + 0x48)); Vp9ProbabilityTables probs = new Vp9ProbabilityTables() { SegmentationTreeProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x387, 0x7), SegmentationPredProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x38e, 0x3), Tx8x8Probs = vmm.ReadBytes(_vpxProbTablesAddress + 0x470, 0x2), Tx16x16Probs = vmm.ReadBytes(_vpxProbTablesAddress + 0x472, 0x4), Tx32x32Probs = vmm.ReadBytes(_vpxProbTablesAddress + 0x476, 0x6), CoefProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x5a0, 0x900), SkipProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x537, 0x3), InterModeProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x400, 0x1c), InterpFilterProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x52a, 0x8), IsInterProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x41c, 0x4), CompModeProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x532, 0x5), SingleRefProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x580, 0xa), CompRefProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x58a, 0x5), YModeProbs0 = vmm.ReadBytes(_vpxProbTablesAddress + 0x480, 0x20), YModeProbs1 = vmm.ReadBytes(_vpxProbTablesAddress + 0x47c, 0x4), PartitionProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x4e0, 0x40), MvJointProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x53b, 0x3), MvSignProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x53e, 0x3), MvClassProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x54c, 0x14), MvClass0BitProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x540, 0x3), MvBitsProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x56c, 0x14), MvClass0FrProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x560, 0xc), MvFrProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x542, 0x6), MvClass0HpProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x548, 0x2), MvHpProbs = vmm.ReadBytes(_vpxProbTablesAddress + 0x54a, 0x2) }; byte[] frameData = vmm.ReadBytes(_frameDataAddress, frameDataSize); _vp9Decoder.Decode(keys, header, probs, frameData); } else { ThrowUnimplementedCodec(); } }