Esempio n. 1
0
        private void UploadConstBuffers(NvGpuVmm vmm, GalPipelineState state, long[] keys)
        {
            Profile.Begin(Profiles.GPU.Engine3d.UploadConstBuffers);

            for (int stage = 0; stage < keys.Length; stage++)
            {
                foreach (CBufferDescriptor desc in _gpu.Renderer.Shader.GetConstBufferUsage(keys[stage]))
                {
                    ConstBuffer cb = _constBuffers[stage][desc.Slot];

                    if (!cb.Enabled)
                    {
                        continue;
                    }

                    long key = vmm.GetPhysicalAddress(cb.Position);

                    if (_gpu.ResourceManager.MemoryRegionModified(vmm, key, cb.Size, NvGpuBufferType.ConstBuffer))
                    {
                        if (vmm.TryGetHostAddress(cb.Position, cb.Size, out IntPtr cbPtr))
                        {
                            _gpu.Renderer.Buffer.SetData(key, cb.Size, cbPtr);
                        }
                        else
                        {
                            _gpu.Renderer.Buffer.SetData(key, vmm.ReadBytes(cb.Position, cb.Size));
                        }
                    }

                    state.ConstBufferKeys[stage][desc.Slot] = key;
                }
            }

            Profile.End(Profiles.GPU.Engine3d.UploadConstBuffers);
        }
Esempio n. 2
0
        private void BindConstBuffers(GalPipelineState New)
        {
            int FreeBinding = OGLShader.ReservedCbufCount;

            void BindIfNotNull(OGLShaderStage Stage)
            {
                if (Stage != null)
                {
                    foreach (ShaderDeclInfo DeclInfo in Stage.ConstBufferUsage)
                    {
                        long Key = New.ConstBufferKeys[(int)Stage.Type][DeclInfo.Cbuf];

                        if (Key != 0 && Buffer.TryGetUbo(Key, out int UboHandle))
                        {
                            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, FreeBinding, UboHandle);
                        }

                        FreeBinding++;
                    }
                }
            }

            BindIfNotNull(Shader.Current.Vertex);
            BindIfNotNull(Shader.Current.TessControl);
            BindIfNotNull(Shader.Current.TessEvaluation);
            BindIfNotNull(Shader.Current.Geometry);
            BindIfNotNull(Shader.Current.Fragment);
        }
Esempio n. 3
0
 public void Unbind(GalPipelineState state)
 {
     if (state.ScissorTestCount > 0)
     {
         GL.Disable(EnableCap.ScissorTest);
     }
 }
Esempio n. 4
0
        private void BindConstBuffers(GalPipelineState New)
        {
            int freeBinding = OglShader.ReservedCbufCount;

            void BindIfNotNull(OglShaderStage stage)
            {
                if (stage != null)
                {
                    foreach (CBufferDescriptor desc in stage.ConstBufferUsage)
                    {
                        long key = New.ConstBufferKeys[(int)stage.Type][desc.Slot];

                        if (key != 0 && _buffer.TryGetUbo(key, out int uboHandle))
                        {
                            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, freeBinding, uboHandle);
                        }

                        freeBinding++;
                    }
                }
            }

            BindIfNotNull(_shader.Current.Vertex);
            BindIfNotNull(_shader.Current.TessControl);
            BindIfNotNull(_shader.Current.TessEvaluation);
            BindIfNotNull(_shader.Current.Geometry);
            BindIfNotNull(_shader.Current.Fragment);
        }
Esempio n. 5
0
        private void SetFrameBuffer(GalPipelineState State)
        {
            State.FramebufferSrgb = ReadRegisterBool(NvGpuEngine3dReg.FrameBufferSrgb);

            State.FlipX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX);
            State.FlipY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY);
        }
