internal VertexBufferBuilder(ResourceUsage usage, uint length, ArraySlice <TVertex>?initialData) : base(usage, initialData) { Assure.True(typeof(TVertex).IsBlittable()); Assure.GreaterThan(UnsafeUtils.SizeOf <TVertex>(), 0); this.length = length; }
/// <summary> /// Creates a new <see cref="IndexBuffer"/> with the supplied builder parameters. /// </summary> /// <remarks> /// In debug mode, this method will check a large number of <see cref="Assure">assurances</see> /// on the builder parameters before creating the resource. /// </remarks> /// <returns>A new <see cref="IndexBuffer"/>.</returns> public unsafe override IndexBuffer Create() { Assure.True(Usage != ResourceUsage.Immutable || InitialData != null, "You must supply initial data to an immutable resource."); Assure.GreaterThan(length, 0U, "Can not create an index buffer with 0 indices."); GCHandle?pinnedArrayHandle = null; IntPtr initialDataPtr = IntPtr.Zero; if (InitialData != null) { pinnedArrayHandle = GCHandle.Alloc(InitialData.Value.ContainingArray, GCHandleType.Pinned); initialDataPtr = pinnedArrayHandle.Value.AddrOfPinnedObject() + (IndexBuffer.INDEX_SIZE_BYTES * (int)InitialData.Value.Offset); } try { BufferResourceHandle outResourceHandle; InteropUtils.CallNative(NativeMethods.ResourceFactory_CreateIndexBuffer, RenderingModule.Device, length, Usage.GetUsage(), Usage.GetCPUUsage(), initialDataPtr, (IntPtr)(&outResourceHandle) ).ThrowOnFailure(); return(new IndexBuffer(outResourceHandle, Usage, length)); } finally { if (pinnedArrayHandle != null) { pinnedArrayHandle.Value.Free(); } } }
internal BufferBuilder(ResourceUsage usage, uint length, GPUBindings permittedBindings, ArraySlice <TElement>?initialData) : base(usage, initialData) { Assure.True(typeof(TElement).IsBlittable()); Assure.GreaterThan(UnsafeUtils.SizeOf <TElement>(), 0); this.length = length; this.permittedBindings = permittedBindings; }
public PresetMovementEntity(LevelEntityMovementStep[] movementSteps, bool alternateMovementDirection, float initialDelay) { Assure.GreaterThan(movementSteps.Length, 1); this.movementSteps = movementSteps; this.alternateMovementDirection = alternateMovementDirection; initialDelayTimeRemaining = this.initialDelay = initialDelay; tiltedTransforms = new Transform[movementSteps.Length]; for (int i = 0; i < movementSteps.Length; i++) { tiltedTransforms[i] = movementSteps[i].Transform; } }
/// <summary> /// Creates a new <see cref="Buffer{TElement}"/> with the supplied builder parameters. /// </summary> /// <remarks> /// In debug mode, this method will check a large number of <see cref="Assure">assurances</see> /// on the builder parameters before creating the resource. /// </remarks> /// <returns>A new <see cref="Buffer{TElement}"/>.</returns> public unsafe override Buffer <TElement> Create() { Assure.True(Usage != ResourceUsage.Immutable || InitialData != null, "You must supply initial data to an immutable resource."); Assure.False( (Usage == ResourceUsage.Immutable || Usage == ResourceUsage.DiscardWrite) && permittedBindings == GPUBindings.None, "An immutable or discard-write resource with no permitted bindings is useless." ); Assure.False( Usage.GetUsage() == 0x3 && permittedBindings != GPUBindings.None, "Staging resources can not be bound to the pipeline." ); Assure.GreaterThan(length, 0U, "Can not create a buffer with 0 elements."); InteropBool isStructured = (BaseResource.GetFormatForType(typeof(TElement)) == ResourceFormat.Unknown); InteropBool allowRawAccess = !isStructured && (int)(permittedBindings & (GPUBindings.WritableShaderResource | GPUBindings.ReadableShaderResource)) != 0; GCHandle?pinnedArrayHandle = null; IntPtr initialDataPtr = IntPtr.Zero; try { int elementSizeBytes = UnsafeUtils.SizeOf <TElement>(); if (InitialData != null) { pinnedArrayHandle = GCHandle.Alloc(InitialData.Value.ContainingArray, GCHandleType.Pinned); initialDataPtr = pinnedArrayHandle.Value.AddrOfPinnedObject() + (elementSizeBytes * (int)InitialData.Value.Offset); } BufferResourceHandle outResourceHandle; InteropUtils.CallNative(NativeMethods.ResourceFactory_CreateBuffer, RenderingModule.Device, (uint)elementSizeBytes, length, Usage.GetUsage(), Usage.GetCPUUsage(), (PipelineBindings)permittedBindings, isStructured, allowRawAccess, initialDataPtr, (IntPtr)(&outResourceHandle) ).ThrowOnFailure(); return(new Buffer <TElement>(outResourceHandle, Usage, (uint)elementSizeBytes, length, permittedBindings, isStructured)); } finally { if (pinnedArrayHandle != null) { pinnedArrayHandle.Value.Free(); } } }
internal Texture1DBuilder(ResourceUsage usage, ArraySlice <TTexel>?initialData, GPUBindings permittedBindings, uint width, bool mipAllocation, bool mipGenerationTarget, bool dynamicDetail) : base(usage, initialData) { Assure.True(typeof(TTexel).IsBlittable()); Assure.GreaterThan(UnsafeUtils.SizeOf <TTexel>(), 0); this.permittedBindings = permittedBindings; this.width = width; this.mipAllocation = mipAllocation; this.mipGenerationTarget = mipGenerationTarget; this.dynamicDetail = dynamicDetail; this.numMips = mipAllocation ? TextureUtils.GetNumMips(width) : 1U; }
private static unsafe IEnumerable <ModelVertex> TriangulateFace(int numVertices, uint[] pIndices, uint[] tIndices, uint[] nIndices) { Assure.GreaterThan(numVertices, 2); ModelVertex[] result = new ModelVertex[(numVertices - 2) * 3]; for (int i = 2, resultIndex = 0; i < numVertices; i++) { result[resultIndex++] = new ModelVertex(pIndices[0], tIndices[0], nIndices[0]); result[resultIndex++] = new ModelVertex(pIndices[i - 1], tIndices[i - 1], nIndices[i - 1]); result[resultIndex++] = new ModelVertex(pIndices[i], tIndices[i], nIndices[i]); } return(result); }
public AlignedAllocation(long alignment, uint sizeOfT) { Assure.GreaterThan(alignment, 0L, "Alignment must be positive."); this.sizeOfT = sizeOfT; ReservedMemory = Marshal.AllocHGlobal(new IntPtr(sizeOfT + alignment - 1)); long allocationOffset = (long)ReservedMemory % alignment; if (allocationOffset == 0L) { AlignedPointer = ReservedMemory; } else { AlignedPointer = ReservedMemory + (int)(alignment - allocationOffset); } }
internal GeometryCache(IVertexBuffer[] vertexComponentBuffers, string[] vertexComponentSemantics, ResourceFormat[] vertexComponentFormats, IndexBuffer indices, AlignedAllocation <uint> componentStartPointsAlloc, AlignedAllocation <uint> indexStartPointsAlloc, uint numModels, Type vertexType, int cacheID, Dictionary <string, ModelHandle> nameToHandleMap, bool orderFirst) { Assure.NotNull(vertexComponentBuffers); Assure.NotNull(vertexComponentSemantics); Assure.NotNull(vertexComponentFormats); Assure.NotNull(indices); Assure.Equal(vertexComponentBuffers.Length, vertexComponentSemantics.Length, "One or more vertex component arrays have different lengths."); Assure.Equal(vertexComponentFormats.Length, vertexComponentSemantics.Length, "One or more vertex component arrays have different lengths."); Assure.GreaterThan(vertexComponentBuffers.Length, 0, "Geometry cache with no vertex buffers is invalid."); Assure.NotNull(nameToHandleMap); this.vertexComponentBuffers = vertexComponentBuffers; this.vertexComponentSemantics = vertexComponentSemantics; this.vertexComponentFormats = vertexComponentFormats; this.indices = indices; this.componentStartPointsAlloc = componentStartPointsAlloc; this.indexStartPointsAlloc = indexStartPointsAlloc; this.componentStartPoints = (uint *)this.componentStartPointsAlloc.AlignedPointer; this.indexStartPoints = (uint *)this.indexStartPointsAlloc.AlignedPointer; this.NumModels = numModels; this.VertexType = vertexType; this.ID = cacheID; this.nameToHandleMap = nameToHandleMap; lock (staticMutationLock) { activeCaches.Add(ID, this); if (orderFirst) { activeCacheList.Insert(0, this); } else { activeCacheList.Add(this); } } this.createInputLayoutFunc = CreateInputLayout; GC.AddMemoryPressure(sizeof(uint) * 2 * (NumModels + 1)); }
public static AlignedAllocation <T> AllocArray(long alignment, uint arrLen) { Assure.GreaterThan(alignment, 0L, "Alignment must be positive."); uint sizeOfT = (uint)UnsafeUtils.SizeOf <T>(); uint reservationSize = sizeOfT * arrLen; IntPtr allocStart = Marshal.AllocHGlobal(new IntPtr(reservationSize + alignment - 1)); long allocationOffset = (long)allocStart % alignment; IntPtr alignedStart; if (allocationOffset == 0L) { alignedStart = allocStart; } else { alignedStart = allocStart + (int)(alignment - allocationOffset); } return(new AlignedAllocation <T>(alignedStart, sizeOfT, allocStart)); }
/// <summary> /// Creates a new <see cref="Texture3D{TTexel}"/> with the supplied builder parameters. /// </summary> /// <remarks> /// In debug mode, this method will check a large number of <see cref="Assure">assurances</see> /// on the builder parameters before creating the resource. /// </remarks> /// <returns>A new <see cref="Texture3D{TTexel}"/>.</returns> public unsafe override Texture3D <TTexel> Create() { Assure.True(Usage != ResourceUsage.Immutable || InitialData != null, "You must supply initial data to an immutable resource."); Assure.False( (Usage == ResourceUsage.Immutable || Usage == ResourceUsage.DiscardWrite) && permittedBindings == GPUBindings.None, "An immutable or discard-write resource with no permitted bindings is useless." ); Assure.False( Usage.GetUsage() == 0x3 && permittedBindings != GPUBindings.None, "Staging resources can not be bound to the pipeline." ); Assure.False((Usage == ResourceUsage.DiscardWrite || Usage == ResourceUsage.Immutable) && ((permittedBindings & GPUBindings.RenderTarget) > 0 || (permittedBindings & GPUBindings.DepthStencilTarget) > 0 || (permittedBindings & GPUBindings.WritableShaderResource) > 0), "Can not bind an immutable or discard-write texture as a render target or depth stencil target, or as a GPU-writeable shader resource." ); Assure.GreaterThan(width, 0U, "Please specify a width for the texture."); Assure.GreaterThan(height, 0U, "Please specify a height for the texture."); Assure.GreaterThan(depth, 0U, "Please specify a depth for the texture."); Assure.False( mipAllocation && !MathUtils.IsPowerOfTwo(width), "Can not create mipmapped texture with any non-power-of-two (NPOT) dimension. " + "Dimensions: " + width + "x" + height + "x" + depth + "." ); Assure.False( mipAllocation && !MathUtils.IsPowerOfTwo(height), "Can not create mipmapped texture with any non-power-of-two (NPOT) dimension. " + "Dimensions: " + width + "x" + height + "x" + depth + "." ); Assure.False( mipAllocation && !MathUtils.IsPowerOfTwo(depth), "Can not create mipmapped texture with any non-power-of-two (NPOT) dimension. " + "Dimensions: " + width + "x" + height + "x" + depth + "." ); Assure.False( mipAllocation && Usage == ResourceUsage.DiscardWrite, "Can not allocate mips on a discard-write texture." ); Assure.False( mipGenerationTarget && !mipAllocation, "Can not generate mips without allocating space for them." ); Assure.False( mipGenerationTarget && ((permittedBindings & GPUBindings.RenderTarget) == 0x0 || (permittedBindings & GPUBindings.ReadableShaderResource) == 0x0), "To make a texture a viable mip generation target, it must be created with the RenderTarget and ReadableShaderResource GPU bindings." ); Assure.False( mipGenerationTarget && InitialData != null, "Can not supply initial data to a mip generation target." ); Assure.True( InitialData == null || (InitialData.Value.Length == TextureUtils.GetSizeTexels(mipAllocation, width, height, depth)), "Initial data is of incorrect length (" + (InitialData != null ? InitialData.Value.Length : 0) + ") for this resource. " + "It should have a length of: " + TextureUtils.GetSizeTexels(mipAllocation, width, height, depth) + "." ); Assure.False(dynamicDetail && Usage.GetUsage() == 0x3, "Can not create a dynamic-detail staging resource."); Assure.False( (permittedBindings & GPUBindings.DepthStencilTarget) == GPUBindings.DepthStencilTarget && texelFormat != TexelFormat.DSV_FORMAT_CODE, "Can not create a depth-stencil target with any texel format other than " + typeof(TexelFormat.DepthStencil).Name + "." ); Texture3DResourceHandle outResourceHandle; GCHandle?pinnedInitData = null; GCHandle?pinnedDataHandle = null; IntPtr initialDataPtr = IntPtr.Zero; InitialResourceDataDesc[] dataArr = null; if (InitialData != null) { pinnedInitData = GCHandle.Alloc(InitialData.Value.ContainingArray, GCHandleType.Pinned); dataArr = InitialResourceDataDesc.CreateDataArr( pinnedInitData.Value.AddrOfPinnedObject() + (int)(InitialData.Value.Offset * texelSizeBytes), 1U, numMips, width, height, depth, texelSizeBytes ); pinnedDataHandle = GCHandle.Alloc(dataArr, GCHandleType.Pinned); initialDataPtr = pinnedDataHandle.Value.AddrOfPinnedObject(); } try { InteropUtils.CallNative(NativeMethods.ResourceFactory_CreateTexture3D, RenderingModule.Device, width, height, depth, (InteropBool)mipAllocation, texelFormat, Usage.GetUsage(), Usage.GetCPUUsage(), (PipelineBindings)permittedBindings, (InteropBool)mipGenerationTarget, (InteropBool)dynamicDetail, initialDataPtr, dataArr != null ? (uint)dataArr.Length : 0U, (IntPtr)(&outResourceHandle) ).ThrowOnFailure(); } finally { if (pinnedDataHandle != null) { pinnedDataHandle.Value.Free(); } if (pinnedInitData != null) { pinnedInitData.Value.Free(); } } return(new Texture3D <TTexel>( outResourceHandle, Usage, TextureUtils.GetSize(texelSizeBytes, mipAllocation, width, height, depth), permittedBindings, mipGenerationTarget, dynamicDetail, width, height, depth, texelSizeBytes, mipAllocation, numMips, 0U )); }
internal ConstantBufferBuilder(ResourceUsage usage, TConstants initialData) : base(usage, initialData) { Assure.True(typeof(TConstants).IsBlittable()); Assure.GreaterThan(UnsafeUtils.SizeOf <TConstants>(), 0); Assure.Equal(UnsafeUtils.SizeOf <TConstants>() % 16, 0, "Constant buffer size must be a multiple of 16 bytes."); }