// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
+ {
+ "name": ".NET Core Launch (VulkanContext)",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build VulkanContext",
+ "program": "${workspaceFolder}/build/Debug/netcoreapp3.1/VulkanContext",
+ "args": [],
+ "cwd": "${workspaceFolder}/build/Debug/netcoreapp3.1/",
+ "stopAtEntry": false,
+ "console": "internalConsole",
+ "env": {
+ "VK_INSTANCE_LAYERS": "VK_LAYER_KHRONOS_validation"
+ }
+ },
{
"name": ".NET Core Launch (ClearScreen)",
"type": "coreclr",
],
"problemMatcher": "$msCompile"
},
+ {
+ "label": "build VulkanContext",
+ "command": "dotnet",
+ "type": "process",
+ "args": [
+ "build",
+ "${workspaceFolder}/samples/VulkanContext/VulkanContext.csproj",
+ "/property:GenerateFullPaths=true",
+ "/property:SolutionDir=${workspaceFolder}/",
+ "/property:Configuration=Debug",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "problemMatcher": "$msCompile"
+ },
{
"label": "build Triangle",
"command": "dotnet",
Matrix4x4[] matrices = {
// POSITIVE_X
- Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Utils.DegreesToRadians(90)),
+ Matrix4x4.CreateRotationX(Helpers.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Helpers.DegreesToRadians(90)),
// NEGATIVE_X
- Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Utils.DegreesToRadians(-90)),
+ Matrix4x4.CreateRotationX(Helpers.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Helpers.DegreesToRadians(-90)),
// POSITIVE_Y
- Matrix4x4.CreateRotationX(Utils.DegreesToRadians(-90)),
+ Matrix4x4.CreateRotationX(Helpers.DegreesToRadians(-90)),
// NEGATIVE_Y
- Matrix4x4.CreateRotationX(Utils.DegreesToRadians(90)),
+ Matrix4x4.CreateRotationX(Helpers.DegreesToRadians(90)),
// POSITIVE_Z
- Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)),
+ Matrix4x4.CreateRotationX(Helpers.DegreesToRadians(180)),
// NEGATIVE_Z
- Matrix4x4.CreateRotationZ(Utils.DegreesToRadians(180))
+ Matrix4x4.CreateRotationZ(Helpers.DegreesToRadians(180))
};
VkImageSubresourceRange subRes = new VkImageSubresourceRange (VkImageAspectFlags.Color, 0, numMips, 0, 6);
float viewPortSize = (float)Math.Pow (0.5, m) * dim;
cmd.SetViewport (viewPortSize, viewPortSize);
cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment,
- matrices[f] * Matrix4x4.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (90), 1f, 0.1f, 512f));
+ matrices[f] * Matrix4x4.CreatePerspectiveFieldOfView (Helpers.DegreesToRadians (90), 1f, 0.1f, 512f));
if (target == CBTarget.IRRADIANCE) {
cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaPhi, (uint)Marshal.SizeOf<Matrix4x4> ());
cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaTheta, (uint)Marshal.SizeOf<Matrix4x4> () + 4);
}
if (gltfNode.Translation != null)
- FromFloatArray (ref translation, gltfNode.Translation);
+ Helpers.FromFloatArray (ref translation, gltfNode.Translation);
if (gltfNode.Translation != null)
- FromFloatArray (ref rotation, gltfNode.Rotation);
+ Helpers.FromFloatArray (ref rotation, gltfNode.Rotation);
if (gltfNode.Translation != null)
- FromFloatArray (ref scale, gltfNode.Scale);
+ Helpers.FromFloatArray (ref scale, gltfNode.Scale);
localTransform *=
Matrix4x4.CreateScale (scale) *
pbr.alphaCutoff = mat.AlphaCutoff;
pbr.alphaMode = (AlphaMode)mat.AlphaMode;
- FromFloatArray (ref pbr.emissiveFactor, mat.EmissiveFactor);
+ Helpers.FromFloatArray (ref pbr.emissiveFactor, mat.EmissiveFactor);
if (mat.EmissiveTexture != null) {
pbr.emissiveTexture = mat.EmissiveTexture.Index;
pbr.availableAttachments |= AttachmentType.Color;
}
- FromFloatArray (ref pbr.baseColorFactor, mat.PbrMetallicRoughness.BaseColorFactor);
+ Helpers.FromFloatArray (ref pbr.baseColorFactor, mat.PbrMetallicRoughness.BaseColorFactor);
if (mat.PbrMetallicRoughness.MetallicRoughnessTexture != null) {
pbr.metallicRoughnessTexture = mat.PbrMetallicRoughness.MetallicRoughnessTexture.Index;
public override void UpdateView () {
- matrices.projection = Matrix4x4.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (60f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
+ matrices.projection = Matrix4x4.CreatePerspectiveFieldOfView (Helpers.DegreesToRadians (60f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
matrices.view = Matrix4x4.CreateTranslation (0, 0, -2.5f * zoom);
matrices.model =
Matrix4x4.CreateFromAxisAngle (Vector3.UnitZ, rotZ) *
Console.ResetColor();
- VkPhysicalDeviceImageFormatInfo2 imgFormatInfo2 = VkPhysicalDeviceImageFormatInfo2.New();
- VkImageFormatProperties2 imgProps2 = VkImageFormatProperties2.New();
+ VkPhysicalDeviceImageFormatInfo2 imgFormatInfo2 = default;
+ VkImageFormatProperties2 imgProps2 = default;
- VkPhysicalDeviceExternalImageFormatInfo extImgFormatInfo = VkPhysicalDeviceExternalImageFormatInfo.New();
- VkExternalImageFormatProperties extProps = VkExternalImageFormatProperties.New ();
+ VkPhysicalDeviceExternalImageFormatInfo extImgFormatInfo = default;
+ VkExternalImageFormatProperties extProps = default;
imgFormatInfo2.format = format;
imgFormatInfo2.tiling = VkImageTiling.Optimal;
void updateMatrices () {
- matrices.projection = Matrix4x4.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (60f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
+ matrices.projection = Matrix4x4.CreatePerspectiveFieldOfView (Helpers.DegreesToRadians (60f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
matrices.view = Matrix4x4.CreateTranslation (0, 0, -2.5f * zoom);
matrices.model =
Matrix4x4.CreateFromAxisAngle (Vector3.UnitZ, rotZ) *
+++ /dev/null
-### Creating buffers
-
-Vke has two classes to handle buffers. Mappable [`HostBuffer`](../../../../wiki/vke.HostBuffer) and device only [`GPUBuffer`](../../../../wiki/vke.GPUBuffer).
-For this first simple example, we will only use host mappable buffers. Those classes can handle a Generic argument of a blittable type to handle arrays. Resources like buffers or images are activated in constructor, and they need to be explicitly disposed on cleanup. Create them in the `initVulkan` override.
-
-```csharp
-//the vertex buffer
-vbo = new HostBuffer<Vertex> (dev, VkBufferUsageFlags.VertexBuffer, vertices);
-//the index buffer
-ibo = new HostBuffer<ushort> (dev, VkBufferUsageFlags.IndexBuffer, indices);
-//a permanantly mapped buffer for the mvp matrice
-uboMats = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, mvp, true);
-```
-
-To be able to access the mvp matrix in a shader, we need a descriptor. This implies to create a descriptor pool to allocate it from and configure the triangle pipeline layout with a corresponding descriptor layout for our matrix.
-```csharp
-descriptorPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer));
-```
-Graphic pipeline configuration are predefined by the [`GraphicPipelineConfig`](../../../../wiki/vke.GraphicPipelineConfig) class, which ease sharing configs for several pipelines having lots in common. The pipeline layout will be automatically activated on pipeline creation, so that sharing layout among different pipelines will benefit from the reference counting to automatically dispose unused layout on pipeline clean up. It's the same for [`DescriptorSetLayout`](../../wiki/api/DescriptorSetLayout).
-```csharp
-GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (
- VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false);
-
-cfg.Layout = new PipelineLayout (dev,
- new DescriptorSetLayout (dev,
- new VkDescriptorSetLayoutBinding (
- 0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer)));
-```
-Next we configure a default [`RenderPass`](../../../../wiki/vke.RenderPass) with just a color attachment for the swap chain image, a default sub-pass is automatically created and the render pass activation will follow the pipeline life cycle and will be automatically disposed when no longer in use.
-```csharp
- cfg.RenderPass = new RenderPass (dev, swapChain.ColorFormat, cfg.Samples);
-```
-Configuration of vertex bindings and attributes
-```csharp
-cfg.AddVertexBinding<Vertex> (0);
-cfg.AddVertexAttributes (0, VkFormat.R32g32b32Sfloat, //position
- VkFormat.R32g32b32Sfloat);//color
-```
-shader are automatically compiled by [`SpirVTasks`](../../SpirVTasks/README.md) if added to the project. The resulting shaders are automatically embedded in the assembly. To specifiy that the shader path is a resource name, put the **'#'** prefix. Else the path will be search on disk.
-```csharp
-cfg.AddShader (dev, VkShaderStageFlags.Vertex, "#shaders.main.vert.spv");
-cfg.AddShader (dev, VkShaderStageFlags.Fragment, "#shaders.main.frag.spv");
-```
-Once the pipeline configuration is complete, we use it to effectively create and activate a graphic pipeline. Activables used by the pipeline (like the RenderPass, or the PipelineLayout) are referenced in the newly created managed pipeline. So the Configuration object doesn't need cleanup.
-```csharp
- pipeline = new GraphicPipeline (cfg);
-```
-Because descriptor layouts used for a pipeline are only activated on pipeline activation, descriptor sets must not be allocated before, except if the layout has been manually activated, but in this case, layouts will also need to be explicitly disposed.
-```csharp
- descriptorSet = descriptorPool.Allocate (pipeline.Layout.DescriptorSetLayouts[0]);
-```
-The descriptor update is a two step operation. First we create a [`DescriptorSetWrites`](../../../../wiki/vke.DescriptorSetWrites) object defining the layout(s), than we write the descriptor(s).
-The `Descriptor` property of the mvp HostBuffer will return a default descriptor with no offset of the full size of the buffer.
-
-```csharp
-DescriptorSetWrites uboUpdate =
- new DescriptorSetWrites (descriptorSet, pipeline.Layout.DescriptorSetLayouts[0]);
-
-uboUpdate.Write (dev, uboMats.Descriptor);
-```
+++ /dev/null
-<Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <IncludeDefaultNoneItems>false</IncludeDefaultNoneItems>
- </PropertyGroup>
-</Project>
+++ /dev/null
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using System;
-using System.Numerics;
-using System.Runtime.InteropServices;
-using vke;
-using Vulkan;
-using Glfw;
-
-namespace Tesselation {
- class Program : SampleBase {
- static void Main (string[] args) {
-#if DEBUG
- Instance.VALIDATION = true;
-#endif
- using (Program vke = new Program ()) {
- vke.Run ();
- }
- }
-
- const float rotSpeed = 0.01f, zoomSpeed = 0.01f;
- float rotX, rotY, zoom = 1f;
-
- //vertex structure
- [StructLayout(LayoutKind.Sequential)]
- struct Vertex {
- Vector3 position;
- Vector3 color;
-
- public Vertex (float x, float y, float z, float r, float g, float b) {
- position = new Vector3 (x, y, z);
- color = new Vector3 (r, g, b);
- }
- }
-
- Matrix4x4 mvp; //the model view projection matrix
-
- HostBuffer ibo; //a host mappable buffer to hold the indices.
- HostBuffer vbo; //a host mappable buffer to hold vertices.
- HostBuffer uboMats; //a host mappable buffer for mvp matrice.
-
- DescriptorPool descriptorPool;
- DescriptorSet descriptorSet;//descriptor set for the mvp matrice.
-
- FrameBuffers frameBuffers; //the frame buffer collection coupled to the swapchain images
- GraphicPipeline pipeline; //the triangle rendering pipeline
-
- //triangle vertices (position + color per vertex) and indices.
- Vertex[] vertices = {
- new Vertex (-1.0f, -1.0f, 0.0f , 1.0f, 0.0f, 0.0f),
- new Vertex ( 1.0f, -1.0f, 0.0f , 0.0f, 1.0f, 0.0f),
- new Vertex ( 0.0f, 1.0f, 0.0f , 0.0f, 0.0f, 1.0f),
- };
- ushort[] indices = new ushort[] { 0, 1, 2 };
-
- protected override void initVulkan () {
- base.initVulkan ();
-
- //first create the needed buffers
- vbo = new HostBuffer<Vertex> (dev, VkBufferUsageFlags.VertexBuffer, vertices);
- ibo = new HostBuffer<ushort> (dev, VkBufferUsageFlags.IndexBuffer, indices);
- //because mvp matrice may be updated by mouse move, we keep it mapped after creation.
- uboMats = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, mvp, true);
-
- //a descriptor pool to allocate the mvp matrice descriptor from.
- descriptorPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer));
-
- //Graphic pipeline configuration are predefined by the GraphicPipelineConfig class, which ease sharing config for several pipelines having lots in common.
- using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false)) {
- //Create the pipeline layout, it will be automatically activated on pipeline creation, so that sharing layout among different pipelines will benefit
- //from the reference counting to automatically dispose unused layout on pipeline clean up. It's the same for DescriptorSetLayout.
- cfg.Layout = new PipelineLayout (dev,
- new DescriptorSetLayout (dev, new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer)));
- //create a default renderpass with just a color attachment for the swapchain image, a default subpass is automatically created and the renderpass activation
- //will follow the pipeline life cicle and will be automatically disposed when no longuer used.
- cfg.RenderPass = new RenderPass (dev, swapChain.ColorFormat, cfg.Samples);
- //configuration of vertex bindings and attributes
- cfg.AddVertexBinding<Vertex> (0);
- cfg.AddVertexAttributes (0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat);//position + color
-
- //shader are automatically compiled by SpirVTasks if added to the project. The resulting shaders are automatically embedded in the assembly.
- //To specifiy that the shader path is a resource name, put the '#' prefix. Else the path will be search on disk.
- cfg.AddShaders (
- new ShaderInfo (dev, VkShaderStageFlags.Vertex, "#shaders.main.vert.spv"),
- new ShaderInfo (dev, VkShaderStageFlags.Fragment, "#shaders.main.frag.spv")
- );
-
- //create and activate the pipeline with the configuration we've just done.
- pipeline = new GraphicPipeline (cfg);
- }
-
- //because descriptor layout used for a pipeline are only activated on pipeline activation, descriptor set must not be allocated before, except if the layout has been manually activated,
- //but in this case, layout will need also to be explicitly disposed.
- descriptorSet = descriptorPool.Allocate (pipeline.Layout.DescriptorSetLayouts[0]);
-
- //Write the content of the descriptor, the mvp matrice.
- DescriptorSetWrites uboUpdate = new DescriptorSetWrites (descriptorSet, pipeline.Layout.DescriptorSetLayouts[0]);
- //Descriptor property of the mvp buffer will return a default descriptor with no offset of the full size of the buffer.
- uboUpdate.Write (dev, uboMats.Descriptor);
-
- //allocate the default VkWindow buffers, one per swapchain image. Their will be only reset when rebuilding and not reallocated.
- cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount);
- }
-
- //view update override, see base method for more informations.
- public override void UpdateView () {
- mvp =
- Matrix4x4.CreateFromAxisAngle (Vector3.UnitY, rotY) *
- Matrix4x4.CreateFromAxisAngle (Vector3.UnitX, rotX) *
- Matrix4x4.CreateTranslation (0, 0, -3f * zoom) *
- Utils.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (45f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
-
- uboMats.Update (mvp, (uint)Marshal.SizeOf<Matrix4x4> ());
- base.UpdateView ();
- }
- protected override void onMouseMove (double xPos, double yPos) {
- double diffX = lastMouseX - xPos;
- double diffY = lastMouseY - yPos;
- if (GetButton (MouseButton.Left) == InputAction.Press) {
- rotY -= rotSpeed * (float)diffX;
- rotX += rotSpeed * (float)diffY;
- updateViewRequested = true;
- } else if (GetButton (MouseButton.Right) == InputAction.Press) {
- zoom += zoomSpeed * (float)diffY;
- updateViewRequested = true;
- }
- }
-
- void buildCommandBuffers() {
- cmdPool.Reset (VkCommandPoolResetFlags.ReleaseResources);
-
- for (int i = 0; i < swapChain.ImageCount; ++i) {
- FrameBuffer fb = frameBuffers[i];
- cmds[i].Start ();
-
- pipeline.RenderPass.Begin (cmds[i], fb);
-
- cmds[i].SetViewport (swapChain.Width, swapChain.Height);
- cmds[i].SetScissor (swapChain.Width, swapChain.Height);
-
- cmds[i].BindDescriptorSet (pipeline.Layout, descriptorSet);
-
- cmds[i].BindPipeline (pipeline);
-
- cmds[i].BindVertexBuffer (vbo);
- cmds[i].BindIndexBuffer (ibo, VkIndexType.Uint16);
- cmds[i].DrawIndexed ((uint)indices.Length);
-
- pipeline.RenderPass.End (cmds[i]);
-
- cmds[i].End ();
- }
- }
-
- protected override void OnResize () {
- base.OnResize ();
- UpdateView ();
-
- frameBuffers?.Dispose();
- frameBuffers = pipeline.RenderPass.CreateFrameBuffers(swapChain);
-
- buildCommandBuffers ();
- }
- //clean up
- protected override void Dispose (bool disposing) {
- dev.WaitIdle ();
- if (disposing) {
- if (!isDisposed) {
- //pipeline clean up will dispose PipelineLayout, DescriptorSet layouts and render pass automatically. If their reference count is zero, their handles will be destroyed.
- pipeline.Dispose ();
- //frame buffers are automatically activated on creation as for resources, so it requests an explicit call to dispose.
- frameBuffers?.Dispose();
- //the descriptor pool
- descriptorPool.Dispose ();
- //resources have to be explicityly disposed.
- vbo.Dispose ();
- ibo.Dispose ();
- uboMats.Dispose ();
- }
- }
-
- base.Dispose (disposing);
- }
- }
-}
+++ /dev/null
-#version 450
-
-#extension GL_ARB_separate_shader_objects : enable
-#extension GL_ARB_shading_language_420pack : enable
-
-layout (location = 0) in vec3 inColor;
-layout (location = 0) out vec4 outFragColor;
-
-void main()
-{
- outFragColor = vec4(inColor, 1.0);
-}
\ No newline at end of file
+++ /dev/null
-#version 450
-
-#extension GL_ARB_separate_shader_objects : enable
-#extension GL_ARB_shading_language_420pack : enable
-
-layout (location = 0) in vec3 inPos;
-layout (location = 1) in vec3 inColor;
-
-layout (binding = 0) uniform UBO
-{
- mat4 mvp;
-};
-
-layout (location = 0) out vec3 outColor;
-
-out gl_PerVertex
-{
- vec4 gl_Position;
-};
-
-
-void main()
-{
- outColor = inColor;
- gl_Position = mvp * vec4(inPos.xyz, 1.0);
-}
}
void updateMatrices () {
- matrices.projection = Matrix4x4.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (60f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
+ matrices.projection = Matrix4x4.CreatePerspectiveFieldOfView (Helpers.DegreesToRadians (60f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
matrices.view = Matrix4x4.CreateTranslation (0, 0, -2.5f * zoom);
matrices.model =
Matrix4x4.CreateFromAxisAngle (Vector3.UnitZ, rotZ) *
nextTexture = null;
}
void updateMatrices () {
- matrices.projection = Matrix4x4.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (60f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 5.0f);
+ matrices.projection = Matrix4x4.CreatePerspectiveFieldOfView (Helpers.DegreesToRadians (60f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 5.0f);
matrices.view =
Matrix4x4.CreateFromAxisAngle (Vector3.UnitZ, rotZ) *
Matrix4x4.CreateFromAxisAngle (Vector3.UnitY, rotY) *
Matrix4x4.CreateFromAxisAngle (Vector3.UnitY, rotY) *
Matrix4x4.CreateFromAxisAngle (Vector3.UnitX, rotX) *
Matrix4x4.CreateTranslation (0, 0, -3f * zoom) *
- Utils.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (45f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
+ Helpers.CreatePerspectiveFieldOfView (Helpers.DegreesToRadians (45f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
base.UpdateView ();
}
--- /dev/null
+### Creating buffers
+
+Vke has two classes to handle buffers. Mappable [`HostBuffer`](../../../../wiki/vke.HostBuffer) and device only [`GPUBuffer`](../../../../wiki/vke.GPUBuffer).
+For this first simple example, we will only use host mappable buffers. Those classes can handle a Generic argument of a blittable type to handle arrays. Resources like buffers or images are activated in constructor, and they need to be explicitly disposed on cleanup. Create them in the `initVulkan` override.
+
+```csharp
+//the vertex buffer
+vbo = new HostBuffer<Vertex> (dev, VkBufferUsageFlags.VertexBuffer, vertices);
+//the index buffer
+ibo = new HostBuffer<ushort> (dev, VkBufferUsageFlags.IndexBuffer, indices);
+//a permanantly mapped buffer for the mvp matrice
+uboMats = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, mvp, true);
+```
+
+To be able to access the mvp matrix in a shader, we need a descriptor. This implies to create a descriptor pool to allocate it from and configure the triangle pipeline layout with a corresponding descriptor layout for our matrix.
+```csharp
+descriptorPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer));
+```
+Graphic pipeline configuration are predefined by the [`GraphicPipelineConfig`](../../../../wiki/vke.GraphicPipelineConfig) class, which ease sharing configs for several pipelines having lots in common. The pipeline layout will be automatically activated on pipeline creation, so that sharing layout among different pipelines will benefit from the reference counting to automatically dispose unused layout on pipeline clean up. It's the same for [`DescriptorSetLayout`](../../wiki/api/DescriptorSetLayout).
+```csharp
+GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (
+ VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false);
+
+cfg.Layout = new PipelineLayout (dev,
+ new DescriptorSetLayout (dev,
+ new VkDescriptorSetLayoutBinding (
+ 0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer)));
+```
+Next we configure a default [`RenderPass`](../../../../wiki/vke.RenderPass) with just a color attachment for the swap chain image, a default sub-pass is automatically created and the render pass activation will follow the pipeline life cycle and will be automatically disposed when no longer in use.
+```csharp
+ cfg.RenderPass = new RenderPass (dev, swapChain.ColorFormat, cfg.Samples);
+```
+Configuration of vertex bindings and attributes
+```csharp
+cfg.AddVertexBinding<Vertex> (0);
+cfg.AddVertexAttributes (0, VkFormat.R32g32b32Sfloat, //position
+ VkFormat.R32g32b32Sfloat);//color
+```
+shader are automatically compiled by [`SpirVTasks`](../../SpirVTasks/README.md) if added to the project. The resulting shaders are automatically embedded in the assembly. To specifiy that the shader path is a resource name, put the **'#'** prefix. Else the path will be search on disk.
+```csharp
+cfg.AddShader (dev, VkShaderStageFlags.Vertex, "#shaders.main.vert.spv");
+cfg.AddShader (dev, VkShaderStageFlags.Fragment, "#shaders.main.frag.spv");
+```
+Once the pipeline configuration is complete, we use it to effectively create and activate a graphic pipeline. Activables used by the pipeline (like the RenderPass, or the PipelineLayout) are referenced in the newly created managed pipeline. So the Configuration object doesn't need cleanup.
+```csharp
+ pipeline = new GraphicPipeline (cfg);
+```
+Because descriptor layouts used for a pipeline are only activated on pipeline activation, descriptor sets must not be allocated before, except if the layout has been manually activated, but in this case, layouts will also need to be explicitly disposed.
+```csharp
+ descriptorSet = descriptorPool.Allocate (pipeline.Layout.DescriptorSetLayouts[0]);
+```
+The descriptor update is a two step operation. First we create a [`DescriptorSetWrites`](../../../../wiki/vke.DescriptorSetWrites) object defining the layout(s), than we write the descriptor(s).
+The `Descriptor` property of the mvp HostBuffer will return a default descriptor with no offset of the full size of the buffer.
+
+```csharp
+DescriptorSetWrites uboUpdate =
+ new DescriptorSetWrites (descriptorSet, pipeline.Layout.DescriptorSetLayouts[0]);
+
+uboUpdate.Write (dev, uboMats.Descriptor);
+```
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <IncludeDefaultNoneItems>false</IncludeDefaultNoneItems>
+ </PropertyGroup>
+</Project>
--- /dev/null
+// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using System;
+using Vulkan;
+using static Vulkan.Vk;
+using static Vulkan.Utils;
+using Version = Vulkan.Version;
+using Context = vke.Context;
+using Glfw;
+
+namespace Tesselation {
+ class Program {
+ static void Main (string[] args) {
+ using (Context ctx = new Context()) {
+ ctx.Run();
+
+ }
+ }
+ }
+}
--- /dev/null
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec3 inColor;
+layout (location = 0) out vec4 outFragColor;
+
+void main()
+{
+ outFragColor = vec4(inColor, 1.0);
+}
\ No newline at end of file
--- /dev/null
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec3 inPos;
+layout (location = 1) in vec3 inColor;
+
+layout (binding = 0) uniform UBO
+{
+ mat4 mvp;
+};
+
+layout (location = 0) out vec3 outColor;
+
+out gl_PerVertex
+{
+ vec4 gl_Position;
+};
+
+
+void main()
+{
+ outColor = inColor;
+ gl_Position = mvp * vec4(inPos.xyz, 1.0);
+}
public abstract class SampleBase : VkWindow {
public SampleBase (string name = "VkWindow", uint _width = 800, uint _height = 600, bool vSync = false) :
base (name, _width, _height, vSync){}
- /*protected override void initVulkan()
+ protected override void initVulkan()
{
base.initVulkan();
#if DEBUG
Console.ResetColor ();
}
#endif
- }*/
+ }
}
}
camera.AspectRatio = (float)width / height;
matrices.projection = camera.Projection;
- //matrices.projection = Utils.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (60), 1, 0.1f, 16f);
+ //matrices.projection = Utils.CreatePerspectiveFieldOfView (Helpers.DegreesToRadians (60), 1, 0.1f, 16f);
matrices.view = camera.View;
//matrices.view = Matrix4x4.CreateLookAt (lights[0].position.ToVector3 (), Vector3.Zero, Vector3.UnitY);
matrices.model = camera.Model;
VkDebugUtilsMessageSeverityFlagsEXT.VerboseEXT);
#endif
- camera = new Camera (Utils.DegreesToRadians (45f), 1f, 0.1f, 16f);
+ camera = new Camera (Helpers.DegreesToRadians (45f), 1f, 0.1f, 16f);
camera.SetPosition (0, 0, -2);
//renderer = new DeferredPbrRenderer (presentQueue, cubemapPathes[2], swapChain.Width, swapChain.Height, camera.NearPlane, camera.FarPlane);
public float depthBiasConstant = 1.5f;
public float depthBiasSlope = 1.75f;
- float lightFOV = Utils.DegreesToRadians (60);
+ float lightFOV = Helpers.DegreesToRadians (60);
float lightFarPlane;
}
public void update_light_matrices () {
- Matrix4x4 proj = Utils.CreatePerspectiveFieldOfView (lightFOV, 1, 0.1f, lightFarPlane);
+ Matrix4x4 proj = Helpers.CreatePerspectiveFieldOfView (lightFOV, 1, 0.1f, lightFarPlane);
for (int i = 0; i < renderer.lights.Length; i++) {
Matrix4x4 view = Matrix4x4.CreateLookAt (renderer.lights[i].position.ToVector3 (), Vector3.Zero, Vector3.UnitY);
renderer.lights[i].mvp = view * proj;
base.initVulkan ();
//UpdateFrequency = 20;
- camera = new Camera (Utils.DegreesToRadians (45f), 1f, 0.1f, 64f);
+ camera = new Camera (Helpers.DegreesToRadians (45f), 1f, 0.1f, 64f);
camera.SetPosition (0, 0, -2);
pbrPipeline = new PBRPipeline (presentQueue,
camera.AspectRatio = (float)width / height;
matrices.projection = camera.Projection;
- //matrices.projection = Utils.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (60), 1, 0.1f, 16f);
+ //matrices.projection = Utils.CreatePerspectiveFieldOfView (Helpers.DegreesToRadians (60), 1, 0.1f, 16f);
matrices.view = camera.View;
//matrices.view = Matrix4x4.CreateLookAt (lights[0].position.ToVector3 (), Vector3.Zero, Vector3.UnitY);
matrices.model = camera.Model;
Matrix4x4[] matrices = {
// POSITIVE_X
- Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Utils.DegreesToRadians(90)),
+ Matrix4x4.CreateRotationX(Helpers.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Helpers.DegreesToRadians(90)),
// NEGATIVE_X
- Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Utils.DegreesToRadians(-90)),
+ Matrix4x4.CreateRotationX(Helpers.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Helpers.DegreesToRadians(-90)),
// POSITIVE_Y
- Matrix4x4.CreateRotationX(Utils.DegreesToRadians(-90)),
+ Matrix4x4.CreateRotationX(Helpers.DegreesToRadians(-90)),
// NEGATIVE_Y
- Matrix4x4.CreateRotationX(Utils.DegreesToRadians(90)),
+ Matrix4x4.CreateRotationX(Helpers.DegreesToRadians(90)),
// POSITIVE_Z
- Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)),
+ Matrix4x4.CreateRotationX(Helpers.DegreesToRadians(180)),
// NEGATIVE_Z
- Matrix4x4.CreateRotationZ(Utils.DegreesToRadians(180))
+ Matrix4x4.CreateRotationZ(Helpers.DegreesToRadians(180))
};
VkImageSubresourceRange subRes = new VkImageSubresourceRange (VkImageAspectFlags.Color, 0, numMips, 0, 6);
float viewPortSize = (float)Math.Pow (0.5, m) * dim;
cmd.SetViewport (viewPortSize, viewPortSize);
cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment,
- matrices[f] * Matrix4x4.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (90), 1f, 0.1f, 512f));
+ matrices[f] * Matrix4x4.CreatePerspectiveFieldOfView (Helpers.DegreesToRadians (90), 1f, 0.1f, 512f));
if (target == CBTarget.IRRADIANCE) {
cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaPhi, (uint)Marshal.SizeOf<Matrix4x4> ());
cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaTheta, (uint)Marshal.SizeOf<Matrix4x4> () + 4);
);
#endif
- camera = new Camera (Utils.DegreesToRadians (45f), 1f, 0.1f, 16f);
+ camera = new Camera (Helpers.DegreesToRadians (45f), 1f, 0.1f, 16f);
camera.SetPosition (0, 0, 2);
renderer = new DeferredPbrRenderer (dev, swapChain, presentQueue, cubemapPathes[2], camera.NearPlane, camera.FarPlane);
VkDebugUtilsMessageSeverityFlagsEXT.VerboseEXT);
#endif
- camera = new Camera (Utils.DegreesToRadians (45f), 1f, 0.1f, 16f);
+ camera = new Camera (Helpers.DegreesToRadians (45f), 1f, 0.1f, 16f);
camera.SetPosition (0, 0, -2);
//renderer = new DeferredPbrRenderer (presentQueue, cubemapPathes[2], swapChain.Width, swapChain.Height, camera.NearPlane, camera.FarPlane);
}
Program () : base(true) {
- //camera.Model = Matrix4x4.CreateRotationX (Utils.DegreesToRadians (-90)) * Matrix4x4.CreateRotationY (Utils.DegreesToRadians (180));
+ //camera.Model = Matrix4x4.CreateRotationX (Helpers.DegreesToRadians (-90)) * Matrix4x4.CreateRotationY (Helpers.DegreesToRadians (180));
//camera.SetRotation (-0.1f,-0.4f);
camera.SetPosition (0, 0, -3);
}
Program () : base(true) {
- camera.Model = Matrix4x4.CreateRotationX (Utils.DegreesToRadians (-90)) * Matrix4x4.CreateRotationY (Utils.DegreesToRadians (180));
+ camera.Model = Matrix4x4.CreateRotationX (Helpers.DegreesToRadians (-90)) * Matrix4x4.CreateRotationY (Helpers.DegreesToRadians (180));
camera.SetRotation (-0.1f,-0.4f);
camera.SetPosition (0, 0, -3);
public float depthBiasConstant = 1.5f;
public float depthBiasSlope = 1.75f;
- float lightFOV = Utils.DegreesToRadians (60);
+ float lightFOV = Helpers.DegreesToRadians (60);
float lightFarPlane;
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pbr", "samples\pbr\pbr.csproj", "{7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tesselation", "samples\Tesselation\Tesselation.csproj", "{FCE58652-47B9-4A3C-90B0-3B2EE2C8042D}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExternalMemmories", "samples\ExternalMemmories\ExternalMemmories.csproj", "{85CD9813-E182-4ED1-8D2C-38467657BEF3}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VulkanContext", "samples\VulkanContext\VulkanContext.csproj", "{CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
BuildPackages|Any CPU = BuildPackages|Any CPU
{7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Release|Any CPU.Build.0 = Release|Any CPU
{7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Release|Any CPU
- {FCE58652-47B9-4A3C-90B0-3B2EE2C8042D}.BuildPackages|Any CPU.ActiveCfg = Debug|Any CPU
- {FCE58652-47B9-4A3C-90B0-3B2EE2C8042D}.BuildPackages|Any CPU.Build.0 = Debug|Any CPU
- {FCE58652-47B9-4A3C-90B0-3B2EE2C8042D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {FCE58652-47B9-4A3C-90B0-3B2EE2C8042D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FCE58652-47B9-4A3C-90B0-3B2EE2C8042D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {FCE58652-47B9-4A3C-90B0-3B2EE2C8042D}.Release|Any CPU.Build.0 = Release|Any CPU
- {FCE58652-47B9-4A3C-90B0-3B2EE2C8042D}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Debug|Any CPU
- {FCE58652-47B9-4A3C-90B0-3B2EE2C8042D}.ReleaseSpirVTasks|Any CPU.Build.0 = Debug|Any CPU
{85CD9813-E182-4ED1-8D2C-38467657BEF3}.BuildPackages|Any CPU.ActiveCfg = Debug|Any CPU
{85CD9813-E182-4ED1-8D2C-38467657BEF3}.BuildPackages|Any CPU.Build.0 = Debug|Any CPU
{85CD9813-E182-4ED1-8D2C-38467657BEF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85CD9813-E182-4ED1-8D2C-38467657BEF3}.Release|Any CPU.Build.0 = Release|Any CPU
{85CD9813-E182-4ED1-8D2C-38467657BEF3}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Debug|Any CPU
{85CD9813-E182-4ED1-8D2C-38467657BEF3}.ReleaseSpirVTasks|Any CPU.Build.0 = Debug|Any CPU
+ {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.BuildPackages|Any CPU.ActiveCfg = Debug|Any CPU
+ {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.BuildPackages|Any CPU.Build.0 = Debug|Any CPU
+ {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Debug|Any CPU
+ {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.ReleaseSpirVTasks|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
{8185163E-A67C-4C0E-8548-67E2A9F16309} = {16439374-B8DB-4643-8116-EB3358B49A12}
{D9A41382-444E-44ED-B638-3D8F06F2FBC2} = {16439374-B8DB-4643-8116-EB3358B49A12}
{7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5} = {16439374-B8DB-4643-8116-EB3358B49A12}
- {FCE58652-47B9-4A3C-90B0-3B2EE2C8042D} = {16439374-B8DB-4643-8116-EB3358B49A12}
{85CD9813-E182-4ED1-8D2C-38467657BEF3} = {16439374-B8DB-4643-8116-EB3358B49A12}
+ {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD} = {16439374-B8DB-4643-8116-EB3358B49A12}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1360F94D-CF3C-4121-A8D7-E227F41668F1}
/// in sync with the parameters. It's automatically called after rotation, move, etc...
/// </summary>
void update () {
- Projection = Vulkan.Utils.CreatePerspectiveFieldOfView (fov, aspectRatio, zNear, zFar);
+ Projection = Helpers.CreatePerspectiveFieldOfView (fov, aspectRatio, zNear, zFar);
Matrix4x4 translation = Matrix4x4.CreateTranslation (position * zoom);
if (Type == CamType.LookAt) {
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
public static class ExtensionMethods {
return;
VkDebugUtilsObjectNameInfoEXT dmo = new VkDebugUtilsObjectNameInfoEXT (VkObjectType.CommandBuffer,
(ulong)obj.Handle.ToInt64 ()) { pObjectName = name.Pin () };
- Utils.CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
+ CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
name.Unpin ();
}
public static void SetDebugMarkerName (this VkImageView obj, Device dev, string name) {
return;
VkDebugUtilsObjectNameInfoEXT dmo = new VkDebugUtilsObjectNameInfoEXT (VkObjectType.ImageView,
(ulong)obj.Handle) { pObjectName = name.Pin () };
- Utils.CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
+ CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
name.Unpin ();
}
public static void SetDebugMarkerName (this VkSampler obj, Device dev, string name) {
return;
VkDebugUtilsObjectNameInfoEXT dmo = new VkDebugUtilsObjectNameInfoEXT (VkObjectType.Sampler,
(ulong)obj.Handle) { pObjectName = name.Pin () };
- Utils.CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
+ CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
name.Unpin ();
}
public static void SetDebugMarkerName (this VkPipeline obj, Device dev, string name) {
return;
VkDebugUtilsObjectNameInfoEXT dmo = new VkDebugUtilsObjectNameInfoEXT (VkObjectType.Pipeline,
obj.Handle) { pObjectName = name.Pin () };
- Utils.CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
+ CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
name.Unpin ();
}
public static void SetDebugMarkerName (this VkDescriptorSet obj, Device dev, string name) {
return;
VkDebugUtilsObjectNameInfoEXT dmo = new VkDebugUtilsObjectNameInfoEXT (VkObjectType.DescriptorSet,
(ulong)obj.Handle) { pObjectName = name.Pin () };
- Utils.CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
+ CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
name.Unpin ();
}
public static void SetDebugMarkerName (this VkSemaphore obj, Device dev, string name) {
return;
VkDebugUtilsObjectNameInfoEXT dmo = new VkDebugUtilsObjectNameInfoEXT (VkObjectType.Semaphore,
(ulong)obj.Handle) { pObjectName = name.Pin () };
- Utils.CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
+ CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
name.Unpin ();
}
public static void SetDebugMarkerName (this VkFence obj, Device dev, string name) {
return;
VkDebugUtilsObjectNameInfoEXT dmo = new VkDebugUtilsObjectNameInfoEXT (VkObjectType.Fence,
(ulong)obj.Handle) { pObjectName = name.Pin () };
- Utils.CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
+ CheckResult (vkSetDebugUtilsObjectNameEXT (dev.Handle, ref dmo));
name.Unpin ();
}
#endregion
}
#endregion
+ public static VkSurfaceKHR CreateSurface (this VkInstance inst, IntPtr hWindow) {
+ ulong surf;
+ CheckResult ((VkResult)Glfw.Glfw3.CreateWindowSurface (inst.Handle, hWindow, IntPtr.Zero, out surf), "Create Surface Failed.");
+ return surf;
+ }
+
+ public static VkSurfaceFormatKHR [] GetSurfaceFormats (this VkPhysicalDevice phy, VkSurfaceKHR surf)
+ {
+ vkGetPhysicalDeviceSurfaceFormatsKHR (phy, surf, out uint count, IntPtr.Zero);
+ VkSurfaceFormatKHR [] formats = new VkSurfaceFormatKHR [count];
+ vkGetPhysicalDeviceSurfaceFormatsKHR (phy, surf, out count, formats.Pin ());
+ formats.Unpin ();
+ return formats;
+ }
+ public static VkPresentModeKHR[] GetSurfacePresentModes (this VkPhysicalDevice phy, VkSurfaceKHR surf) {
+ vkGetPhysicalDeviceSurfacePresentModesKHR (phy, surf, out uint count, IntPtr.Zero);
+ int[] modes = new int[count];
+ vkGetPhysicalDeviceSurfacePresentModesKHR (phy, surf, out count, modes.Pin ());
+ modes.Unpin ();
+ return modes.Cast<VkPresentModeKHR>().ToArray();
+ }
}
}
bufferImageGranularity = dev.phy.Limits.bufferImageGranularity;
memInfo.allocationSize = size;
memInfo.memoryTypeIndex = memoryTypeIndex;
- Utils.CheckResult (vkAllocateMemory (Dev.Handle, ref memInfo, IntPtr.Zero, out vkMemory));
+ CheckResult (vkAllocateMemory (Dev.Handle, ref memInfo, IntPtr.Zero, out vkMemory));
}
/// <summary>
/// Allocate memory for a new resource in this memory pool.
/// <param name="size">Size.</param>
/// <param name="offset">Offset.</param>
public void Map (ulong size = Vk.WholeSize, ulong offset = 0) {
- Utils.CheckResult (vkMapMemory (Dev.Handle, vkMemory, offset, size, 0, ref mappedPointer));
+ CheckResult (vkMapMemory (Dev.Handle, vkMemory, offset, size, 0, ref mappedPointer));
}
/// <summary>
/// Unmap previously mapped memory of this pool.
/// This class is a helper class for VkPipelineShaderStageCreateInfo creation.
/// </summary>
public class ShaderInfo : IDisposable {
- protected VkPipelineShaderStageCreateInfo info = VkPipelineShaderStageCreateInfo.New ();
+ protected VkPipelineShaderStageCreateInfo info;
protected Device dev;
public VkShaderStageFlags Stage => info.stage;
/// <param name="dev">vke Device</param>
/// <param name="_stageFlags">Stage flags.</param>
/// <param name="_spirvPath">
- /// Path to a compiled SpirV Shader on disk or as embedded ressource. See <see cref="Utils.GetStreamFromPath"/> for more information.
+ /// Path to a compiled SpirV Shader on disk or as embedded ressource. See <see cref="Helpers.GetStreamFromPath"/> for more information.
/// </param>
/// <param name="specializationInfo">Specialization info</param>
/// <param name="entryPoint">shader entry point, 'main' by default.</param>
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Xml.Serialization;
+using Vulkan;
-namespace Vulkan {
- public static partial class Utils {
+namespace vke {
+ public static partial class Helpers {
/// <summary>Throw an erro if VkResult != Success.</summary>
- public static void CheckResult (VkResult result, string errorString = "Call failed") {
- if (result != VkResult.Success)
- throw new InvalidOperationException (errorString + ": " + result.ToString ());
- }
static void xmlMakeTypeFieldsAsAttributes (Type t, ref XmlAttributeOverrides overrides)
{
foreach (FieldInfo fi in t.GetFields (BindingFlags.Public | BindingFlags.Instance))
}
/// <summary>Convert angle from degree to radian.</summary>
public static float DegreesToRadians (float degrees) {
- return degrees * (float)Math.PI / 180f;
- }
+ return degrees * (float)Math.PI / 180f;
+ }
/// <summary>
/// Populate a Vector3 with values from a float array
/// Populate a Vector4 with values from a float array
/// </summary>
public static void FromFloatArray (ref Vector4 v, float[] floats) {
- v = Unsafe.As<float[], Vector4[]>(ref floats)[0];
+ MemoryMarshal.Cast<float, Vector4>(floats.AsSpan());
}
/// <summary>
/// Populate a Quaternion with values from a float array
/// </summary>
public static void FromByteArray (ref Vector2 v, byte[] byteArray, int offset) {
v = Unsafe.As<byte[], Vector2[]>(ref Unsafe.AsRef(byteArray.SubArray(offset, 8)))[0];
- }
+ }
/// <summary>
/// Populate a Vector3 with values from a byte array starting at offset
/// </summary>
// Fixed sub resource on first mip level and layer
public static void setImageLayout (
- VkCommandBuffer cmdbuffer,
- VkImage image,
- VkImageAspectFlags aspectMask,
- VkImageLayout oldImageLayout,
- VkImageLayout newImageLayout,
- VkPipelineStageFlags srcStageMask = VkPipelineStageFlags.AllCommands,
- VkPipelineStageFlags dstStageMask = VkPipelineStageFlags.AllCommands) {
- VkImageSubresourceRange subresourceRange = new VkImageSubresourceRange {
- aspectMask = aspectMask,
- baseMipLevel = 0,
- levelCount = 1,
- layerCount = 1,
- };
- setImageLayout (cmdbuffer, image, aspectMask, oldImageLayout, newImageLayout, subresourceRange);
- }
-
- // Create an image memory barrier for changing the layout of
- // an image and put it into an active command buffer
- // See chapter 11.4 "Image Layout" for details
-
- public static void setImageLayout (
- VkCommandBuffer cmdbuffer,
- VkImage image,
- VkImageAspectFlags aspectMask,
- VkImageLayout oldImageLayout,
- VkImageLayout newImageLayout,
- VkImageSubresourceRange subresourceRange,
- VkPipelineStageFlags srcStageMask = VkPipelineStageFlags.AllCommands,
- VkPipelineStageFlags dstStageMask = VkPipelineStageFlags.AllCommands) {
- // Create an image barrier object
- VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New();
- imageMemoryBarrier.srcQueueFamilyIndex = Vk.QueueFamilyIgnored;
- imageMemoryBarrier.dstQueueFamilyIndex = Vk.QueueFamilyIgnored;
- imageMemoryBarrier.oldLayout = oldImageLayout;
- imageMemoryBarrier.newLayout = newImageLayout;
- imageMemoryBarrier.image = image;
- imageMemoryBarrier.subresourceRange = subresourceRange;
-
- // Source layouts (old)
- // Source access mask controls actions that have to be finished on the old layout
- // before it will be transitioned to the new layout
- switch (oldImageLayout) {
- case VkImageLayout.Undefined:
- // Image layout is undefined (or does not matter)
- // Only valid as initial layout
- // No flags required, listed only for completeness
- imageMemoryBarrier.srcAccessMask = 0;
- break;
-
- case VkImageLayout.Preinitialized:
- // Image is preinitialized
- // Only valid as initial layout for linear images, preserves memory contents
- // Make sure host writes have been finished
- imageMemoryBarrier.srcAccessMask = VkAccessFlags.HostWrite;
- break;
-
- case VkImageLayout.ColorAttachmentOptimal:
- // Image is a color attachment
- // Make sure any writes to the color buffer have been finished
- imageMemoryBarrier.srcAccessMask = VkAccessFlags.ColorAttachmentWrite;
- break;
-
- case VkImageLayout.DepthStencilAttachmentOptimal:
- // Image is a depth/stencil attachment
- // Make sure any writes to the depth/stencil buffer have been finished
- imageMemoryBarrier.srcAccessMask = VkAccessFlags.DepthStencilAttachmentWrite;
- break;
-
- case VkImageLayout.TransferSrcOptimal:
- // Image is a transfer source
- // Make sure any reads from the image have been finished
- imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
- break;
-
- case VkImageLayout.TransferDstOptimal:
- // Image is a transfer destination
- // Make sure any writes to the image have been finished
- imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferWrite;
- break;
-
- case VkImageLayout.ShaderReadOnlyOptimal:
- // Image is read by a shader
- // Make sure any shader reads from the image have been finished
- imageMemoryBarrier.srcAccessMask = VkAccessFlags.ShaderRead;
- break;
- }
-
- // Target layouts (new)
- // Destination access mask controls the dependency for the new image layout
- switch (newImageLayout) {
- case VkImageLayout.TransferDstOptimal:
- // Image will be used as a transfer destination
- // Make sure any writes to the image have been finished
- imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferWrite;
- break;
-
- case VkImageLayout.TransferSrcOptimal:
- // Image will be used as a transfer source
- // Make sure any reads from and writes to the image have been finished
- imageMemoryBarrier.srcAccessMask = imageMemoryBarrier.srcAccessMask | VkAccessFlags.TransferRead;
- imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferRead;
- break;
-
- case VkImageLayout.ColorAttachmentOptimal:
- // Image will be used as a color attachment
- // Make sure any writes to the color buffer have been finished
- imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
- imageMemoryBarrier.dstAccessMask = VkAccessFlags.ColorAttachmentWrite;
- break;
-
- case VkImageLayout.DepthStencilAttachmentOptimal:
- // Image layout will be used as a depth/stencil attachment
- // Make sure any writes to depth/stencil buffer have been finished
- imageMemoryBarrier.dstAccessMask = imageMemoryBarrier.dstAccessMask | VkAccessFlags.DepthStencilAttachmentWrite;
- break;
-
- case VkImageLayout.ShaderReadOnlyOptimal:
- // Image will be read in a shader (sampler, input attachment)
- // Make sure any writes to the image have been finished
- if (imageMemoryBarrier.srcAccessMask == 0) {
- imageMemoryBarrier.srcAccessMask = VkAccessFlags.HostWrite | VkAccessFlags.TransferWrite;
- }
- imageMemoryBarrier.dstAccessMask = VkAccessFlags.ShaderRead;
- break;
- }
-
- // Put barrier inside setup command buffer
- Vk.vkCmdPipelineBarrier (
- cmdbuffer,
- srcStageMask,
- dstStageMask,
- 0,
- 0, IntPtr.Zero,
- 0, IntPtr.Zero,
- 1, ref imageMemoryBarrier);
- }
+ VkCommandBuffer cmdbuffer,
+ VkImage image,
+ VkImageAspectFlags aspectMask,
+ VkImageLayout oldImageLayout,
+ VkImageLayout newImageLayout,
+ VkPipelineStageFlags srcStageMask = VkPipelineStageFlags.AllCommands,
+ VkPipelineStageFlags dstStageMask = VkPipelineStageFlags.AllCommands) {
+ VkImageSubresourceRange subresourceRange = new VkImageSubresourceRange {
+ aspectMask = aspectMask,
+ baseMipLevel = 0,
+ levelCount = 1,
+ layerCount = 1,
+ };
+ setImageLayout (cmdbuffer, image, aspectMask, oldImageLayout, newImageLayout, subresourceRange);
+ }
+
+ // Create an image memory barrier for changing the layout of
+ // an image and put it into an active command buffer
+ // See chapter 11.4 "Image Layout" for details
+
+ public static void setImageLayout (
+ VkCommandBuffer cmdbuffer,
+ VkImage image,
+ VkImageAspectFlags aspectMask,
+ VkImageLayout oldImageLayout,
+ VkImageLayout newImageLayout,
+ VkImageSubresourceRange subresourceRange,
+ VkPipelineStageFlags srcStageMask = VkPipelineStageFlags.AllCommands,
+ VkPipelineStageFlags dstStageMask = VkPipelineStageFlags.AllCommands) {
+ // Create an image barrier object
+ VkImageMemoryBarrier imageMemoryBarrier = default;
+ imageMemoryBarrier.srcQueueFamilyIndex = Vk.QueueFamilyIgnored;
+ imageMemoryBarrier.dstQueueFamilyIndex = Vk.QueueFamilyIgnored;
+ imageMemoryBarrier.oldLayout = oldImageLayout;
+ imageMemoryBarrier.newLayout = newImageLayout;
+ imageMemoryBarrier.image = image;
+ imageMemoryBarrier.subresourceRange = subresourceRange;
+
+ // Source layouts (old)
+ // Source access mask controls actions that have to be finished on the old layout
+ // before it will be transitioned to the new layout
+ switch (oldImageLayout) {
+ case VkImageLayout.Undefined:
+ // Image layout is undefined (or does not matter)
+ // Only valid as initial layout
+ // No flags required, listed only for completeness
+ imageMemoryBarrier.srcAccessMask = 0;
+ break;
+
+ case VkImageLayout.Preinitialized:
+ // Image is preinitialized
+ // Only valid as initial layout for linear images, preserves memory contents
+ // Make sure host writes have been finished
+ imageMemoryBarrier.srcAccessMask = VkAccessFlags.HostWrite;
+ break;
+
+ case VkImageLayout.ColorAttachmentOptimal:
+ // Image is a color attachment
+ // Make sure any writes to the color buffer have been finished
+ imageMemoryBarrier.srcAccessMask = VkAccessFlags.ColorAttachmentWrite;
+ break;
+
+ case VkImageLayout.DepthStencilAttachmentOptimal:
+ // Image is a depth/stencil attachment
+ // Make sure any writes to the depth/stencil buffer have been finished
+ imageMemoryBarrier.srcAccessMask = VkAccessFlags.DepthStencilAttachmentWrite;
+ break;
+
+ case VkImageLayout.TransferSrcOptimal:
+ // Image is a transfer source
+ // Make sure any reads from the image have been finished
+ imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
+ break;
+
+ case VkImageLayout.TransferDstOptimal:
+ // Image is a transfer destination
+ // Make sure any writes to the image have been finished
+ imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferWrite;
+ break;
+
+ case VkImageLayout.ShaderReadOnlyOptimal:
+ // Image is read by a shader
+ // Make sure any shader reads from the image have been finished
+ imageMemoryBarrier.srcAccessMask = VkAccessFlags.ShaderRead;
+ break;
+ }
+
+ // Target layouts (new)
+ // Destination access mask controls the dependency for the new image layout
+ switch (newImageLayout) {
+ case VkImageLayout.TransferDstOptimal:
+ // Image will be used as a transfer destination
+ // Make sure any writes to the image have been finished
+ imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferWrite;
+ break;
+
+ case VkImageLayout.TransferSrcOptimal:
+ // Image will be used as a transfer source
+ // Make sure any reads from and writes to the image have been finished
+ imageMemoryBarrier.srcAccessMask = imageMemoryBarrier.srcAccessMask | VkAccessFlags.TransferRead;
+ imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferRead;
+ break;
+
+ case VkImageLayout.ColorAttachmentOptimal:
+ // Image will be used as a color attachment
+ // Make sure any writes to the color buffer have been finished
+ imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
+ imageMemoryBarrier.dstAccessMask = VkAccessFlags.ColorAttachmentWrite;
+ break;
+
+ case VkImageLayout.DepthStencilAttachmentOptimal:
+ // Image layout will be used as a depth/stencil attachment
+ // Make sure any writes to depth/stencil buffer have been finished
+ imageMemoryBarrier.dstAccessMask = imageMemoryBarrier.dstAccessMask | VkAccessFlags.DepthStencilAttachmentWrite;
+ break;
+
+ case VkImageLayout.ShaderReadOnlyOptimal:
+ // Image will be read in a shader (sampler, input attachment)
+ // Make sure any writes to the image have been finished
+ if (imageMemoryBarrier.srcAccessMask == 0) {
+ imageMemoryBarrier.srcAccessMask = VkAccessFlags.HostWrite | VkAccessFlags.TransferWrite;
+ }
+ imageMemoryBarrier.dstAccessMask = VkAccessFlags.ShaderRead;
+ break;
+ }
+
+ // Put barrier inside setup command buffer
+ Vk.vkCmdPipelineBarrier (
+ cmdbuffer,
+ srcStageMask,
+ dstStageMask,
+ 0,
+ 0, IntPtr.Zero,
+ 0, IntPtr.Zero,
+ 1, ref imageMemoryBarrier);
+ }
/// <summary>
/// Find usage flags and aspect flag from image layout
/// </summary>
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
+using Vulkan;
-namespace Vulkan {
+namespace vke {
[Flags]
public enum VkFormatSizeFlag {
SizePacked = 0x00000001,
SizeDepth = 0x00000008,
SizeStencil = 0x00000010,
};
-
+
public struct VkFormatSize {
public VkFormatSizeFlag flags;
public uint paletteSizeInBits;
};
- public static partial class Utils {
+ public static partial class Helpers {
public static void vkGetFormatSize(VkFormat format, out VkFormatSize pFormatSize )
{
switch ( format )
public IntPtr WindowHandle => hWin;
/**Default camera initialized with a Field of view of 40° and and aspect ratio of 1. */
- protected Camera camera = new Camera (Utils.DegreesToRadians (45f), 1f);
+ protected Camera camera = new Camera (Helpers.DegreesToRadians (45f), 1f);
public Modifier KeyModifiers = 0;
IntPtr currentCursor;
using System.Xml.Serialization;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
/// <summary>
VkDebugUtilsObjectNameInfoEXT dmo = DebugUtilsInfo;
dmo.pObjectName = name.Pin();
- Utils.CheckResult (vkSetDebugUtilsObjectNameEXT (Dev.Handle, ref dmo));
+ CheckResult (vkSetDebugUtilsObjectNameEXT (Dev.Handle, ref dmo));
name.Unpin ();
}
/// <summary>
using System;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
/// </summary>
public class Buffer : Resource {
internal VkBuffer handle;
- protected VkBufferCreateInfo createInfo = VkBufferCreateInfo.New ();
+ protected VkBufferCreateInfo createInfo;
/// <summary>Native handle of this vulkan buffer.</summary>
/// <value>The handle.</value>
public VkBuffer Handle => handle;
/// </summary>
public sealed override void Activate () {
if (state != ActivableState.Activated) {
- Utils.CheckResult (vkCreateBuffer (Dev.Handle, ref createInfo, IntPtr.Zero, out handle));
+ CheckResult (vkCreateBuffer (Dev.Handle, ref createInfo, IntPtr.Zero, out handle));
#if MEMORY_POOLS
Dev.resourceManager.Add (this);
#else
internal override void bindMemory () {
#if MEMORY_POOLS
- Utils.CheckResult (vkBindBufferMemory (Dev.Handle, handle, memoryPool.vkMemory, poolOffset));
+ CheckResult (vkBindBufferMemory (Dev.Handle, handle, memoryPool.vkMemory, poolOffset));
#else
- Utils.CheckResult (vkBindBufferMemory (Dev.Handle, handle, vkMemory, 0));
+ CheckResult (vkBindBufferMemory (Dev.Handle, handle, vkMemory, 0));
#endif
}
#endregion
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
public class SecondaryCommandBuffer : CommandBuffer {
}
public void Start (VkCommandBufferUsageFlags usage = 0, RenderPass rp = null, uint subpass = 0, FrameBuffer fb = null,
bool occlusionQueryEnable = false, VkQueryControlFlags queryFlags = 0, VkQueryPipelineStatisticFlags statFlags = 0) {
- VkCommandBufferInheritanceInfo inheri = VkCommandBufferInheritanceInfo.New ();
+ VkCommandBufferInheritanceInfo inheri = default;
inheri.renderPass = rp == null ? 0 : rp.handle;
inheri.subpass = subpass;
inheri.framebuffer = fb == null ? 0 : fb.handle;
inheri.pipelineStatistics = statFlags;
VkCommandBufferBeginInfo cmdBufInfo = new VkCommandBufferBeginInfo (usage);
cmdBufInfo.pInheritanceInfo = inheri;
- Utils.CheckResult (vkBeginCommandBuffer (handle, ref cmdBufInfo));
+ CheckResult (vkBeginCommandBuffer (handle, ref cmdBufInfo));
cmdBufInfo.Dispose();
}
}
/// <param name="signal">Signal.</param>
/// <param name="fence">Fence.</param>
public void Submit (VkQueue queue, VkSemaphore wait = default, VkSemaphore signal = default, Fence fence = null) {
- VkSubmitInfo submit_info = VkSubmitInfo.New ();
+ VkSubmitInfo submit_info = default;
submit_info.pWaitDstStageMask = VkPipelineStageFlags.ColorAttachmentOutput;
if (signal == VkSemaphore.Null)
submit_info.pSignalSemaphores = null;
submit_info.pWaitSemaphores = wait;
submit_info.pCommandBuffers = handle;
- Utils.CheckResult (vkQueueSubmit (queue, 1, ref submit_info, fence));
+ CheckResult (vkQueueSubmit (queue, 1, submit_info, fence));
submit_info.Dispose();
}
/// <summary>
/// <param name="usage">optional command buffer usage flags.</param>
public void Start (VkCommandBufferUsageFlags usage = 0) {
VkCommandBufferBeginInfo cmdBufInfo = new VkCommandBufferBeginInfo (usage);
- Utils.CheckResult (vkBeginCommandBuffer (handle, ref cmdBufInfo));
+ CheckResult (vkBeginCommandBuffer (handle, ref cmdBufInfo));
}
/// <summary>
/// Execute secondary command buffers.
/// Put the command buffer in the executable state if no errors are present in the recording.
/// </summary>
public void End () {
- Utils.CheckResult (vkEndCommandBuffer (handle));
+ CheckResult (vkEndCommandBuffer (handle));
}
/// <summary>
/// Update dynamic viewport state
}
public void SetMemoryBarrier (VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkDependencyFlags dependencyFlags = VkDependencyFlags.ByRegion) {
- VkMemoryBarrier memoryBarrier = VkMemoryBarrier.New ();
+ VkMemoryBarrier memoryBarrier = default;
memoryBarrier.srcAccessMask = srcAccessMask;
memoryBarrier.dstAccessMask = dstAccessMask;
Vk.vkCmdPipelineBarrier (Handle, srcStageMask, dstStageMask,
public void BeginRegion (string name, float r = 1f, float g = 0.1f, float b=0.1f, float a = 1f) {
if (!Device.debugUtilsEnabled)
return;
- VkDebugMarkerMarkerInfoEXT info = VkDebugMarkerMarkerInfoEXT.New();
+ VkDebugMarkerMarkerInfoEXT info = default;
info.pMarkerName = name.Pin ();
info.color.X = r;
info.color.Y = g;
public void InsertDebugMarker (string name, float r = 1f, float g = 0.1f, float b=0.1f, float a = 1f) {
if (!Device.debugUtilsEnabled)
return;
- VkDebugMarkerMarkerInfoEXT info = VkDebugMarkerMarkerInfoEXT.New();
+ VkDebugMarkerMarkerInfoEXT info = default;
info.pMarkerName = name.Pin ();
info.color.X = r;
info.color.Y = g;
using System.Runtime.InteropServices;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
/// <summary>
public override void Activate () {
if (state != ActivableState.Activated) {
- VkCommandPoolCreateInfo infos = VkCommandPoolCreateInfo.New();
+ VkCommandPoolCreateInfo infos = default;
infos.queueFamilyIndex = QFamIndex;
infos.flags = Flags;
- Utils.CheckResult (vkCreateCommandPool (Dev.Handle, ref infos, IntPtr.Zero, out handle));
+ CheckResult (vkCreateCommandPool (Dev.Handle, ref infos, IntPtr.Zero, out handle));
}
base.Activate ();
}
/// <returns>The command buffer in the Init state.</returns>
public PrimaryCommandBuffer AllocateCommandBuffer () {
VkCommandBuffer buff;
- VkCommandBufferAllocateInfo infos = VkCommandBufferAllocateInfo.New();
+ VkCommandBufferAllocateInfo infos = default;
infos.commandPool = handle;
infos.level = VkCommandBufferLevel.Primary;
infos.commandBufferCount = 1;
- Utils.CheckResult (vkAllocateCommandBuffers (Dev.Handle, ref infos, out buff));
+ CheckResult (vkAllocateCommandBuffers (Dev.Handle, ref infos, out buff));
return new PrimaryCommandBuffer (Dev.Handle, this, buff);
}
/// <returns>The command buffer in the Init state.</returns>
public SecondaryCommandBuffer AllocateSecondaryCommandBuffer () {
VkCommandBuffer buff;
- VkCommandBufferAllocateInfo infos = VkCommandBufferAllocateInfo.New ();
+ VkCommandBufferAllocateInfo infos = default;
infos.commandPool = handle;
infos.level = VkCommandBufferLevel.Secondary;
infos.commandBufferCount = 1;
- Utils.CheckResult (vkAllocateCommandBuffers (Dev.Handle, ref infos, out buff));
+ CheckResult (vkAllocateCommandBuffers (Dev.Handle, ref infos, out buff));
return new SecondaryCommandBuffer (Dev.Handle, this, buff);
}
/// <returns>An array of command buffers alloocated from this pool.</returns>
/// <param name="count">Buffer count to create.</param>
public PrimaryCommandBuffer[] AllocateCommandBuffer (uint count) {
- VkCommandBufferAllocateInfo infos = VkCommandBufferAllocateInfo.New ();
+ VkCommandBufferAllocateInfo infos = default;
infos.commandPool = handle;
infos.level = VkCommandBufferLevel.Primary;
infos.commandBufferCount = count;
VkCommandBuffer[] buffs = new VkCommandBuffer[count];
- Utils.CheckResult (vkAllocateCommandBuffers (Dev.Handle, ref infos, buffs.Pin()));
+ CheckResult (vkAllocateCommandBuffers (Dev.Handle, ref infos, buffs.Pin()));
buffs.Unpin ();
PrimaryCommandBuffer[] cmds = new PrimaryCommandBuffer[count];
for (int i = 0; i < count; i++)
using System;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
public sealed class ComputePipeline : Pipeline {
Cache?.Activate ();
using (ShaderInfo shader = new ShaderInfo (Dev, VkShaderStageFlags.Compute, SpirVPath)) {
- VkComputePipelineCreateInfo info = VkComputePipelineCreateInfo.New ();
+ VkComputePipelineCreateInfo info = default;
info.layout = layout.Handle;
info.stage = shader.Info;
info.basePipelineHandle = 0;
info.basePipelineIndex = 0;
- Utils.CheckResult (Vk.vkCreateComputePipelines (Dev.Handle, Cache == null ? VkPipelineCache.Null : Cache.handle, 1, ref info, IntPtr.Zero, out handle));
+ CheckResult (Vk.vkCreateComputePipelines (Dev.Handle, Cache == null ? VkPipelineCache.Null : Cache.handle, 1, ref info, IntPtr.Zero, out handle));
}
}
base.Activate ();
using System.Runtime.InteropServices;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
[Obsolete("Use the new VK_EXT_debug_utils extension")]
- public class DebugReport : IDisposable {
+ public class DebugReport : IDisposable {
VkDebugReportCallbackEXT handle;
Instance inst;
Console.ForegroundColor = ConsoleColor.White;
return VkBool32.False;
}
-
+
public DebugReport (Instance instance, VkDebugReportFlagsEXT flags = VkDebugReportFlagsEXT.ErrorEXT | VkDebugReportFlagsEXT.WarningEXT) {
inst = instance;
pfnCallback = Marshal.GetFunctionPointerForDelegate (debugCallbackDelegate)
};
- Utils.CheckResult (vkCreateDebugReportCallbackEXT (inst.Handle, ref dbgInfo, IntPtr.Zero, out handle));
+ CheckResult (vkCreateDebugReportCallbackEXT (inst.Handle, ref dbgInfo, IntPtr.Zero, out handle));
}
#region IDisposable Support
using System.Text;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke.DebugUtils {
/// <summary>
VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT |
VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT) {
inst = instance;
- VkDebugUtilsMessengerCreateInfoEXT info = VkDebugUtilsMessengerCreateInfoEXT.New ();
+ VkDebugUtilsMessengerCreateInfoEXT info = default;
info.messageType = typeMask;
info.messageSeverity = severityMask;
info.pfnUserCallback = Marshal.GetFunctionPointerForDelegate (onMessageDelegate);
info.pUserData = IntPtr.Zero;
- Utils.CheckResult (vkCreateDebugUtilsMessengerEXT (inst.VkInstance, ref info, IntPtr.Zero, out handle));
+ CheckResult (vkCreateDebugUtilsMessengerEXT (inst.VkInstance, ref info, IntPtr.Zero, out handle));
}
/// <summary>
/// Create a new debug utils messenger with default message callback outputing to Console.
using System.Collections.Generic;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
[Serializable]
public sealed override void Activate () {
if (state != ActivableState.Activated) {
- VkDescriptorPoolCreateInfo info = VkDescriptorPoolCreateInfo.New();
+ VkDescriptorPoolCreateInfo info = default;
info.pPoolSizes = PoolSizes;
info.maxSets = MaxSets;
- Utils.CheckResult (vkCreateDescriptorPool (Dev.Handle, ref info, IntPtr.Zero, out handle));
+ CheckResult (vkCreateDescriptorPool (Dev.Handle, ref info, IntPtr.Zero, out handle));
info.Dispose();
}
base.Activate ();
return ds;
}
public void Allocate (DescriptorSet descriptorSet) {
- VkDescriptorSetAllocateInfo allocInfo = VkDescriptorSetAllocateInfo.New();
+ VkDescriptorSetAllocateInfo allocInfo = default;
allocInfo.descriptorPool = handle;
allocInfo.pSetLayouts = descriptorSet.descriptorSetLayouts;
- Utils.CheckResult (vkAllocateDescriptorSets (Dev.Handle, ref allocInfo, out descriptorSet.handle));
+ CheckResult (vkAllocateDescriptorSets (Dev.Handle, ref allocInfo, out descriptorSet.handle));
allocInfo.Dispose();
}
public void FreeDescriptorSet (params DescriptorSet[] descriptorSets) {
if (descriptorSets.Length == 1) {
- Utils.CheckResult (vkFreeDescriptorSets (Dev.Handle, handle, 1, ref descriptorSets[0].handle));
+ CheckResult (vkFreeDescriptorSets (Dev.Handle, handle, 1, ref descriptorSets[0].handle));
return;
}
- Utils.CheckResult (vkFreeDescriptorSets (Dev.Handle, handle, (uint)descriptorSets.Length, descriptorSets.Pin()));
+ CheckResult (vkFreeDescriptorSets (Dev.Handle, handle, (uint)descriptorSets.Length, descriptorSets.Pin()));
descriptorSets.Unpin ();
}
public void Reset () {
- Utils.CheckResult (vkResetDescriptorPool (Dev.Handle, handle, 0));
+ CheckResult (vkResetDescriptorPool (Dev.Handle, handle, 0));
}
public override string ToString () {
using System.Collections.Generic;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
/// <summary>
public override void Activate () {
if (state != ActivableState.Activated) {
VkDescriptorSetLayoutCreateInfo info = new VkDescriptorSetLayoutCreateInfo (Flags, (uint)Bindings.Count, Bindings.Pin());
- Utils.CheckResult (vkCreateDescriptorSetLayout (Dev.Handle, ref info, IntPtr.Zero, out handle));
+ CheckResult (vkCreateDescriptorSetLayout (Dev.Handle, ref info, IntPtr.Zero, out handle));
Bindings.Unpin ();
}
base.Activate ();
/// with another descriptorSet in parametters
/// </summary>
public void AddWriteInfo (DescriptorSet destSet, VkDescriptorSetLayoutBinding binding) {
- VkWriteDescriptorSet wds = VkWriteDescriptorSet.New();
+ VkWriteDescriptorSet wds = default;
wds.descriptorType = binding.descriptorType;
wds.descriptorCount = binding.descriptorCount;
wds.dstBinding = binding.binding;
/// provide a desDescriptor!
/// </summary>
public void AddWriteInfo (VkDescriptorSetLayoutBinding binding) {
- VkWriteDescriptorSet wds = VkWriteDescriptorSet.New();
+ VkWriteDescriptorSet wds = default;
wds.descriptorType = binding.descriptorType;
wds.descriptorCount = binding.descriptorCount;
wds.dstBinding = binding.binding;
while (i < descriptors.Length) {
int firstDescriptor = i;
VkWriteDescriptorSet wds = WriteDescriptorSets[wdsPtr];
+ wds.sType = VkStructureType.WriteDescriptorSet;
if (dstSetOverride != null)
wds.dstSet = dstSetOverride.Value.Handle;
public void AddWriteInfo (DescriptorSet destSet, VkDescriptorSetLayoutBinding binding, VkDescriptorBufferInfo descriptor) {
if (!descriptors.Contains (descriptor))
descriptors.Add (descriptor);
- VkWriteDescriptorSet wds = VkWriteDescriptorSet.New();
+ VkWriteDescriptorSet wds = default;
wds.descriptorType = binding.descriptorType;
wds.descriptorCount = binding.descriptorCount;
wds.dstBinding = binding.binding;
public void AddWriteInfo (DescriptorSet destSet, VkDescriptorSetLayoutBinding binding, VkDescriptorImageInfo descriptor) {
if (!descriptors.Contains (descriptor))
descriptors.Add (descriptor);
- VkWriteDescriptorSet wds = VkWriteDescriptorSet.New();
+ VkWriteDescriptorSet wds = default;
wds.descriptorType = binding.descriptorType;
wds.descriptorCount = binding.descriptorCount;
wds.dstBinding = binding.binding;
using System.Runtime.InteropServices;
using Vulkan;
using static Vulkan.Vk;
-
+using static Vulkan.Utils;
namespace vke {
/// <summary>
Console.WriteLine ($"Unsupported device extension: {extensions[i]}");
}
- VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo.New ();
+ VkDeviceCreateInfo deviceCreateInfo = new VkDeviceCreateInfo ();
deviceCreateInfo.pQueueCreateInfos = qInfos;
deviceCreateInfo.pEnabledFeatures = enabledFeatures;
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.Pin ();
}
- Utils.CheckResult (vkCreateDevice (phy.Handle, ref deviceCreateInfo, IntPtr.Zero, out dev));
+ CheckResult (vkCreateDevice (phy.Handle, ref deviceCreateInfo, IntPtr.Zero, out dev));
deviceCreateInfo.Dispose();
foreach (VkDeviceQueueCreateInfo qI in qInfos)
/// <returns>The semaphore native handle</returns>
public VkSemaphore CreateSemaphore () {
VkSemaphore tmp;
- VkSemaphoreCreateInfo info = VkSemaphoreCreateInfo.New ();
- Utils.CheckResult (vkCreateSemaphore (dev, ref info, IntPtr.Zero, out tmp));
+ VkSemaphoreCreateInfo info = default;
+ CheckResult (vkCreateSemaphore (dev, ref info, IntPtr.Zero, out tmp));
return tmp;
}
public void DestroySemaphore (VkSemaphore semaphore) {
/// Wait for this logical device to enter the idle state.
/// </summary>
public void WaitIdle () {
- Utils.CheckResult (vkDeviceWaitIdle (dev));
+ CheckResult (vkDeviceWaitIdle (dev));
}
public VkRenderPass CreateRenderPass (VkRenderPassCreateInfo info) {
VkRenderPass renderPass;
- Utils.CheckResult (vkCreateRenderPass (dev, ref info, IntPtr.Zero, out renderPass));
+ CheckResult (vkCreateRenderPass (dev, ref info, IntPtr.Zero, out renderPass));
return renderPass;
}
public VkImageView CreateImageView (VkImage image, VkFormat format, VkImageViewType viewType = VkImageViewType.ImageView2D, VkImageAspectFlags aspectFlags = VkImageAspectFlags.Color) {
VkImageView view;
- VkImageViewCreateInfo infos = VkImageViewCreateInfo.New ();
+ VkImageViewCreateInfo infos = default;
infos.image = image;
infos.viewType = viewType;
infos.format = format;
infos.components = new VkComponentMapping { r = VkComponentSwizzle.R, g = VkComponentSwizzle.G, b = VkComponentSwizzle.B, a = VkComponentSwizzle.A };
infos.subresourceRange = new VkImageSubresourceRange (aspectFlags);
- Utils.CheckResult (vkCreateImageView (dev, ref infos, IntPtr.Zero, out view));
+ CheckResult (vkCreateImageView (dev, ref infos, IntPtr.Zero, out view));
return view;
}
public void DestroyImageView (VkImageView view) {
/// <returns>the vulkan shader module.</returns>
/// <param name="filename">path of the spv shader.</param>
public VkShaderModule CreateShaderModule (string filename) {
- using (Stream stream = Utils.GetStreamFromPath (filename)) {
+ using (Stream stream = Helpers.GetStreamFromPath (filename)) {
using (BinaryReader br = new BinaryReader (stream)) {
byte[] shaderCode = br.ReadBytes ((int)stream.Length);
UIntPtr shaderSize = (UIntPtr)shaderCode.Length;
/// the call to this method.</param>
/// <param name="codeSize">spirv code byte size.</param>
public VkShaderModule CreateShaderModule (uint[] code, UIntPtr codeSize) {
- VkShaderModuleCreateInfo moduleCreateInfo = VkShaderModuleCreateInfo.New ();
- moduleCreateInfo.codeSize = codeSize;
- moduleCreateInfo.pCode = code;
- Utils.CheckResult (vkCreateShaderModule (Handle, ref moduleCreateInfo, IntPtr.Zero, out VkShaderModule shaderModule));
- moduleCreateInfo.Dispose();
- return shaderModule;
+ using (VkShaderModuleCreateInfo moduleCreateInfo = new VkShaderModuleCreateInfo (codeSize, code)) {
+ CheckResult (vkCreateShaderModule (Handle, moduleCreateInfo, IntPtr.Zero, out VkShaderModule shaderModule));
+ return shaderModule;
+ }
}
#region IDisposable Support
using System.Linq;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
/// <summary>
/// </summary>
public class Fence : Activable {
internal VkFence handle;
- VkFenceCreateInfo info = VkFenceCreateInfo.New ();
+ VkFenceCreateInfo info = default;
public Fence (Device dev, bool signaled = false, string name = "fence") : base (dev, name) {
info.flags = signaled ? VkFenceCreateFlags.Signaled : 0;
public sealed override void Activate () {
if (state != ActivableState.Activated) {
- Utils.CheckResult (vkCreateFence (Dev.Handle, ref info, IntPtr.Zero, out handle));
+ CheckResult (vkCreateFence (Dev.Handle, ref info, IntPtr.Zero, out handle));
}
base.Activate ();
}
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
RenderPass renderPass;
public List<Image> attachments = new List<Image> ();
- VkFramebufferCreateInfo createInfo = VkFramebufferCreateInfo.New ();
+ VkFramebufferCreateInfo createInfo;
/// <summary>Framebuffer width.</summary>
public uint Width => createInfo.width;
/// <summary>Framebuffer height.</summary>
VkImageUsageFlags usage = 0;
VkImageAspectFlags aspectFlags = 0;
- Utils.QueryLayoutRequirements (ad.initialLayout, ref usage, ref aspectFlags);
- Utils.QueryLayoutRequirements (ad.finalLayout, ref usage, ref aspectFlags);
+ Helpers.QueryLayoutRequirements (ad.initialLayout, ref usage, ref aspectFlags);
+ Helpers.QueryLayoutRequirements (ad.finalLayout, ref usage, ref aspectFlags);
foreach (SubPass sp in renderPass.SubPasses) {
//TODO:check subpass usage
}
if (PNext != null)
createInfo.pNext = PNext.GetPointer();
- Utils.CheckResult (vkCreateFramebuffer (renderPass.Dev.Handle, ref createInfo, IntPtr.Zero, out handle));
+ CheckResult (vkCreateFramebuffer (renderPass.Dev.Handle, ref createInfo, IntPtr.Zero, out handle));
createInfo.Dispose();
using Vulkan;
using System.Linq;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
public class GraphicPipeline : Pipeline {
using (PinnedObjects pctx = new PinnedObjects ()) {
- VkPipelineColorBlendStateCreateInfo colorBlendInfo = VkPipelineColorBlendStateCreateInfo.New ();
+ VkPipelineColorBlendStateCreateInfo colorBlendInfo = default;
colorBlendInfo.logicOpEnable = cfg.ColorBlendLogicOpEnable;
colorBlendInfo.logicOp = cfg.ColorBlendLogicOp;
colorBlendInfo.blendConstants = cfg.ColorBlendConstants;
colorBlendInfo.pAttachments = cfg.blendAttachments;
- VkPipelineDynamicStateCreateInfo dynStatesInfo = VkPipelineDynamicStateCreateInfo.New ();
+ VkPipelineDynamicStateCreateInfo dynStatesInfo = default;
dynStatesInfo.pDynamicStates = cfg.dynamicStates;
- VkPipelineVertexInputStateCreateInfo vertInputInfo = VkPipelineVertexInputStateCreateInfo.New ();
+ VkPipelineVertexInputStateCreateInfo vertInputInfo = default;
vertInputInfo.pVertexBindingDescriptions = cfg.vertexBindings;
vertInputInfo.pVertexAttributeDescriptions = cfg.vertexAttributes;
- VkPipelineViewportStateCreateInfo viewportState = VkPipelineViewportStateCreateInfo.New ();
+ VkPipelineViewportStateCreateInfo viewportState = default;
if (cfg.Viewports.Count > 0) {
viewportState.pViewports = cfg.Viewports;
} else
} else
viewportState.scissorCount = 1;
- VkGraphicsPipelineCreateInfo info = VkGraphicsPipelineCreateInfo.New ();
+ VkGraphicsPipelineCreateInfo info = default;
info.renderPass = RenderPass.handle;
info.layout = Layout.handle;
info.pVertexInputState = vertInputInfo;
info.subpass = cfg.SubpassIndex;
if (enableTesselation) {
- VkPipelineTessellationStateCreateInfo tessellationInfo = VkPipelineTessellationStateCreateInfo.New();
+ VkPipelineTessellationStateCreateInfo tessellationInfo = default;
tessellationInfo.patchControlPoints = cfg.TessellationPatchControlPoints;
info.pTessellationState = tessellationInfo;
}
- Utils.CheckResult (vkCreateGraphicsPipelines (Dev.Handle, Cache == null ? VkPipelineCache.Null : Cache.handle, 1, ref info, IntPtr.Zero, out handle));
+ CheckResult (vkCreateGraphicsPipelines (Dev.Handle, Cache == null ? VkPipelineCache.Null : Cache.handle, 1, ref info, IntPtr.Zero, out handle));
vertInputInfo.Dispose();
viewportState.Dispose();
/// VkPipelineBindPoint.Graphics is set by default,
/// </summary>
public VkPipelineBindPoint bindPoint = VkPipelineBindPoint.Graphics;
- public VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = VkPipelineInputAssemblyStateCreateInfo.New ();
- public VkPipelineRasterizationStateCreateInfo rasterizationState = VkPipelineRasterizationStateCreateInfo.New ();
+ public VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
+ public VkPipelineRasterizationStateCreateInfo rasterizationState;
public List<VkViewport> Viewports = new List<VkViewport> ();
public List<VkRect2D> Scissors = new List<VkRect2D> ();
- public VkPipelineDepthStencilStateCreateInfo depthStencilState = VkPipelineDepthStencilStateCreateInfo.New ();
- public VkPipelineMultisampleStateCreateInfo multisampleState = VkPipelineMultisampleStateCreateInfo.New ();
+ public VkPipelineDepthStencilStateCreateInfo depthStencilState;
+ public VkPipelineMultisampleStateCreateInfo multisampleState;
public List<VkPipelineColorBlendAttachmentState> blendAttachments = new List<VkPipelineColorBlendAttachmentState> ();
public List<VkDynamicState> dynamicStates = new List<VkDynamicState> ();
public List<VkVertexInputBindingDescription> vertexBindings = new List<VkVertexInputBindingDescription> ();
for (uint i = 0; i < attribsDesc.Length; i++) {
vertexAttributes.Add (new VkVertexInputAttributeDescription (binding, i + currentAttributeIndex, attribsDesc[i], currentAttributeoffset));
VkFormatSize fs;
- Utils.vkGetFormatSize (attribsDesc[i], out fs);
+ Helpers.vkGetFormatSize (attribsDesc[i], out fs);
currentAttributeoffset += fs.blockSizeInBits / 8;
}
currentAttributeIndex += (uint)attribsDesc.Length;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
/// <summary>
public static VkFormat DefaultTextureFormat = VkFormat.R8g8b8a8Unorm;
internal VkImage handle;
- VkImageCreateInfo info = VkImageCreateInfo.New ();
+ VkImageCreateInfo info;
uint[] queuesFamillies;
/// <summary>
}
internal override void bindMemory () {
#if MEMORY_POOLS
- Utils.CheckResult (vkBindImageMemory (Dev.Handle, handle, memoryPool.vkMemory, poolOffset));
+ CheckResult (vkBindImageMemory (Dev.Handle, handle, memoryPool.vkMemory, poolOffset));
#else
- Utils.CheckResult (vkBindImageMemory (Dev.Handle, handle, vkMemory, 0));
+ CheckResult (vkBindImageMemory (Dev.Handle, handle, vkMemory, 0));
#endif
}
public sealed override void Activate () {
if (state != ActivableState.Activated) {
- VkExternalMemoryImageCreateInfo externalImgInfo = VkExternalMemoryImageCreateInfo.New ();
+ VkExternalMemoryImageCreateInfo externalImgInfo = default;
if (importExportHandleTypes > 0 && importedHandle != IntPtr.Zero) {
externalImgInfo.handleTypes = importExportHandleTypes;
info.pNext = externalImgInfo.Pin ();
if (info.sharingMode == VkSharingMode.Concurrent && queuesFamillies?.Length > 0) {
info.queueFamilyIndexCount = (uint)queuesFamillies.Length;
info.pQueueFamilyIndices = queuesFamillies;
- Utils.CheckResult (vkCreateImage (Dev.Handle, ref info, IntPtr.Zero, out handle));
+ CheckResult (vkCreateImage (Dev.Handle, ref info, IntPtr.Zero, out handle));
} else
- Utils.CheckResult (vkCreateImage (Dev.Handle, ref info, IntPtr.Zero, out handle));
+ CheckResult (vkCreateImage (Dev.Handle, ref info, IntPtr.Zero, out handle));
if (importExportHandleTypes > 0 && importedHandle != IntPtr.Zero)
externalImgInfo.Unpin ();
}
public Image ExportTo (Device targetdev, VkExternalMemoryHandleTypeFlags handleTypes) {
- VkMemoryHostPointerPropertiesEXT hostPointerProps = VkMemoryHostPointerPropertiesEXT.New();
+ VkMemoryHostPointerPropertiesEXT hostPointerProps = default;
VkResult res = vkGetMemoryHostPointerPropertiesEXT (Dev.Handle, handleTypes, importedHandle, out hostPointerProps);
if (res != VkResult.Success)
return null;
layerCount = 1;
VkImageView view = default (VkImageView);
- VkImageViewCreateInfo viewInfo = VkImageViewCreateInfo.New ();
+ VkImageViewCreateInfo viewInfo = default;
viewInfo.image = handle;
viewInfo.viewType = type;
viewInfo.format = Format;
viewInfo.subresourceRange.baseArrayLayer = baseArrayLayer;
viewInfo.subresourceRange.layerCount = layerCount < 0 ? info.arrayLayers : (uint)layerCount;
- Utils.CheckResult (vkCreateImageView (Dev.Handle, ref viewInfo, IntPtr.Zero, out view));
+ CheckResult (vkCreateImageView (Dev.Handle, ref viewInfo, IntPtr.Zero, out view));
if (Descriptor.imageView.Handle != 0)
Dev.DestroyImageView (Descriptor.imageView);
VkSamplerMipmapMode mipmapMode = VkSamplerMipmapMode.Linear, VkSamplerAddressMode addressMode = VkSamplerAddressMode.Repeat,
float maxAnisotropy = 1.0f, float minLod = 0.0f, float maxLod = -1f) {
VkSampler sampler;
- VkSamplerCreateInfo sampInfo = VkSamplerCreateInfo.New ();
+ VkSamplerCreateInfo sampInfo = default;
sampInfo.maxAnisotropy = maxAnisotropy;
sampInfo.maxAnisotropy = 1.0f;// device->enabledFeatures.samplerAnisotropy ? device->properties.limits.maxSamplerAnisotropy : 1.0f;
//samplerInfo.anisotropyEnable = device->enabledFeatures.samplerAnisotropy;
sampInfo.compareOp = VkCompareOp.Never;
sampInfo.borderColor = VkBorderColor.FloatOpaqueWhite;
- Utils.CheckResult (vkCreateSampler (Dev.Handle, ref sampInfo, IntPtr.Zero, out sampler));
+ CheckResult (vkCreateSampler (Dev.Handle, ref sampInfo, IntPtr.Zero, out sampler));
if (Descriptor.sampler.Handle != 0)
Dev.DestroySampler (Descriptor.sampler);
uint srcQueueFamilyIndex = Vk.QueueFamilyIgnored,
uint dstQueueFamilyIndex = Vk.QueueFamilyIgnored) {
- VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New ();
+ VkImageMemoryBarrier imageMemoryBarrier = default;
imageMemoryBarrier.srcQueueFamilyIndex = srcQueueFamilyIndex;
imageMemoryBarrier.dstQueueFamilyIndex = dstQueueFamilyIndex;
imageMemoryBarrier.oldLayout = oldImageLayout;
uint srcQueueFamilyIndex = Vk.QueueFamilyIgnored,
uint dstQueueFamilyIndex = Vk.QueueFamilyIgnored) {
// Create an image barrier object
- VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New ();
+ VkImageMemoryBarrier imageMemoryBarrier = default;
imageMemoryBarrier.srcQueueFamilyIndex = srcQueueFamilyIndex;
imageMemoryBarrier.dstQueueFamilyIndex = dstQueueFamilyIndex;
imageMemoryBarrier.oldLayout = oldImageLayout;
using System.Runtime.InteropServices;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
/// <summary>
pEngineName = APPLICATION_NAME,
};
- VkInstanceCreateInfo instanceCreateInfo = VkInstanceCreateInfo.New ();
+ VkInstanceCreateInfo instanceCreateInfo = default;
instanceCreateInfo.pApplicationInfo = appInfo;
if (instanceExtensions.Count > 0) {
}
public static string[] SupportedExtensions () => SupportedExtensions (IntPtr.Zero);
public static string[] SupportedExtensions (IntPtr layer) {
- Utils.CheckResult (vkEnumerateInstanceExtensionProperties (layer, out uint count, IntPtr.Zero));
+ CheckResult (vkEnumerateInstanceExtensionProperties (layer, out uint count, IntPtr.Zero));
int sizeStruct = Marshal.SizeOf<VkExtensionProperties> ();
IntPtr ptrSupExts = Marshal.AllocHGlobal (sizeStruct * (int)count);
- Utils.CheckResult (vkEnumerateInstanceExtensionProperties (layer, out count, ptrSupExts));
+ CheckResult (vkEnumerateInstanceExtensionProperties (layer, out count, ptrSupExts));
string[] result = new string[count];
IntPtr tmp = ptrSupExts;
/// </summary>
public VkSurfaceKHR CreateSurface (IntPtr hWindow) {
ulong surf;
- Utils.CheckResult ((VkResult)Glfw.Glfw3.CreateWindowSurface (inst.Handle, hWindow, IntPtr.Zero, out surf), "Create Surface Failed.");
+ CheckResult ((VkResult)Glfw.Glfw3.CreateWindowSurface (inst.Handle, hWindow, IntPtr.Zero, out surf), "Create Surface Failed.");
return surf;
}
public void GetDelegate<T> (string name, out T del) {
vkGetPhysicalDeviceQueueFamilyProperties (phy, out queueFamilyCount, QueueFamilies.Pin ());
QueueFamilies.Unpin ();
- Console.WriteLine("PhysicalDeviceCollection");
HasSwapChainSupport = GetDeviceExtensionSupported (Ext.D.VK_KHR_swapchain);
}
return result == VkResult.Success;
}
public VkPhysicalDeviceToolPropertiesEXT[] GetToolProperties () {
- Utils.CheckResult (vkGetPhysicalDeviceToolPropertiesEXT (phy , out uint count, IntPtr.Zero));
+ CheckResult (vkGetPhysicalDeviceToolPropertiesEXT (phy , out uint count, IntPtr.Zero));
int sizeStruct = Marshal.SizeOf<VkPhysicalDeviceToolPropertiesEXT> ();
IntPtr ptrTools = Marshal.AllocHGlobal (sizeStruct * (int)count);
- Utils.CheckResult (vkGetPhysicalDeviceToolPropertiesEXT (phy , out count, ptrTools));
+ CheckResult (vkGetPhysicalDeviceToolPropertiesEXT (phy , out count, ptrTools));
VkPhysicalDeviceToolPropertiesEXT[] result = new VkPhysicalDeviceToolPropertiesEXT[count];
IntPtr tmp = ptrTools;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
/// <summary>
string path = Path.Combine (globalConfigPath, cacheFile);
if (state != ActivableState.Activated) {
- VkPipelineCacheCreateInfo info = VkPipelineCacheCreateInfo.New ();
+ VkPipelineCacheCreateInfo info = default;
if (File.Exists (path) && LoadOnActivation) {
using (FileStream fs = File.Open (path, FileMode.Open)) {
}
}
- Utils.CheckResult (vkCreatePipelineCache (Dev.Handle, ref info, IntPtr.Zero, out handle));
+ CheckResult (vkCreatePipelineCache (Dev.Handle, ref info, IntPtr.Zero, out handle));
if (info.pInitialData != IntPtr.Zero)
Marshal.FreeHGlobal (info.pInitialData);
File.Delete (path);
UIntPtr dataSize;
- Utils.CheckResult (vkGetPipelineCacheData (Dev.Handle, handle, out dataSize, IntPtr.Zero));
+ CheckResult (vkGetPipelineCacheData (Dev.Handle, handle, out dataSize, IntPtr.Zero));
byte[] pData = new byte[(int)dataSize];
- Utils.CheckResult (vkGetPipelineCacheData (Dev.Handle, handle, out dataSize, pData.Pin ()));
+ CheckResult (vkGetPipelineCacheData (Dev.Handle, handle, out dataSize, pData.Pin ()));
pData.Unpin ();
using (FileStream fs = File.Open (path, FileMode.CreateNew))
using System.Linq;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
public sealed class PipelineLayout : Activable {
if (state != ActivableState.Activated) {
foreach (DescriptorSetLayout dsl in DescriptorSetLayouts)
dsl.Activate ();
- VkPipelineLayoutCreateInfo info = VkPipelineLayoutCreateInfo.New();
+ VkPipelineLayoutCreateInfo info = default;
VkDescriptorSetLayout[] dsls = DescriptorSetLayouts.Select (dsl => dsl.handle).ToArray ();
if (dsls.Length > 0) {
if (PushConstantRanges.Count > 0) {
info.pPushConstantRanges = PushConstantRanges;
}
- Utils.CheckResult (vkCreatePipelineLayout (Dev.Handle, ref info, IntPtr.Zero, out handle));
+ CheckResult (vkCreatePipelineLayout (Dev.Handle, ref info, IntPtr.Zero, out handle));
info.Dispose();
using System.Collections.Generic;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
public class TimestampQueryPool : QueryPool {
}
}
- public abstract class QueryPool : Activable {
+ public abstract class QueryPool : Activable {
protected VkQueryPool handle;
protected readonly VkQueryPoolCreateInfo createInfos;
public readonly VkQueryType QueryType;
protected QueryPool (Device device, VkQueryType queryType, VkQueryPipelineStatisticFlags statisticFlags, uint count = 1)
: base(device)
{
- createInfos = VkQueryPoolCreateInfo.New (queryType, statisticFlags, count);
+ createInfos = VkQueryPoolCreateInfo.CreateNew (queryType, statisticFlags, count);
//Activate ();
}
public override void Activate () {
if (state != ActivableState.Activated) {
- VkQueryPoolCreateInfo infos = createInfos;
- Utils.CheckResult (vkCreateQueryPool (Dev.Handle, ref infos, IntPtr.Zero, out handle));
+ VkQueryPoolCreateInfo infos = createInfos;
+ CheckResult (vkCreateQueryPool (Dev.Handle, ref infos, IntPtr.Zero, out handle));
}
base.Activate ();
}
return results;
}
-
+
public override string ToString () {
return string.Format ($"{base.ToString ()}[0x{handle.Handle.ToString("x")}]");
}
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
}
public void Present (VkPresentInfoKHR present) {
- Utils.CheckResult (vkQueuePresentKHR (handle, ref present));
+ CheckResult (vkQueuePresentKHR (handle, ref present));
}
public void Present (SwapChain swapChain, VkSemaphore wait) {
- VkPresentInfoKHR present = VkPresentInfoKHR.New();
+ VkPresentInfoKHR present = default;
uint idx = swapChain.currentImageIndex;
VkSwapchainKHR sc = swapChain.Handle;
cmd.Submit (handle, wait, signal, fence);
}
public void WaitIdle () {
- Utils.CheckResult (vkQueueWaitIdle (handle));
+ CheckResult (vkQueueWaitIdle (handle));
}
uint searchQFamily (VkQueueFlags requestedFlags) {
foreach (SubPass sp in subpasses)
spDescs.Add (sp.SubpassDescription);
- VkRenderPassCreateInfo renderPassInfo = VkRenderPassCreateInfo.New();
+ VkRenderPassCreateInfo renderPassInfo = default;
renderPassInfo.pAttachments = attachments;
renderPassInfo.pSubpasses = spDescs;
renderPassInfo.pDependencies = dependencies;
/// </summary>
public void Begin (PrimaryCommandBuffer cmd, FrameBuffer frameBuffer, uint width, uint height, VkSubpassContents contents = VkSubpassContents.Inline) {
- VkRenderPassBeginInfo info = VkRenderPassBeginInfo.New();
- info.renderPass = handle;
- info.renderArea.extent.width = width;
- info.renderArea.extent.height = height;
- info.pClearValues = ClearValues;
- info.framebuffer = frameBuffer.handle;
+ using (VkRenderPassBeginInfo info = new VkRenderPassBeginInfo {
+ renderPass = handle,
+ renderArea = new VkRect2D (default, new VkExtent2D (width, height)),
+ pClearValues = ClearValues,
+ framebuffer = frameBuffer.handle
+ }){
- vkCmdBeginRenderPass (cmd.Handle, ref info, contents);
+ vkCmdBeginRenderPass (cmd.Handle, info, contents);
- info.Dispose ();
+ }
}
/// <summary>
/// Switch to next subpass
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
/// <summary>
#if !MEMORY_POOLS
protected uint importedMemoryTypeBits = 0;
protected void allocateMemory () {
- VkMemoryAllocateInfo memInfo = VkMemoryAllocateInfo.New ();
+ VkMemoryAllocateInfo memInfo = default;
memInfo.allocationSize = memReqs.size;
/*if (importedMemoryTypeBits > 0)
memReqs.memoryTypeBits = importedMemoryTypeBits;*/
if (importExportHandleTypes > 0) {
if (importedHandle != IntPtr.Zero) {
- VkImportMemoryHostPointerInfoEXT importInfo = VkImportMemoryHostPointerInfoEXT.New ();
+ VkImportMemoryHostPointerInfoEXT importInfo = default;
importInfo.pHostPointer = importedHandle.Pin();
importInfo.handleType = importExportHandleTypes;
memInfo.pNext = importInfo.Pin ();
- Utils.CheckResult (vkAllocateMemory (Dev.Handle, ref memInfo, IntPtr.Zero, out vkMemory));
+ CheckResult (vkAllocateMemory (Dev.Handle, ref memInfo, IntPtr.Zero, out vkMemory));
importedHandle.Unpin();
importInfo.Unpin ();
} else {
- VkExportMemoryAllocateInfo exportInfo = VkExportMemoryAllocateInfo.New ();
+ VkExportMemoryAllocateInfo exportInfo = default;
exportInfo.handleTypes = importExportHandleTypes;
memInfo.pNext = exportInfo.Pin ();
- Utils.CheckResult (vkAllocateMemory (Dev.Handle, ref memInfo, IntPtr.Zero, out vkMemory));
+ CheckResult (vkAllocateMemory (Dev.Handle, ref memInfo, IntPtr.Zero, out vkMemory));
exportInfo.Unpin ();
}
} else
- Utils.CheckResult (vkAllocateMemory (Dev.Handle, ref memInfo, IntPtr.Zero, out vkMemory));
+ CheckResult (vkAllocateMemory (Dev.Handle, ref memInfo, IntPtr.Zero, out vkMemory));
}
#endif
public bool IsMapped => mappedData != IntPtr.Zero;
memoryPool.Map ();
mappedData = new IntPtr (memoryPool.MappedData.ToInt64 () + (long)(poolOffset + offset));
#else
- Utils.CheckResult (vkMapMemory (Dev.Handle, vkMemory, offset, AllocatedDeviceMemorySize, 0, ref mappedData));
+ CheckResult (vkMapMemory (Dev.Handle, vkMemory, offset, AllocatedDeviceMemorySize, 0, ref mappedData));
#endif
}
public void Unmap () {
using System;
using Vulkan;
using static Vulkan.Vk;
+using static Vulkan.Utils;
namespace vke {
/// <summary>
: base (_presentableQueue.dev) {
presentQueue = _presentableQueue;
- createInfos = VkSwapchainCreateInfoKHR.New ();
+ createInfos = default;
VkSurfaceFormatKHR[] formats = Dev.phy.GetSurfaceFormats (presentQueue.Surface);
for (int i = 0; i < formats.Length; i++) {
} else
createInfos.imageExtent = capabilities.currentExtent;
- Utils.CheckResult (vkCreateSwapchainKHR (Dev.Handle, ref createInfos, IntPtr.Zero, out VkSwapchainKHR newSwapChain));
+ CheckResult (vkCreateSwapchainKHR (Dev.Handle, ref createInfos, IntPtr.Zero, out VkSwapchainKHR newSwapChain));
if (Handle.Handle != 0)
_destroy ();
presentComplete.SetDebugMarkerName (Dev, "Semaphore PresentComplete");
Handle = newSwapChain;
- Utils.CheckResult (vkGetSwapchainImagesKHR (Dev.Handle, Handle, out uint imageCount, IntPtr.Zero));
+ CheckResult (vkGetSwapchainImagesKHR (Dev.Handle, Handle, out uint imageCount, IntPtr.Zero));
if (imageCount == 0)
throw new Exception ("Swapchain image count is 0.");
VkImage[] imgs = new VkImage[imageCount];
- Utils.CheckResult (vkGetSwapchainImagesKHR (Dev.Handle, Handle, out imageCount, imgs.Pin ()));
+ CheckResult (vkGetSwapchainImagesKHR (Dev.Handle, Handle, out imageCount, imgs.Pin ()));
imgs.Unpin ();
images = new Image[imgs.Length];
Create ();
return -1;
}
- Utils.CheckResult (res);
+ CheckResult (res);
return (int)currentImageIndex;
}
--- /dev/null
+// Copyright (c) 2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using Vulkan;
+using static Vulkan.Vk;
+using static Vulkan.Utils;
+using System.Linq;
+using System.Collections.Generic;
+using Glfw;
+
+namespace vke {
+ public class Context : IDisposable {
+ /** GLFW callback may return a custom pointer, this list makes the link between the GLFW window pointer and the
+ manage VkWindow instance. */
+ static Dictionary<IntPtr,Context> windows = new Dictionary<IntPtr, Context>();
+ /** GLFW window native pointer. */
+ IntPtr hWin;
+ /**Vulkan Surface */
+ protected VkSurfaceKHR hSurf;
+ VkInstance inst;
+ VkPhysicalDevice phy;
+ VkDevice dev;
+ VkQueue queue;
+ VkSwapchainCreateInfoKHR createInfos;
+ VkSwapchainKHR swapchainHandle;
+
+ public VkInstance Inst => inst;
+ public VkPhysicalDevice Phy => phy;
+ public VkDevice Dev=> dev;
+ public VkQueue Queue => queue;
+ public uint Width { get; private set; }
+ public uint Height { get; private set; }
+ public bool VSync { get; private set; }
+
+ VkPresentModeKHR presentMode => VSync ? VkPresentModeKHR.FifoKHR : VkPresentModeKHR.MailboxKHR;
+
+ public Context (uint width = 800, uint height = 600, VkFormat format = VkFormat.B8g8r8a8Unorm,
+ VkImageUsageFlags IMAGES_USAGE = VkImageUsageFlags.ColorAttachment,
+ string windowName = "vulkan") {
+
+ Width = width;
+ Height = height;
+
+ Glfw3.Init ();
+
+ Glfw3.WindowHint (WindowAttribute.ClientApi, 0);
+ Glfw3.WindowHint (WindowAttribute.Resizable, 1);
+
+ hWin = Glfw3.CreateWindow ((int)Width, (int)Height, windowName, MonitorHandle.Zero, IntPtr.Zero);
+ windows.Add (hWin, this);
+
+ if (hWin == IntPtr.Zero)
+ throw new Exception ("[GLFW3] Unable to create vulkan Window");
+
+ Glfw3.SetKeyCallback (hWin, HandleKeyDelegate);
+ Glfw3.SetMouseButtonPosCallback (hWin, HandleMouseButtonDelegate);
+ Glfw3.SetCursorPosCallback (hWin, HandleCursorPosDelegate);
+ Glfw3.SetScrollCallback (hWin, HandleScrollDelegate);
+ Glfw3.SetCharCallback (hWin, HandleCharDelegate);
+
+ string[] exts = Glfw3.GetRequiredInstanceExtensions ();
+
+ IntPtr[] extensions = new IntPtr[exts.Length];
+ for (int i = 0; i < exts.Length; i++)
+ extensions[i] = exts[i].PinPointer();
+
+ using (VkApplicationInfo ai = new VkApplicationInfo ()) {
+ using (VkInstanceCreateInfo ci = new VkInstanceCreateInfo {
+ pApplicationInfo = ai,
+ enabledExtensionCount = (uint)extensions.Length,
+ ppEnabledExtensionNames = extensions.Pin() }){
+ CheckResult (vkCreateInstance (ci, IntPtr.Zero, out inst));
+ }
+ }
+ extensions.Unpin();
+ for (int i = 0; i < extensions.Length; i++)
+ extensions[i].Unpin();
+
+ Vk.LoadInstanceFunctionPointers (inst);
+
+ hSurf = inst.CreateSurface (hWin);
+
+ if (!inst.TryGetPhysicalDevice (VkPhysicalDeviceType.DiscreteGpu, out phy))
+ if (!inst.TryGetPhysicalDevice (VkPhysicalDeviceType.IntegratedGpu, out phy))
+ if (!inst.TryGetPhysicalDevice (VkPhysicalDeviceType.Cpu, out phy))
+ throw new Exception ("no suitable physical device found");
+
+ VkQueueFamilyProperties[] qFamProps = phy.GetQueueFamilyProperties ();
+
+ uint qFamIndex = (uint)qFamProps.Select((qFam, index) => (qFam, index))
+ .First (qfp=>qfp.qFam.queueFlags.HasFlag (VkQueueFlags.Graphics)).index;
+
+ float[] priorities = {0};
+
+ exts = new string[] { Ext.D.VK_KHR_swapchain };
+ extensions = new IntPtr[exts.Length];
+ for (int i = 0; i < exts.Length; i++)
+ extensions[i] = exts[i].PinPointer();
+
+ using (VkDeviceQueueCreateInfo qInfo = new VkDeviceQueueCreateInfo (qFamIndex,1,priorities)) {
+ using (VkDeviceCreateInfo deviceCreateInfo = new VkDeviceCreateInfo () {
+ pQueueCreateInfos = qInfo,
+ enabledExtensionCount = (uint)extensions.Length,
+ ppEnabledExtensionNames = extensions.Pin() }) {
+
+ CheckResult (vkCreateDevice (phy, deviceCreateInfo, IntPtr.Zero, out dev));
+
+ }
+ }
+ Vk.LoadDeviceFunctionPointers (dev);
+ vkGetDeviceQueue (dev, qFamIndex, 0, out VkQueue gQ);
+
+ VkSurfaceFormatKHR[] formats = phy.GetSurfaceFormats (hSurf);
+ for (int i = 0; i < formats.Length; i++) {
+ if (formats[i].format == format) {
+ createInfos.imageFormat = format;
+ createInfos.imageColorSpace = formats[i].colorSpace;
+ break;
+ }
+ }
+ if (createInfos.imageFormat == VkFormat.Undefined)
+ throw new Exception ("Invalid format for swapchain: " + format);
+
+ VkPresentModeKHR[] presentModes = phy.GetSurfacePresentModes (hSurf);
+ for (int i = 0; i < presentModes.Length; i++) {
+ if (presentModes[i] == presentMode) {
+ createInfos.presentMode = presentMode;
+ break;
+ }
+ }
+ if (createInfos.presentMode != presentMode)
+ throw new Exception ("Invalid presentMode for swapchain: " + presentMode);
+
+ createInfos.surface = hSurf;
+ createInfos.imageExtent = new VkExtent2D (Width, Height);
+ createInfos.imageArrayLayers = 1;
+ createInfos.imageUsage = IMAGES_USAGE;
+ createInfos.imageSharingMode = VkSharingMode.Exclusive;
+ createInfos.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR;
+ createInfos.presentMode = presentMode;
+ createInfos.clipped = 1;
+ vkGetPhysicalDeviceSurfaceCapabilitiesKHR (phy, hSurf, out VkSurfaceCapabilitiesKHR capabilities);
+ createInfos.minImageCount = capabilities.minImageCount;
+ createInfos.preTransform = capabilities.currentTransform;
+
+ CreateSwapChain();
+ }
+
+ internal void CreateSwapChain () {
+ vkDeviceWaitIdle (dev);
+ vkGetPhysicalDeviceSurfaceCapabilitiesKHR (phy, hSurf, out VkSurfaceCapabilitiesKHR caps);
+ createInfos.oldSwapchain = swapchainHandle;
+
+ if (caps.currentExtent.width == 0xFFFFFFFF) {
+ if (createInfos.imageExtent.width < caps.minImageExtent.width)
+ createInfos.imageExtent.width = caps.minImageExtent.width;
+ else if (createInfos.imageExtent.width > caps.maxImageExtent.width)
+ createInfos.imageExtent.width = caps.maxImageExtent.width;
+
+ if (createInfos.imageExtent.height < caps.minImageExtent.height)
+ createInfos.imageExtent.height = caps.minImageExtent.height;
+ else if (createInfos.imageExtent.height > caps.maxImageExtent.height)
+ createInfos.imageExtent.height = caps.maxImageExtent.height;
+ } else
+ createInfos.imageExtent = caps.currentExtent;
+
+ CheckResult (vkCreateSwapchainKHR (dev, ref createInfos, IntPtr.Zero, out VkSwapchainKHR newSwapChain));
+
+ if (swapchainHandle != VkSwapchainKHR.Null)
+ vkDestroySwapchainKHR (dev, swapchainHandle, IntPtr.Zero);
+
+ swapchainHandle = newSwapChain;
+ }
+
+ public virtual void Run () {
+
+
+ while (!Glfw3.WindowShouldClose (hWin)) {
+
+ Glfw3.PollEvents ();
+ }
+ }
+
+ #region events
+ protected double lastMouseX { get; private set; }
+ protected double lastMouseY { get; private set; }
+ protected virtual void onScroll (double xOffset, double yOffset) { }
+ protected virtual void onMouseMove (double xPos, double yPos) {
+ }
+ protected virtual void onMouseButtonDown (MouseButton button) { }
+ protected virtual void onMouseButtonUp (MouseButton button) { }
+ protected virtual void onKeyDown (Key key, int scanCode, Modifier modifiers) {
+ switch (key) {
+ case Key.Escape:
+ Glfw3.SetWindowShouldClose (hWin, 1);
+ break;
+ }
+ }
+ protected virtual void onKeyUp (Key key, int scanCode, Modifier modifiers) { }
+ protected virtual void onChar (CodePoint cp) { }
+ static CursorPosDelegate HandleCursorPosDelegate = (window, xPosition, yPosition) => {
+ windows[window].onMouseMove (xPosition, yPosition);
+ windows[window].lastMouseX = xPosition;
+ windows[window].lastMouseY = yPosition;
+ };
+ static MouseButtonDelegate HandleMouseButtonDelegate = (IntPtr window, Glfw.MouseButton button, InputAction action, Modifier mods) => {
+ if (action == InputAction.Press)
+ windows[window].onMouseButtonDown (button);
+ else
+ windows[window].onMouseButtonUp (button);
+ };
+ static ScrollDelegate HandleScrollDelegate = (IntPtr window, double xOffset, double yOffset) => {
+ windows[window].onScroll (xOffset, yOffset);
+ };
+ static KeyDelegate HandleKeyDelegate = (IntPtr window, Key key, int scanCode, InputAction action, Modifier modifiers) => {
+ if (action == InputAction.Press || action == InputAction.Repeat) {
+ windows[window].onKeyDown (key, scanCode, modifiers);
+ } else {
+ windows[window].onKeyUp (key, scanCode, modifiers);
+ }
+ };
+ static CharDelegate HandleCharDelegate = (IntPtr window, CodePoint codepoint) => {
+ windows[window].onChar (codepoint);
+ };
+ #endregion
+ #region IDisposable implementation
+ bool disposedValue;
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ // TODO: dispose managed state (managed objects)
+ }
+
+ vkDestroyDevice (dev, IntPtr.Zero);
+ vkDestroyInstance (inst, IntPtr.Zero);
+ disposedValue = true;
+ }
+ }
+ ~Context() {
+ Dispose(disposing: false);
+ }
+ public void Dispose() {
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}