Esempio n. 6
0
        private void UploadConstBuffers(NvGpuVmm Vmm, GalPipelineState State, long[] Keys)
        {
            for (int Stage = 0; Stage < Keys.Length; Stage++)
            {
                foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.Shader.GetConstBufferUsage(Keys[Stage]))
                {
                    ConstBuffer Cb = ConstBuffers[Stage][DeclInfo.Cbuf];

                    if (!Cb.Enabled)
                    {
                        continue;
                    }

                    long Key = Vmm.GetPhysicalAddress(Cb.Position);

                    if (Gpu.ResourceManager.MemoryRegionModified(Vmm, Key, Cb.Size, NvGpuBufferType.ConstBuffer))
                    {
                        if (Vmm.TryGetHostAddress(Cb.Position, Cb.Size, out IntPtr CbPtr))
                        {
                            Gpu.Renderer.Buffer.SetData(Key, Cb.Size, CbPtr);
                        }
                        else
                        {
                            Gpu.Renderer.Buffer.SetData(Key, Vmm.ReadBytes(Cb.Position, Cb.Size));
                        }
                    }

                    State.ConstBufferKeys[Stage][DeclInfo.Cbuf] = Key;
                }
            }
        }
Esempio n. 7
0
        private void UploadConstBuffers(NvGpuVmm Vmm, GalPipelineState State, long[] Keys)
        {
            for (int Stage = 0; Stage < Keys.Length; Stage++)
            {
                foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.Shader.GetConstBufferUsage(Keys[Stage]))
                {
                    ConstBuffer Cb = ConstBuffers[Stage][DeclInfo.Cbuf];

                    if (!Cb.Enabled)
                    {
                        continue;
                    }

                    long Key = Vmm.GetPhysicalAddress(Cb.Position);

                    if (QueryKeyUpload(Vmm, Key, Cb.Size, NvGpuBufferType.ConstBuffer))
                    {
                        IntPtr Source = Vmm.GetHostAddress(Cb.Position, Cb.Size);

                        Gpu.Renderer.Buffer.SetData(Key, Cb.Size, Source);
                    }

                    State.ConstBufferKeys[Stage][DeclInfo.Cbuf] = Key;
                }
            }
        }
Esempio n. 8
0
        private void UploadTextures(NvGpuVmm Vmm, GalPipelineState State, long[] Keys)
        {
            long BaseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress);

            int TextureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex);

            int TexIndex = 0;

            for (int Index = 0; Index < Keys.Length; Index++)
            {
                foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.Shader.GetTextureUsage(Keys[Index]))
                {
                    long Position;

                    if (DeclInfo.IsCb)
                    {
                        Position = ConstBuffers[Index][DeclInfo.Cbuf].Position;
                    }
                    else
                    {
                        Position = ConstBuffers[Index][TextureCbIndex].Position;
                    }

                    int TextureHandle = Vmm.ReadInt32(Position + DeclInfo.Index * 4);

                    UploadTexture(Vmm, TexIndex, TextureHandle);

                    TexIndex++;
                }
            }
        }
Esempio n. 9
0
        private void SetScissor(GalPipelineState State)
        {
            // FIXME: Stubbed, only the first scissor test is valid without a geometry shader loaded. At time of writing geometry shaders are also stubbed.
            // Once geometry shaders are fixed it should be equal to GalPipelineState.RenderTargetCount when shader loaded, otherwise equal to 1
            State.ScissorTestCount = 1;

            for (int Index = 0; Index < State.ScissorTestCount; Index++)
            {
                State.ScissorTestEnabled[Index] = ReadRegisterBool(NvGpuEngine3dReg.ScissorEnable + Index * 4);

                if (State.ScissorTestEnabled[Index])
                {
                    uint ScissorHorizontal = (uint)ReadRegister(NvGpuEngine3dReg.ScissorHorizontal + Index * 4);
                    uint ScissorVertical   = (uint)ReadRegister(NvGpuEngine3dReg.ScissorVertical + Index * 4);

                    State.ScissorTestX[Index]     = (int)((ScissorHorizontal & 0xFFFF) * State.FlipX);                          // X, lower 16 bits
                    State.ScissorTestWidth[Index] = (int)((ScissorHorizontal >> 16) * State.FlipX) - State.ScissorTestX[Index]; // Width, right side is upper 16 bits

                    State.ScissorTestY[Index]      = (int)((ScissorVertical & 0xFFFF));                                         // Y, lower 16 bits
                    State.ScissorTestHeight[Index] = (int)((ScissorVertical >> 16)) - State.ScissorTestY[Index];                // Height, top side is upper 16 bits

                    // Y coordinates may have to be flipped
                    if ((int)State.FlipY == -1)
                    {
                        State.ScissorTestY[Index] = ViewportHeight - State.ScissorTestY[Index] - State.ScissorTestHeight[Index];

                        // Handle negative viewpont coordinate
                        if (State.ScissorTestY[Index] < 0)
                        {
                            State.ScissorTestY[Index] = 0;
                        }
                    }
                }
            }
        }
