Ejemplo n.º 1
0
        private void UploadTexture(NvGpuVmm Vmm, long BasePosition, int TexIndex, int HndIndex)
        {
            long Position = BasePosition + HndIndex * 4;

            int TextureHandle = Vmm.ReadInt32(Position);

            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 TextureAddress = Vmm.ReadInt64(TicPosition + 4) & 0xffffffffffff;

            long Tag = TextureAddress;

            TextureAddress = Vmm.GetPhysicalAddress(TextureAddress);

            if (IsFrameBufferPosition(TextureAddress))
            {
                //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.BindFrameBufferTexture(TextureAddress, TexIndex, Sampler);
            }
            else
            {
                GalTexture NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition);

                long Size = (uint)TextureHelper.GetTextureSize(NewTexture);

                if (Gpu.Renderer.TryGetCachedTexture(Tag, Size, out GalTexture Texture))
                {
                    if (NewTexture.Equals(Texture) && !Vmm.IsRegionModified(Tag, Size, NvGpuBufferType.Texture))
                    {
                        Gpu.Renderer.BindTexture(Tag, TexIndex);

                        return;
                    }
                }

                byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition);

                Gpu.Renderer.SetTextureAndSampler(Tag, Data, NewTexture, Sampler);

                Gpu.Renderer.BindTexture(Tag, TexIndex);
            }
        }
Ejemplo n.º 2
0
        private void SetFrameBuffer(NvGpuVmm Vmm, int FbIndex)
        {
            long VA = MakeInt64From2xInt32(NvGpuEngine3dReg.FrameBufferNAddress + FbIndex * 0x10);

            long PA = Vmm.GetPhysicalAddress(VA);

            FrameBuffers.Add(PA);

            int Width  = ReadRegister(NvGpuEngine3dReg.FrameBufferNWidth + FbIndex * 0x10);
            int Height = ReadRegister(NvGpuEngine3dReg.FrameBufferNHeight + FbIndex * 0x10);

            //Note: Using the Width/Height results seems to give incorrect results.
            //Maybe the size of all frame buffers is hardcoded to screen size? This seems unlikely.
            Gpu.Renderer.CreateFrameBuffer(PA, 1280, 720);
            Gpu.Renderer.BindFrameBuffer(PA);
        }
Ejemplo n.º 3
0
        private void TextureCopy(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
        {
            CopyOperation Operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation);

            bool SrcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0;
            int  SrcWidth  = ReadRegister(NvGpuEngine2dReg.SrcWidth);
            int  SrcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight);

            bool DstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0;
            int  DstWidth  = ReadRegister(NvGpuEngine2dReg.DstWidth);
            int  DstHeight = ReadRegister(NvGpuEngine2dReg.DstHeight);
            int  DstPitch  = ReadRegister(NvGpuEngine2dReg.DstPitch);
            int  DstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions);

            TextureSwizzle DstSwizzle = DstLinear
                ? TextureSwizzle.Pitch
                : TextureSwizzle.BlockLinear;

            int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf);

            long Tag = Vmm.GetPhysicalAddress(MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress));

            long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress);
            long DstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress);

            bool IsFbTexture = Gpu.Engine3d.IsFrameBufferPosition(Tag);

            if (IsFbTexture && DstLinear)
            {
                DstSwizzle = TextureSwizzle.BlockLinear;
            }

            Texture DstTexture = new Texture(
                DstAddress,
                DstWidth,
                DstHeight,
                DstBlockHeight,
                DstBlockHeight,
                DstSwizzle,
                GalTextureFormat.A8B8G8R8);

            if (IsFbTexture)
            {
                //TODO: Change this when the correct frame buffer resolution is used.
                //Currently, the frame buffer size is hardcoded to 1280x720.
                SrcWidth  = 1280;
                SrcHeight = 720;

                Gpu.Renderer.GetFrameBufferData(Tag, (byte[] Buffer) =>
                {
                    CopyTexture(
                        Vmm,
                        DstTexture,
                        Buffer,
                        SrcWidth,
                        SrcHeight);
                });
            }
            else
            {
                long Size = SrcWidth * SrcHeight * 4;

                byte[] Buffer = Vmm.ReadBytes(SrcAddress, Size);

                CopyTexture(
                    Vmm,
                    DstTexture,
                    Buffer,
                    SrcWidth,
                    SrcHeight);
            }
        }