Exemplo n.º 1
0
        /// <summary>
        /// Performs a indirect multi-draw, with parameters from a GPU buffer.
        /// </summary>
        /// <param name="engine">3D engine where this method is being called</param>
        /// <param name="topology">Primitive topology</param>
        /// <param name="indirectBuffer">GPU buffer with the draw parameters, such as count, first index, etc</param>
        /// <param name="parameterBuffer">GPU buffer with the draw count</param>
        /// <param name="maxDrawCount">Maximum number of draws that can be made</param>
        /// <param name="stride">Distance in bytes between each element on the <paramref name="indirectBuffer"/> array</param>
        public void MultiDrawIndirectCount(
            ThreedClass engine,
            int indexCount,
            PrimitiveTopology topology,
            BufferRange indirectBuffer,
            BufferRange parameterBuffer,
            int maxDrawCount,
            int stride)
        {
            engine.Write(IndexBufferCountMethodOffset * 4, indexCount);

            _context.Renderer.Pipeline.SetPrimitiveTopology(topology);
            _drawState.Topology = topology;

            ConditionalRenderEnabled renderEnable = ConditionalRendering.GetRenderEnable(
                _context,
                _channel.MemoryManager,
                _state.State.RenderEnableAddress,
                _state.State.RenderEnableCondition);

            if (renderEnable == ConditionalRenderEnabled.False)
            {
                _drawState.DrawIndexed = false;
                return;
            }

            _drawState.FirstIndex = _state.State.IndexBufferState.First;
            _drawState.IndexCount = indexCount;

            engine.UpdateState();

            if (_drawState.DrawIndexed)
            {
                _context.Renderer.Pipeline.MultiDrawIndexedIndirectCount(indirectBuffer, parameterBuffer, maxDrawCount, stride);
            }
            else
            {
                _context.Renderer.Pipeline.MultiDrawIndirectCount(indirectBuffer, parameterBuffer, maxDrawCount, stride);
            }

            _drawState.DrawIndexed = false;

            if (renderEnable == ConditionalRenderEnabled.Host)
            {
                _context.Renderer.Pipeline.EndHostConditionalRendering();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Performs a indirect multi-draw, with parameters from a GPU buffer.
        /// </summary>
        /// <param name="state">Current GPU state</param>
        /// <param name="topology">Primitive topology</param>
        /// <param name="indirectBuffer">GPU buffer with the draw parameters, such as count, first index, etc</param>
        /// <param name="parameterBuffer">GPU buffer with the draw count</param>
        /// <param name="maxDrawCount">Maximum number of draws that can be made</param>
        /// <param name="stride">Distance in bytes between each element on the <paramref name="indirectBuffer"/> array</param>
        public void MultiDrawIndirectCount(
            GpuState state,
            PrimitiveTopology topology,
            BufferRange indirectBuffer,
            BufferRange parameterBuffer,
            int maxDrawCount,
            int stride)
        {
            _context.Renderer.Pipeline.SetPrimitiveTopology(topology);
            Topology = topology;

            ConditionalRenderEnabled renderEnable = GetRenderEnable(state);

            if (renderEnable == ConditionalRenderEnabled.False)
            {
                _drawIndexed = false;
                return;
            }

            var indexBuffer = state.Get <IndexBufferState>(MethodOffset.IndexBufferState);

            FlushUboDirty();

            UpdateState(state, indexBuffer.First, indexBuffer.Count);

            if (_drawIndexed)
            {
                _context.Renderer.Pipeline.MultiDrawIndexedIndirectCount(indirectBuffer, parameterBuffer, maxDrawCount, stride);
            }
            else
            {
                _context.Renderer.Pipeline.MultiDrawIndirectCount(indirectBuffer, parameterBuffer, maxDrawCount, stride);
            }

            _drawIndexed = false;

            if (renderEnable == ConditionalRenderEnabled.Host)
            {
                _context.Renderer.Pipeline.EndHostConditionalRendering();
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Finishes the draw call.
        /// This draws geometry on the bound buffers based on the current GPU state.
        /// </summary>
        /// <param name="engine">3D engine where this method is being called</param>
        /// <param name="firstIndex">Index of the first index buffer element used on the draw</param>
        /// <param name="indexCount">Number of index buffer elements used on the draw</param>
        private void DrawEnd(ThreedClass engine, int firstIndex, int indexCount)
        {
            ConditionalRenderEnabled renderEnable = ConditionalRendering.GetRenderEnable(
                _context,
                _channel.MemoryManager,
                _state.State.RenderEnableAddress,
                _state.State.RenderEnableCondition);

            if (renderEnable == ConditionalRenderEnabled.False || _instancedDrawPending)
            {
                if (renderEnable == ConditionalRenderEnabled.False)
                {
                    PerformDeferredDraws();
                }

                _drawState.DrawIndexed = false;

                if (renderEnable == ConditionalRenderEnabled.Host)
                {
                    _context.Renderer.Pipeline.EndHostConditionalRendering();
                }

                return;
            }

            _drawState.FirstIndex = firstIndex;
            _drawState.IndexCount = indexCount;

            engine.UpdateState();

            bool instanced = _drawState.VsUsesInstanceId || _drawState.IsAnyVbInstanced;

            if (instanced)
            {
                _instancedDrawPending = true;

                _instancedIndexed = _drawState.DrawIndexed;

                _instancedFirstIndex    = firstIndex;
                _instancedFirstVertex   = (int)_state.State.FirstVertex;
                _instancedFirstInstance = (int)_state.State.FirstInstance;

                _instancedIndexCount = indexCount;

                var drawState = _state.State.VertexBufferDrawState;

                _instancedDrawStateFirst = drawState.First;
                _instancedDrawStateCount = drawState.Count;

                _drawState.DrawIndexed = false;

                if (renderEnable == ConditionalRenderEnabled.Host)
                {
                    _context.Renderer.Pipeline.EndHostConditionalRendering();
                }

                return;
            }

            int firstInstance = (int)_state.State.FirstInstance;

            int inlineIndexCount = _drawState.IbStreamer.GetAndResetInlineIndexCount();

            if (inlineIndexCount != 0)
            {
                int firstVertex = (int)_state.State.FirstVertex;

                BufferRange br = new BufferRange(_drawState.IbStreamer.GetInlineIndexBuffer(), 0, inlineIndexCount * 4);

                _channel.BufferManager.SetIndexBuffer(br, IndexType.UInt);

                _context.Renderer.Pipeline.DrawIndexed(inlineIndexCount, 1, firstIndex, firstVertex, firstInstance);
            }
            else if (_drawState.DrawIndexed)
            {
                int firstVertex = (int)_state.State.FirstVertex;

                _context.Renderer.Pipeline.DrawIndexed(indexCount, 1, firstIndex, firstVertex, firstInstance);
            }
            else
            {
                var drawState = _state.State.VertexBufferDrawState;

                _context.Renderer.Pipeline.Draw(drawState.Count, 1, drawState.First, firstInstance);
            }

            _drawState.DrawIndexed = false;

            if (renderEnable == ConditionalRenderEnabled.Host)
            {
                _context.Renderer.Pipeline.EndHostConditionalRendering();
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Finishes the draw call.
        /// This draws geometry on the bound buffers based on the current GPU state.
        /// </summary>
        /// <param name="state">Current GPU state</param>
        /// <param name="firstIndex">Index of the first index buffer element used on the draw</param>
        /// <param name="indexCount">Number of index buffer elements used on the draw</param>
        private void DrawEnd(GpuState state, int firstIndex, int indexCount)
        {
            ConditionalRenderEnabled renderEnable = GetRenderEnable(state);

            if (renderEnable == ConditionalRenderEnabled.False || _instancedDrawPending)
            {
                if (renderEnable == ConditionalRenderEnabled.False)
                {
                    PerformDeferredDraws();
                }

                _drawIndexed = false;

                if (renderEnable == ConditionalRenderEnabled.Host)
                {
                    _context.Renderer.Pipeline.EndHostConditionalRendering();
                }

                return;
            }

            FlushUboDirty();

            UpdateState(state, firstIndex, indexCount);

            bool instanced = _vsUsesInstanceId || _isAnyVbInstanced;

            if (instanced)
            {
                _instancedDrawPending = true;

                _instancedIndexed = _drawIndexed;

                _instancedFirstIndex    = firstIndex;
                _instancedFirstVertex   = state.Get <int>(MethodOffset.FirstVertex);
                _instancedFirstInstance = state.Get <int>(MethodOffset.FirstInstance);

                _instancedIndexCount = indexCount;

                var drawState = state.Get <VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);

                _instancedDrawStateFirst = drawState.First;
                _instancedDrawStateCount = drawState.Count;

                _drawIndexed = false;

                if (renderEnable == ConditionalRenderEnabled.Host)
                {
                    _context.Renderer.Pipeline.EndHostConditionalRendering();
                }

                return;
            }

            int firstInstance = state.Get <int>(MethodOffset.FirstInstance);

            int inlineIndexCount = _ibStreamer.GetAndResetInlineIndexCount();

            if (inlineIndexCount != 0)
            {
                int firstVertex = state.Get <int>(MethodOffset.FirstVertex);

                BufferRange br = new BufferRange(_ibStreamer.GetInlineIndexBuffer(), 0, inlineIndexCount * 4);

                _context.Methods.BufferManager.SetIndexBuffer(br, IndexType.UInt);

                _context.Renderer.Pipeline.DrawIndexed(
                    inlineIndexCount,
                    1,
                    firstIndex,
                    firstVertex,
                    firstInstance);
            }
            else if (_drawIndexed)
            {
                int firstVertex = state.Get <int>(MethodOffset.FirstVertex);

                _context.Renderer.Pipeline.DrawIndexed(
                    indexCount,
                    1,
                    firstIndex,
                    firstVertex,
                    firstInstance);
            }
            else
            {
                var drawState = state.Get <VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);

                _context.Renderer.Pipeline.Draw(
                    drawState.Count,
                    1,
                    drawState.First,
                    firstInstance);
            }

            _drawIndexed = false;

            if (renderEnable == ConditionalRenderEnabled.Host)
            {
                _context.Renderer.Pipeline.EndHostConditionalRendering();
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Clears the current color and depth-stencil buffers.
        /// Which buffers should be cleared is also specified on the argument.
        /// </summary>
        /// <param name="engine">3D engine where this method is being called</param>
        /// <param name="argument">Method call argument</param>
        public void Clear(ThreedClass engine, int argument)
        {
            ConditionalRenderEnabled renderEnable = ConditionalRendering.GetRenderEnable(
                _context,
                _channel.MemoryManager,
                _state.State.RenderEnableAddress,
                _state.State.RenderEnableCondition);

            if (renderEnable == ConditionalRenderEnabled.False)
            {
                return;
            }

            // Scissor and rasterizer discard also affect clears.
            engine.UpdateState((1UL << StateUpdater.RasterizerStateIndex) | (1UL << StateUpdater.ScissorStateIndex));

            int index = (argument >> 6) & 0xf;

            engine.UpdateRenderTargetState(useControl: false, singleUse: index);

            _channel.TextureManager.UpdateRenderTargets();

            bool clearDepth   = (argument & 1) != 0;
            bool clearStencil = (argument & 2) != 0;

            uint componentMask = (uint)((argument >> 2) & 0xf);

            if (componentMask != 0)
            {
                var clearColor = _state.State.ClearColors;

                ColorF color = new ColorF(clearColor.Red, clearColor.Green, clearColor.Blue, clearColor.Alpha);

                _context.Renderer.Pipeline.ClearRenderTargetColor(index, componentMask, color);
            }

            if (clearDepth || clearStencil)
            {
                float depthValue   = _state.State.ClearDepthValue;
                int   stencilValue = (int)_state.State.ClearStencilValue;

                int stencilMask = 0;

                if (clearStencil)
                {
                    stencilMask = _state.State.StencilTestState.FrontMask;
                }

                _context.Renderer.Pipeline.ClearRenderTargetDepthStencil(
                    depthValue,
                    clearDepth,
                    stencilValue,
                    stencilMask);
            }

            engine.UpdateRenderTargetState(useControl: true);

            if (renderEnable == ConditionalRenderEnabled.Host)
            {
                _context.Renderer.Pipeline.EndHostConditionalRendering();
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Clears the current color and depth-stencil buffers.
        /// Which buffers should be cleared is also specified on the argument.
        /// </summary>
        /// <param name="state">Current GPU state</param>
        /// <param name="argument">Method call argument</param>
        private void Clear(GpuState state, int argument)
        {
            ConditionalRenderEnabled renderEnable = GetRenderEnable(state);

            if (renderEnable == ConditionalRenderEnabled.False)
            {
                return;
            }

            // Scissor and rasterizer discard also affect clears.
            if (state.QueryModified(MethodOffset.ScissorState))
            {
                UpdateScissorState(state);
            }

            if (state.QueryModified(MethodOffset.RasterizeEnable))
            {
                UpdateRasterizerState(state);
            }

            int index = (argument >> 6) & 0xf;

            UpdateRenderTargetState(state, useControl: false, singleUse: index);

            state.Channel.TextureManager.UpdateRenderTargets();

            bool clearDepth   = (argument & 1) != 0;
            bool clearStencil = (argument & 2) != 0;

            uint componentMask = (uint)((argument >> 2) & 0xf);

            if (componentMask != 0)
            {
                var clearColor = state.Get <ClearColors>(MethodOffset.ClearColors);

                ColorF color = new ColorF(
                    clearColor.Red,
                    clearColor.Green,
                    clearColor.Blue,
                    clearColor.Alpha);

                _context.Renderer.Pipeline.ClearRenderTargetColor(index, componentMask, color);
            }

            if (clearDepth || clearStencil)
            {
                float depthValue   = state.Get <float>(MethodOffset.ClearDepthValue);
                int   stencilValue = state.Get <int>  (MethodOffset.ClearStencilValue);

                int stencilMask = 0;

                if (clearStencil)
                {
                    stencilMask = state.Get <StencilTestState>(MethodOffset.StencilTestState).FrontMask;
                }

                _context.Renderer.Pipeline.ClearRenderTargetDepthStencil(
                    depthValue,
                    clearDepth,
                    stencilValue,
                    stencilMask);
            }

            UpdateRenderTargetState(state, useControl: true);

            if (renderEnable == ConditionalRenderEnabled.Host)
            {
                _context.Renderer.Pipeline.EndHostConditionalRendering();
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Finishes draw call.
        /// This draws geometry on the bound buffers based on the current GPU state.
        /// </summary>
        /// <param name="state">Current GPU state</param>
        /// <param name="argument">Method call argument</param>
        private void DrawEnd(GpuState state, int argument)
        {
            ConditionalRenderEnabled renderEnable = GetRenderEnable(state);

            if (renderEnable == ConditionalRenderEnabled.False || _instancedDrawPending)
            {
                if (renderEnable == ConditionalRenderEnabled.False)
                {
                    PerformDeferredDraws();
                }

                _drawIndexed = false;

                if (renderEnable == ConditionalRenderEnabled.Host)
                {
                    _context.Renderer.Pipeline.EndHostConditionalRendering();
                }

                return;
            }

            UpdateState(state);

            bool instanced = _vsUsesInstanceId || _isAnyVbInstanced;

            if (instanced)
            {
                _instancedDrawPending = true;

                _instancedIndexed = _drawIndexed;

                _instancedFirstIndex    = _firstIndex;
                _instancedFirstVertex   = state.Get <int>(MethodOffset.FirstVertex);
                _instancedFirstInstance = state.Get <int>(MethodOffset.FirstInstance);

                _instancedIndexCount = _indexCount;

                var drawState = state.Get <VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);

                _instancedDrawStateFirst = drawState.First;
                _instancedDrawStateCount = drawState.Count;

                _drawIndexed = false;

                if (renderEnable == ConditionalRenderEnabled.Host)
                {
                    _context.Renderer.Pipeline.EndHostConditionalRendering();
                }

                return;
            }

            int firstInstance = state.Get <int>(MethodOffset.FirstInstance);

            if (_drawIndexed)
            {
                _drawIndexed = false;

                int firstVertex = state.Get <int>(MethodOffset.FirstVertex);

                _context.Renderer.Pipeline.DrawIndexed(
                    _indexCount,
                    1,
                    _firstIndex,
                    firstVertex,
                    firstInstance);
            }
            else
            {
                var drawState = state.Get <VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);

                _context.Renderer.Pipeline.Draw(
                    drawState.Count,
                    1,
                    drawState.First,
                    firstInstance);
            }

            if (renderEnable == ConditionalRenderEnabled.Host)
            {
                _context.Renderer.Pipeline.EndHostConditionalRendering();
            }
        }