Esempio n. 10
0
        private void DispatchRender(NvGpuVmm Vmm, GalPipelineState State)
        {
            int IndexCount = ReadRegister(NvGpuEngine3dReg.IndexBatchCount);
            int PrimCtrl   = ReadRegister(NvGpuEngine3dReg.VertexBeginGl);

            GalPrimitiveType PrimType = (GalPrimitiveType)(PrimCtrl & 0xffff);

            Gpu.Renderer.Pipeline.Bind(State);

            if (IndexCount != 0)
            {
                int IndexEntryFmt = ReadRegister(NvGpuEngine3dReg.IndexArrayFormat);
                int IndexFirst    = ReadRegister(NvGpuEngine3dReg.IndexBatchFirst);
                int VertexBase    = ReadRegister(NvGpuEngine3dReg.VertexArrayElemBase);

                long IndexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.IndexArrayAddress);

                long IboKey = Vmm.GetPhysicalAddress(IndexPosition);

                Gpu.Renderer.Rasterizer.DrawElements(IboKey, IndexFirst, VertexBase, PrimType);
            }
            else
            {
                int VertexFirst = ReadRegister(NvGpuEngine3dReg.VertexArrayFirst);
                int VertexCount = ReadRegister(NvGpuEngine3dReg.VertexArrayCount);

                Gpu.Renderer.Rasterizer.DrawArrays(VertexFirst, VertexCount, PrimType);
            }

            //Is the GPU really clearing those registers after draw?
            WriteRegister(NvGpuEngine3dReg.IndexBatchFirst, 0);
            WriteRegister(NvGpuEngine3dReg.IndexBatchCount, 0);
        }
