Example #1
0
        /// <summary>
        /// Function to return the dispatch call.
        /// </summary>
        /// <param name="allocator">The allocator used to create an instance of the object</param>
        /// <returns>The dispatch call created or updated by this builder.</returns>
        /// <exception cref="GorgonException">Thrown if a <see cref="GorgonComputeShader"/> is not assigned to the <see cref="GorgonComputeShader"/> property with the <see cref="ComputeShader"/> command.</exception>
        /// <remarks>
        /// <para>
        /// Using an <paramref name="allocator"/> can provide different strategies when building dispatch calls.  If omitted, the dispatch call will be created using the standard <see langword="new"/> keyword.
        /// </para>
        /// <para>
        /// A custom allocator can be beneficial because it allows us to use a pool for allocating the objects, and thus allows for recycling of objects. This keeps the garbage collector happy by keeping objects
        /// around for as long as we need them, instead of creating objects that can potentially end up in the large object heap or in Gen 2.
        /// </para>
        /// <para>
        /// A dispatch call requires that at least a vertex shader be bound. If none is present, then the method will throw an exception.
        /// </para>
        /// </remarks>
        public GorgonDispatchCall Build(IGorgonAllocator <GorgonDispatchCall> allocator)
        {
            var final = new GorgonDispatchCall();

            final.Setup();

            // Copy over the available constants.
            StateCopy.CopyConstantBuffers(final.D3DState.CsConstantBuffers, _worker.D3DState.CsConstantBuffers, 0);

            // Copy over samplers.
            StateCopy.CopySamplers(final.D3DState.CsSamplers, _worker.D3DState.CsSamplers, 0);

            // Copy over shader resource views.
            (int _, int _) = _worker.D3DState.CsSrvs.GetDirtyItems();

            StateCopy.CopySrvs(final.D3DState.CsSrvs, _worker.D3DState.CsSrvs);

            // Copy over unordered access views.
            StateCopy.CopyReadWriteViews(final.D3DState.CsReadWriteViews, _worker.D3DState.CsReadWriteViews, 0);

            if (_worker.D3DState.ComputeShader == null)
            {
                throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_ERR_NO_COMPUTE_SHADER);
            }

            final.D3DState.ComputeShader = _worker.D3DState.ComputeShader;

            return(final);
        }
        /// <summary>
        /// Function to build a pipeline state.
        /// </summary>
        /// <param name="allocator">The allocator used to create an instance of the object</param>
        /// <returns>The object created or updated by this builder.</returns>
        /// <remarks>
        ///   <para>
        /// Using an <paramref name="allocator" /> can provide different strategies when building objects.  If omitted, the object will be created using the standard <span class="keyword">new</span> keyword.
        /// </para>
        ///   <para>
        /// A custom allocator can be beneficial because it allows us to use a pool for allocating the objects, and thus allows for recycling of objects. This keeps the garbage collector happy by keeping objects
        /// around for as long as we need them, instead of creating objects that can potentially end up in the large object heap or in Gen 2.
        /// </para>
        /// </remarks>
        public GorgonStreamOutPipelineState Build(IGorgonAllocator <GorgonStreamOutPipelineState> allocator)
        {
            if (allocator == null)
            {
                return(new GorgonStreamOutPipelineState(Graphics.CachePipelineState(_workState.PipelineState)));
            }

            // Caches the state info.
            void CacheState(GorgonStreamOutPipelineState state) => Graphics.CachePipelineState(state.PipelineState);

            return(allocator.Allocate(CacheState));
        }
        /// <summary>Function to return the object.</summary>
        /// <param name="allocator">The allocator used to create an instance of the object</param>
        /// <returns>The object created or updated by this builder.</returns>
        /// <remarks>
        ///   <para>
        /// Using an <paramref name="allocator" /> can provide different strategies when building objects.  If omitted, the object will be created using the standard <span class="keyword">new</span> keyword.
        /// </para>
        ///   <para>
        /// A custom allocator can be beneficial because it allows us to use a pool for allocating the objects, and thus allows for recycling of objects. This keeps the garbage collector happy by keeping objects
        /// around for as long as we need them, instead of creating objects that can potentially end up in the large object heap or in Gen 2.
        /// </para>
        /// </remarks>
        public TRs Build(IGorgonAllocator <TRs> allocator)
        {
            if (allocator == null)
            {
                return(OnCreateState());
            }

            TRs state = allocator.Allocate();

            OnUpdate(state);

            return(state);
        }
        /// <summary>Function to return the object.</summary>
        /// <param name="allocator">The allocator used to create an instance of the object</param>
        /// <returns>The object created or updated by this builder.</returns>
        /// <remarks>
        ///   <para>
        /// Using an <paramref name="allocator" /> can provide different strategies when building objects.  If omitted, the object will be created using the standard <span class="keyword">new</span> keyword.
        /// </para>
        ///   <para>
        /// A custom allocator can be beneficial because it allows us to use a pool for allocating the objects, and thus allows for recycling of objects. This keeps the garbage collector happy by keeping objects
        /// around for as long as we need them, instead of creating objects that can potentially end up in the large object heap or in Gen 2.
        /// </para>
        /// </remarks>
        public Gorgon2DBatchState Build(IGorgonAllocator <Gorgon2DBatchState> allocator)
        {
            if (allocator == null)
            {
                return(Build());
            }

            Gorgon2DBatchState state = allocator.Allocate();

            state.PixelShaderState  = _worker.PixelShaderState;
            state.VertexShaderState = _worker.VertexShaderState;
            state.BlendState        = _worker.BlendState;
            state.DepthStencilState = _worker.DepthStencilState;
            state.RasterState       = _worker.RasterState;

            return(state);
        }
