private void CopyBuffersInto(MgOptimizedStorageContainer container, List <byte[]> buffers, BufferViewInfo[] bufferViews, List <GltfMeshAccessor> attributes) { for (var i = 0; i < attributes.Count; i += 1) { var src = attributes[i]; if (src.BufferViewIndex.HasValue) { var srcView = bufferViews[src.BufferViewIndex.Value]; var dst = container.Map.Allocations[i]; var dstBuffer = container.Storage.Blocks[dst.BlockIndex]; var dstDeviceMemory = dstBuffer.DeviceMemory; var err = dstBuffer.DeviceMemory.MapMemory( mConfiguration.Device, dst.Offset, dst.Size, 0U, out IntPtr ppData); if (err == Result.SUCCESS) { // COPY HERE byte[] srcData = buffers[srcView.BufferIndex]; //Marshal.Copy(srcData, 0, ppData, (int) dst.Size); dstBuffer.DeviceMemory.UnmapMemory(mConfiguration.Device); } } } }
private MeshDrawCommand[] ExtractDrawCommand(MgOptimizedStorageContainer container, List <GltfMeshAccessor> accessors) { const MgBufferUsageFlagBits VERT_MASK = MgBufferUsageFlagBits.VERTEX_BUFFER_BIT; const MgBufferUsageFlagBits INDEX_MASK = MgBufferUsageFlagBits.INDEX_BUFFER_BIT; var primitives = new Dictionary <uint, MeshDrawCommand>(); for (var i = 0; i < accessors.Count; i += 1) { var srcAttribute = accessors[i]; if (!primitives.TryGetValue(srcAttribute.PrimitiveIndex, out MeshDrawCommand found)) { found = new MeshDrawCommand { PrimitiveIndex = srcAttribute.PrimitiveIndex, Vertices = new List <VertexDataBinding>(), }; primitives.Add(srcAttribute.PrimitiveIndex, found); } if ((srcAttribute.Usage & VERT_MASK) == VERT_MASK) { var dstAttribute = container.Map.Allocations[i]; var dstInstance = container.Storage.Blocks[dstAttribute.BlockIndex]; var vertexInfo = new VertexDataBinding { BlockIndex = dstAttribute.BlockIndex, Buffer = dstInstance.Buffer, Offset = dstAttribute.Offset + dstInstance.MemoryOffset, }; found.Vertices.Add(vertexInfo); } if ((srcAttribute.Usage & INDEX_MASK) == INDEX_MASK) { var dstAttribute = container.Map.Allocations[i]; var dstInstance = container.Storage.Blocks[dstAttribute.BlockIndex]; var indexInfo = new IndexDataBinding { Buffer = dstInstance.Buffer, IndexType = (srcAttribute.Format == MgFormat.R32_UINT) ? MgIndexType.UINT32 : MgIndexType.UINT16, Offset = dstAttribute.Offset + dstInstance.MemoryOffset, }; found.IndexBuffer = indexInfo; } } var commands = new MeshDrawCommand[primitives.Count]; primitives.Values.CopyTo(commands, 0); return(commands); }
private static List <MgVertexInputBindingDescription> ExtractBindings(MgOptimizedStorageContainer container, BufferViewInfo[] bufferViews, List <GltfMeshAccessor> accessors) { var bindings = new List <MgVertexInputBindingDescription>(); const MgBufferUsageFlagBits VERT_MASK = MgBufferUsageFlagBits.VERTEX_BUFFER_BIT; for (var i = 0U; i < container.Storage.Blocks.Length; i += 1) { var srcBlock = bufferViews[i]; var dstBlock = container.Storage.Blocks[i]; if ((dstBlock.Usage & VERT_MASK) == VERT_MASK) { var byteStride = 0U; if (srcBlock.ByteStride.HasValue) { byteStride = (uint)srcBlock.ByteStride.Value; } else { foreach (var order in dstBlock.PackingOrder) { var attrIndex = (int)order; var srcAttribute = accessors[attrIndex]; var dstAttribute = container.Map.Allocations[attrIndex]; if ((dstAttribute.Usage & VERT_MASK) == VERT_MASK) { byteStride += (uint)(srcAttribute.ElementByteSize * srcAttribute.ElementCount); } } } var binding = new MgVertexInputBindingDescription { Binding = (uint)bindings.Count, InputRate = MgVertexInputRate.VERTEX, Stride = byteStride, }; bindings.Add(binding); } } return(bindings); }
MeshMetaData InitializeMetaData(MgOptimizedStorageContainer container, bool[] usedBufferViews, BufferViewInfo[] bufferViews, List <GltfMeshAccessor> accessors) { var bindings = ExtractBindings(container, bufferViews, accessors); var inputAttributes = ExtractAttributeDescriptions(container, accessors); var commands = ExtractDrawCommand(container, accessors); return(new MeshMetaData { Commands = commands, Pipeline = new MeshMetaPipeline { VertexBindingDescriptions = bindings.ToArray(), VertexAttributeDescriptions = inputAttributes.ToArray(), } }); }
private static List <MgVertexInputAttributeDescription> ExtractAttributeDescriptions(MgOptimizedStorageContainer container, List <GltfMeshAccessor> accessors) { const MgBufferUsageFlagBits VERT_MASK = MgBufferUsageFlagBits.VERTEX_BUFFER_BIT; var inputAttributes = new List <MgVertexInputAttributeDescription>(); for (var i = 0; i < accessors.Count; i += 1) { var srcAttribute = accessors[i]; var dstAttribute = container.Map.Allocations[i]; if ((dstAttribute.Usage & VERT_MASK) == VERT_MASK) { var attribute = new MgVertexInputAttributeDescription { Location = srcAttribute.LocationIndex, Binding = dstAttribute.BlockIndex, Format = srcAttribute.Format, Offset = (uint)dstAttribute.Offset, }; inputAttributes.Add(attribute); } } return(inputAttributes); }
public void Prepare(IMgGraphicsConfiguration configuration, IMgGraphicsDevice screen) { var loader = new Loader(); var dataLoader = new DataLoader(); var device = configuration.Device; using (var fs = File.Open("Data/Triangle.gltf", FileMode.Open)) { // load model file var model = glTFLoader.Interface.LoadModel(fs); // load meta data var metaData = loader.LoadMetaData(model); // load data var data = dataLoader.LoadData(".", model); var staticRequest = new MgStorageBlockAllocationRequest(); // allocate partitions for static data // mesh var meshLocations = AllocateMeshes(staticRequest, metaData.Meshes, metaData.Accessors, metaData.BufferViews); var meshPrimitives = ExtractMeshPrimitives(metaData.Materials, out MgtfMaterial[] sceneMaterials, metaData.Meshes, meshLocations); // images var images = ExamineImages(data.Images, data.Buffers); // initialize static data storage var staticCreateInfo = new MgOptimizedStorageCreateInfo { Allocations = staticRequest.ToArray(), }; mStaticStorage = mBuilder.Build(staticCreateInfo); // build static artifacts // render target // descriptor set layout + pipeline layout var pass = new ScenePass { RenderTarget = screen, Effects = new[] { new ScenePassEffect { Factory = mPbrFactory, EffectLayout = mPbrFactory.CreateEffectLayout(configuration.Device), } } }; pass.Initialize( configuration.Device, meshPrimitives, sceneMaterials); // allocate dynamic data var dynamicRequest = new MgStorageBlockAllocationRequest(); var limits = new MgPhysicalDeviceLimits(); var worldData = AllocateWorldData(dynamicRequest, limits.MaxUniformBufferRange); var storageIndices = AllocateMaterials(sceneMaterials, dynamicRequest, limits); // per instance data // build dynamic artifacts // semaphores // fences // descriptor sets // initialize dynamic data storage // copy data across // buffers // images // map dynamic data // build command buffers } }