Esempio n. 11
0
        private void VertexEndGl(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
        {
            LockCaches();

            GalPipelineState State = new GalPipelineState();

            SetFlip(State);
            SetFrontFace(State);
            SetCullFace(State);
            SetDepth(State);
            SetStencil(State);
            SetAlphaBlending(State);
            SetPrimitiveRestart(State);

            //Enabling multiple framebuffer attachments cause graphics reggresions
            SetFrameBuffer(Vmm, 0);
            SetZeta(Vmm);

            long[] Keys = UploadShaders(Vmm);

            Gpu.Renderer.Shader.BindProgram();

            UploadTextures(Vmm, State, Keys);
            UploadConstBuffers(Vmm, State, Keys);
            UploadVertexArrays(Vmm, State);

            DispatchRender(Vmm, State);

            UnlockCaches();
        }
Esempio n. 12
0
        private void VertexEndGl(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
        {
            LockCaches();

            GalPipelineState State = new GalPipelineState();

            SetFrameBuffer(State);
            SetFrontFace(State);
            SetCullFace(State);
            SetDepth(State);
            SetStencil(State);
            SetAlphaBlending(State);
            SetPrimitiveRestart(State);

            for (int FbIndex = 0; FbIndex < 8; FbIndex++)
            {
                SetFrameBuffer(Vmm, FbIndex);
            }

            SetZeta(Vmm);

            SetRenderTargets();

            long[] Keys = UploadShaders(Vmm);

            Gpu.Renderer.Shader.BindProgram();

            UploadTextures(Vmm, State, Keys);
            UploadConstBuffers(Vmm, State, Keys);
            UploadVertexArrays(Vmm, State);

            DispatchRender(Vmm, State);

            UnlockCaches();
        }
Esempio n. 13
0
        private void SetDepth(GalPipelineState State)
        {
            State.DepthTestEnabled = (ReadRegister(NvGpuEngine3dReg.DepthTestEnable) & 1) != 0;

            if (State.DepthTestEnabled)
            {
                State.DepthFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.DepthTestFunction);
            }
        }
Esempio n. 14
0
        public OGLPipeline(OGLConstBuffer Buffer, OGLRasterizer Rasterizer, OGLShader Shader)
        {
            this.Buffer     = Buffer;
            this.Rasterizer = Rasterizer;
            this.Shader     = Shader;

            //These values match OpenGL's defaults
            Old = new GalPipelineState
            {
                FrontFace = GalFrontFace.CCW,

                CullFaceEnabled = false,
                CullFace        = GalCullFace.Back,

                DepthTestEnabled  = false,
                DepthWriteEnabled = true,
                DepthFunc         = GalComparisonOp.Less,
                DepthRangeNear    = 0,
                DepthRangeFar     = 1,

                StencilTestEnabled = false,

                StencilBackFuncFunc = GalComparisonOp.Always,
                StencilBackFuncRef  = 0,
                StencilBackFuncMask = UInt32.MaxValue,
                StencilBackOpFail   = GalStencilOp.Keep,
                StencilBackOpZFail  = GalStencilOp.Keep,
                StencilBackOpZPass  = GalStencilOp.Keep,
                StencilBackMask     = UInt32.MaxValue,

                StencilFrontFuncFunc = GalComparisonOp.Always,
                StencilFrontFuncRef  = 0,
                StencilFrontFuncMask = UInt32.MaxValue,
                StencilFrontOpFail   = GalStencilOp.Keep,
                StencilFrontOpZFail  = GalStencilOp.Keep,
                StencilFrontOpZPass  = GalStencilOp.Keep,
                StencilFrontMask     = UInt32.MaxValue,

                BlendEnabled       = false,
                BlendSeparateAlpha = false,

                BlendEquationRgb   = 0,
                BlendFuncSrcRgb    = GalBlendFactor.One,
                BlendFuncDstRgb    = GalBlendFactor.Zero,
                BlendEquationAlpha = 0,
                BlendFuncSrcAlpha  = GalBlendFactor.One,
                BlendFuncDstAlpha  = GalBlendFactor.Zero,

                PrimitiveRestartEnabled = false,
                PrimitiveRestartIndex   = 0
            };

            for (int Index = 0; Index < GalPipelineState.RenderTargetsCount; Index++)
            {
                Old.ColorMasks[Index] = ColorMaskRgba.Default;
            }
        }
Esempio n. 15
0
        private void SetPrimitiveRestart(GalPipelineState State)
        {
            State.PrimitiveRestartEnabled = ReadRegisterBool(NvGpuEngine3dReg.PrimRestartEnable);

            if (State.PrimitiveRestartEnabled)
            {
                State.PrimitiveRestartIndex = (uint)ReadRegister(NvGpuEngine3dReg.PrimRestartIndex);
            }
        }
Esempio n. 16
0
        private void SetCullFace(GalPipelineState State)
        {
            State.CullFaceEnabled = ReadRegisterBool(NvGpuEngine3dReg.CullFaceEnable);

            if (State.CullFaceEnabled)
            {
                State.CullFace = (GalCullFace)ReadRegister(NvGpuEngine3dReg.CullFace);
            }
        }
Esempio n. 17
0
        public OglPipeline(
            OglConstBuffer buffer,
            OglRenderTarget renderTarget,
            OglRasterizer rasterizer,
            OglShader shader)
        {
            _buffer       = buffer;
            _renderTarget = renderTarget;
            _rasterizer   = rasterizer;
            _shader       = shader;

            // These values match OpenGL's defaults
            _old = new GalPipelineState
            {
                FrontFace = GalFrontFace.Ccw,

                CullFaceEnabled = false,
                CullFace        = GalCullFace.Back,

                DepthTestEnabled  = false,
                DepthWriteEnabled = true,
                DepthFunc         = GalComparisonOp.Less,
                DepthRangeNear    = 0,
                DepthRangeFar     = 1,

                StencilTestEnabled = false,

                StencilBackFuncFunc = GalComparisonOp.Always,
                StencilBackFuncRef  = 0,
                StencilBackFuncMask = UInt32.MaxValue,
                StencilBackOpFail   = GalStencilOp.Keep,
                StencilBackOpZFail  = GalStencilOp.Keep,
                StencilBackOpZPass  = GalStencilOp.Keep,
                StencilBackMask     = UInt32.MaxValue,

                StencilFrontFuncFunc = GalComparisonOp.Always,
                StencilFrontFuncRef  = 0,
                StencilFrontFuncMask = UInt32.MaxValue,
                StencilFrontOpFail   = GalStencilOp.Keep,
                StencilFrontOpZFail  = GalStencilOp.Keep,
                StencilFrontOpZPass  = GalStencilOp.Keep,
                StencilFrontMask     = UInt32.MaxValue,

                BlendIndependent = false,

                PrimitiveRestartEnabled = false,
                PrimitiveRestartIndex   = 0
            };

            for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++)
            {
                _old.Blends[index] = BlendState.Default;

                _old.ColorMasks[index] = ColorMaskState.Default;
            }
        }
