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 BufferInfo(IMgThreadPartition partition, MgBufferUsageFlagBits usage, MgMemoryPropertyFlagBits propertyFlags, uint bufferSize) { Debug.Assert(partition != null); mDevice = partition.Device; Debug.Assert(mDevice != null); mUsageFlags = usage; mMemoryPropertyFlags = propertyFlags; var bufferCreateInfo = new MgBufferCreateInfo { Usage = usage, Size = bufferSize, }; IMgBuffer buffer; var device = partition.Device; var result = device.CreateBuffer(bufferCreateInfo, null, out buffer); Debug.Assert(result == Result.SUCCESS); MgMemoryRequirements memReqs; device.GetBufferMemoryRequirements(buffer, out memReqs); mAlignment = memReqs.Alignment; mBufferSize = memReqs.Size; uint memoryTypeIndex; partition.GetMemoryType(memReqs.MemoryTypeBits, mMemoryPropertyFlags, out memoryTypeIndex); var memAlloc = new MgMemoryAllocateInfo { MemoryTypeIndex = memoryTypeIndex, AllocationSize = memReqs.Size, }; IMgDeviceMemory deviceMemory; result = device.AllocateMemory(memAlloc, null, out deviceMemory); Debug.Assert(result == Result.SUCCESS); buffer.BindBufferMemory(device, deviceMemory, 0); mBuffer = buffer; mDeviceMemory = deviceMemory; mDescriptor = new MgDescriptorBufferInfo { Buffer = mBuffer, Offset = 0, Range = mBufferSize, }; }
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 uint DetermineBufferMemoryType(MgBufferUsageFlagBits usage) { var flags = MgBufferUsageFlagBits.STORAGE_BUFFER_BIT; // 1st precedence if ((usage & flags) == flags) { return(GLMemoryBufferType.SSBO.GetMask()); } flags = MgBufferUsageFlagBits.VERTEX_BUFFER_BIT; if ((usage & flags) == flags) { return(GLMemoryBufferType.VERTEX.GetMask()); } flags = MgBufferUsageFlagBits.INDIRECT_BUFFER_BIT; if ((usage & flags) == flags) { return(GLMemoryBufferType.INDIRECT.GetMask()); } flags = MgBufferUsageFlagBits.UNIFORM_BUFFER_BIT; if ((usage & flags) == flags) { return(GLMemoryBufferType.UNIFORM.GetMask()); } flags = MgBufferUsageFlagBits.INDEX_BUFFER_BIT; if ((usage & flags) == flags) { return(GLMemoryBufferType.INDEX.GetMask()); } flags = MgBufferUsageFlagBits.TRANSFER_DST_BIT; if ((usage & flags) == flags) { return(GLMemoryBufferType.TRANSFER_DST.GetMask()); } flags = MgBufferUsageFlagBits.TRANSFER_SRC_BIT; if ((usage & flags) == flags) { return(GLMemoryBufferType.TRANSFER_SRC.GetMask()); } else { throw new NotSupportedException("BufferMemoryType not supported"); } }
private MgBufferUsageFlagBits?[] TransformAttributes(MgStorageBlockAllocationInfo[] attributes) { var unallocatedAttributes = new MgBufferUsageFlagBits?[attributes.Length]; for (var i = 0; i < unallocatedAttributes.Length; i += 1) { MgBufferUsageFlagBits original = attributes[i].Usage; bool isFound = mLayout.PreTransforms.TryGetValue( original, out MgBufferUsageFlagBits updated); unallocatedAttributes[i] = isFound ? updated : original; } return(unallocatedAttributes); }
public void AsStorageBufferUsage() { var expected = MgBufferUsageFlagBits.STORAGE_BUFFER_BIT; var selector = new PerMaterialTextureStorageQuery( new MgPhysicalDeviceLimits { MaxPerStageDescriptorStorageBuffers = 1, MaxUniformBufferRange = 100, MaxStorageBufferRange = 1000, } ); MgBufferUsageFlagBits actual = selector.GetAppropriateBufferUsage(); Assert.AreEqual(expected, actual); }
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); }
public uint GetElementRange( MgBufferUsageFlagBits usage, uint texturesPerMaterial, uint sizeOfBlock ) { var countPerMaxTextures = mLimits.MaxPerStageDescriptorSampledImages / texturesPerMaterial; var maxBufferSize = (usage == MgBufferUsageFlagBits.STORAGE_BUFFER_BIT) ? mLimits.MaxStorageBufferRange : mLimits.MaxUniformBufferRange; var countPerBlockSize = maxBufferSize / sizeOfBlock; return(Math.Min(countPerBlockSize, countPerMaxTextures)); }
public void BindBufferRange(MgBufferUsageFlagBits usage, int index, int buffer, IntPtr offset, ulong size) { // GL.BindBufferRange(); }
private bool DoPack(MgStorageBlockInfo sector, MgOptimizedStorageCreateInfo createInfo, out MgStorageBufferInstance instance) { MgBufferUsageFlagBits bufferUsage = 0; MgMemoryPropertyFlagBits deviceMemoryProperties = 0; var sortedList = new SortedDictionary <SortedKey, uint>(); foreach (var attr in sector.Attributes) { bufferUsage |= attr.Usage; deviceMemoryProperties |= createInfo.Allocations[attr.Index].MemoryPropertyFlags; var firstGroup = 0U; for (var i = 0U; i < mPackingOrder.Length; i += 1) { firstGroup = i; var first = (mPackingOrder[i] & createInfo.Allocations[attr.Index].Usage) > 0; if (first) { break; } } Debug.Assert(firstGroup <= mPackingOrder.Length); var key = new SortedKey { Group = firstGroup, SubOrder = attr.Index, }; sortedList.Add(key, attr.Index); } ulong overallSize = 0; var pCreateInfo = new MgBufferCreateInfo { SharingMode = createInfo.SharingMode, QueueFamilyIndices = createInfo.QueueFamilyIndices, Size = 0, Usage = bufferUsage, }; // The alignment member is identical for all VkBuffer objects created with the same combination of values // for the usage and flags members in the VkBufferCreateInfo structure passed to vkCreateBuffer. var err = mConfiguration.Device.CreateBuffer(pCreateInfo, null, out IMgBuffer pZeroBuffer); if (err != Result.SUCCESS) { instance = null; return(false); } mConfiguration.Device.GetBufferMemoryRequirements(pZeroBuffer, out MgMemoryRequirements pZeroMemReqs); pZeroBuffer.DestroyBuffer(mConfiguration.Device, null); var requiredAlignment = pZeroMemReqs.Alignment; var mappings = new List <MgStorageBufferOffset>(); foreach (var element in sortedList.Values) { var attr = createInfo.Allocations[element]; var mapping = new MgStorageBufferOffset { Index = element, Offset = UpperBounded(overallSize, requiredAlignment), Size = attr.Size, Usage = attr.Usage, }; mappings.Add(mapping); overallSize = mapping.Offset + mapping.Size; } // Real memory allocation pCreateInfo.Size = overallSize; err = mConfiguration.Device.CreateBuffer(pCreateInfo, null, out IMgBuffer pBuffer); if (err != Result.SUCCESS) { instance = null; return(false); } mConfiguration.Device.GetBufferMemoryRequirements(pBuffer, out MgMemoryRequirements pMemReqs); if (mConfiguration.MemoryProperties.GetMemoryType(pMemReqs.MemoryTypeBits, deviceMemoryProperties, out uint typeIndex)) { instance = new MgStorageBufferInstance { Buffer = pBuffer, Usage = bufferUsage, MemoryPropertyFlags = deviceMemoryProperties, TypeIndex = typeIndex, AllocationSize = pMemReqs.Size, Mappings = mappings.ToArray(), }; return(true); } else { // CLEAN UP pBuffer.DestroyBuffer(mConfiguration.Device, null); instance = null; return(false); } }