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);
        }
Exemple #2
0
 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;
 }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
        /// <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);
        }