コード例 #1
0
    public unsafe void TestSetNext()
    {
        var indexingFeatures = new PhysicalDeviceDescriptorIndexingFeatures
        {
            ShaderInputAttachmentArrayDynamicIndexing = true
        };
        var accelerationStructureFeaturesKhr = new PhysicalDeviceAccelerationStructureFeaturesKHR
        {
            AccelerationStructure = true
        };

        PhysicalDeviceFeatures2
        .Chain(out var features2)
        // SetNext accepts an existing struct, note, it will coerce the SType and blank the PNext
        .SetNext(ref indexingFeatures)
        .SetNext(ref accelerationStructureFeaturesKhr);

        Assert.Equal((nint)(&indexingFeatures), (nint)features2.PNext);
        Assert.Equal((nint)(&accelerationStructureFeaturesKhr), (nint)indexingFeatures.PNext);
        Assert.Equal(0, (nint)accelerationStructureFeaturesKhr.PNext);

        Assert.Equal(StructureType.PhysicalDeviceFeatures2, features2.SType);
        Assert.Equal(StructureType.PhysicalDeviceDescriptorIndexingFeatures, indexingFeatures.SType);
        Assert.Equal
        (
            StructureType.PhysicalDeviceAccelerationStructureFeaturesKhr,
            accelerationStructureFeaturesKhr.SType
        );

        Assert.True(indexingFeatures.ShaderInputAttachmentArrayDynamicIndexing);
        Assert.True(accelerationStructureFeaturesKhr.AccelerationStructure);
    }
コード例 #2
0
    public unsafe void TestAddNextUnchecked()
    {
        var accelerationStructureFeatures = new PhysicalDeviceAccelerationStructureFeaturesKHR();

        accelerationStructureFeatures
        .AddNextAny(out PhysicalDeviceDescriptorIndexingFeatures indexingFeatures)
        .AddNextAny(out DeviceCreateInfo deviceCreateInfo);

        // Ensure all pointers set correctly
        Assert.Equal((nint)(&indexingFeatures), (nint)accelerationStructureFeatures.PNext);
        Assert.Equal((nint)(&deviceCreateInfo), (nint)indexingFeatures.PNext);
        Assert.Equal(0, (nint)deviceCreateInfo.PNext);

        // Ensure all STypes set correctly
        Assert.Equal(StructureType.PhysicalDeviceAccelerationStructureFeaturesKhr, accelerationStructureFeatures.SType);
        Assert.Equal(StructureType.PhysicalDeviceDescriptorIndexingFeatures, indexingFeatures.SType);
        Assert.Equal(StructureType.DeviceCreateInfo, deviceCreateInfo.SType);

        // Check indices
        Assert.Equal(1, accelerationStructureFeatures.IndexOfAny(ref indexingFeatures));
        Assert.Equal(2, accelerationStructureFeatures.IndexOfAny(ref deviceCreateInfo));
    }
