/// <summary> /// Initializes the specified device. /// </summary> /// <param name="graphicsProfiles">The graphics profiles.</param> /// <param name="deviceCreationFlags">The device creation flags.</param> /// <param name="windowHandle">The window handle.</param> private void InitializePlatformDevice(GraphicsProfile[] graphicsProfiles, DeviceCreationFlags deviceCreationFlags, object windowHandle) { if (nativeDevice != null) { // Destroy previous device ReleaseDevice(); } // Profiling is supported through pix markers IsProfilingSupported = true; // Map GraphicsProfile to D3D11 FeatureLevel SharpDX.Direct3D.FeatureLevel[] levels = graphicsProfiles.ToFeatureLevel(); creationFlags = (SharpDX.Direct3D11.DeviceCreationFlags)deviceCreationFlags; // Create Device D3D11 with feature Level based on profile nativeDevice = new SharpDX.Direct3D11.Device(Adapter.NativeAdapter, creationFlags, levels); nativeDeviceContext = nativeDevice.ImmediateContext; if (IsDebugMode) { GraphicsResourceBase.SetDebugName(this, nativeDeviceContext, "ImmediateContext"); } InitializeStages(); // Create the input layout manager if (InputLayoutManager == null) { InputLayoutManager = new InputLayoutManager(this).DisposeBy(this); } }
/// <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; } } } }
internal void OnDestroyed() { // Clear input layouts cache InputLayoutManager.OnDestroyed(); }