public void CreateDevice() { /* * We create the logical device in this function. */ /* * When creating the device, we also specify what queues it has. */ // Store memory properties of the physical device. PhysicalDeviceMemoryProperties MemoryProperties = physicalDevice.GetMemoryProperties(); PhysicalDeviceFeatures Features = physicalDevice.GetFeatures(); PhysicalDeviceProperties Properties = physicalDevice.GetProperties(); // Create a logical device. var queueCreateInfos = new DeviceQueueCreateInfo[1]; queueCreateInfos[0] = new DeviceQueueCreateInfo(computeQueueFamilyIndex, 1, 1.0f); var deviceCreateInfo = new DeviceCreateInfo( queueCreateInfos, new[] { Constant.DeviceExtension.NVExternalMemory }, Features); device = physicalDevice.CreateDevice(deviceCreateInfo); // Get queue(s). queue = device.GetQueue(computeQueueFamilyIndex); // Create command pool(s). //commandPool = device.CreateCommandPool(new CommandPoolCreateInfo(computeQueueFamilyIndex)); }
protected unsafe DeviceMemory AllocateMemory(MemoryPropertyFlags memoryProperties, MemoryRequirements memoryRequirements) { var allocateInfo = new MemoryAllocateInfo { StructureType = StructureType.MemoryAllocateInfo, AllocationSize = memoryRequirements.Size, }; PhysicalDeviceMemoryProperties physicalDeviceMemoryProperties; physicalDevice.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; } return(device.AllocateMemory(ref allocateInfo)); }
AppGpu AppGpuInit(uint id, PhysicalDevice obj) { // TODO : Limits AppGpu gpu = new AppGpu { Id = id, Obj = obj, Props = obj.GetProperties(), QueueProps = obj.GetQueueFamilyProperties(), MemoryProps = obj.GetMemoryProperties(), Features = obj.GetFeatures(), Limits = null, }; gpu.QueueReqs = new DeviceQueueCreateInfo[gpu.QueueProps.Length]; for (uint i = 0; i < gpu.QueueProps.Length; i++) { uint queueCount = gpu.QueueProps[i].QueueCount; DeviceQueueCreateInfo queueReq = new DeviceQueueCreateInfo { QueueFamilyIndex = i, QueueCount = queueCount, QueuePriorities = new float[queueCount], }; gpu.QueueReqs[i] = queueReq; } gpu.Device = AppDevInit(gpu); AppDevInitFormats(gpu.Device); return(gpu); }
public void BindMemoryAndCreateView() { using (Image image = CreateImage()) { PhysicalDeviceMemoryProperties deviceMemProps = PhysicalDevice.GetMemoryProperties(); MemoryRequirements memReq = image.GetMemoryRequirements(); using (DeviceMemory memory = Device.AllocateMemory(new MemoryAllocateInfo( memReq.Size, deviceMemProps.MemoryTypes.IndexOf(memReq.MemoryTypeBits, 0)))) { image.BindMemory(memory); var createInfo = new ImageViewCreateInfo { Format = Format.B8G8R8A8UNorm, ViewType = ImageViewType.Image2D, SubresourceRange = new ImageSubresourceRange { AspectMask = ImageAspects.Color, LayerCount = 1, LevelCount = 1 } }; using (image.CreateView(createInfo)) { } using (image.CreateView(createInfo, CustomAllocator)) { } } } }
private void PickPhysicalDevice() { // Currently simply picks the first physical device. We might want a smarter choice here. PhysicalDevice = Instance.EnumeratePhysicalDevices()[0]; PhysicalDeviceFeatures = PhysicalDevice.GetFeatures(); PhysicalDeviceMemoryProperties = PhysicalDevice.GetMemoryProperties(); AvailableDeviceExtensions = PhysicalDevice.EnumerateExtensionProperties(); }
public void Write(PhysicalDevice physicalDevice) { WriteLine("PhysicalDeviceProperties:"); WriteLine("========================="); var properties = physicalDevice.GetProperties(); _tabs++; PhysicalDeviceProperties(properties); WriteLine("PhysicalDeviceLimits:"); WriteLine("---------------------"); var limits = properties.Limits; _tabs++; PhysicalDeviceLimits(limits); _tabs--; WriteLine("PhysicalDeviceSparseProperties:"); WriteLine("-------------------------------"); var sparse = properties.SparseProperties; _tabs++; PhysicalDeviceSparseProperties(sparse); _tabs = 0; WriteLine(""); var queueFamilyProperties = physicalDevice.GetQueueFamilyProperties(); for (int x = 0; x < queueFamilyProperties.Length; x++) { WriteLine($"QueueFamilyProperties[{x}]:"); WriteLine("=========================="); _tabs++; QueueFamilyProperties(queueFamilyProperties[x]); _tabs--; WriteLine(""); } _tabs = 0; WriteLine("PhysicalDeviceMemoryProperties"); WriteLine("=============================="); var physicalDeviceMemoryProperties = physicalDevice.GetMemoryProperties(); _tabs++; PhysicalDeviceMemoryProperties(physicalDeviceMemoryProperties); WriteLine(""); _tabs = 0; WriteLine("PhysicalDeviceFeatures:"); WriteLine("======================="); var features = physicalDevice.GetFeatures(); _tabs++; PhysicalDeviceFeatures(features); Console.WriteLine(_sb.ToString()); }
Buffer CreateBuffer(PhysicalDevice physicalDevice, object values, BufferUsageFlags usageFlags, System.Type type) { var array = values as System.Array; var length = (array != null) ? array.Length : 1; var size = System.Runtime.InteropServices.Marshal.SizeOf(type) * length; var createBufferInfo = new BufferCreateInfo { Size = size, Usage = usageFlags, SharingMode = SharingMode.Exclusive, QueueFamilyIndices = new uint [] { 0 } }; var buffer = device.CreateBuffer(createBufferInfo); var memoryReq = device.GetBufferMemoryRequirements(buffer); var allocInfo = new MemoryAllocateInfo { AllocationSize = memoryReq.Size }; var memoryProperties = physicalDevice.GetMemoryProperties(); bool heapIndexSet = false; var memoryTypes = memoryProperties.MemoryTypes; for (uint i = 0; i < memoryProperties.MemoryTypeCount; i++) { if (((memoryReq.MemoryTypeBits >> (int)i) & 1) == 1 && (memoryTypes [i].PropertyFlags & MemoryPropertyFlags.HostVisible) == MemoryPropertyFlags.HostVisible) { allocInfo.MemoryTypeIndex = i; heapIndexSet = true; } } if (!heapIndexSet) { allocInfo.MemoryTypeIndex = memoryProperties.MemoryTypes [0].HeapIndex; } var deviceMemory = device.AllocateMemory(allocInfo); var memPtr = device.MapMemory(deviceMemory, 0, size, 0); if (type == typeof(float)) { System.Runtime.InteropServices.Marshal.Copy(values as float [], 0, memPtr, length); } else if (type == typeof(short)) { System.Runtime.InteropServices.Marshal.Copy(values as short [], 0, memPtr, length); } else if (type == typeof(AreaUniformBuffer)) { System.Runtime.InteropServices.Marshal.StructureToPtr(values, memPtr, false); } device.UnmapMemory(deviceMemory); device.BindBufferMemory(buffer, deviceMemory, 0); return(buffer); }
public void GetMemoryProperties() { PhysicalDeviceMemoryProperties properties = PhysicalDevice.GetMemoryProperties(); Assert.True(properties.MemoryHeaps.Length > 0); Assert.True(properties.MemoryHeaps.All(x => x.Size > 0)); Assert.True(properties.MemoryTypes.Length > 0); Assert.True(properties.MemoryTypes.All(x => x.HeapIndex >= 0 && x.HeapIndex < properties.MemoryHeaps.Length)); }
public PhysicalDeviceInfo(PhysicalDevice physicalDevice) { PhysicalDevice = physicalDevice; Properties = PhysicalDevice.GetProperties(); QueueFamilyProperties = PhysicalDevice.GetQueueFamilyProperties(); MemoryProperties = PhysicalDevice.GetMemoryProperties(); Features = PhysicalDevice.GetFeatures(); GraphicsQFamilies = Array.AsReadOnly(QueueFamiliesWithFlag(QueueFlags.Graphics)); ComputeQFamilies = Array.AsReadOnly(QueueFamiliesWithFlag(QueueFlags.Compute)); TransferQFamilies = Array.AsReadOnly(QueueFamiliesWithFlag(QueueFlags.Transfer)); SparseBindingQFamilies = Array.AsReadOnly(QueueFamiliesWithFlag(QueueFlags.SparseBinding)); }
public void InvalidateMappedMemoryRange() { PhysicalDeviceMemoryProperties memoryProperties = PhysicalDevice.GetMemoryProperties(); int memoryTypeIndex = memoryProperties.MemoryTypes.IndexOf(~0, MemoryProperties.HostVisible); const int size = 1024; using (var memory = Device.AllocateMemory(new MemoryAllocateInfo(size, memoryTypeIndex))) { memory.Map(0, size); Device.InvalidateMappedMemoryRange(new MappedMemoryRange(memory, 0, size)); Device.InvalidateMappedMemoryRanges(new MappedMemoryRange(memory, 0, size)); memory.Unmap(); } }
private uint FindMemoryType(uint typeFilter, MemoryPropertyFlags properties) { var memProperties = vkPhysicalDevice.GetMemoryProperties(); for (var i = 0; i < memProperties.MemoryTypeCount; ++i) { if ((typeFilter & (1 << i)) != 0 && (memProperties.MemoryTypes[i].PropertyFlags & properties) != 0) { return((uint)i); } } throw new InvalidOperationException("Failed to find suitable memory type"); }
static uint FindMemoryType(PhysicalDevice physicalDevice, uint typeFilter, MemoryPropertyFlags propertyFlags) { var memProperties = physicalDevice.GetMemoryProperties(); uint i = 0; foreach (var memType in memProperties.MemoryTypes) { if ((((typeFilter >> (int)i) & 1) == 1) && ((memType.PropertyFlags & propertyFlags) == propertyFlags)) { return(i); } i++; } MGlobal.displayError("failed to find memory type"); throw new Exception("failed to find memory type"); }
public void BindMemoryAndCreateBufferView() { using (Buffer buffer = CreateBuffer()) { PhysicalDeviceMemoryProperties deviceMemProps = PhysicalDevice.GetMemoryProperties(); MemoryRequirements memReq = buffer.GetMemoryRequirements(); var memoryAllocateInfo = new MemoryAllocateInfo( memReq.Size, deviceMemProps.MemoryTypes.IndexOf(memReq.MemoryTypeBits, 0)); using (DeviceMemory memory = Device.AllocateMemory(memoryAllocateInfo)) { buffer.BindMemory(memory); var bufferViewCreateInfo = new BufferViewCreateInfo(Format.R32UInt); using (buffer.CreateView(bufferViewCreateInfo)) { } using (buffer.CreateView(bufferViewCreateInfo, CustomAllocator)) { } } } }
internal HostDevice( PhysicalDevice vulkanPhysicaldevice, SurfaceType surfaceType, Logger logger = null) { if (vulkanPhysicaldevice == null) { throw new ArgumentNullException(nameof(vulkanPhysicaldevice)); } this.physicalDevice = vulkanPhysicaldevice; this.surfaceType = surfaceType; this.logger = logger; this.properties = vulkanPhysicaldevice.GetProperties(); this.deviceMemoryProperties = vulkanPhysicaldevice.GetMemoryProperties(); this.supportedFeatures = vulkanPhysicaldevice.GetFeatures(); this.availableExtensions = vulkanPhysicaldevice.EnumerateExtensionProperties(); this.queueFamilies = vulkanPhysicaldevice.GetQueueFamilyProperties(); logger?.Log(nameof(HostDevice), $"Found device: {Name}"); logger?.LogList(nameof(HostDevice), $"{Name} available extensions:", availableExtensions); }
public Context(GameWindow window) { Window = window; Instance = ToDispose(VKHelper.CreateInstance()); DebugReportCallback = ToDispose(VKHelper.CreateDebugReportCallback(Instance)); Surface = ToDispose(VKHelper.CreateSurface(Instance, Window.Handle)); foreach (PhysicalDevice physicalDevice in Instance.EnumeratePhysicalDevices()) { QueueFamilyProperties[] queueFamilyProperties = physicalDevice.GetQueueFamilyProperties(); for (int i = 0; i < queueFamilyProperties.Length; i++) { if (queueFamilyProperties[i].QueueFlags.HasFlag(Queues.Graphics)) { if (GraphicsQueueFamilyIndex == -1) { GraphicsQueueFamilyIndex = i; } if (ComputeQueueFamilyIndex == -1) { ComputeQueueFamilyIndex = i; } if (physicalDevice.GetSurfaceSupportKhr(i, Surface) && VKHelper.GetPresentationSupport(physicalDevice, i)) { PresentQueueFamilyIndex = i; } if (GraphicsQueueFamilyIndex != -1 && ComputeQueueFamilyIndex != -1 && PresentQueueFamilyIndex != -1) { PhysicalDevice = physicalDevice; break; } } } if (PhysicalDevice != null) { break; } } if (PhysicalDevice == null) { throw new InvalidOperationException("No suitable physical device found."); } GenerateDepthStencilFormat(); // Store memory properties of the physical device. MemoryProperties = PhysicalDevice.GetMemoryProperties(); Features = PhysicalDevice.GetFeatures(); Properties = PhysicalDevice.GetProperties(); // Create a logical device. bool sameGraphicsAndPresent = GraphicsQueueFamilyIndex == PresentQueueFamilyIndex; var queueCreateInfos = new DeviceQueueCreateInfo[sameGraphicsAndPresent ? 1 : 2]; queueCreateInfos[0] = new DeviceQueueCreateInfo(GraphicsQueueFamilyIndex, 1, 1.0f); if (!sameGraphicsAndPresent) { queueCreateInfos[1] = new DeviceQueueCreateInfo(PresentQueueFamilyIndex, 1, 1.0f); } var deviceCreateInfo = new DeviceCreateInfo( queueCreateInfos, new[] { Constant.DeviceExtension.KhrSwapchain, Constant.DeviceExtension.KhrMaintenance1 }, Features); Device = PhysicalDevice.CreateDevice(deviceCreateInfo); // Get queue(s). GraphicsQueue = Device.GetQueue(GraphicsQueueFamilyIndex); ComputeQueue = ComputeQueueFamilyIndex == GraphicsQueueFamilyIndex ? GraphicsQueue : Device.GetQueue(ComputeQueueFamilyIndex); PresentQueue = PresentQueueFamilyIndex == GraphicsQueueFamilyIndex ? GraphicsQueue : Device.GetQueue(PresentQueueFamilyIndex); Content = new Content(this); GraphicsCommandPool = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(GraphicsQueueFamilyIndex, CommandPoolCreateFlags.ResetCommandBuffer))); ComputeCommandPool = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(ComputeQueueFamilyIndex))); Graphics = ToDispose(new Graphics(this)); Build(); }
public VulkanContext(Instance instance, SurfaceKhr surface, Platform platform) { // Find graphics and presentation capable physical device(s) that support // the provided surface for platform. int graphicsQueueFamilyIndex = -1; int computeQueueFamilyIndex = -1; int presentQueueFamilyIndex = -1; foreach (PhysicalDevice physicalDevice in instance.EnumeratePhysicalDevices()) { QueueFamilyProperties[] queueFamilyProperties = physicalDevice.GetQueueFamilyProperties(); for (int i = 0; i < queueFamilyProperties.Length; i++) { if (queueFamilyProperties[i].QueueFlags.HasFlag(Queues.Graphics)) { if (graphicsQueueFamilyIndex == -1) { graphicsQueueFamilyIndex = i; } if (computeQueueFamilyIndex == -1) { computeQueueFamilyIndex = i; } if (physicalDevice.GetSurfaceSupportKhr(i, surface) && GetPresentationSupport(physicalDevice, i)) { presentQueueFamilyIndex = i; } if (graphicsQueueFamilyIndex != -1 && computeQueueFamilyIndex != -1 && presentQueueFamilyIndex != -1) { PhysicalDevice = physicalDevice; break; } } } if (PhysicalDevice != null) { break; } } bool GetPresentationSupport(PhysicalDevice physicalDevice, int queueFamilyIndex) { switch (platform) { case Platform.Android: return(true); case Platform.Win32: return(physicalDevice.GetWin32PresentationSupportKhr(queueFamilyIndex)); default: throw new NotImplementedException(); } } if (PhysicalDevice == null) { throw new InvalidOperationException("No suitable physical device found."); } // Store memory properties of the physical device. MemoryProperties = PhysicalDevice.GetMemoryProperties(); Features = PhysicalDevice.GetFeatures(); Properties = PhysicalDevice.GetProperties(); // Create a logical device. bool sameGraphicsAndPresent = graphicsQueueFamilyIndex == presentQueueFamilyIndex; var queueCreateInfos = new DeviceQueueCreateInfo[sameGraphicsAndPresent ? 1 : 2]; queueCreateInfos[0] = new DeviceQueueCreateInfo(graphicsQueueFamilyIndex, 1, 1.0f); if (!sameGraphicsAndPresent) { queueCreateInfos[1] = new DeviceQueueCreateInfo(presentQueueFamilyIndex, 1, 1.0f); } var deviceCreateInfo = new DeviceCreateInfo( queueCreateInfos, new[] { Constant.DeviceExtension.KhrSwapchain }, Features); Device = PhysicalDevice.CreateDevice(deviceCreateInfo); // Get queue(s). GraphicsQueue = Device.GetQueue(graphicsQueueFamilyIndex); ComputeQueue = computeQueueFamilyIndex == graphicsQueueFamilyIndex ? GraphicsQueue : Device.GetQueue(computeQueueFamilyIndex); PresentQueue = presentQueueFamilyIndex == graphicsQueueFamilyIndex ? GraphicsQueue : Device.GetQueue(presentQueueFamilyIndex); // Create command pool(s). GraphicsCommandPool = Device.CreateCommandPool(new CommandPoolCreateInfo(graphicsQueueFamilyIndex)); ComputeCommandPool = Device.CreateCommandPool(new CommandPoolCreateInfo(computeQueueFamilyIndex)); }
private static IEnumerable <MemoryTypeInfo> GetMemoryTypesAllowed(PhysicalDevice physicalDevice, uint memoryTypeBits) { var memoryTypes = physicalDevice.GetMemoryProperties().MemoryTypes; return(memoryTypes.Select((m, i) => new MemoryTypeInfo(i, m)).Where(m => ((memoryTypeBits >> m.MemoryTypeIndex) & 0x01) != 0)); }
/// <summary> /// Construct a Graphics object belonging to a window /// </summary> /// <param name="window"></param> public Graphics(WyvernWindow window) { // Argument checks if (window is null) { throw new ArgumentNullException(nameof(window)); } // Initialize the static part of Graphics if necessary InitializeStatic(); // Store window Window = window; // Create window surface { AllocationCallbacks?allocationCallbacks = null; Surface = new SurfaceKhr( Instance, ref allocationCallbacks, VkGLFW3.VkGlfw.CreateWindowSurface(Instance.Handle, Window, IntPtr.Zero) ); Surface.PrintDebug(); } // Choose a physical device { PhysicalDevice = Instance.EnumeratePhysicalDevices() .Where(e => GetDeviceMeetsRequirements(e, Surface)) .OrderByDescending(GetDeviceScore) .FirstOrDefault(); if (PhysicalDevice is null) { throw new InvalidOperationException("No physical device found that meets the requirements for the application"); } MemoryProperties = PhysicalDevice.GetMemoryProperties(); } // Create default queue families { ComputeQueueFamily = new QueueFamily( $"{Name}'s {nameof(ComputeQueueFamily)}", this, QueueFamily.QueueType.Compute, 2, true, ComputeCommandPoolFlags ); GraphicsQueueFamily = new QueueFamily( $"{Name}'s {nameof(GraphicsQueueFamily)}", this, QueueFamily.QueueType.Graphics, 2, true, GraphicsCommandPoolFlags ); TransferQueueFamily = new QueueFamily( $"{Name}'s {nameof(TransferQueueFamily)}", this, QueueFamily.QueueType.Transfer, 2, true, TransferCommandPoolFlags ); PresentQueueFamily = new QueueFamily( $"{Name}'s {nameof(PresentQueueFamily)}", this, QueueFamily.QueueType.Present, 1, false ); } // Create a logical device { // Generate queue create info structs var queueCreateInfos = QueueFamilies.Select(queueFamily => { // Generate queue priorities var priorities = new float[queueFamily.Count]; for (var i = 0; i < priorities.Length; i++) { priorities[i] = 1f - (i / (float)(priorities.Length - 1)); } // Create create info var createInfo = new DeviceQueueCreateInfo() { QueueFamilyIndex = queueFamily.Index, QueueCount = queueFamily.Count, QueuePriorities = priorities }; return(createInfo); }); // Merge multiple queue families' queue create infos { var alreadyHave = new List <int>(); var uniqueCreateInfos = new List <DeviceQueueCreateInfo>(); foreach (var createInfo in queueCreateInfos.OrderByDescending(e => e.QueueCount)) { if (!alreadyHave.Contains(createInfo.QueueFamilyIndex)) { alreadyHave.Add(createInfo.QueueFamilyIndex); uniqueCreateInfos.Add(createInfo); } } queueCreateInfos = uniqueCreateInfos; foreach (var createInfo in queueCreateInfos) { createInfo.PrintDebug(); } } // Create device Device = PhysicalDevice.CreateDevice(new DeviceCreateInfo() { EnabledExtensionNames = EnabledDeviceExtensions.ToArray(), QueueCreateInfos = queueCreateInfos.ToArray(), EnabledFeatures = EnabledPhysicalDeviceFeatures }); // Set the queues in the queue families, using those created with the device foreach (var family in QueueFamilies) { var queues = new Queue[family.Count]; for (var i = 0; i < queues.Length; i++) { queues[i] = Device.GetQueue(family.Index, i); } family.SetQueues(queues); } // Create and set the command pools in the queue families foreach (var family in QueueFamilies) { // Skip family that shouldn't have a command pool if (!family.HasCommandPool) { continue; } // Create command pool var commandPool = Device.CreateCommandPool(new CommandPoolCreateInfo() { QueueFamilyIndex = family.Index, Flags = family.CommandPoolFlags }); family.SetCommandPool(commandPool); } } // Create swapchain { // Query supported capabilities and formats var surfaceCapabilities = SurfaceCapabilities; var surfaceFormats = SurfaceFormats; var surfacePresentModes = SurfacePresentModes; surfaceCapabilities.PrintDebug(); // Choose the best image format and color space { var imageFormat = Array.Find( PreferredSwapchainFormats, preferred => surfaceFormats.Any(available => available.Format == preferred) ); if (imageFormat == Format.Undefined) { imageFormat = surfaceFormats.FirstOrDefault().Format; } if (imageFormat == Format.Undefined) { throw new InvalidOperationException("Surface somehow does not support any known image formats"); } SwapchainImageFormat = imageFormat; SwapchainColorSpace = surfaceFormats.First(e => e.Format == SwapchainImageFormat).ColorSpace; } // Choose the best present mode { var presentMode = Array.Find( PreferredPresentModes, preferred => surfacePresentModes.Any(available => available == preferred) ); SwapchainPresentMode = presentMode; } // Create the swapchain SwapchainExtent = surfaceCapabilities.CurrentExtent; Swapchain = Device.CreateSwapchainKhr(new SwapchainCreateInfoKhr( surface: Surface, imageFormat: SwapchainImageFormat, imageExtent: SwapchainExtent, preTransform: surfaceCapabilities.CurrentTransform, presentMode: SwapchainPresentMode, minImageCount: SurfaceCapabilities.MinImageCount, imageArrayLayers: SurfaceCapabilities.MaxImageArrayLayers, imageSharingMode: SharingMode.Exclusive, imageColorSpace: SwapchainColorSpace )); SwapchainAttachmentImages = Swapchain.GetImages().Select( e => new VKImage( e, SwapchainImageFormat, SwapchainExtent, new ImageSubresourceRange(ImageAspects.Color, 0, 1, 0, 1) ) ).ToArray(); Swapchain.PrintDebug(); } // Create semaphores & fences { // Image available semaphore ImageAvailableSemaphore = Device.CreateSemaphore(); ReadyToPresentSemaphore = Device.CreateSemaphore(); // Swapchain image rendering fences RenderToImageFences = new Fence[SwapchainAttachmentImages.Length]; for (var i = 0; i < RenderToImageFences.Length; i++) { RenderToImageFences[i] = Device.CreateFence(new FenceCreateInfo(flags: FenceCreateFlags.Signaled)); } } // Create content collection { Content = new ContentCollection(this); } // Misc Stopwatch = Stopwatch.StartNew(); CurrentTime = 0.0; }