public ComputeShader(Vk vk, Instance instance, Device device, PhysicalDevice physicalDevice, PipelineLayout pipelineLayout, ReadOnlySpan <byte> data, string functionName, SpecializationInfo *specializationInfo) { var subgroupProperties = new PhysicalDeviceSubgroupProperties(pNext: null); var properties = new PhysicalDeviceProperties2(pNext: &subgroupProperties); vk.GetPhysicalDeviceProperties2(physicalDevice, &properties); var subgroupSize = subgroupProperties.SubgroupSize; Console.WriteLine($"Detected subgroup size {subgroupSize}"); var data2 = new byte[data.Length + 32]; data.CopyTo(data2); _vk = vk; _device = device; ShaderModule shaderModule; fixed(byte *pData = data2) _vk.CreateShaderModule(_device, new ShaderModuleCreateInfo(codeSize: (nuint)data.Length, pCode: (uint *)pData), null, out shaderModule).ThrowCode(); try { var pName = SilkMarshal.StringToPtr(functionName); try { PipelineCreateFlags flags = 0; _vk.CreateComputePipelines(_device, default, 1, new ComputePipelineCreateInfo(flags: flags , layout: pipelineLayout, stage: new PipelineShaderStageCreateInfo(stage: ShaderStageFlags.ShaderStageComputeBit, module: shaderModule, pName: (byte *)pName, pSpecializationInfo: specializationInfo)), null, out _pipeline).ThrowCode(); }
public unsafe ShaderProgram(GL gl, ShaderType shaderType, string path) : base(gl) { void CacheUniformsImpl() { GL.GetProgram(Handle, ProgramPropertyARB.ActiveUniforms, out int uniformCount); for (uint uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) { string name = GL.GetActiveUniform(Handle, uniformIndex, out _, out _); int location = GL.GetUniformLocation(Handle, name); _CachedUniforms.Add(name, location); } } _CachedUniforms = new Dictionary <string, int>(); Type = shaderType; // this is kinda dumb, right? byte *shader = (byte *)SilkMarshal.StringToPtr(File.ReadAllText(path)); Handle = GL.CreateShaderProgram(Type, 1, shader); CheckInfoLogAndThrow(); CacheUniformsImpl(); Log.Debug(string.Format(FormatHelper.DEFAULT_LOGGING, nameof(ShaderProgram), $"Loaded ({Type}): {path}")); }
private unsafe void Name(ObjectType type, ulong handle, string name) { if (_debugUtils is not null) { var ptr = SilkMarshal.StringToPtr(name); _debugUtils.SetDebugUtilsObjectName(_logicalDevice, new DebugUtilsObjectNameInfoEXT(objectType: type, objectHandle: handle, pObjectName: (byte *)ptr)) .ThrowCode(); SilkMarshal.Free(ptr); } }
private static unsafe PipelineShaderStageCreateInfo ShaderStageCreateInfo(ShaderModule module, ShaderStageFlags stage) { return(new PipelineShaderStageCreateInfo() { SType = StructureType.PipelineShaderStageCreateInfo, Module = module, PName = (byte *)SilkMarshal.StringToPtr("main"), PSpecializationInfo = null, Stage = stage }); }
public static unsafe Func <string, nint> GetLoader(bool alwaysPresent, out nint loaderPtr, out nint ctxLoaderPtr) { var wrapper = new nint[2]; var theDelegate = (LoaderDelegate)Loader; // The wrapper array is so the delegates can use eachothers resources without having to worry about // modifications outside of the delegate's scope. wrapper[0] = loaderPtr = SilkMarshal.DelegateToPtr(theDelegate); wrapper[1] = ctxLoaderPtr = SilkMarshal.DelegateToPtr((ContextLoaderDelegate)((_, x) => theDelegate(x))); return(x => theDelegate((byte *)SilkMarshal.StringToPtr(x))); nint Loader(byte *x) => SilkMarshal.PtrToString((nint)x) switch { "alcIsExtensionPresent" or "alIsExtensionPresent" => alwaysPresent ? (nint)(delegate * unmanaged[Cdecl] < byte *, int >) & AlwaysOne : (nint)(delegate * unmanaged[Cdecl] < byte *, int >) & AlwaysZero, "alGetProcAddress" => wrapper[0], "alcGetProcAddress" => wrapper[1], "alGetEnumValue" => (nint)(delegate * unmanaged[Cdecl] < byte *, int >) & AlwaysZero, _ => 0 }; }
public static unsafe Instance CreateInstance(string[] instanceLayers, string[] instanceExtensions, IVkSurface windowSurface) { ApplicationInfo appInfo = new() { SType = StructureType.ApplicationInfo, PApplicationName = (byte *)SilkMarshal.StringToPtr("SilkyNvg-Vulkan-Example"), ApplicationVersion = Vk.MakeVersion(1, 0, 0), PEngineName = (byte *)SilkMarshal.StringToPtr("SilkyNvg (Renderer: Vulkan)"), EngineVersion = Vk.MakeVersion(1, 0, 0), ApiVersion = Vk.Version12 }; byte **windowExtensionsPtr = windowSurface.GetRequiredExtensions(out uint windowExtensionCount); byte **instanceExtensionsPtr = (byte **)SilkMarshal.StringArrayToPtr(instanceExtensions); byte **extensions = stackalloc byte *[(int)windowExtensionCount + instanceExtensions.Length]; int i = 0; for (; i < windowExtensionCount; i++) { extensions[i] = windowExtensionsPtr[i]; } for (; i < windowExtensionCount + instanceExtensions.Length; i++) { extensions[i] = instanceExtensionsPtr[i]; } CheckInstanceExtensionsPresent(extensions, (int)windowExtensionCount + instanceExtensions.Length); CheckInstanceLayersPresent(instanceLayers); byte **layers = (byte **)SilkMarshal.StringArrayToPtr(instanceLayers); InstanceCreateInfo instanceCreateInfo = VkInit.InstanceCreateInfo(appInfo, layers, (uint)instanceLayers.Length, extensions, windowExtensionCount); AssertVulkan(Vk.CreateInstance(instanceCreateInfo, null, out Instance instance)); return(instance); }
private void InitializeVulkan(string applicationName, uint applicationVersion) { Console.WriteLine("Initializing Vulkan"); #if VALIDITION DebugUtilsMessengerCreateInfoEXT GetDebugMessenger(void *pNext) { return(new DebugUtilsMessengerCreateInfoEXT( messageSeverity: DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityVerboseBitExt | DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityInfoBitExt | DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityWarningBitExt | DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt, messageType: DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeGeneralBitExt | DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypePerformanceBitExt | DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeValidationBitExt, pfnUserCallback: new PfnDebugUtilsMessengerCallbackEXT(DebugCallback), pNext: pNext)); } #endif _vk = Vk.GetApi(); const uint engineVersion = 1; const string engineName = "Videre"; var instanceLayers = new List <string>(); var instanceExtensions = new List <string>(); var pApplicationName = SilkMarshal.StringToPtr(applicationName); var pEngineName = SilkMarshal.StringToPtr(engineName); var applicationInfo = new ApplicationInfo(pApplicationName: (byte *)pApplicationName, applicationVersion: applicationVersion, pEngineName: (byte *)pEngineName, engineVersion: engineVersion, apiVersion: new Version32(1, 1, 0)); Version32 apiVersion = default; _vk.EnumerateInstanceVersion((uint *)&apiVersion); Console.WriteLine($"Instance Version: {apiVersion.Major}.{apiVersion.Minor}.{apiVersion.Patch}"); void *instancepNext = default; // instanceExtensions.Add(KhrSurface.ExtensionName); instanceExtensions.AddRange(SilkMarshal.PtrToStringArray((nint)View.VkSurface.GetRequiredExtensions(out var requiredExtensionsCount), (int)requiredExtensionsCount)); instanceExtensions.Add(ExtDebugUtils.ExtensionName); Console.WriteLine($"Creating Instance with {instanceExtensions.Count} extensions"); VerifyInstanceExtensionsAvailable(_vk, instanceExtensions); var ppEnabledLayers = instanceLayers.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(instanceLayers) : null; var ppEnabledExtensions = instanceExtensions.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(instanceExtensions) : null; _vk.CreateInstance( new InstanceCreateInfo(pApplicationInfo: &applicationInfo, enabledLayerCount: (uint)instanceLayers.Count, ppEnabledLayerNames: ppEnabledLayers, enabledExtensionCount: (uint)instanceExtensions.Count, ppEnabledExtensionNames: ppEnabledExtensions, pNext: instancepNext), _allocationCallbacks.AllocationCallbacks, out _instance) .ThrowCode(); SilkMarshal.Free((nint)ppEnabledLayers); SilkMarshal.Free((nint)ppEnabledExtensions); _vk.CurrentInstance = _instance; if (!_vk.TryGetInstanceExtension(_instance, out _khrSurface)) { Console.WriteLine($"Could not load {KhrSurface.ExtensionName}"); } _vk.TryGetInstanceExtension(_instance, out _debugUtils); Console.WriteLine("Creating Surface"); _surface = View.VkSurface.Create(_instance.ToHandle(), (AllocationCallbacks *)null).ToSurface(); uint deviceCount = 0; _vk.EnumeratePhysicalDevices(_instance, ref deviceCount, null).ThrowCode(); var devices = (PhysicalDevice *)SilkMarshal.Allocate((int)(deviceCount * sizeof(PhysicalDevice))); _vk.EnumeratePhysicalDevices(_instance, ref deviceCount, devices).ThrowCode(); Console.WriteLine($"Found {deviceCount} devices"); Console.WriteLine("Creating Device"); // TODO: actually somehow reasonably find the best device. for (int i = 0; i < deviceCount; i++) { var physicalDevice = devices[i]; _physicalDeviceFeatures = _vk.GetPhysicalDeviceFeature(physicalDevice); uint presentModeCount = 0; _khrSurface.GetPhysicalDeviceSurfacePresentModes(physicalDevice, _surface, ref presentModeCount, null).ThrowCode(); if (presentModeCount <= 0) { continue; } var presentModes = (PresentModeKHR *)SilkMarshal.Allocate((int)(presentModeCount * sizeof(PresentModeKHR))); _khrSurface.GetPhysicalDeviceSurfacePresentModes(physicalDevice, _surface, ref presentModeCount, presentModes).ThrowCode(); _presentMode = PresentModeKHR.PresentModeFifoKhr; View.FramesPerSecond = -1; for (int j = 0; j < presentModeCount; j++) { if (presentModes[j] == PresentModeKHR.PresentModeMailboxKhr) { _presentMode = PresentModeKHR.PresentModeMailboxKhr; View.FramesPerSecond = -1; break; } } SilkMarshal.Free((nint)presentModes); uint surfaceFormatCount = 0; _khrSurface.GetPhysicalDeviceSurfaceFormats(physicalDevice, _surface, ref surfaceFormatCount, null).ThrowCode(); var surfaceFormats = (SurfaceFormatKHR *)SilkMarshal.Allocate((int)(surfaceFormatCount * sizeof(SurfaceFormatKHR))); _khrSurface.GetPhysicalDeviceSurfaceFormats(physicalDevice, _surface, ref surfaceFormatCount, surfaceFormats).ThrowCode(); int max = int.MinValue; SurfaceFormatKHR maxFormat = surfaceFormats[0]; for (int j = 0; j < surfaceFormatCount; j++) { var score = FormatRater.Rate(surfaceFormats[j].Format) + ColorSpaceRater.Rate(surfaceFormats[j].ColorSpace); if (score > max) { max = score; maxFormat = surfaceFormats[j]; } } SilkMarshal.Free((nint)surfaceFormats); _swapchainFormat = maxFormat.Format; _swapchainColorSpace = maxFormat.ColorSpace; Console.WriteLine($"Chose Swapchain Properties: {Enum.GetName(typeof(PresentModeKHR), _presentMode)} {Enum.GetName(typeof(Format), _swapchainFormat)} {Enum.GetName(typeof(ColorSpaceKHR), _swapchainColorSpace)}"); _khrSurface.GetPhysicalDeviceSurfaceCapabilities(physicalDevice, _surface, out var surfaceCapabilities).ThrowCode(); uint queueFamilyPropertyCount = 0; _vk.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref queueFamilyPropertyCount, null); var deviceQueueFamilyProperties = (QueueFamilyProperties *)SilkMarshal.Allocate((int)(queueFamilyPropertyCount * sizeof(QueueFamilyProperties))); _vk.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref queueFamilyPropertyCount, deviceQueueFamilyProperties); var queueCreateInfoList = new List <DeviceQueueCreateInfo>(); var deviceExtensions = new List <string>(); var deviceLayers = new List <string>(); for (int j = 0; j < queueFamilyPropertyCount; j++) { var queueCount = deviceQueueFamilyProperties[j].QueueCount; float *pQueuePriorities = stackalloc float[(int)queueCount]; // queue count should generally be 1 for (int k = 0; k < queueCount; k++) { pQueuePriorities[k] = 1.0f; } queueCreateInfoList.Add(new DeviceQueueCreateInfo(queueFamilyIndex: (uint)j, queueCount: queueCount, pQueuePriorities: pQueuePriorities)); } deviceExtensions.Add(KhrSwapchain.ExtensionName); // deviceExtensions.Add(KhrSynchronization2.ExtensionName); // deviceExtensions.Add(ExtBufferDeviceAddress.ExtensionName); var features = new PhysicalDeviceFeatures(); features.ShaderInt64 = true; void *devicePNext = null; // var physicalDeviceDescriptorIndexingFeaturesExt = new PhysicalDeviceDescriptorIndexingFeaturesEXT( // descriptorBindingSampledImageUpdateAfterBind: true, // descriptorBindingStorageBufferUpdateAfterBind: true, // descriptorBindingStorageImageUpdateAfterBind: true, // descriptorBindingUniformBufferUpdateAfterBind: true, // descriptorBindingStorageTexelBufferUpdateAfterBind: true, // descriptorBindingUniformTexelBufferUpdateAfterBind: true, // descriptorBindingUpdateUnusedWhilePending: true, // runtimeDescriptorArray: true, // pNext: devicePNext); // devicePNext = &physicalDeviceDescriptorIndexingFeaturesExt; // var physicalDeviceBufferDeviceAddressFeatures = new PhysicalDeviceBufferDeviceAddressFeatures(bufferDeviceAddress: true, #if DEBUG bufferDeviceAddressCaptureReplay: true, #endif pNext: devicePNext); devicePNext = &physicalDeviceBufferDeviceAddressFeatures; // var version12 = new PhysicalDeviceVulkan12Features(bufferDeviceAddress: true, // #if DEBUG // bufferDeviceAddressCaptureReplay: true, // #endif // descriptorBindingSampledImageUpdateAfterBind: true, // descriptorBindingStorageBufferUpdateAfterBind: true, // descriptorBindingStorageImageUpdateAfterBind: true, // descriptorBindingUniformBufferUpdateAfterBind: true, // descriptorBindingStorageTexelBufferUpdateAfterBind: true, // descriptorBindingUniformTexelBufferUpdateAfterBind: true, // descriptorBindingUpdateUnusedWhilePending: true, // runtimeDescriptorArray: true, // pNext: devicePNext); // devicePNext = &version12; var queueCreateInfos = queueCreateInfoList.Distinct().ToArray(); queueCreateInfoList = null; VerifyDeviceExtensionsAvailable(_vk, devices[i], deviceExtensions, ref deviceLayers); _physicalDevice = devices[i]; Console.WriteLine("Creating Logical Device"); var ppDeviceExtensions = deviceExtensions.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(deviceExtensions) : null; var ppDeviceLayers = deviceLayers.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(deviceLayers) : null; fixed(DeviceQueueCreateInfo *pQueueCreateInfos = queueCreateInfos) _vk.CreateDevice(physicalDevice, new DeviceCreateInfo(queueCreateInfoCount: (uint)queueCreateInfos.Length, pQueueCreateInfos: pQueueCreateInfos, enabledExtensionCount: (uint)deviceExtensions.Count, enabledLayerCount: (uint)deviceLayers.Count, ppEnabledExtensionNames: ppDeviceExtensions, ppEnabledLayerNames: ppDeviceLayers, pEnabledFeatures: &features, pNext: devicePNext), null, out _logicalDevice) .ThrowCode(); _vk.CurrentDevice = _logicalDevice; if (!_vk.TryGetDeviceExtension(_instance, _logicalDevice, out _khrSwapchain)) { Console.WriteLine($"Could not load {KhrSwapchain.ExtensionName}!"); } _queueManager = new(_vk, _khrSurface, _instance, _physicalDevice, _logicalDevice, _surface, new Span <QueueFamilyProperties>(deviceQueueFamilyProperties, (int)queueFamilyPropertyCount)); Console.WriteLine($"{_queueManager.QueueCount} queues found"); SilkMarshal.Free((nint)ppDeviceExtensions); SilkMarshal.Free((nint)ppDeviceLayers); SilkMarshal.Free((nint)deviceQueueFamilyProperties); break; } SilkMarshal.Free((nint)devices); Console.WriteLine("Initialized Vulkan"); }
public static nint Marshal(this string str, NativeStringEncoding nativeStringEncoding = NativeStringEncoding.LPStr) => SilkMarshal.StringToPtr(str, nativeStringEncoding);