Example #5
0
        /// <summary>
        /// Function to return the object.
        /// </summary>
        /// <param name="allocator">The allocator used to create an instance of the object</param>
        /// <returns>The object created or updated by this builder.</returns>
        /// <remarks>
        ///   <para>
        /// Using an <paramref name="allocator" /> can provide different strategies when building objects.  If omitted, the object will be created using the standard <span class="keyword">new</span> keyword.
        /// </para>
        ///   <para>
        /// A custom allocator can be beneficial because it allows us to use a pool for allocating the objects, and thus allows for recycling of objects. This keeps the garbage collector happy by keeping objects
        /// around for as long as we need them, instead of creating objects that can potentially end up in the large object heap or in Gen 2.
        /// </para>
        /// </remarks>
        public Gorgon2DShaderState <T> Build(IGorgonAllocator <Gorgon2DShaderState <T> > allocator)
        {
            Gorgon2DShaderState <T> shader;

            if (allocator == null)
            {
                shader = new Gorgon2DShaderState <T>();
            }
            else
            {
                shader = allocator.Allocate();
            }

            Copy(shader.RwConstantBuffers, _workingShader.RwConstantBuffers, 0);
            Copy(shader.RwSrvs, _workingShader.RwSrvs, 0);
            Copy(shader.RwSamplers, _workingShader.RwSamplers, 0);
            shader.Shader = _workingShader.Shader;
            return(shader);
        }
Example #6
0
 /// <summary>
 /// Function to create a new draw call.
 /// </summary>
 /// <param name="allocator">The allocator to use when creating draw call objects.</param>
 /// <returns>A new draw call.</returns>
 protected override GorgonDrawCall OnCreate(IGorgonAllocator <GorgonDrawCall> allocator) => allocator == null ? new GorgonDrawCall() : allocator.Allocate();
Example #7
0
 /// <summary>
 /// Function to create a new draw call.
 /// </summary>
 /// <param name="allocator">The allocator to use when creating draw call objects.</param>
 /// <returns>A new draw call.</returns>
 protected override GorgonInstancedIndexCall OnCreate(IGorgonAllocator <GorgonInstancedIndexCall> allocator) => allocator == null ? new GorgonInstancedIndexCall() : allocator.Allocate();
Example #8
0
 /// <summary>
 /// Function to create a new draw call.
 /// </summary>
 /// <param name="allocator">The allocator to use when creating draw call objects.</param>
 /// <returns>A new draw call.</returns>
 protected abstract TDc OnCreate(IGorgonAllocator <TDc> allocator);