Esempio n. 18
0
        private void DispatchRender(NvGpuVmm Vmm, GalPipelineState State)
        {
            int IndexCount = ReadRegister(NvGpuEngine3dReg.IndexBatchCount);
            int PrimCtrl   = ReadRegister(NvGpuEngine3dReg.VertexBeginGl);

            GalPrimitiveType PrimType = (GalPrimitiveType)(PrimCtrl & 0xffff);

            bool InstanceNext = ((PrimCtrl >> 26) & 1) != 0;
            bool InstanceCont = ((PrimCtrl >> 27) & 1) != 0;

            if (InstanceNext && InstanceCont)
            {
                throw new InvalidOperationException("GPU tried to increase and reset instance count at the same time");
            }

            if (InstanceNext)
            {
                CurrentInstance++;
            }
            else if (!InstanceCont)
            {
                CurrentInstance = 0;
            }

            State.Instance = CurrentInstance;

            Gpu.Renderer.Pipeline.Bind(State);

            Gpu.Renderer.RenderTarget.Bind();

            if (IndexCount != 0)
            {
                int IndexEntryFmt = ReadRegister(NvGpuEngine3dReg.IndexArrayFormat);
                int IndexFirst    = ReadRegister(NvGpuEngine3dReg.IndexBatchFirst);
                int VertexBase    = ReadRegister(NvGpuEngine3dReg.VertexArrayElemBase);

                long IndexPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.IndexArrayAddress);

                long IboKey = Vmm.GetPhysicalAddress(IndexPosition);

                Gpu.Renderer.Rasterizer.DrawElements(IboKey, IndexFirst, VertexBase, PrimType);
            }
            else
            {
                int VertexFirst = ReadRegister(NvGpuEngine3dReg.VertexArrayFirst);
                int VertexCount = ReadRegister(NvGpuEngine3dReg.VertexArrayCount);

                Gpu.Renderer.Rasterizer.DrawArrays(VertexFirst, VertexCount, PrimType);
            }

            //Is the GPU really clearing those registers after draw?
            WriteRegister(NvGpuEngine3dReg.IndexBatchFirst, 0);
            WriteRegister(NvGpuEngine3dReg.IndexBatchCount, 0);
        }
Esempio n. 19
0
        private void SetDepth(GalPipelineState State)
        {
            State.DepthTestEnabled = ReadRegisterBool(NvGpuEngine3dReg.DepthTestEnable);

            State.DepthWriteEnabled = ReadRegisterBool(NvGpuEngine3dReg.DepthWriteEnable);

            if (State.DepthTestEnabled)
            {
                State.DepthFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.DepthTestFunction);
            }
        }
