public InputLayout GetInputLayout(EffectInputSignature effectInputSignature, VertexArrayLayout vertexArrayLayout)
        {
            var inputKey = new InputKey(effectInputSignature, vertexArrayLayout);

            InputLayout inputLayout;

            // TODO: Check if it is really worth to use ConcurrentDictionary
            lock (registeredSignatures)
            {
                if (!registeredSignatures.TryGetValue(inputKey, out inputLayout))
                {
                    try
                    {
                        inputLayout = new InputLayout(graphicsDevice.NativeDevice, effectInputSignature.NativeSignature, vertexArrayLayout.InputElements);
                    }
                    catch (Exception)
                    {
                        throw new InvalidOperationException("The provided vertex array input elements are not matching the ones of the shader." +
                                                            " [Details: EffectInputSignature='{0}', VertexArrayLayout='{1}]".ToFormat(effectInputSignature.ToString(), vertexArrayLayout.ToString()));
                    }
                    registeredSignatures.Add(inputKey, inputLayout);
                }

                ((IUnknown)inputLayout).AddReference();
            }
            return(inputLayout);
        }
        private void ClearStateImpl()
        {
            NativeDeviceContext.ClearState();

            for (int i = 0; i < samplerStates.Length; ++i)
            {
                samplerStates[i] = null;
            }
            for (int i = 0; i < constantBuffers.Length; ++i)
            {
                constantBuffers[i] = null;
            }
            for (int i = 0; i < unorderedAccessViews.Length; ++i)
            {
                unorderedAccessViews[i] = null;
            }
            for (int i = 0; i < currentRenderTargetViews.Length; i++)
            {
                currentRenderTargetViews[i] = null;
            }

            currentEffectInputSignature = null;
            currentVertexArrayLayout    = null;
            currentInputLayout          = null;
            currentVertexArrayObject    = null;
            CurrentEffect = null;
        }
 public bool Equals(VertexArrayLayout other)
 {
     if (ReferenceEquals(this, other))
     {
         return(true);
     }
     return(hashCode == other.hashCode && Utilities.Compare(InputElements, other.InputElements));
 }
 /// <summary>
 /// Gets the original create layout.
 /// </summary>
 /// <param name="layout">The layout.</param>
 /// <returns>VertexArrayLayout.</returns>
 public static VertexArrayLayout GetOrCreateLayout(VertexArrayLayout layout)
 {
     VertexArrayLayout registeredLayout;
     lock (RegisteredLayouts)
     {
         if (!RegisteredLayouts.TryGetValue(layout, out registeredLayout))
         {
             RegisteredLayouts.Add(layout, layout);
             registeredLayout = layout;
         }
     }
     return registeredLayout;
 }
        /// <summary>
        /// Gets the original create layout.
        /// </summary>
        /// <param name="layout">The layout.</param>
        /// <returns>VertexArrayLayout.</returns>
        public static VertexArrayLayout GetOrCreateLayout(VertexArrayLayout layout)
        {
            VertexArrayLayout registeredLayout;

            lock (RegisteredLayouts)
            {
                if (!RegisteredLayouts.TryGetValue(layout, out registeredLayout))
                {
                    RegisteredLayouts.Add(layout, layout);
                    registeredLayout = layout;
                }
            }
            return(registeredLayout);
        }
        private void ReleaseDevice()
        {
            // Display D3D11 ref counting info
            ClearState();
            NativeDevice.ImmediateContext.Flush();
            NativeDevice.ImmediateContext.Dispose();

            if (IsDebugMode)
            {
                var deviceDebug = new DeviceDebug(NativeDevice);
                deviceDebug.ReportLiveDeviceObjects(ReportingLevel.Detail);
            }

            currentInputLayout          = null;
            currentEffectInputSignature = null;
            currentVertexArrayObject    = null;
            currentVertexArrayLayout    = null;
            nativeDevice.Dispose();
        }