Example #9
0
        /// <summary>
        /// Function to return the draw call.
        /// </summary>
        /// <param name="allocator">The allocator used to create an instance of the object</param>
        /// <returns>The draw call created or updated by this builder.</returns>
        /// <exception cref="GorgonException">Thrown if a <see cref="GorgonVertexShader"/> is not assigned to the <see cref="GorgonPipelineState.VertexShader"/> property with the <see cref="PipelineState(GorgonPipelineStateBuilder)"/> command.</exception>
        /// <remarks>
        /// <para>
        /// Using an <paramref name="allocator"/> can provide different strategies when building draw calls.  If omitted, the draw call will be created using the standard <see langword="new"/> keyword.
        /// </para>
        /// <para>
        /// A custom allocator can be beneficial because it allows us to use a pool for allocating the objects, and thus allows for recycling of objects. This keeps the garbage collector happy by keeping objects
        /// around for as long as we need them, instead of creating objects that can potentially end up in the large object heap or in Gen 2.
        /// </para>
        /// <para>
        /// A draw call requires that at least a vertex shader be bound. If none is present, then the method will throw an exception.
        /// </para>
        /// </remarks>
        public TDc Build(IGorgonAllocator <TDc> allocator)
        {
            TDc final = OnCreate(allocator);

            if ((allocator == null) ||
                (final.VertexShader.ConstantBuffers == null) ||
                (final.PixelShader.Samplers == null) ||
                (final.PixelShader.ShaderResources == null))
            {
                final.SetupConstantBuffers();
                final.SetupSamplers();
                final.SetupViews();
            }

            if (final.D3DState.VertexBuffers == null)
            {
                final.D3DState.VertexBuffers = new GorgonVertexBufferBindings();
            }

            if (final.D3DState.StreamOutBindings == null)
            {
                final.D3DState.StreamOutBindings = new GorgonStreamOutBindings();
            }

            StateCopy.CopyVertexBuffers(final.D3DState.VertexBuffers, DrawCall.VertexBufferBindings, DrawCall.InputLayout);
            StateCopy.CopyStreamOutBuffers(final.D3DState.StreamOutBindings, DrawCall.StreamOutBufferBindings);

            // Copy over the shader resources.
            if (DrawCall.D3DState.PipelineState?.PixelShader != null)
            {
                StateCopy.CopyConstantBuffers(final.D3DState.PsConstantBuffers, DrawCall.D3DState.PsConstantBuffers, 0);
                StateCopy.CopySamplers(final.D3DState.PsSamplers, DrawCall.D3DState.PsSamplers, 0);
                StateCopy.CopySrvs(final.D3DState.PsSrvs, DrawCall.D3DState.PsSrvs);
            }
            else
            {
                final.D3DState.PsConstantBuffers.Clear();
                final.D3DState.PsSamplers.Clear();
                final.D3DState.PsSrvs.Clear();
            }

            if (DrawCall.D3DState.PipelineState?.VertexShader != null)
            {
                StateCopy.CopyConstantBuffers(final.D3DState.VsConstantBuffers, DrawCall.D3DState.VsConstantBuffers, 0);
                StateCopy.CopySamplers(final.D3DState.VsSamplers, DrawCall.D3DState.VsSamplers, 0);
                StateCopy.CopySrvs(final.D3DState.VsSrvs, DrawCall.D3DState.VsSrvs);
            }
            else
            {
                final.D3DState.VsConstantBuffers.Clear();
                final.D3DState.VsSamplers.Clear();
                final.D3DState.VsSrvs.Clear();
            }

            if (DrawCall.D3DState.PipelineState?.GeometryShader != null)
            {
                StateCopy.CopyConstantBuffers(final.D3DState.GsConstantBuffers, DrawCall.D3DState.GsConstantBuffers, 0);
                StateCopy.CopySamplers(final.D3DState.GsSamplers, DrawCall.D3DState.GsSamplers, 0);
                StateCopy.CopySrvs(final.D3DState.GsSrvs, DrawCall.D3DState.GsSrvs);
            }
            else
            {
                final.D3DState.GsConstantBuffers.Clear();
                final.D3DState.GsSamplers.Clear();
                final.D3DState.GsSrvs.Clear();
            }

            if (DrawCall.D3DState.PipelineState?.DomainShader != null)
            {
                StateCopy.CopyConstantBuffers(final.D3DState.DsConstantBuffers, DrawCall.D3DState.DsConstantBuffers, 0);
                StateCopy.CopySamplers(final.D3DState.DsSamplers, DrawCall.D3DState.DsSamplers, 0);
                StateCopy.CopySrvs(final.D3DState.DsSrvs, DrawCall.D3DState.DsSrvs);
            }
            else
            {
                final.D3DState.DsConstantBuffers.Clear();
                final.D3DState.DsSamplers.Clear();
                final.D3DState.DsSrvs.Clear();
            }

            if (DrawCall.D3DState.PipelineState?.HullShader != null)
            {
                StateCopy.CopyConstantBuffers(final.D3DState.HsConstantBuffers, DrawCall.D3DState.HsConstantBuffers, 0);
                StateCopy.CopySamplers(final.D3DState.HsSamplers, DrawCall.D3DState.HsSamplers, 0);
                StateCopy.CopySrvs(final.D3DState.HsSrvs, DrawCall.D3DState.HsSrvs);
            }
            else
            {
                final.D3DState.HsConstantBuffers.Clear();
                final.D3DState.HsSamplers.Clear();
                final.D3DState.HsSrvs.Clear();
            }

            // Copy over unordered access views.
            StateCopy.CopyReadWriteViews(final.D3DState.ReadWriteViews, DrawCall.D3DState.ReadWriteViews, 0);

            final.D3DState.PipelineState = DrawCall.PipelineState;

            // Copy the cached states.
            final.PipelineState.D3DBlendState        = DrawCall.PipelineState.D3DBlendState;
            final.PipelineState.D3DDepthStencilState = DrawCall.PipelineState.D3DDepthStencilState;
            final.PipelineState.D3DRasterState       = DrawCall.PipelineState.D3DRasterState;

            OnUpdate(final);

            if (final.PipelineState.VertexShader == null)
            {
                throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_ERR_NO_VERTEX_SHADER);
            }

            return(final);
        }