Esempio n. 20
0
        private void SetDepth(GalPipelineState state)
        {
            state.DepthTestEnabled = ReadRegisterBool(NvGpuEngine3dReg.DepthTestEnable);

            state.DepthWriteEnabled = ReadRegisterBool(NvGpuEngine3dReg.DepthWriteEnable);

            if (state.DepthTestEnabled)
            {
                state.DepthFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.DepthTestFunction);
            }

            state.DepthRangeNear = ReadRegisterFloat(NvGpuEngine3dReg.DepthRangeNNear);
            state.DepthRangeFar  = ReadRegisterFloat(NvGpuEngine3dReg.DepthRangeNFar);
        }
Esempio n. 21
0
        private void UploadTextures(NvGpuVmm vmm, GalPipelineState state, long[] keys)
        {
            Profile.Begin(Profiles.GPU.Engine3d.UploadTextures);

            long baseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress);

            int textureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex);

            List <(long, GalImage, GalTextureSampler)> unboundTextures = new List <(long, GalImage, GalTextureSampler)>();

            for (int index = 0; index < keys.Length; index++)
            {
                foreach (TextureDescriptor desc in _gpu.Renderer.Shader.GetTextureUsage(keys[index]))
                {
                    int textureHandle;

                    if (desc.IsBindless)
                    {
                        long position = _constBuffers[index][desc.CbufSlot].Position;

                        textureHandle = vmm.ReadInt32(position + desc.CbufOffset * 4);
                    }
                    else
                    {
                        long position = _constBuffers[index][textureCbIndex].Position;

                        textureHandle = vmm.ReadInt32(position + desc.HandleIndex * 4);
                    }

                    unboundTextures.Add(UploadTexture(vmm, textureHandle));
                }
            }

            for (int index = 0; index < unboundTextures.Count; index++)
            {
                (long key, GalImage image, GalTextureSampler sampler) = unboundTextures[index];

                if (key == 0)
                {
                    continue;
                }

                _gpu.Renderer.Texture.Bind(key, index, image);
                _gpu.Renderer.Texture.SetSampler(image, sampler);
            }

            Profile.End(Profiles.GPU.Engine3d.UploadTextures);
        }
Esempio n. 22
0
        private void SetColorMask(GalPipelineState state)
        {
            bool colorMaskCommon = ReadRegisterBool(NvGpuEngine3dReg.ColorMaskCommon);

            state.ColorMaskCommon = colorMaskCommon;

            for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++)
            {
                int colorMask = ReadRegister(NvGpuEngine3dReg.ColorMaskN + (colorMaskCommon ? 0 : index));

                state.ColorMasks[index].Red   = ((colorMask >> 0) & 0xf) != 0;
                state.ColorMasks[index].Green = ((colorMask >> 4) & 0xf) != 0;
                state.ColorMasks[index].Blue  = ((colorMask >> 8) & 0xf) != 0;
                state.ColorMasks[index].Alpha = ((colorMask >> 12) & 0xf) != 0;
            }
        }
Esempio n. 23
0
        private void SetFrameBuffer(GalPipelineState state)
        {
            state.FramebufferSrgb = ReadRegisterBool(NvGpuEngine3dReg.FrameBufferSrgb);

            state.FlipX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX);
            state.FlipY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY);

            int screenYControl = ReadRegister(NvGpuEngine3dReg.ScreenYControl);

            bool negateY = (screenYControl & 1) != 0;

            if (negateY)
            {
                state.FlipY = -state.FlipY;
            }
        }
Esempio n. 24
0
        private void VertexEndGl(NvGpuVmm vmm, GpuMethodCall methCall)
        {
            Profile.Begin(Profiles.GPU.Engine3d.VertexEnd);

            LockCaches();

            Profile.Begin(Profiles.GPU.Engine3d.ConfigureState);

            GalPipelineState state = new GalPipelineState();

            // Framebuffer must be run configured because viewport dimensions may be used in other methods
            SetFrameBuffer(state);

            Profile.End(Profiles.GPU.Engine3d.ConfigureState);

            for (int fbIndex = 0; fbIndex < 8; fbIndex++)
            {
                SetFrameBuffer(vmm, fbIndex);
            }

            SetFrontFace(state);
            SetCullFace(state);
            SetDepth(state);
            SetStencil(state);
            SetScissor(state);
            SetBlending(state);
            SetColorMask(state);
            SetPrimitiveRestart(state);

            SetZeta(vmm);

            SetRenderTargets();

            long[] keys = UploadShaders(vmm);

            _gpu.Renderer.Shader.BindProgram();

            UploadTextures(vmm, state, keys);
            UploadConstBuffers(vmm, state, keys);
            UploadVertexArrays(vmm, state);

            DispatchRender(vmm, state);

            UnlockCaches();

            Profile.End(Profiles.GPU.Engine3d.VertexEnd);
        }
