public static bool SetupStructuredBuffer2 <TElement, TElementBufferLayout>(Device device, TElement[] elements, Func <TElement, TElementBufferLayout> bufferLayoutCreator, // generics support only parameterless ctors, so pass in a delegate which creates the struct ref Buffer structuredBuffer, bool createSRV, ref ShaderResourceView srv, bool createUAV, ref UnorderedAccessView uav) where TElementBufferLayout : struct { int elementSizeInBytes = Marshal.SizeOf(typeof(TElementBufferLayout)); int numElements = elements.Count(); int bufferSizeInBytes = elementSizeInBytes * numElements; if (bufferSizeInBytes == 0) { Utilities.DisposeObj(ref structuredBuffer); return(false); } if (structuredBuffer == null || structuredBuffer.Description.SizeInBytes != bufferSizeInBytes) { Utilities.DisposeObj(ref structuredBuffer); var bufferDesc = new BufferDescription { Usage = ResourceUsage.Default, SizeInBytes = elementSizeInBytes * numElements, StructureByteStride = elementSizeInBytes, OptionFlags = ResourceOptionFlags.BufferStructured, CpuAccessFlags = CpuAccessFlags.None, BindFlags = BindFlags.ShaderResource | BindFlags.UnorderedAccess }; structuredBuffer = new Buffer(device, bufferDesc); if (createSRV) { Utilities.DisposeObj(ref srv); var bufferResource = new ShaderResourceViewDescription.ExtendedBufferResource { ElementCount = numElements, FirstElement = 0, }; var srvDesc = new ShaderResourceViewDescription() { Format = Format.Unknown, Dimension = ShaderResourceViewDimension.Buffer, BufferEx = bufferResource }; srv = new ShaderResourceView(device, structuredBuffer, srvDesc); } if (createUAV) { Utilities.DisposeObj(ref uav); var uavDesc = new UnorderedAccessViewDescription { Format = Format.Unknown, Dimension = UnorderedAccessViewDimension.Buffer, Buffer = new UnorderedAccessViewDescription.BufferResource { FirstElement = 0, ElementCount = numElements, Flags = UnorderedAccessViewBufferFlags.None } }; uav = new UnorderedAccessView(device, structuredBuffer, uavDesc); } } return(true); }
protected bool SetupStructuredBuffer <TElement, TElementBufferLayout>(Device device, TElement[] elements, Func <TElement, TElementBufferLayout> bufferLayoutCreator, // generics support only parameterless ctors, so pass in a delegate which creates the struct ref Buffer structuredBuffer, ref ShaderResourceView srv) where TElementBufferLayout : struct { int elementSizeInBytes = Marshal.SizeOf(typeof(TElementBufferLayout)); int numElements = elements.Count(); int bufferSizeInBytes = elementSizeInBytes * numElements; if (bufferSizeInBytes == 0) { Utilities.DisposeObj(ref structuredBuffer); return(false); } if (structuredBuffer == null || structuredBuffer.Description.SizeInBytes != bufferSizeInBytes) { using (var data = new DataStream(bufferSizeInBytes, true, true)) { foreach (var structureElement in elements) { data.Write(bufferLayoutCreator(structureElement)); } data.Position = 0; Utilities.DisposeObj(ref structuredBuffer); Utilities.DisposeObj(ref srv); var bufferDesc = new BufferDescription { Usage = ResourceUsage.Dynamic, SizeInBytes = elementSizeInBytes * numElements, StructureByteStride = elementSizeInBytes, OptionFlags = ResourceOptionFlags.BufferStructured, CpuAccessFlags = CpuAccessFlags.Write, BindFlags = BindFlags.ShaderResource }; structuredBuffer = new Buffer(device, data, bufferDesc); var bufferResource = new ShaderResourceViewDescription.ExtendedBufferResource() { ElementCount = numElements, FirstElement = 0, }; var srvDesc = new ShaderResourceViewDescription() { Format = Format.Unknown, Dimension = ShaderResourceViewDimension.Buffer, BufferEx = bufferResource }; srv = new ShaderResourceView(device, structuredBuffer, srvDesc); } } else { DataStream dataStream; device.ImmediateContext.MapSubresource(structuredBuffer, MapMode.WriteDiscard, MapFlags.None, out dataStream); foreach (var pointLight in elements) { dataStream.Write(bufferLayoutCreator(pointLight)); } device.ImmediateContext.UnmapSubresource(structuredBuffer, 0); } return(true); }