public void TestInteropUtilsNativeCallMethods() { // Define variables and constants const string EXPECTED_FAIL_REASON = "I feel sad, so left alone; words are not enough, to live on"; // Set up context // Execute bool manualSuccessResult; unsafe { char *failReason = stackalloc char[InteropUtils.MAX_INTEROP_FAIL_REASON_STRING_LENGTH + 1]; manualSuccessResult = ReturnSuccess((IntPtr)failReason); } bool manualFailureResult; string manualFailureMessage; unsafe { char *failReason = stackalloc char[InteropUtils.MAX_INTEROP_FAIL_REASON_STRING_LENGTH + 1]; manualFailureResult = ReturnFailure((IntPtr)failReason, EXPECTED_FAIL_REASON); manualFailureMessage = Marshal.PtrToStringUni((IntPtr)failReason); } NativeCallResult successNCR = InteropUtils.CallNative(ReturnSuccess); NativeCallResult failureNCR = InteropUtils.CallNative(ReturnFailure, EXPECTED_FAIL_REASON); // Assert outcome Assert.AreEqual(manualSuccessResult, successNCR.Success); Assert.AreEqual(manualFailureResult, failureNCR.Success); Assert.IsNull(null, successNCR.FailureMessage); Assert.AreEqual(manualFailureMessage, failureNCR.FailureMessage); }
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)); }