protected unsafe void AllocateMemory(MemoryPropertyFlags memoryProperties) { MemoryRequirements memoryRequirements; NativeDevice.GetBufferMemoryRequirements(nativeUploadBuffer, out memoryRequirements); if (memoryRequirements.Size == 0) { return; } var allocateInfo = new MemoryAllocateInfo { StructureType = StructureType.MemoryAllocateInfo, AllocationSize = memoryRequirements.Size, }; PhysicalDeviceMemoryProperties physicalDeviceMemoryProperties; NativePhysicalDevice.GetMemoryProperties(out physicalDeviceMemoryProperties); var typeBits = memoryRequirements.MemoryTypeBits; for (uint i = 0; i < physicalDeviceMemoryProperties.MemoryTypeCount; i++) { if ((typeBits & 1) == 1) { // Type is available, does it match user properties? var memoryType = *((MemoryType *)&physicalDeviceMemoryProperties.MemoryTypes + i); if ((memoryType.PropertyFlags & memoryProperties) == memoryProperties) { allocateInfo.MemoryTypeIndex = i; break; } } typeBits >>= 1; } nativeUploadBufferMemory = NativeDevice.AllocateMemory(ref allocateInfo); NativeDevice.BindBufferMemory(nativeUploadBuffer, nativeUploadBufferMemory, 0); }
/// <summary> /// Initializes the specified device. /// </summary> /// <param name="graphicsProfiles">The graphics profiles.</param> /// <param name="deviceCreationFlags">The device creation flags.</param> /// <param name="windowHandle">The window handle.</param> private unsafe void InitializePlatformDevice(GraphicsProfile[] graphicsProfiles, DeviceCreationFlags deviceCreationFlags, object windowHandle) { if (nativeDevice != Device.Null) { // Destroy previous device ReleaseDevice(); } rendererName = Adapter.Description; PhysicalDeviceProperties physicalDeviceProperties; NativePhysicalDevice.GetProperties(out physicalDeviceProperties); ConstantBufferDataPlacementAlignment = (int)physicalDeviceProperties.Limits.MinUniformBufferOffsetAlignment; RequestedProfile = graphicsProfiles.Last(); var queueProperties = NativePhysicalDevice.QueueFamilyProperties; // Command lists are thread-safe and execute deferred IsDeferred = true; // TODO VULKAN // Create Vulkan device based on profile uint queuePriorities = 0; var queueCreateInfo = new DeviceQueueCreateInfo { StructureType = StructureType.DeviceQueueCreateInfo, QueueFamilyIndex = 0, QueueCount = 1, QueuePriorities = new IntPtr(&queuePriorities) }; var enabledFeature = new PhysicalDeviceFeatures { FillModeNonSolid = true, ShaderClipDistance = true, ShaderCullDistance = true, SamplerAnisotropy = true, DepthClamp = true, }; var extensionProperties = NativePhysicalDevice.GetDeviceExtensionProperties(); var availableExtensionNames = new List <string>(); var desiredExtensionNames = new List <string>(); for (int index = 0; index < extensionProperties.Length; index++) { var namePointer = new IntPtr(Interop.Fixed(ref extensionProperties[index].ExtensionName)); var name = Marshal.PtrToStringAnsi(namePointer); availableExtensionNames.Add(name); } desiredExtensionNames.Add("VK_KHR_swapchain"); if (!availableExtensionNames.Contains("VK_KHR_swapchain")) { throw new InvalidOperationException(); } if (availableExtensionNames.Contains("VK_EXT_debug_marker") && IsDebugMode) { desiredExtensionNames.Add("VK_EXT_debug_marker"); IsProfilingSupported = true; } var enabledExtensionNames = desiredExtensionNames.Select(Marshal.StringToHGlobalAnsi).ToArray(); try { var deviceCreateInfo = new DeviceCreateInfo { StructureType = StructureType.DeviceCreateInfo, QueueCreateInfoCount = 1, QueueCreateInfos = new IntPtr(&queueCreateInfo), EnabledExtensionCount = (uint)enabledExtensionNames.Length, EnabledExtensionNames = enabledExtensionNames.Length > 0 ? new IntPtr(Interop.Fixed(enabledExtensionNames)) : IntPtr.Zero, EnabledFeatures = new IntPtr(&enabledFeature) }; nativeDevice = NativePhysicalDevice.CreateDevice(ref deviceCreateInfo); } finally { foreach (var enabledExtensionName in enabledExtensionNames) { Marshal.FreeHGlobal(enabledExtensionName); } } NativeCommandQueue = nativeDevice.GetQueue(0, 0); //// Prepare copy command list (start it closed, so that every new use start with a Reset) var commandPoolCreateInfo = new CommandPoolCreateInfo { StructureType = StructureType.CommandPoolCreateInfo, QueueFamilyIndex = 0, //device.NativeCommandQueue.FamilyIndex Flags = CommandPoolCreateFlags.ResetCommandBuffer }; NativeCopyCommandPool = NativeDevice.CreateCommandPool(ref commandPoolCreateInfo); var commandBufferAllocationInfo = new CommandBufferAllocateInfo { StructureType = StructureType.CommandBufferAllocateInfo, Level = CommandBufferLevel.Primary, CommandPool = NativeCopyCommandPool, CommandBufferCount = 1 }; CommandBuffer nativeCommandBuffer; NativeDevice.AllocateCommandBuffers(ref commandBufferAllocationInfo, &nativeCommandBuffer); NativeCopyCommandBuffer = nativeCommandBuffer; DescriptorPools = new HeapPool(this); nativeResourceCollector = new NativeResourceCollector(this); graphicsResourceLinkCollector = new GraphicsResourceLinkCollector(this); EmptyTexelBuffer = Buffer.Typed.New(this, 1, PixelFormat.R32G32B32A32_Float); }