コード例 #3
0
        public unsafe VulkanRenderer(UserSettings userSettings, Window window, IScene scene, CameraInitialState cameraInitialState, ILogger logger, bool enableDebugLogging)
        {
            _userSettings = userSettings;
            _window       = window;

            _api = new Api(enableDebugLogging, logger);

            _presentMode = _userSettings.VSync ? PresentModeKHR.PresentModeFifoKhr : PresentModeKHR.PresentModeImmediateKhr;

            _api.Instance = new Instance(_api, _window, new Version32(1, 2, 0));
            _surface      = new Surface(_api, _window, _api.Instance);

            // Find the vulkan device we want
            var physicalDevice = _api.Instance.PhysicalDevices.Where(d =>
            {
                _api.Vk.GetPhysicalDeviceFeatures(d, out var deviceFeatures);

                if (deviceFeatures.GeometryShader == false)
                {
                    return(false);
                }

                var queueFamilies = Enumerate.Get <PhysicalDevice, QueueFamilyProperties>(d, (device, count, values) =>
                                                                                          _api.Vk.GetPhysicalDeviceQueueFamilyProperties(device, (uint *)count, (QueueFamilyProperties *)values));

                for (var i = 0; i < queueFamilies.Count; i++)
                {
                    if (queueFamilies[i].QueueCount > 0 && queueFamilies[i].QueueFlags.HasFlag(QueueFlags.QueueGraphicsBit))
                    {
                        return(true);
                    }
                }

                return(false);
            }).FirstOrDefault();

            if (physicalDevice.Handle == 0)
            {
                throw new Exception($"{nameof(VulkanRenderer)}: Could not find a suitable graphics device.");
            }

            var deviceProps = new PhysicalDeviceProperties2();

            deviceProps.SType = StructureType.PhysicalDeviceProperties2;

            _api.Vk.GetPhysicalDeviceProperties2(physicalDevice, &deviceProps);

            _api.Logger.Debug($"{nameof(VulkanRenderer)}: Setting physical device: {deviceProps.Properties.DeviceID} ({Marshal.PtrToStringAnsi((nint)deviceProps.Properties.DeviceName)})");

            // Opt-in into mandatory device features.
            var shaderClockFeatures = new PhysicalDeviceShaderClockFeaturesKHR();

            shaderClockFeatures.SType = StructureType.PhysicalDeviceShaderClockFeaturesKhr;
            shaderClockFeatures.PNext = null;
            shaderClockFeatures.ShaderSubgroupClock = true;

            var deviceFeatures = new PhysicalDeviceFeatures();

            deviceFeatures.FillModeNonSolid  = true;
            deviceFeatures.SamplerAnisotropy = true;
            deviceFeatures.ShaderInt64       = true;

            // Required device features.
            var bufferDeviceAddressFeatures = new PhysicalDeviceBufferDeviceAddressFeatures();

            bufferDeviceAddressFeatures.SType = StructureType.PhysicalDeviceBufferDeviceAddressFeatures;
            bufferDeviceAddressFeatures.PNext = &shaderClockFeatures;
            bufferDeviceAddressFeatures.BufferDeviceAddress = true;

            var indexingFeatures = new PhysicalDeviceDescriptorIndexingFeatures();

            indexingFeatures.SType = StructureType.PhysicalDeviceDescriptorIndexingFeatures;
            indexingFeatures.PNext = &bufferDeviceAddressFeatures;
            indexingFeatures.RuntimeDescriptorArray = true;
            indexingFeatures.ShaderSampledImageArrayNonUniformIndexing = true;

            var accelerationStructureFeatures = new PhysicalDeviceAccelerationStructureFeaturesKHR();

            accelerationStructureFeatures.SType = StructureType.PhysicalDeviceAccelerationStructureFeaturesKhr;
            accelerationStructureFeatures.PNext = &indexingFeatures;
            accelerationStructureFeatures.AccelerationStructure = true;

            var rayTracingFeatures = new PhysicalDeviceRayTracingPipelineFeaturesKHR();

            rayTracingFeatures.SType = StructureType.PhysicalDeviceRayTracingPipelineFeaturesKhr;
            rayTracingFeatures.PNext = &accelerationStructureFeatures;
            rayTracingFeatures.RayTracingPipeline = true;

            _api.Device = new Device(_api, physicalDevice, _surface, deviceFeatures, Unsafe.AsPointer(ref rayTracingFeatures));

            // Now that we have an instance and a device, load all of the extentions we need.
            _api.InitializeExtensions();

            _commandPool = new CommandPool(_api, _api.Device.GraphicsFamilyIndex, true);

            _rayTracingProperties = new RayTracingProperties(_api);

            // Load the scene, and create the swap chain / command buffers
            LoadScene(scene, cameraInitialState);

            _currentFrame = 0;

            _api.Device.WaitIdle();
        }