public VertexShader(string filename, params IShaderResourceBinding[] otherBindings) : base(ShaderType.Vertex, filename, otherBindings) { InstanceDataBinding = null; ViewProjMatBinding = null; this.InputBindings = ResourceBindings.OfType <VertexInputBinding>().ToArray(); if (InputBindings.Length > MAX_VS_INPUT_BINDINGS) { throw new ArgumentException("Can not specify more than " + MAX_VS_INPUT_BINDINGS + " vertex input bindings.", "otherBindings"); } this.NumInputSlots = InputBindings.Any() ? InputBindings.Max(bind => bind.SlotIndex) + 1U : 0U; if (NumInputSlots > MAX_VS_INPUT_BINDINGS) { throw new ArgumentException("Can not set more than " + MAX_VS_INPUT_BINDINGS + " input slots."); } }
private GeometryInputLayout CreateInputLayout(VertexShader shader) { uint numInputBindings = (uint)shader.InputBindings.Length; List <KeyValuePair <VertexInputBinding, IVertexBuffer> > inputLayoutComponentBuffers = new List <KeyValuePair <VertexInputBinding, IVertexBuffer> >(); // +3 because the instance matrix is split in to four row vectors InputElementDesc[] inputElements = new InputElementDesc[numInputBindings + 3]; for (int i = 0; i < numInputBindings; ++i) { VertexInputBinding curVIB = shader.InputBindings[i]; if (curVIB == shader.InstanceDataBinding) { continue; } string semantic = curVIB.Identifier; int componentBufferIndex = Array.IndexOf(vertexComponentSemantics, semantic); if (componentBufferIndex < 0) { throw new InvalidOperationException("Can not bind " + this + " to vertex shader with semantics " + shader.InputBindings.Select(srb => srb.Identifier).ToStringOfContents() + ", " + "semantic '" + semantic + "' is not provided in this cache!"); } IVertexBuffer bufferForCurSemantic = vertexComponentBuffers[componentBufferIndex]; ResourceFormat formatForCurSemantic = vertexComponentFormats[componentBufferIndex]; inputLayoutComponentBuffers.Add(new KeyValuePair <VertexInputBinding, IVertexBuffer>(curVIB, bufferForCurSemantic)); inputElements[i] = new InputElementDesc( semantic, 0U, formatForCurSemantic, curVIB.SlotIndex, true ); } // Add the instance data slot uint semanticIndex = 0U; for (uint i = numInputBindings - 1U; i < numInputBindings + 3U; ++i) { inputElements[i] = new InputElementDesc( shader.InstanceDataBinding.Identifier, semanticIndex++, VertexShader.INSTANCE_DATA_FORMAT, shader.InstanceDataBinding.SlotIndex, false ); } InputLayoutHandle outInputLayoutPtr; NativeCallResult createInputLayoutResult = InteropUtils.CallNative(NativeMethods.ShaderManager_CreateInputLayout, RenderingModule.Device, shader.Handle, inputElements, (uint)inputElements.Length, (IntPtr)(&outInputLayoutPtr) ); if (!createInputLayoutResult.Success) { throw new InvalidOperationException("Given shader could not be bound to this cache, " + "this is likely because one or more semantics/bindings are incorrect. Details: " + createInputLayoutResult.FailureMessage); } Logger.Debug("Successfully created input layout for " + shader + " and " + this + ": " + inputElements.ToStringOfContents()); return(new GeometryInputLayout(outInputLayoutPtr, inputLayoutComponentBuffers.ToArray(), shader, this)); }