public static NvViewportSwizzle Convert(this ViewportSwizzle swizzle) { switch (swizzle) { case ViewportSwizzle.PositiveX: return(NvViewportSwizzle.ViewportSwizzlePositiveXNv); case ViewportSwizzle.PositiveY: return(NvViewportSwizzle.ViewportSwizzlePositiveYNv); case ViewportSwizzle.PositiveZ: return(NvViewportSwizzle.ViewportSwizzlePositiveZNv); case ViewportSwizzle.PositiveW: return(NvViewportSwizzle.ViewportSwizzlePositiveWNv); case ViewportSwizzle.NegativeX: return(NvViewportSwizzle.ViewportSwizzleNegativeXNv); case ViewportSwizzle.NegativeY: return(NvViewportSwizzle.ViewportSwizzleNegativeYNv); case ViewportSwizzle.NegativeZ: return(NvViewportSwizzle.ViewportSwizzleNegativeZNv); case ViewportSwizzle.NegativeW: return(NvViewportSwizzle.ViewportSwizzleNegativeWNv); } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(ViewportSwizzle)} enum value: {swizzle}."); return(NvViewportSwizzle.ViewportSwizzlePositiveXNv); }
public Viewport( Rectangle <float> region, ViewportSwizzle swizzleX, ViewportSwizzle swizzleY, ViewportSwizzle swizzleZ, ViewportSwizzle swizzleW, float depthNear, float depthFar) { Region = region; SwizzleX = swizzleX; SwizzleY = swizzleY; SwizzleZ = swizzleZ; SwizzleW = swizzleW; DepthNear = depthNear; DepthFar = depthFar; }
/// <summary> /// Updates host viewport transform and clipping state based on current GPU state. /// </summary> /// <param name="state">Current GPU state</param> private void UpdateViewportTransform(GpuState state) { var yControl = state.Get <YControl> (MethodOffset.YControl); var face = state.Get <FaceState>(MethodOffset.FaceState); UpdateFrontFace(yControl, face.FrontFace); bool flipY = yControl.HasFlag(YControl.NegateY); Span <Viewport> viewports = stackalloc Viewport[Constants.TotalViewports]; for (int index = 0; index < Constants.TotalViewports; index++) { var transform = state.Get <ViewportTransform>(MethodOffset.ViewportTransform, index); var extents = state.Get <ViewportExtents> (MethodOffset.ViewportExtents, index); float scaleX = MathF.Abs(transform.ScaleX); float scaleY = transform.ScaleY; if (flipY) { scaleY = -scaleY; } if (!_context.Capabilities.SupportsViewportSwizzle && transform.UnpackSwizzleY() == ViewportSwizzle.NegativeY) { scaleY = -scaleY; } if (index == 0) { // Try to guess the depth mode being used on the high level API // based on current transform. // It is setup like so by said APIs: // If depth mode is ZeroToOne: // TranslateZ = Near // ScaleZ = Far - Near // If depth mode is MinusOneToOne: // TranslateZ = (Near + Far) / 2 // ScaleZ = (Far - Near) / 2 // DepthNear/Far are sorted such as that Near is always less than Far. DepthMode depthMode = extents.DepthNear != transform.TranslateZ && extents.DepthFar != transform.TranslateZ ? DepthMode.MinusOneToOne : DepthMode.ZeroToOne; _context.Renderer.Pipeline.SetDepthMode(depthMode); } float x = transform.TranslateX - scaleX; float y = transform.TranslateY - scaleY; float width = scaleX * 2; float height = scaleY * 2; float scale = TextureManager.RenderTargetScale; if (scale != 1f) { x *= scale; y *= scale; width *= scale; height *= scale; } RectangleF region = new RectangleF(x, y, width, height); ViewportSwizzle swizzleX = transform.UnpackSwizzleX(); ViewportSwizzle swizzleY = transform.UnpackSwizzleY(); ViewportSwizzle swizzleZ = transform.UnpackSwizzleZ(); ViewportSwizzle swizzleW = transform.UnpackSwizzleW(); float depthNear = extents.DepthNear; float depthFar = extents.DepthFar; if (transform.ScaleZ < 0) { float temp = depthNear; depthNear = depthFar; depthFar = temp; } viewports[index] = new Viewport(region, swizzleX, swizzleY, swizzleZ, swizzleW, depthNear, depthFar); } _context.Renderer.Pipeline.SetViewports(0, viewports); }
/// <summary> /// Updates host viewport transform and clipping state based on current GPU state. /// </summary> /// <param name="state">Current GPU state</param> private void UpdateViewportTransform(GpuState state) { DepthMode depthMode = state.Get <DepthMode>(MethodOffset.DepthMode); _context.Renderer.Pipeline.SetDepthMode(depthMode); YControl yControl = state.Get <YControl>(MethodOffset.YControl); bool flipY = yControl.HasFlag(YControl.NegateY); Origin origin = yControl.HasFlag(YControl.TriangleRastFlip) ? Origin.LowerLeft : Origin.UpperLeft; _context.Renderer.Pipeline.SetOrigin(origin); // The triangle rast flip flag only affects rasterization, the viewport is not flipped. // Setting the origin mode to upper left on the host, however, not only affects rasterization, // but also flips the viewport. // We negate the effects of flipping the viewport by flipping it again using the viewport swizzle. if (origin == Origin.UpperLeft) { flipY = !flipY; } Span <Viewport> viewports = stackalloc Viewport[Constants.TotalViewports]; for (int index = 0; index < Constants.TotalViewports; index++) { var transform = state.Get <ViewportTransform>(MethodOffset.ViewportTransform, index); var extents = state.Get <ViewportExtents> (MethodOffset.ViewportExtents, index); float x = transform.TranslateX - MathF.Abs(transform.ScaleX); float y = transform.TranslateY - MathF.Abs(transform.ScaleY); float width = MathF.Abs(transform.ScaleX) * 2; float height = MathF.Abs(transform.ScaleY) * 2; float scale = TextureManager.RenderTargetScale; if (scale != 1f) { x *= scale; y *= scale; width *= scale; height *= scale; } RectangleF region = new RectangleF(x, y, width, height); ViewportSwizzle swizzleX = transform.UnpackSwizzleX(); ViewportSwizzle swizzleY = transform.UnpackSwizzleY(); ViewportSwizzle swizzleZ = transform.UnpackSwizzleZ(); ViewportSwizzle swizzleW = transform.UnpackSwizzleW(); if (transform.ScaleX < 0) { swizzleX ^= ViewportSwizzle.NegativeFlag; } if (flipY) { swizzleY ^= ViewportSwizzle.NegativeFlag; } if (transform.ScaleY < 0) { swizzleY ^= ViewportSwizzle.NegativeFlag; } if (transform.ScaleZ < 0) { swizzleZ ^= ViewportSwizzle.NegativeFlag; } viewports[index] = new Viewport( region, swizzleX, swizzleY, swizzleZ, swizzleW, extents.DepthNear, extents.DepthFar); } _context.Renderer.Pipeline.SetViewports(0, viewports); }
/// <summary> /// Updates host viewport transform and clipping state based on current GPU state. /// </summary> private void UpdateViewportTransform() { var yControl = _state.State.YControl; var face = _state.State.FaceState; UpdateFrontFace(yControl, face.FrontFace); bool flipY = yControl.HasFlag(YControl.NegateY); Span <Viewport> viewports = stackalloc Viewport[Constants.TotalViewports]; for (int index = 0; index < Constants.TotalViewports; index++) { var transform = _state.State.ViewportTransform[index]; var extents = _state.State.ViewportExtents[index]; float scaleX = MathF.Abs(transform.ScaleX); float scaleY = transform.ScaleY; if (flipY) { scaleY = -scaleY; } if (!_context.Capabilities.SupportsViewportSwizzle && transform.UnpackSwizzleY() == ViewportSwizzle.NegativeY) { scaleY = -scaleY; } float x = transform.TranslateX - scaleX; float y = transform.TranslateY - scaleY; float width = scaleX * 2; float height = scaleY * 2; float scale = _channel.TextureManager.RenderTargetScale; if (scale != 1f) { x *= scale; y *= scale; width *= scale; height *= scale; } Rectangle <float> region = new Rectangle <float>(x, y, width, height); ViewportSwizzle swizzleX = transform.UnpackSwizzleX(); ViewportSwizzle swizzleY = transform.UnpackSwizzleY(); ViewportSwizzle swizzleZ = transform.UnpackSwizzleZ(); ViewportSwizzle swizzleW = transform.UnpackSwizzleW(); float depthNear = extents.DepthNear; float depthFar = extents.DepthFar; if (transform.ScaleZ < 0) { float temp = depthNear; depthNear = depthFar; depthFar = temp; } viewports[index] = new Viewport(region, swizzleX, swizzleY, swizzleZ, swizzleW, depthNear, depthFar); } _context.Renderer.Pipeline.SetDepthMode(GetDepthMode()); _context.Renderer.Pipeline.SetViewports(0, viewports); }