public GalImage( int Width, int Height, int TileWidth, int GobBlockHeight, GalMemoryLayout Layout, GalImageFormat Format, GalTextureSource XSource = GalTextureSource.Red, GalTextureSource YSource = GalTextureSource.Green, GalTextureSource ZSource = GalTextureSource.Blue, GalTextureSource WSource = GalTextureSource.Alpha) { this.Width = Width; this.Height = Height; this.TileWidth = TileWidth; this.GobBlockHeight = GobBlockHeight; this.Layout = Layout; this.Format = Format; this.XSource = XSource; this.YSource = YSource; this.ZSource = ZSource; this.WSource = WSource; Pitch = ImageUtils.GetPitch(Format, Width); }
private void SetZeta(NvGpuVmm Vmm) { long VA = MakeInt64From2xInt32(NvGpuEngine3dReg.ZetaAddress); int ZetaFormat = ReadRegister(NvGpuEngine3dReg.ZetaFormat); int BlockDim = ReadRegister(NvGpuEngine3dReg.ZetaBlockDimensions); int GobBlockHeight = 1 << ((BlockDim >> 4) & 7); GalMemoryLayout Layout = (GalMemoryLayout)((BlockDim >> 12) & 1); //? bool ZetaEnable = ReadRegisterBool(NvGpuEngine3dReg.ZetaEnable); if (VA == 0 || ZetaFormat == 0 || !ZetaEnable) { Gpu.Renderer.RenderTarget.UnbindZeta(); return; } long Key = Vmm.GetPhysicalAddress(VA); int Width = ReadRegister(NvGpuEngine3dReg.ZetaHoriz); int Height = ReadRegister(NvGpuEngine3dReg.ZetaVert); GalImageFormat Format = ImageUtils.ConvertZeta((GalZetaFormat)ZetaFormat); GalImage Image = new GalImage(Width, Height, 1, GobBlockHeight, Layout, Format); Gpu.ResourceManager.SendZetaBuffer(Vmm, Key, Image); }
private void SetZeta(NvGpuVmm vmm) { long va = MakeInt64From2xInt32(NvGpuEngine3dReg.ZetaAddress); int zetaFormat = ReadRegister(NvGpuEngine3dReg.ZetaFormat); int blockDim = ReadRegister(NvGpuEngine3dReg.ZetaBlockDimensions); int gobBlockHeight = 1 << ((blockDim >> 4) & 7); GalMemoryLayout layout = (GalMemoryLayout)((blockDim >> 12) & 1); //? bool zetaEnable = ReadRegisterBool(NvGpuEngine3dReg.ZetaEnable); if (va == 0 || zetaFormat == 0 || !zetaEnable) { _gpu.Renderer.RenderTarget.UnbindZeta(); return; } long key = vmm.GetPhysicalAddress(va); int width = ReadRegister(NvGpuEngine3dReg.ZetaHoriz); int height = ReadRegister(NvGpuEngine3dReg.ZetaVert); GalImageFormat format = ImageUtils.ConvertZeta((GalZetaFormat)zetaFormat); // TODO: Support non 2D? GalImage image = new GalImage(width, height, 1, 1, 1, gobBlockHeight, 1, layout, format, GalTextureTarget.TwoD); _gpu.ResourceManager.SendZetaBuffer(vmm, key, image); }
public GalImage( int width, int height, int depth, int layerCount, int tileWidth, int gobBlockHeight, int gobBlockDepth, GalMemoryLayout layout, GalImageFormat format, GalTextureTarget textureTarget, int maxMipmapLevel = 1, GalTextureSource xSource = GalTextureSource.Red, GalTextureSource ySource = GalTextureSource.Green, GalTextureSource zSource = GalTextureSource.Blue, GalTextureSource wSource = GalTextureSource.Alpha) { Width = width; Height = height; LayerCount = layerCount; Depth = depth; TileWidth = tileWidth; GobBlockHeight = gobBlockHeight; GobBlockDepth = gobBlockDepth; Layout = layout; Format = format; MaxMipmapLevel = maxMipmapLevel; XSource = xSource; YSource = ySource; ZSource = zSource; WSource = wSource; TextureTarget = textureTarget; Pitch = ImageUtils.GetPitch(format, width); }
private void SetFrameBuffer(NvGpuVmm vmm, int fbIndex) { ProfileConfig profile = Profiles.GPU.Engine3d.SetFrameBuffer; profile.SessionItem = fbIndex.ToString(); Profile.Begin(profile); long va = MakeInt64From2xInt32(NvGpuEngine3dReg.FrameBufferNAddress + fbIndex * 0x10); int surfFormat = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + fbIndex * 0x10); if (va == 0 || surfFormat == 0) { _gpu.Renderer.RenderTarget.UnbindColor(fbIndex); Profile.End(profile); return; } long key = vmm.GetPhysicalAddress(va); int width = ReadRegister(NvGpuEngine3dReg.FrameBufferNWidth + fbIndex * 0x10); int height = ReadRegister(NvGpuEngine3dReg.FrameBufferNHeight + fbIndex * 0x10); int arrayMode = ReadRegister(NvGpuEngine3dReg.FrameBufferNArrayMode + fbIndex * 0x10); int layerCount = arrayMode & 0xFFFF; int layerStride = ReadRegister(NvGpuEngine3dReg.FrameBufferNLayerStride + fbIndex * 0x10); int baseLayer = ReadRegister(NvGpuEngine3dReg.FrameBufferNBaseLayer + fbIndex * 0x10); int blockDim = ReadRegister(NvGpuEngine3dReg.FrameBufferNBlockDim + fbIndex * 0x10); int gobBlockHeight = 1 << ((blockDim >> 4) & 7); GalMemoryLayout layout = (GalMemoryLayout)((blockDim >> 12) & 1); float tx = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateX + fbIndex * 8); float ty = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateY + fbIndex * 8); float sx = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNScaleX + fbIndex * 8); float sy = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNScaleY + fbIndex * 8); _viewportX0 = (int)MathF.Max(0, tx - MathF.Abs(sx)); _viewportY0 = (int)MathF.Max(0, ty - MathF.Abs(sy)); _viewportX1 = (int)(tx + MathF.Abs(sx)); _viewportY1 = (int)(ty + MathF.Abs(sy)); GalImageFormat format = ImageUtils.ConvertSurface((GalSurfaceFormat)surfFormat); GalImage image = new GalImage(width, height, 1, 1, 1, gobBlockHeight, 1, layout, format, GalTextureTarget.TwoD); _gpu.ResourceManager.SendColorBuffer(vmm, key, fbIndex, image); _gpu.Renderer.RenderTarget.SetViewport(fbIndex, _viewportX0, _viewportY0, _viewportX1 - _viewportX0, _viewportY1 - _viewportY0); Profile.End(profile); }
private void SetFrameBuffer(NvGpuVmm Vmm, int FbIndex) { long VA = MakeInt64From2xInt32(NvGpuEngine3dReg.FrameBufferNAddress + FbIndex * 0x10); int SurfFormat = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + FbIndex * 0x10); if (VA == 0 || SurfFormat == 0) { Gpu.Renderer.RenderTarget.UnbindColor(FbIndex); return; } long Key = Vmm.GetPhysicalAddress(VA); int Width = ReadRegister(NvGpuEngine3dReg.FrameBufferNWidth + FbIndex * 0x10); int Height = ReadRegister(NvGpuEngine3dReg.FrameBufferNHeight + FbIndex * 0x10); int BlockDim = ReadRegister(NvGpuEngine3dReg.FrameBufferNBlockDim + FbIndex * 0x10); int GobBlockHeight = 1 << ((BlockDim >> 4) & 7); GalMemoryLayout Layout = (GalMemoryLayout)((BlockDim >> 12) & 1); float TX = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateX + FbIndex * 8); float TY = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateY + FbIndex * 8); float SX = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNScaleX + FbIndex * 8); float SY = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNScaleY + FbIndex * 8); int VpX = (int)MathF.Max(0, TX - MathF.Abs(SX)); int VpY = (int)MathF.Max(0, TY - MathF.Abs(SY)); int VpW = (int)(TX + MathF.Abs(SX)) - VpX; int VpH = (int)(TY + MathF.Abs(SY)) - VpY; GalImageFormat Format = ImageUtils.ConvertSurface((GalSurfaceFormat)SurfFormat); GalImage Image = new GalImage(Width, Height, 1, GobBlockHeight, Layout, Format); Gpu.ResourceManager.SendColorBuffer(Vmm, Key, FbIndex, Image); ViewportHeight = VpH; Gpu.Renderer.RenderTarget.SetViewport(FbIndex, VpX, VpY, VpW, VpH); }
private void TextureCopy(NvGpuVmm Vmm) { CopyOperation Operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation); int DstFormat = ReadRegister(NvGpuEngine2dReg.DstFormat); 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); int SrcFormat = ReadRegister(NvGpuEngine2dReg.SrcFormat); bool SrcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0; int SrcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth); int SrcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight); int SrcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch); int SrcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions); int DstBlitX = ReadRegister(NvGpuEngine2dReg.BlitDstX); int DstBlitY = ReadRegister(NvGpuEngine2dReg.BlitDstY); int DstBlitW = ReadRegister(NvGpuEngine2dReg.BlitDstW); int DstBlitH = ReadRegister(NvGpuEngine2dReg.BlitDstH); long BlitDuDx = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDuDxFract); long BlitDvDy = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDvDyFract); long SrcBlitX = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcXFract); long SrcBlitY = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcYFract); GalImageFormat SrcImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)SrcFormat); GalImageFormat DstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)DstFormat); GalMemoryLayout SrcLayout = GetLayout(SrcLinear); GalMemoryLayout DstLayout = GetLayout(DstLinear); int SrcBlockHeight = 1 << ((SrcBlkDim >> 4) & 0xf); int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf); long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress); long DstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress); long SrcKey = Vmm.GetPhysicalAddress(SrcAddress); long DstKey = Vmm.GetPhysicalAddress(DstAddress); GalImage SrcTexture = new GalImage( SrcWidth, SrcHeight, 1, SrcBlockHeight, SrcLayout, SrcImgFormat); GalImage DstTexture = new GalImage( DstWidth, DstHeight, 1, DstBlockHeight, DstLayout, DstImgFormat); SrcTexture.Pitch = SrcPitch; DstTexture.Pitch = DstPitch; Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture); Gpu.ResourceManager.SendTexture(Vmm, DstKey, DstTexture); int SrcBlitX1 = (int)(SrcBlitX >> 32); int SrcBlitY1 = (int)(SrcBlitY >> 32); int SrcBlitX2 = (int)(SrcBlitX + DstBlitW * BlitDuDx >> 32); int SrcBlitY2 = (int)(SrcBlitY + DstBlitH * BlitDvDy >> 32); Gpu.Renderer.RenderTarget.Copy( SrcKey, DstKey, SrcBlitX1, SrcBlitY1, SrcBlitX2, SrcBlitY2, DstBlitX, DstBlitY, DstBlitX + DstBlitW, DstBlitY + DstBlitH); //Do a guest side copy aswell. This is necessary when //the texture is modified by the guest, however it doesn't //work when resources that the gpu can write to are copied, //like framebuffers. ImageUtils.CopyTexture( Vmm, SrcTexture, DstTexture, SrcAddress, DstAddress, SrcBlitX1, SrcBlitY1, DstBlitX, DstBlitY, DstBlitW, DstBlitH); Vmm.IsRegionModified(DstKey, ImageUtils.GetSize(DstTexture), NvGpuBufferType.Texture); }
private void TextureCopy(NvGpuVmm vmm) { CopyOperation operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation); int dstFormat = ReadRegister(NvGpuEngine2dReg.DstFormat); bool dstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0; int dstWidth = ReadRegister(NvGpuEngine2dReg.DstWidth); int dstHeight = ReadRegister(NvGpuEngine2dReg.DstHeight); int dstDepth = ReadRegister(NvGpuEngine2dReg.DstDepth); int dstLayer = ReadRegister(NvGpuEngine2dReg.DstLayer); int dstPitch = ReadRegister(NvGpuEngine2dReg.DstPitch); int dstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions); int srcFormat = ReadRegister(NvGpuEngine2dReg.SrcFormat); bool srcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0; int srcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth); int srcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight); int srcDepth = ReadRegister(NvGpuEngine2dReg.SrcDepth); int srcLayer = ReadRegister(NvGpuEngine2dReg.SrcLayer); int srcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch); int srcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions); int dstBlitX = ReadRegister(NvGpuEngine2dReg.BlitDstX); int dstBlitY = ReadRegister(NvGpuEngine2dReg.BlitDstY); int dstBlitW = ReadRegister(NvGpuEngine2dReg.BlitDstW); int dstBlitH = ReadRegister(NvGpuEngine2dReg.BlitDstH); long blitDuDx = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDuDxFract); long blitDvDy = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitDvDyFract); long srcBlitX = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcXFract); long srcBlitY = ReadRegisterFixed1_31_32(NvGpuEngine2dReg.BlitSrcYFract); GalImageFormat srcImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)srcFormat); GalImageFormat dstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)dstFormat); GalMemoryLayout srcLayout = GetLayout(srcLinear); GalMemoryLayout dstLayout = GetLayout(dstLinear); int srcBlockHeight = 1 << ((srcBlkDim >> 4) & 0xf); int dstBlockHeight = 1 << ((dstBlkDim >> 4) & 0xf); long srcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress); long dstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress); long srcKey = vmm.GetPhysicalAddress(srcAddress); long dstKey = vmm.GetPhysicalAddress(dstAddress); bool isSrcLayered = false; bool isDstLayered = false; GalTextureTarget srcTarget = GalTextureTarget.TwoD; if (srcDepth != 0) { srcTarget = GalTextureTarget.TwoDArray; srcDepth++; isSrcLayered = true; } else { srcDepth = 1; } GalTextureTarget dstTarget = GalTextureTarget.TwoD; if (dstDepth != 0) { dstTarget = GalTextureTarget.TwoDArray; dstDepth++; isDstLayered = true; } else { dstDepth = 1; } GalImage srcTexture = new GalImage( srcWidth, srcHeight, 1, srcDepth, 1, srcBlockHeight, 1, srcLayout, srcImgFormat, srcTarget); GalImage dstTexture = new GalImage( dstWidth, dstHeight, 1, dstDepth, 1, dstBlockHeight, 1, dstLayout, dstImgFormat, dstTarget); srcTexture.Pitch = srcPitch; dstTexture.Pitch = dstPitch; long GetLayerOffset(GalImage image, int layer) { int targetMipLevel = image.MaxMipmapLevel <= 1 ? 1 : image.MaxMipmapLevel - 1; return(ImageUtils.GetLayerOffset(image, targetMipLevel) * layer); } int srcLayerIndex = -1; if (isSrcLayered && _gpu.ResourceManager.TryGetTextureLayer(srcKey, out srcLayerIndex) && srcLayerIndex != 0) { srcKey = srcKey - GetLayerOffset(srcTexture, srcLayerIndex); } int dstLayerIndex = -1; if (isDstLayered && _gpu.ResourceManager.TryGetTextureLayer(dstKey, out dstLayerIndex) && dstLayerIndex != 0) { dstKey = dstKey - GetLayerOffset(dstTexture, dstLayerIndex); } _gpu.ResourceManager.SendTexture(vmm, srcKey, srcTexture); _gpu.ResourceManager.SendTexture(vmm, dstKey, dstTexture); if (isSrcLayered && srcLayerIndex == -1) { for (int layer = 0; layer < srcTexture.LayerCount; layer++) { _gpu.ResourceManager.SetTextureArrayLayer(srcKey + GetLayerOffset(srcTexture, layer), layer); } srcLayerIndex = 0; } if (isDstLayered && dstLayerIndex == -1) { for (int layer = 0; layer < dstTexture.LayerCount; layer++) { _gpu.ResourceManager.SetTextureArrayLayer(dstKey + GetLayerOffset(dstTexture, layer), layer); } dstLayerIndex = 0; } int srcBlitX1 = (int)(srcBlitX >> 32); int srcBlitY1 = (int)(srcBlitY >> 32); int srcBlitX2 = (int)(srcBlitX + dstBlitW * blitDuDx >> 32); int srcBlitY2 = (int)(srcBlitY + dstBlitH * blitDvDy >> 32); _gpu.Renderer.RenderTarget.Copy( srcTexture, dstTexture, srcKey, dstKey, srcLayerIndex, dstLayerIndex, srcBlitX1, srcBlitY1, srcBlitX2, srcBlitY2, dstBlitX, dstBlitY, dstBlitX + dstBlitW, dstBlitY + dstBlitH); //Do a guest side copy aswell. This is necessary when //the texture is modified by the guest, however it doesn't //work when resources that the gpu can write to are copied, //like framebuffers. // FIXME: SUPPORT MULTILAYER CORRECTLY HERE (this will cause weird stuffs on the first layer) ImageUtils.CopyTexture( vmm, srcTexture, dstTexture, srcAddress, dstAddress, srcBlitX1, srcBlitY1, dstBlitX, dstBlitY, dstBlitW, dstBlitH); vmm.IsRegionModified(dstKey, ImageUtils.GetSize(dstTexture), NvGpuBufferType.Texture); }
private void TextureCopy(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) { CopyOperation Operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation); int SrcFormat = ReadRegister(NvGpuEngine2dReg.SrcFormat); bool SrcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0; int SrcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth); int SrcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight); int SrcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch); int SrcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions); int DstFormat = ReadRegister(NvGpuEngine2dReg.DstFormat); 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); GalImageFormat SrcImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)SrcFormat); GalImageFormat DstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)DstFormat); GalMemoryLayout SrcLayout = GetLayout(SrcLinear); GalMemoryLayout DstLayout = GetLayout(DstLinear); int SrcBlockHeight = 1 << ((SrcBlkDim >> 4) & 0xf); int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf); long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress); long DstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress); long SrcKey = Vmm.GetPhysicalAddress(SrcAddress); long DstKey = Vmm.GetPhysicalAddress(DstAddress); GalImage SrcTexture = new GalImage( SrcWidth, SrcHeight, 1, SrcBlockHeight, SrcLayout, SrcImgFormat); GalImage DstTexture = new GalImage( DstWidth, DstHeight, 1, DstBlockHeight, DstLayout, DstImgFormat); Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture); Gpu.ResourceManager.SendTexture(Vmm, DstKey, DstTexture); Gpu.Renderer.RenderTarget.Copy( SrcKey, DstKey, 0, 0, SrcWidth, SrcHeight, 0, 0, DstWidth, DstHeight); }