private (long, GalImage, GalTextureSampler) UploadTexture(NvGpuVmm vmm, int textureHandle) { if (textureHandle == 0) { // FIXME: Some games like puyo puyo will use handles with the value 0. // This is a bug, most likely caused by sync issues. return(0, default(GalImage), default(GalTextureSampler)); } Profile.Begin(Profiles.GPU.Engine3d.UploadTexture); bool linkedTsc = ReadRegisterBool(NvGpuEngine3dReg.LinkedTsc); int ticIndex = (textureHandle >> 0) & 0xfffff; int tscIndex = linkedTsc ? ticIndex : (textureHandle >> 20) & 0xfff; long ticPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexHeaderPoolOffset); long tscPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexSamplerPoolOffset); ticPosition += ticIndex * 0x20; tscPosition += tscIndex * 0x20; GalImage image = TextureFactory.MakeTexture(vmm, ticPosition); GalTextureSampler sampler = TextureFactory.MakeSampler(_gpu, vmm, tscPosition); long key = vmm.ReadInt64(ticPosition + 4) & 0xffffffffffff; if (image.Layout == GalMemoryLayout.BlockLinear) { key &= ~0x1ffL; } else if (image.Layout == GalMemoryLayout.Pitch) { key &= ~0x1fL; } key = vmm.GetPhysicalAddress(key); if (key == -1) { Profile.End(Profiles.GPU.Engine3d.UploadTexture); // FIXME: Shouldn't ignore invalid addresses. return(0, default(GalImage), default(GalTextureSampler)); } _gpu.ResourceManager.SendTexture(vmm, key, image); Profile.End(Profiles.GPU.Engine3d.UploadTexture); return(key, image, sampler); }
private (long, GalImage, GalTextureSampler) UploadTexture(NvGpuVmm Vmm, int TextureHandle) { if (TextureHandle == 0) { //FIXME: Some games like puyo puyo will use handles with the value 0. //This is a bug, most likely caused by sync issues. return(0, default(GalImage), default(GalTextureSampler)); } bool LinkedTsc = ReadRegisterBool(NvGpuEngine3dReg.LinkedTsc); int TicIndex = (TextureHandle >> 0) & 0xfffff; int TscIndex = LinkedTsc ? TicIndex : (TextureHandle >> 20) & 0xfff; long TicPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexHeaderPoolOffset); long TscPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.TexSamplerPoolOffset); TicPosition += TicIndex * 0x20; TscPosition += TscIndex * 0x20; GalImage Image = TextureFactory.MakeTexture(Vmm, TicPosition); GalTextureSampler Sampler = TextureFactory.MakeSampler(Gpu, Vmm, TscPosition); long Key = Vmm.ReadInt64(TicPosition + 4) & 0xffffffffffff; if (Image.Layout == GalMemoryLayout.BlockLinear) { Key &= ~0x1ffL; } else if (Image.Layout == GalMemoryLayout.Pitch) { Key &= ~0x1fL; } Key = Vmm.GetPhysicalAddress(Key); if (Key == -1) { //FIXME: Shouldn't ignore invalid addresses. return(0, default(GalImage), default(GalTextureSampler)); } Gpu.ResourceManager.SendTexture(Vmm, Key, Image); return(Key, Image, Sampler); }
private void UploadTexture(NvGpuVmm Vmm, int TexIndex, int TextureHandle) { 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; GalImage Image = TextureFactory.MakeTexture(Vmm, TicPosition); GalTextureSampler Sampler = TextureFactory.MakeSampler(Gpu, Vmm, TscPosition); long Key = Vmm.ReadInt64(TicPosition + 4) & 0xffffffffffff; if (Image.Layout == GalMemoryLayout.BlockLinear) { Key &= ~0x1ffL; } else if (Image.Layout == GalMemoryLayout.Pitch) { Key &= ~0x1fL; } Key = Vmm.GetPhysicalAddress(Key); if (Key == -1) { //FIXME: Shouldn't ignore invalid addresses. return; } Gpu.ResourceManager.SendTexture(Vmm, Key, Image, TexIndex); Gpu.Renderer.Texture.SetSampler(Sampler); }
private void UploadTexture(NvGpuVmm Vmm, int TexIndex, int TextureHandle) { 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 (Key == -1) { //FIXME: Should'nt ignore invalid addresses. return; } 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 { GalImage NewImage = TextureFactory.MakeTexture(Vmm, TicPosition); long Size = (uint)TextureHelper.GetTextureSize(NewImage); bool HasCachedTexture = false; if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalImage Image)) { if (NewImage.Equals(Image) && !QueryKeyUpload(Vmm, 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, NewImage); } Gpu.Renderer.Texture.Bind(Key, TexIndex); } Gpu.Renderer.Texture.SetSampler(Sampler); }