Esempio n. 25
0
        private void SetAlphaBlending(GalPipelineState State)
        {
            //TODO: Support independent blend properly.
            State.BlendEnabled = ReadRegisterBool(NvGpuEngine3dReg.IBlendNEnable);

            if (State.BlendEnabled)
            {
                State.BlendSeparateAlpha = ReadRegisterBool(NvGpuEngine3dReg.IBlendNSeparateAlpha);

                State.BlendEquationRgb   = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationRgb);
                State.BlendFuncSrcRgb    = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcRgb);
                State.BlendFuncDstRgb    = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstRgb);
                State.BlendEquationAlpha = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationAlpha);
                State.BlendFuncSrcAlpha  = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcAlpha);
                State.BlendFuncDstAlpha  = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstAlpha);
            }
        }
Esempio n. 26
0
        private void SetBlending(GalPipelineState state)
        {
            bool blendIndependent = ReadRegisterBool(NvGpuEngine3dReg.BlendIndependent);

            state.BlendIndependent = blendIndependent;

            for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++)
            {
                if (blendIndependent)
                {
                    state.Blends[index].Enabled = ReadRegisterBool(NvGpuEngine3dReg.IBlendNEnable + index);

                    if (state.Blends[index].Enabled)
                    {
                        state.Blends[index].SeparateAlpha = ReadRegisterBool(NvGpuEngine3dReg.IBlendNSeparateAlpha + index * 8);

                        state.Blends[index].EquationRgb   = ReadBlendEquation(NvGpuEngine3dReg.IBlendNEquationRgb + index * 8);
                        state.Blends[index].FuncSrcRgb    = ReadBlendFactor(NvGpuEngine3dReg.IBlendNFuncSrcRgb + index * 8);
                        state.Blends[index].FuncDstRgb    = ReadBlendFactor(NvGpuEngine3dReg.IBlendNFuncDstRgb + index * 8);
                        state.Blends[index].EquationAlpha = ReadBlendEquation(NvGpuEngine3dReg.IBlendNEquationAlpha + index * 8);
                        state.Blends[index].FuncSrcAlpha  = ReadBlendFactor(NvGpuEngine3dReg.IBlendNFuncSrcAlpha + index * 8);
                        state.Blends[index].FuncDstAlpha  = ReadBlendFactor(NvGpuEngine3dReg.IBlendNFuncDstAlpha + index * 8);
                    }
                }
                else
                {
                    // It seems that even when independent blend is disabled, the first IBlend enable
                    // register is still set to indicate whenever blend is enabled or not (?).
                    state.Blends[index].Enabled = ReadRegisterBool(NvGpuEngine3dReg.IBlendNEnable);

                    if (state.Blends[index].Enabled)
                    {
                        state.Blends[index].SeparateAlpha = ReadRegisterBool(NvGpuEngine3dReg.BlendSeparateAlpha);

                        state.Blends[index].EquationRgb   = ReadBlendEquation(NvGpuEngine3dReg.BlendEquationRgb);
                        state.Blends[index].FuncSrcRgb    = ReadBlendFactor(NvGpuEngine3dReg.BlendFuncSrcRgb);
                        state.Blends[index].FuncDstRgb    = ReadBlendFactor(NvGpuEngine3dReg.BlendFuncDstRgb);
                        state.Blends[index].EquationAlpha = ReadBlendEquation(NvGpuEngine3dReg.BlendEquationAlpha);
                        state.Blends[index].FuncSrcAlpha  = ReadBlendFactor(NvGpuEngine3dReg.BlendFuncSrcAlpha);
                        state.Blends[index].FuncDstAlpha  = ReadBlendFactor(NvGpuEngine3dReg.BlendFuncDstAlpha);
                    }
                }
            }
        }