Beispiel #7
0
        private VertexArrayObject(GraphicsDevice graphicsDevice, EffectInputSignature shaderSignature, IndexBufferBinding indexBufferBinding, VertexBufferBinding[] vertexBufferBindings)
            : base(graphicsDevice)
        {
            this.vertexBufferBindings = vertexBufferBindings;
            this.indexBufferBinding   = indexBufferBinding;
            this.EffectInputSignature = shaderSignature;

            // Calculate Direct3D11 InputElement
            int inputElementCount = vertexBufferBindings.Sum(t => t.Declaration.VertexElements.Length);
            var inputElements     = new InputElement[inputElementCount];

            int j = 0;

            for (int i = 0; i < vertexBufferBindings.Length; i++)
            {
                var declaration = vertexBufferBindings[i].Declaration;
                vertexBufferBindings[i].Buffer.AddReferenceInternal();
                foreach (var vertexElementWithOffset in declaration.EnumerateWithOffsets())
                {
                    var vertexElement = vertexElementWithOffset.VertexElement;
                    inputElements[j++] = new InputElement
                    {
                        Slot              = i,
                        SemanticName      = vertexElement.SemanticName,
                        SemanticIndex     = vertexElement.SemanticIndex,
                        AlignedByteOffset = vertexElementWithOffset.Offset,
                        Format            = (SharpDX.DXGI.Format)vertexElement.Format,
                    };
                }
            }

            Layout = VertexArrayLayout.GetOrCreateLayout(new VertexArrayLayout(inputElements));

            if (indexBufferBinding != null)
            {
                indexBufferBinding.Buffer.AddReferenceInternal();
                indexBufferOffset = indexBufferBinding.Offset;
                indexFormat       = (indexBufferBinding.Is32Bit ? SharpDX.DXGI.Format.R32_UInt : SharpDX.DXGI.Format.R16_UInt);
            }

            CreateResources();
        }
        private VertexArrayObject(GraphicsDevice graphicsDevice, EffectInputSignature shaderSignature, IndexBufferBinding indexBufferBinding, VertexBufferBinding[] vertexBufferBindings)
            : base(graphicsDevice)
        {
            this.vertexBufferBindings = vertexBufferBindings;
            this.indexBufferBinding = indexBufferBinding;
            this.EffectInputSignature = shaderSignature;

            // Calculate Direct3D11 InputElement
            int inputElementCount = vertexBufferBindings.Sum(t => t.Declaration.VertexElements.Length);
            var inputElements = new InputElement[inputElementCount];

            int j = 0;
            for (int i = 0; i < vertexBufferBindings.Length; i++)
            {
                var declaration = vertexBufferBindings[i].Declaration;
                vertexBufferBindings[i].Buffer.AddReferenceInternal();
                foreach (var vertexElementWithOffset in declaration.EnumerateWithOffsets())
                {
                    var vertexElement = vertexElementWithOffset.VertexElement;
                    inputElements[j++] = new InputElement
                        {
                            Slot = i,
                            SemanticName = vertexElement.SemanticName,
                            SemanticIndex = vertexElement.SemanticIndex,
                            AlignedByteOffset = vertexElementWithOffset.Offset,
                            Format = (SharpDX.DXGI.Format)vertexElement.Format,
                        };
                }
            }

            Layout = VertexArrayLayout.GetOrCreateLayout(new VertexArrayLayout(inputElements));

            if (indexBufferBinding != null)
            {
                indexBufferBinding.Buffer.AddReferenceInternal();
                indexBufferOffset = indexBufferBinding.Offset;
                indexFormat = (indexBufferBinding.Is32Bit ? SharpDX.DXGI.Format.R32_UInt : SharpDX.DXGI.Format.R16_UInt);
            }

            CreateResources();
        }
        /// <summary>
        ///     Prepares a draw call. This method is called before each Draw() method to setup the correct Primitive, InputLayout and VertexBuffers.
        /// </summary>
        /// <param name="primitiveType">Type of the primitive.</param>
        /// <exception cref="System.InvalidOperationException">Cannot GraphicsDevice.Draw*() without an effect being previously applied with Effect.Apply() method</exception>
        private void PrepareDraw(PrimitiveType primitiveType)
        {
            if (CurrentEffect == null)
            {
                throw new InvalidOperationException("Cannot GraphicsDevice.Draw*() without an effect being previously applied with Effect.Apply() method");
            }

            // Setup the primitive type
            PrimitiveType = primitiveType;

            // If the vertex array object is null, simply set the InputLayout to null
            if (newVertexArrayObject == null)
            {
                if (currentVertexArrayObject != null)
                {
                    currentVertexArrayObject    = null;
                    currentVertexArrayLayout    = null;
                    currentEffectInputSignature = null;
                    inputAssembler.InputLayout  = currentInputLayout = null;
                }
            }
            else
            {
                var newVertexArrayLayout    = newVertexArrayObject.Layout;
                var newEffectInputSignature = CurrentEffect.InputSignature;
                var oldInputLayout          = currentInputLayout;

                // Apply the VertexArrayObject
                if (newVertexArrayObject != currentVertexArrayObject)
                {
                    currentVertexArrayObject = newVertexArrayObject;
                    newVertexArrayObject.Apply(inputAssembler);
                }

                // If the input layout of the effect or the vertex buffer has changed, get the associated new input layout
                if (!ReferenceEquals(newVertexArrayLayout, currentVertexArrayLayout) || !ReferenceEquals(newEffectInputSignature, currentEffectInputSignature))
                {
                    currentVertexArrayLayout    = newVertexArrayLayout;
                    currentEffectInputSignature = newEffectInputSignature;

                    if (newVertexArrayObject.InputLayout != null && ReferenceEquals(newEffectInputSignature, newVertexArrayObject.EffectInputSignature))
                    {
                        // Default configuration
                        currentInputLayout = newVertexArrayObject.InputLayout;
                    }
                    else if (ReferenceEquals(newEffectInputSignature, newVertexArrayObject.LastEffectInputSignature))
                    {
                        // Reuse previous configuration
                        currentInputLayout = newVertexArrayObject.LastInputLayout;
                    }
                    // Slow path if the current VertexArrayObject is not optimized for the particular input (or not used right before)
                    else
                    {
                        currentInputLayout = InputLayoutManager.GetInputLayout(newEffectInputSignature, currentVertexArrayLayout);

                        // Store it in VAO since it will likely be used with same effect later
                        newVertexArrayObject.LastInputLayout          = currentInputLayout;
                        newVertexArrayObject.LastEffectInputSignature = newEffectInputSignature;
                    }

                    // Setup the input layout (if it changed)
                    if (currentInputLayout != oldInputLayout)
                    {
                        inputAssembler.InputLayout = currentInputLayout;
                    }
                }
            }
        }
 public InputKey(EffectInputSignature effectInputSignature, VertexArrayLayout vertexArrayLayout)
 {
     this.effectInputSignature = effectInputSignature;
     this.vertexArrayLayout    = vertexArrayLayout;
 }
 public bool Equals(VertexArrayLayout other)
 {
     if (ReferenceEquals(this, other))
         return true;
     return hashCode == other.hashCode && Utilities.Compare(InputElements, other.InputElements);
 }
        /// <summary>
        ///     Prepares a draw call. This method is called before each Draw() method to setup the correct Primitive, InputLayout and VertexBuffers.
        /// </summary>
        /// <param name="primitiveType">Type of the primitive.</param>
        /// <exception cref="System.InvalidOperationException">Cannot GraphicsDevice.Draw*() without an effect being previously applied with Effect.Apply() method</exception>
        private void PrepareDraw(PrimitiveType primitiveType)
        {
            if (CurrentEffect == null)
            {
                throw new InvalidOperationException("Cannot GraphicsDevice.Draw*() without an effect being previously applied with Effect.Apply() method");
            }

            // Setup the primitive type
            PrimitiveType = primitiveType;

            // If the vertex array object is null, simply set the InputLayout to null
            if (newVertexArrayObject == null)
            {
                if (currentVertexArrayObject != null)
                {
                    currentVertexArrayObject = null;
                    currentVertexArrayLayout = null;
                    currentEffectInputSignature = null;
                    inputAssembler.InputLayout = currentInputLayout = null;
                }
            }
            else
            {
                var newVertexArrayLayout = newVertexArrayObject.Layout;
                var newEffectInputSignature = CurrentEffect.InputSignature;
                var oldInputLayout = currentInputLayout;

                // Apply the VertexArrayObject
                if (newVertexArrayObject != currentVertexArrayObject)
                {
                    currentVertexArrayObject = newVertexArrayObject;
                    newVertexArrayObject.Apply(inputAssembler);
                }

                // If the input layout of the effect or the vertex buffer has changed, get the associated new input layout
                if (!ReferenceEquals(newVertexArrayLayout, currentVertexArrayLayout) || !ReferenceEquals(newEffectInputSignature, currentEffectInputSignature))
                {
                    currentVertexArrayLayout = newVertexArrayLayout;
                    currentEffectInputSignature = newEffectInputSignature;

                    if (newVertexArrayObject.InputLayout != null && ReferenceEquals(newEffectInputSignature, newVertexArrayObject.EffectInputSignature))
                    {
                        // Default configuration
                        currentInputLayout = newVertexArrayObject.InputLayout;
                    }
                    else if (ReferenceEquals(newEffectInputSignature, newVertexArrayObject.LastEffectInputSignature))
                    {
                        // Reuse previous configuration
                        currentInputLayout = newVertexArrayObject.LastInputLayout;
                    }
                    // Slow path if the current VertexArrayObject is not optimized for the particular input (or not used right before)
                    else
                    {
                        currentInputLayout = InputLayoutManager.GetInputLayout(newEffectInputSignature, currentVertexArrayLayout);

                        // Store it in VAO since it will likely be used with same effect later
                        newVertexArrayObject.LastInputLayout = currentInputLayout;
                        newVertexArrayObject.LastEffectInputSignature = newEffectInputSignature;
                    }

                    // Setup the input layout (if it changed)
                    if (currentInputLayout != oldInputLayout)
                        inputAssembler.InputLayout = currentInputLayout;
                }
            }

            SetViewportImpl();
        }
        private void ReleaseDevice()
        {
            // Display D3D11 ref counting info
            ClearState();
            NativeDevice.ImmediateContext.Flush();
            NativeDevice.ImmediateContext.Dispose();

            if (IsDebugMode)
            {
                var deviceDebug = new DeviceDebug(NativeDevice);
                deviceDebug.ReportLiveDeviceObjects(ReportingLevel.Detail);
            }

            currentInputLayout = null;
            currentEffectInputSignature = null;
            currentVertexArrayObject = null;
            currentVertexArrayLayout = null;
            nativeDevice.Dispose();
        }
        private void ClearStateImpl()
        {
            NativeDeviceContext.ClearState();

            for (int i = 0; i < samplerStates.Length; ++i)
                samplerStates[i] = null;
            for (int i = 0; i < constantBuffers.Length; ++i)
                constantBuffers[i] = null;
            for (int i = 0; i < unorderedAccessViews.Length; ++i)
                unorderedAccessViews[i] = null;
            for (int i = 0; i < currentRenderTargetViews.Length; i++)
                currentRenderTargetViews[i] = null;

            currentEffectInputSignature = null;
            currentVertexArrayLayout = null;
            currentInputLayout = null;
            currentVertexArrayObject = null;
            CurrentEffect = null;
        }