Esempio n. 27
0
        private void UploadTextures(NvGpuVmm vmm, GalPipelineState state, long[] keys)
        {
            long baseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress);

            int textureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex);

            List <(long, GalImage, GalTextureSampler)> unboundTextures = new List <(long, GalImage, GalTextureSampler)>();

            for (int index = 0; index < keys.Length; index++)
            {
                foreach (ShaderDeclInfo declInfo in _gpu.Renderer.Shader.GetTextureUsage(keys[index]))
                {
                    long position;

                    if (declInfo.IsCb)
                    {
                        position = _constBuffers[index][declInfo.Cbuf].Position;
                    }
                    else
                    {
                        position = _constBuffers[index][textureCbIndex].Position;
                    }

                    int textureHandle = vmm.ReadInt32(position + declInfo.Index * 4);

                    unboundTextures.Add(UploadTexture(vmm, textureHandle));
                }
            }

            for (int index = 0; index < unboundTextures.Count; index++)
            {
                (long key, GalImage image, GalTextureSampler sampler) = unboundTextures[index];

                if (key == 0)
                {
                    continue;
                }

                _gpu.Renderer.Texture.Bind(key, index, image);
                _gpu.Renderer.Texture.SetSampler(image, sampler);
            }
        }
Esempio n. 28
0
        private void UploadTextures(NvGpuVmm Vmm, GalPipelineState State, long[] Keys)
        {
            long BaseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress);

            int TextureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex);

            List <(long, GalImage, GalTextureSampler)> UnboundTextures = new List <(long, GalImage, GalTextureSampler)>();

            for (int Index = 0; Index < Keys.Length; Index++)
            {
                foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.Shader.GetTextureUsage(Keys[Index]))
                {
                    long Position;

                    if (DeclInfo.IsCb)
                    {
                        Position = ConstBuffers[Index][DeclInfo.Cbuf].Position;
                    }
                    else
                    {
                        Position = ConstBuffers[Index][TextureCbIndex].Position;
                    }

                    int TextureHandle = Vmm.ReadInt32(Position + DeclInfo.Index * 4);

                    UnboundTextures.Add(UploadTexture(Vmm, TextureHandle));
                }
            }

            for (int Index = 0; Index < UnboundTextures.Count; Index++)
            {
                (long Key, GalImage Image, GalTextureSampler Sampler) = UnboundTextures[Index];

                if (Key == 0)
                {
                    continue;
                }

                Gpu.Renderer.Texture.Bind(Key, Index, Image);
                Gpu.Renderer.Texture.SetSampler(Sampler);
            }
        }
Esempio n. 29
0
        private void SetFrontFace(GalPipelineState state)
        {
            float signX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX);
            float signY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY);

            GalFrontFace frontFace = (GalFrontFace)ReadRegister(NvGpuEngine3dReg.FrontFace);

            // Flipping breaks facing. Flipping front facing too fixes it
            if (signX != signY)
            {
                switch (frontFace)
                {
                case GalFrontFace.Cw:  frontFace = GalFrontFace.Ccw; break;

                case GalFrontFace.Ccw: frontFace = GalFrontFace.Cw;  break;
                }
            }

            state.FrontFace = frontFace;
        }
Esempio n. 30
0
        private void SetFrontFace(GalPipelineState State)
        {
            float SignX = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleX);
            float SignY = GetFlipSign(NvGpuEngine3dReg.ViewportNScaleY);

            GalFrontFace FrontFace = (GalFrontFace)ReadRegister(NvGpuEngine3dReg.FrontFace);

            //Flipping breaks facing. Flipping front facing too fixes it
            if (SignX != SignY)
            {
                switch (FrontFace)
                {
                case GalFrontFace.CW:  FrontFace = GalFrontFace.CCW; break;

                case GalFrontFace.CCW: FrontFace = GalFrontFace.CW;  break;
                }
            }

            State.FrontFace = FrontFace;
        }