From: Jean-Philippe Bruyère Date: Wed, 8 Dec 2021 20:54:48 +0000 (+0100) Subject: update with vk.net 0.4.0-beta X-Git-Tag: v0.2.4-beta X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=refs%2Fpull%2F14%2Fhead;p=jp%2Fvke.net.git update with vk.net 0.4.0-beta --- diff --git a/.vscode/launch.json b/.vscode/launch.json index dfc6833..39584b8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,20 @@ // 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", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 4da8453..b58cf5b 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -15,6 +15,20 @@ ], "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", diff --git a/addons/EnvironmentPipeline/EnvironmentPipeline.cs b/addons/EnvironmentPipeline/EnvironmentPipeline.cs index ec56cb0..a63ffd4 100644 --- a/addons/EnvironmentPipeline/EnvironmentPipeline.cs +++ b/addons/EnvironmentPipeline/EnvironmentPipeline.cs @@ -206,17 +206,17 @@ namespace vke.Environment { 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); @@ -250,7 +250,7 @@ namespace vke.Environment { 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 ()); cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaTheta, (uint)Marshal.SizeOf () + 4); diff --git a/addons/gltfLoader/glTFLoader.cs b/addons/gltfLoader/glTFLoader.cs index 9a08362..d73b841 100644 --- a/addons/gltfLoader/glTFLoader.cs +++ b/addons/gltfLoader/glTFLoader.cs @@ -384,11 +384,11 @@ namespace vke.glTF { } 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) * @@ -555,7 +555,7 @@ namespace vke.glTF { 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; @@ -588,7 +588,7 @@ namespace vke.glTF { 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; diff --git a/samples/DistanceFieldFontTest/Program.cs b/samples/DistanceFieldFontTest/Program.cs index 8a3e064..31990cd 100644 --- a/samples/DistanceFieldFontTest/Program.cs +++ b/samples/DistanceFieldFontTest/Program.cs @@ -239,7 +239,7 @@ namespace DistanceFieldFontTest { 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) * diff --git a/samples/ExternalMemmories/Program.cs b/samples/ExternalMemmories/Program.cs index 2a9f404..2526b49 100644 --- a/samples/ExternalMemmories/Program.cs +++ b/samples/ExternalMemmories/Program.cs @@ -82,11 +82,11 @@ namespace ExternalMemmories 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; diff --git a/samples/ImmutableSampler/main.cs b/samples/ImmutableSampler/main.cs index 6496adb..3a9bf68 100644 --- a/samples/ImmutableSampler/main.cs +++ b/samples/ImmutableSampler/main.cs @@ -148,7 +148,7 @@ namespace Textured { 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) * diff --git a/samples/Tesselation/README.md b/samples/Tesselation/README.md deleted file mode 100644 index 27f9eb3..0000000 --- a/samples/Tesselation/README.md +++ /dev/null @@ -1,60 +0,0 @@ -### 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 (dev, VkBufferUsageFlags.VertexBuffer, vertices); -//the index buffer -ibo = new HostBuffer (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 (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); -``` diff --git a/samples/Tesselation/Tesselation.csproj b/samples/Tesselation/Tesselation.csproj deleted file mode 100644 index 672fb5a..0000000 --- a/samples/Tesselation/Tesselation.csproj +++ /dev/null @@ -1,5 +0,0 @@ - - - false - - diff --git a/samples/Tesselation/main.cs b/samples/Tesselation/main.cs deleted file mode 100644 index 6f95779..0000000 --- a/samples/Tesselation/main.cs +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) 2019 Jean-Philippe Bruyère -// -// 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 (dev, VkBufferUsageFlags.VertexBuffer, vertices); - ibo = new HostBuffer (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 (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 ()); - 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); - } - } -} diff --git a/samples/Tesselation/shaders/main.frag b/samples/Tesselation/shaders/main.frag deleted file mode 100644 index a3cafac..0000000 --- a/samples/Tesselation/shaders/main.frag +++ /dev/null @@ -1,12 +0,0 @@ -#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 diff --git a/samples/Tesselation/shaders/main.vert b/samples/Tesselation/shaders/main.vert deleted file mode 100644 index 0997ca9..0000000 --- a/samples/Tesselation/shaders/main.vert +++ /dev/null @@ -1,26 +0,0 @@ -#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); -} diff --git a/samples/Textured/main.cs b/samples/Textured/main.cs index 15e6567..f9ffd8b 100644 --- a/samples/Textured/main.cs +++ b/samples/Textured/main.cs @@ -176,7 +176,7 @@ namespace Textured { } 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) * diff --git a/samples/TexturedCube/main.cs b/samples/TexturedCube/main.cs index 5b00644..257a0fd 100644 --- a/samples/TexturedCube/main.cs +++ b/samples/TexturedCube/main.cs @@ -192,7 +192,7 @@ namespace TextureCube { 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) * diff --git a/samples/Triangle/main.cs b/samples/Triangle/main.cs index 075f9f3..aabed92 100644 --- a/samples/Triangle/main.cs +++ b/samples/Triangle/main.cs @@ -111,7 +111,7 @@ namespace Triangle { 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 (); } diff --git a/samples/VulkanContext/README.md b/samples/VulkanContext/README.md new file mode 100644 index 0000000..27f9eb3 --- /dev/null +++ b/samples/VulkanContext/README.md @@ -0,0 +1,60 @@ +### 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 (dev, VkBufferUsageFlags.VertexBuffer, vertices); +//the index buffer +ibo = new HostBuffer (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 (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); +``` diff --git a/samples/VulkanContext/VulkanContext.csproj b/samples/VulkanContext/VulkanContext.csproj new file mode 100644 index 0000000..672fb5a --- /dev/null +++ b/samples/VulkanContext/VulkanContext.csproj @@ -0,0 +1,5 @@ + + + false + + diff --git a/samples/VulkanContext/main.cs b/samples/VulkanContext/main.cs new file mode 100644 index 0000000..b15e4bc --- /dev/null +++ b/samples/VulkanContext/main.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2019 Jean-Philippe Bruyère +// +// 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(); + + } + } + } +} diff --git a/samples/VulkanContext/shaders/main.frag b/samples/VulkanContext/shaders/main.frag new file mode 100644 index 0000000..a3cafac --- /dev/null +++ b/samples/VulkanContext/shaders/main.frag @@ -0,0 +1,12 @@ +#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 diff --git a/samples/VulkanContext/shaders/main.vert b/samples/VulkanContext/shaders/main.vert new file mode 100644 index 0000000..0997ca9 --- /dev/null +++ b/samples/VulkanContext/shaders/main.vert @@ -0,0 +1,26 @@ +#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); +} diff --git a/samples/common/SampleBase.cs b/samples/common/SampleBase.cs index 959d821..2104a69 100644 --- a/samples/common/SampleBase.cs +++ b/samples/common/SampleBase.cs @@ -6,7 +6,7 @@ namespace vke 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 @@ -16,6 +16,6 @@ namespace vke Console.ResetColor (); } #endif - }*/ + } } } diff --git a/samples/deferred/DeferredPbrRenderer.cs b/samples/deferred/DeferredPbrRenderer.cs index e1f394a..e37deb4 100644 --- a/samples/deferred/DeferredPbrRenderer.cs +++ b/samples/deferred/DeferredPbrRenderer.cs @@ -408,7 +408,7 @@ namespace deferred { 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; diff --git a/samples/deferred/main.cs b/samples/deferred/main.cs index 5d23027..ecdc687 100644 --- a/samples/deferred/main.cs +++ b/samples/deferred/main.cs @@ -81,7 +81,7 @@ namespace deferred { 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); diff --git a/samples/deferred/shadowMapRenderer.cs b/samples/deferred/shadowMapRenderer.cs index 511d387..df42f2a 100644 --- a/samples/deferred/shadowMapRenderer.cs +++ b/samples/deferred/shadowMapRenderer.cs @@ -23,7 +23,7 @@ namespace deferred { public float depthBiasConstant = 1.5f; public float depthBiasSlope = 1.75f; - float lightFOV = Utils.DegreesToRadians (60); + float lightFOV = Helpers.DegreesToRadians (60); float lightFarPlane; @@ -112,7 +112,7 @@ namespace deferred { } 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; diff --git a/samples/pbr/main.cs b/samples/pbr/main.cs index a49b701..d0e43bf 100644 --- a/samples/pbr/main.cs +++ b/samples/pbr/main.cs @@ -52,7 +52,7 @@ namespace pbrSample { 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, diff --git a/samples/shadow/DeferredPbrRenderer.cs b/samples/shadow/DeferredPbrRenderer.cs index 0668628..6f6ddea 100644 --- a/samples/shadow/DeferredPbrRenderer.cs +++ b/samples/shadow/DeferredPbrRenderer.cs @@ -410,7 +410,7 @@ namespace deferred { 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; diff --git a/samples/shadow/EnvironmentPipeline.cs b/samples/shadow/EnvironmentPipeline.cs index 32f8e6a..8fde7a0 100644 --- a/samples/shadow/EnvironmentPipeline.cs +++ b/samples/shadow/EnvironmentPipeline.cs @@ -200,17 +200,17 @@ namespace vke { 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); @@ -244,7 +244,7 @@ namespace vke { 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 ()); cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaTheta, (uint)Marshal.SizeOf () + 4); diff --git a/samples/shadow/main-crow.cs b/samples/shadow/main-crow.cs index f90efcb..ed73ba3 100644 --- a/samples/shadow/main-crow.cs +++ b/samples/shadow/main-crow.cs @@ -150,7 +150,7 @@ namespace deferred { ); #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); diff --git a/samples/shadow/main.cs b/samples/shadow/main.cs index 56ba57f..a414854 100644 --- a/samples/shadow/main.cs +++ b/samples/shadow/main.cs @@ -100,7 +100,7 @@ namespace deferred { 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); diff --git a/samples/shadow/mainShadow.cs b/samples/shadow/mainShadow.cs index 0bc3103..31473ec 100644 --- a/samples/shadow/mainShadow.cs +++ b/samples/shadow/mainShadow.cs @@ -47,7 +47,7 @@ namespace deferredShadow { } 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); diff --git a/samples/shadow/mainWithDebugDrawer.cs b/samples/shadow/mainWithDebugDrawer.cs index f95ed0a..a36e1f7 100644 --- a/samples/shadow/mainWithDebugDrawer.cs +++ b/samples/shadow/mainWithDebugDrawer.cs @@ -44,7 +44,7 @@ namespace deferredDebug { } 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); diff --git a/samples/shadow/shadowMapRenderer.cs b/samples/shadow/shadowMapRenderer.cs index 875e11c..4ce637b 100644 --- a/samples/shadow/shadowMapRenderer.cs +++ b/samples/shadow/shadowMapRenderer.cs @@ -23,7 +23,7 @@ namespace deferred { public float depthBiasConstant = 1.5f; public float depthBiasSlope = 1.75f; - float lightFOV = Utils.DegreesToRadians (60); + float lightFOV = Helpers.DegreesToRadians (60); float lightFarPlane; diff --git a/vke.net.sln b/vke.net.sln index 5d4ccbe..0e5ac98 100644 --- a/vke.net.sln +++ b/vke.net.sln @@ -44,10 +44,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "deferred", "samples\deferre 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 @@ -141,14 +141,6 @@ Global {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 @@ -157,6 +149,14 @@ Global {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 @@ -173,8 +173,8 @@ Global {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} diff --git a/vke/src/Camera.cs b/vke/src/Camera.cs index 383e700..739e4cf 100644 --- a/vke/src/Camera.cs +++ b/vke/src/Camera.cs @@ -164,7 +164,7 @@ namespace vke { /// in sync with the parameters. It's automatically called after rotation, move, etc... /// 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) { diff --git a/vke/src/ExtensionMethods.cs b/vke/src/ExtensionMethods.cs index 6c94a66..20fbc35 100644 --- a/vke/src/ExtensionMethods.cs +++ b/vke/src/ExtensionMethods.cs @@ -9,6 +9,7 @@ using System.Runtime.InteropServices; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { public static class ExtensionMethods { @@ -31,7 +32,7 @@ namespace vke { 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) { @@ -39,7 +40,7 @@ namespace vke { 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) { @@ -47,7 +48,7 @@ namespace vke { 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) { @@ -55,7 +56,7 @@ namespace vke { 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) { @@ -63,7 +64,7 @@ namespace vke { 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) { @@ -71,7 +72,7 @@ namespace vke { 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) { @@ -79,7 +80,7 @@ namespace vke { 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 @@ -107,5 +108,26 @@ namespace vke { } #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().ToArray(); + } } } diff --git a/vke/src/MemoryPool.cs b/vke/src/MemoryPool.cs index 76a1901..0a9450d 100644 --- a/vke/src/MemoryPool.cs +++ b/vke/src/MemoryPool.cs @@ -46,7 +46,7 @@ namespace vke { 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)); } /// /// Allocate memory for a new resource in this memory pool. @@ -140,7 +140,7 @@ namespace vke { /// Size. /// Offset. 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)); } /// /// Unmap previously mapped memory of this pool. diff --git a/vke/src/ShaderInfo.cs b/vke/src/ShaderInfo.cs index c3fcea1..34138b5 100644 --- a/vke/src/ShaderInfo.cs +++ b/vke/src/ShaderInfo.cs @@ -9,7 +9,7 @@ namespace vke { /// This class is a helper class for VkPipelineShaderStageCreateInfo creation. /// public class ShaderInfo : IDisposable { - protected VkPipelineShaderStageCreateInfo info = VkPipelineShaderStageCreateInfo.New (); + protected VkPipelineShaderStageCreateInfo info; protected Device dev; public VkShaderStageFlags Stage => info.stage; @@ -42,7 +42,7 @@ namespace vke { /// vke Device /// Stage flags. /// - /// Path to a compiled SpirV Shader on disk or as embedded ressource. See for more information. + /// Path to a compiled SpirV Shader on disk or as embedded ressource. See for more information. /// /// Specialization info /// shader entry point, 'main' by default. diff --git a/vke/src/Utils.cs b/vke/src/Utils.cs index f7786d5..86d026b 100644 --- a/vke/src/Utils.cs +++ b/vke/src/Utils.cs @@ -7,15 +7,13 @@ using System.Linq; 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 { /// Throw an erro if VkResult != Success. - 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)) @@ -84,8 +82,8 @@ namespace Vulkan { } /// Convert angle from degree to radian. public static float DegreesToRadians (float degrees) { - return degrees * (float)Math.PI / 180f; - } + return degrees * (float)Math.PI / 180f; + } /// /// Populate a Vector3 with values from a float array @@ -97,7 +95,7 @@ namespace Vulkan { /// Populate a Vector4 with values from a float array /// public static void FromFloatArray (ref Vector4 v, float[] floats) { - v = Unsafe.As(ref floats)[0]; + MemoryMarshal.Cast(floats.AsSpan()); } /// /// Populate a Quaternion with values from a float array @@ -110,7 +108,7 @@ namespace Vulkan { /// public static void FromByteArray (ref Vector2 v, byte[] byteArray, int offset) { v = Unsafe.As(ref Unsafe.AsRef(byteArray.SubArray(offset, 8)))[0]; - } + } /// /// Populate a Vector3 with values from a byte array starting at offset /// @@ -151,142 +149,142 @@ namespace Vulkan { // 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); + } /// /// Find usage flags and aspect flag from image layout /// diff --git a/vke/src/VkFormatSize.cs b/vke/src/VkFormatSize.cs index 9f816f4..6495575 100644 --- a/vke/src/VkFormatSize.cs +++ b/vke/src/VkFormatSize.cs @@ -2,8 +2,9 @@ // // 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, @@ -12,7 +13,7 @@ namespace Vulkan { SizeDepth = 0x00000008, SizeStencil = 0x00000010, }; - + public struct VkFormatSize { public VkFormatSizeFlag flags; public uint paletteSizeInBits; @@ -23,7 +24,7 @@ namespace Vulkan { }; - public static partial class Utils { + public static partial class Helpers { public static void vkGetFormatSize(VkFormat format, out VkFormatSize pFormatSize ) { switch ( format ) diff --git a/vke/src/VkWindow.cs b/vke/src/VkWindow.cs index 65dd3dd..1fa6203 100644 --- a/vke/src/VkWindow.cs +++ b/vke/src/VkWindow.cs @@ -45,7 +45,7 @@ namespace vke { 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; diff --git a/vke/src/base/Activable.cs b/vke/src/base/Activable.cs index 02dec89..81a88b7 100644 --- a/vke/src/base/Activable.cs +++ b/vke/src/base/Activable.cs @@ -5,6 +5,7 @@ using System; using System.Xml.Serialization; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { /// @@ -74,7 +75,7 @@ namespace vke { VkDebugUtilsObjectNameInfoEXT dmo = DebugUtilsInfo; dmo.pObjectName = name.Pin(); - Utils.CheckResult (vkSetDebugUtilsObjectNameEXT (Dev.Handle, ref dmo)); + CheckResult (vkSetDebugUtilsObjectNameEXT (Dev.Handle, ref dmo)); name.Unpin (); } /// diff --git a/vke/src/base/Buffer.cs b/vke/src/base/Buffer.cs index 74f74bc..c252575 100644 --- a/vke/src/base/Buffer.cs +++ b/vke/src/base/Buffer.cs @@ -4,6 +4,7 @@ using System; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { @@ -12,7 +13,7 @@ namespace vke { /// public class Buffer : Resource { internal VkBuffer handle; - protected VkBufferCreateInfo createInfo = VkBufferCreateInfo.New (); + protected VkBufferCreateInfo createInfo; /// Native handle of this vulkan buffer. /// The handle. public VkBuffer Handle => handle; @@ -47,7 +48,7 @@ namespace vke { /// 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 @@ -66,9 +67,9 @@ namespace vke { 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 diff --git a/vke/src/base/CommandBuffer.cs b/vke/src/base/CommandBuffer.cs index a25b23a..aaad0f5 100644 --- a/vke/src/base/CommandBuffer.cs +++ b/vke/src/base/CommandBuffer.cs @@ -6,6 +6,7 @@ using System.Runtime.InteropServices; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { public class SecondaryCommandBuffer : CommandBuffer { @@ -13,7 +14,7 @@ namespace vke { } 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; @@ -22,7 +23,7 @@ namespace vke { inheri.pipelineStatistics = statFlags; VkCommandBufferBeginInfo cmdBufInfo = new VkCommandBufferBeginInfo (usage); cmdBufInfo.pInheritanceInfo = inheri; - Utils.CheckResult (vkBeginCommandBuffer (handle, ref cmdBufInfo)); + CheckResult (vkBeginCommandBuffer (handle, ref cmdBufInfo)); cmdBufInfo.Dispose(); } } @@ -37,7 +38,7 @@ namespace vke { /// Signal. /// Fence. 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; @@ -50,7 +51,7 @@ namespace vke { 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(); } /// @@ -59,7 +60,7 @@ namespace vke { /// optional command buffer usage flags. public void Start (VkCommandBufferUsageFlags usage = 0) { VkCommandBufferBeginInfo cmdBufInfo = new VkCommandBufferBeginInfo (usage); - Utils.CheckResult (vkBeginCommandBuffer (handle, ref cmdBufInfo)); + CheckResult (vkBeginCommandBuffer (handle, ref cmdBufInfo)); } /// /// Execute secondary command buffers. @@ -116,7 +117,7 @@ namespace vke { /// Put the command buffer in the executable state if no errors are present in the recording. /// public void End () { - Utils.CheckResult (vkEndCommandBuffer (handle)); + CheckResult (vkEndCommandBuffer (handle)); } /// /// Update dynamic viewport state @@ -199,7 +200,7 @@ namespace vke { } 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, @@ -208,7 +209,7 @@ namespace vke { 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; @@ -220,7 +221,7 @@ namespace vke { 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; diff --git a/vke/src/base/CommandPool.cs b/vke/src/base/CommandPool.cs index 1278fa6..55f0f97 100644 --- a/vke/src/base/CommandPool.cs +++ b/vke/src/base/CommandPool.cs @@ -5,6 +5,7 @@ using System; using System.Runtime.InteropServices; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { /// @@ -46,10 +47,10 @@ namespace vke { 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 (); } @@ -60,12 +61,12 @@ namespace vke { /// The command buffer in the Init state. 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); } @@ -76,12 +77,12 @@ namespace vke { /// The command buffer in the Init state. 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); } @@ -92,12 +93,12 @@ namespace vke { /// An array of command buffers alloocated from this pool. /// Buffer count to create. 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++) diff --git a/vke/src/base/ComputePipeline.cs b/vke/src/base/ComputePipeline.cs index a202f11..efea103 100644 --- a/vke/src/base/ComputePipeline.cs +++ b/vke/src/base/ComputePipeline.cs @@ -5,6 +5,7 @@ using System; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { public sealed class ComputePipeline : Pipeline { @@ -32,13 +33,13 @@ namespace vke { 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 (); diff --git a/vke/src/base/DebugReport.cs b/vke/src/base/DebugReport.cs index e5e8e88..0fddb68 100644 --- a/vke/src/base/DebugReport.cs +++ b/vke/src/base/DebugReport.cs @@ -5,10 +5,11 @@ using System; 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; @@ -52,7 +53,7 @@ namespace vke { Console.ForegroundColor = ConsoleColor.White; return VkBool32.False; } - + public DebugReport (Instance instance, VkDebugReportFlagsEXT flags = VkDebugReportFlagsEXT.ErrorEXT | VkDebugReportFlagsEXT.WarningEXT) { inst = instance; @@ -62,7 +63,7 @@ namespace vke { 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 diff --git a/vke/src/base/DebugUtilsMessenger.cs b/vke/src/base/DebugUtilsMessenger.cs index 67f13d9..1cd8935 100644 --- a/vke/src/base/DebugUtilsMessenger.cs +++ b/vke/src/base/DebugUtilsMessenger.cs @@ -6,6 +6,7 @@ using System.Runtime.InteropServices; using System.Text; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke.DebugUtils { /// @@ -73,13 +74,13 @@ namespace vke.DebugUtils { 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)); } /// /// Create a new debug utils messenger with default message callback outputing to Console. diff --git a/vke/src/base/DescriptorPool.cs b/vke/src/base/DescriptorPool.cs index b832f6a..604332d 100644 --- a/vke/src/base/DescriptorPool.cs +++ b/vke/src/base/DescriptorPool.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { [Serializable] @@ -43,11 +44,11 @@ namespace vke { 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 (); @@ -63,24 +64,24 @@ namespace vke { 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 () { diff --git a/vke/src/base/DescriptorSetLayout.cs b/vke/src/base/DescriptorSetLayout.cs index 3b29edc..291db74 100644 --- a/vke/src/base/DescriptorSetLayout.cs +++ b/vke/src/base/DescriptorSetLayout.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { /// @@ -38,7 +39,7 @@ namespace vke { 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 (); diff --git a/vke/src/base/DescriptorSetWrites.cs b/vke/src/base/DescriptorSetWrites.cs index b6fdeca..9260798 100644 --- a/vke/src/base/DescriptorSetWrites.cs +++ b/vke/src/base/DescriptorSetWrites.cs @@ -62,7 +62,7 @@ namespace vke { /// with another descriptorSet in parametters /// 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; @@ -82,7 +82,7 @@ namespace vke { /// provide a desDescriptor! /// public void AddWriteInfo (VkDescriptorSetLayoutBinding binding) { - VkWriteDescriptorSet wds = VkWriteDescriptorSet.New(); + VkWriteDescriptorSet wds = default; wds.descriptorType = binding.descriptorType; wds.descriptorCount = binding.descriptorCount; wds.dstBinding = binding.binding; @@ -107,6 +107,7 @@ namespace vke { while (i < descriptors.Length) { int firstDescriptor = i; VkWriteDescriptorSet wds = WriteDescriptorSets[wdsPtr]; + wds.sType = VkStructureType.WriteDescriptorSet; if (dstSetOverride != null) wds.dstSet = dstSetOverride.Value.Handle; @@ -177,7 +178,7 @@ namespace vke { 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; @@ -189,7 +190,7 @@ namespace vke { 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; diff --git a/vke/src/base/Device.cs b/vke/src/base/Device.cs index cd47146..8020b35 100644 --- a/vke/src/base/Device.cs +++ b/vke/src/base/Device.cs @@ -9,7 +9,7 @@ using System.Reflection; using System.Runtime.InteropServices; using Vulkan; using static Vulkan.Vk; - +using static Vulkan.Utils; namespace vke { /// @@ -73,7 +73,7 @@ namespace vke { Console.WriteLine ($"Unsupported device extension: {extensions[i]}"); } - VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo.New (); + VkDeviceCreateInfo deviceCreateInfo = new VkDeviceCreateInfo (); deviceCreateInfo.pQueueCreateInfos = qInfos; deviceCreateInfo.pEnabledFeatures = enabledFeatures; @@ -82,7 +82,7 @@ namespace vke { 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) @@ -106,8 +106,8 @@ namespace vke { /// The semaphore native handle 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) { @@ -123,24 +123,24 @@ namespace vke { /// Wait for this logical device to enter the idle state. /// 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) { @@ -191,7 +191,7 @@ namespace vke { /// the vulkan shader module. /// path of the spv shader. 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; @@ -208,12 +208,10 @@ namespace vke { /// the call to this method. /// spirv code byte size. 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 diff --git a/vke/src/base/Fence.cs b/vke/src/base/Fence.cs index ab04404..6d4ef6b 100644 --- a/vke/src/base/Fence.cs +++ b/vke/src/base/Fence.cs @@ -6,6 +6,7 @@ using System.Collections.ObjectModel; using System.Linq; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { /// @@ -13,7 +14,7 @@ namespace vke { /// 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; @@ -25,7 +26,7 @@ namespace vke { 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 (); } diff --git a/vke/src/base/FrameBuffer.cs b/vke/src/base/FrameBuffer.cs index 5cb9332..e6319aa 100644 --- a/vke/src/base/FrameBuffer.cs +++ b/vke/src/base/FrameBuffer.cs @@ -7,6 +7,7 @@ using System.Linq; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { @@ -18,7 +19,7 @@ namespace vke { RenderPass renderPass; public List attachments = new List (); - VkFramebufferCreateInfo createInfo = VkFramebufferCreateInfo.New (); + VkFramebufferCreateInfo createInfo; /// Framebuffer width. public uint Width => createInfo.width; /// Framebuffer height. @@ -65,8 +66,8 @@ namespace vke { 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 } @@ -92,7 +93,7 @@ namespace vke { 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(); diff --git a/vke/src/base/GraphicPipeline.cs b/vke/src/base/GraphicPipeline.cs index 01a8ef4..c20cd1f 100644 --- a/vke/src/base/GraphicPipeline.cs +++ b/vke/src/base/GraphicPipeline.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using Vulkan; using System.Linq; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { public class GraphicPipeline : Pipeline { @@ -53,20 +54,20 @@ namespace vke { 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 @@ -77,7 +78,7 @@ namespace vke { } else viewportState.scissorCount = 1; - VkGraphicsPipelineCreateInfo info = VkGraphicsPipelineCreateInfo.New (); + VkGraphicsPipelineCreateInfo info = default; info.renderPass = RenderPass.handle; info.layout = Layout.handle; info.pVertexInputState = vertInputInfo; @@ -92,12 +93,12 @@ namespace vke { 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(); diff --git a/vke/src/base/GraphicPipelineConfig.cs b/vke/src/base/GraphicPipelineConfig.cs index 97be93b..1e656a1 100644 --- a/vke/src/base/GraphicPipelineConfig.cs +++ b/vke/src/base/GraphicPipelineConfig.cs @@ -35,12 +35,12 @@ namespace vke { /// VkPipelineBindPoint.Graphics is set by default, /// public VkPipelineBindPoint bindPoint = VkPipelineBindPoint.Graphics; - public VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = VkPipelineInputAssemblyStateCreateInfo.New (); - public VkPipelineRasterizationStateCreateInfo rasterizationState = VkPipelineRasterizationStateCreateInfo.New (); + public VkPipelineInputAssemblyStateCreateInfo inputAssemblyState; + public VkPipelineRasterizationStateCreateInfo rasterizationState; public List Viewports = new List (); public List Scissors = new List (); - public VkPipelineDepthStencilStateCreateInfo depthStencilState = VkPipelineDepthStencilStateCreateInfo.New (); - public VkPipelineMultisampleStateCreateInfo multisampleState = VkPipelineMultisampleStateCreateInfo.New (); + public VkPipelineDepthStencilStateCreateInfo depthStencilState; + public VkPipelineMultisampleStateCreateInfo multisampleState; public List blendAttachments = new List (); public List dynamicStates = new List (); public List vertexBindings = new List (); @@ -122,7 +122,7 @@ namespace vke { 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; diff --git a/vke/src/base/Image.cs b/vke/src/base/Image.cs index 821053a..7cdfb37 100644 --- a/vke/src/base/Image.cs +++ b/vke/src/base/Image.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { /// @@ -24,7 +25,7 @@ namespace vke { public static VkFormat DefaultTextureFormat = VkFormat.R8g8b8a8Unorm; internal VkImage handle; - VkImageCreateInfo info = VkImageCreateInfo.New (); + VkImageCreateInfo info; uint[] queuesFamillies; /// @@ -436,14 +437,14 @@ namespace vke { } 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 (); @@ -452,9 +453,9 @@ namespace vke { 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 (); @@ -473,7 +474,7 @@ namespace vke { } 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; @@ -496,7 +497,7 @@ namespace vke { layerCount = 1; VkImageView view = default (VkImageView); - VkImageViewCreateInfo viewInfo = VkImageViewCreateInfo.New (); + VkImageViewCreateInfo viewInfo = default; viewInfo.image = handle; viewInfo.viewType = type; viewInfo.format = Format; @@ -510,7 +511,7 @@ namespace vke { 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); @@ -536,7 +537,7 @@ namespace vke { 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; @@ -551,7 +552,7 @@ namespace vke { 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); @@ -616,7 +617,7 @@ namespace vke { uint srcQueueFamilyIndex = Vk.QueueFamilyIgnored, uint dstQueueFamilyIndex = Vk.QueueFamilyIgnored) { - VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New (); + VkImageMemoryBarrier imageMemoryBarrier = default; imageMemoryBarrier.srcQueueFamilyIndex = srcQueueFamilyIndex; imageMemoryBarrier.dstQueueFamilyIndex = dstQueueFamilyIndex; imageMemoryBarrier.oldLayout = oldImageLayout; @@ -649,7 +650,7 @@ namespace vke { 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; diff --git a/vke/src/base/Instance.cs b/vke/src/base/Instance.cs index de1fe5b..966383a 100644 --- a/vke/src/base/Instance.cs +++ b/vke/src/base/Instance.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Runtime.InteropServices; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { /// @@ -85,7 +86,7 @@ namespace vke { pEngineName = APPLICATION_NAME, }; - VkInstanceCreateInfo instanceCreateInfo = VkInstanceCreateInfo.New (); + VkInstanceCreateInfo instanceCreateInfo = default; instanceCreateInfo.pApplicationInfo = appInfo; if (instanceExtensions.Count > 0) { @@ -109,11 +110,11 @@ namespace vke { } 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 (); 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; @@ -132,7 +133,7 @@ namespace vke { /// 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 (string name, out T del) { diff --git a/vke/src/base/PhysicalDevice.cs b/vke/src/base/PhysicalDevice.cs index 1ab1d48..859f129 100644 --- a/vke/src/base/PhysicalDevice.cs +++ b/vke/src/base/PhysicalDevice.cs @@ -89,7 +89,6 @@ namespace vke { vkGetPhysicalDeviceQueueFamilyProperties (phy, out queueFamilyCount, QueueFamilies.Pin ()); QueueFamilies.Unpin (); - Console.WriteLine("PhysicalDeviceCollection"); HasSwapChainSupport = GetDeviceExtensionSupported (Ext.D.VK_KHR_swapchain); } @@ -168,10 +167,10 @@ namespace vke { 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 (); 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; diff --git a/vke/src/base/PipelineCache.cs b/vke/src/base/PipelineCache.cs index abc739b..0ec2e48 100644 --- a/vke/src/base/PipelineCache.cs +++ b/vke/src/base/PipelineCache.cs @@ -9,6 +9,7 @@ using System.Runtime.InteropServices; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { /// @@ -54,7 +55,7 @@ namespace vke { 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)) { @@ -67,7 +68,7 @@ namespace vke { } } - 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); @@ -95,9 +96,9 @@ namespace vke { 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)) diff --git a/vke/src/base/PipelineLayout.cs b/vke/src/base/PipelineLayout.cs index 42a0975..7227097 100644 --- a/vke/src/base/PipelineLayout.cs +++ b/vke/src/base/PipelineLayout.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { public sealed class PipelineLayout : Activable { @@ -46,7 +47,7 @@ namespace vke { 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) { @@ -55,7 +56,7 @@ namespace vke { 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(); diff --git a/vke/src/base/QueryPool.cs b/vke/src/base/QueryPool.cs index f17c46b..53987e2 100644 --- a/vke/src/base/QueryPool.cs +++ b/vke/src/base/QueryPool.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { public class TimestampQueryPool : QueryPool { @@ -87,7 +88,7 @@ namespace vke { } } - public abstract class QueryPool : Activable { + public abstract class QueryPool : Activable { protected VkQueryPool handle; protected readonly VkQueryPoolCreateInfo createInfos; public readonly VkQueryType QueryType; @@ -97,7 +98,7 @@ namespace vke { 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 (); } @@ -109,8 +110,8 @@ namespace vke { 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 (); } @@ -123,7 +124,7 @@ namespace vke { return results; } - + public override string ToString () { return string.Format ($"{base.ToString ()}[0x{handle.Handle.ToString("x")}]"); } diff --git a/vke/src/base/Queue.cs b/vke/src/base/Queue.cs index 13fa8c5..8325bcb 100644 --- a/vke/src/base/Queue.cs +++ b/vke/src/base/Queue.cs @@ -5,6 +5,7 @@ using System; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { @@ -36,10 +37,10 @@ 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; @@ -89,7 +90,7 @@ namespace vke { cmd.Submit (handle, wait, signal, fence); } public void WaitIdle () { - Utils.CheckResult (vkQueueWaitIdle (handle)); + CheckResult (vkQueueWaitIdle (handle)); } uint searchQFamily (VkQueueFlags requestedFlags) { diff --git a/vke/src/base/RenderPass.cs b/vke/src/base/RenderPass.cs index ea9cda9..95683fd 100644 --- a/vke/src/base/RenderPass.cs +++ b/vke/src/base/RenderPass.cs @@ -104,7 +104,7 @@ namespace vke { 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; @@ -198,16 +198,16 @@ namespace vke { /// 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 (); + } } /// /// Switch to next subpass diff --git a/vke/src/base/Resource.cs b/vke/src/base/Resource.cs index 77a8d4d..dfb2df0 100644 --- a/vke/src/base/Resource.cs +++ b/vke/src/base/Resource.cs @@ -8,6 +8,7 @@ using System.Runtime.InteropServices; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { /// @@ -66,7 +67,7 @@ namespace vke { #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;*/ @@ -74,22 +75,22 @@ namespace vke { 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; @@ -99,7 +100,7 @@ namespace vke { 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 () { diff --git a/vke/src/base/SwapChain.cs b/vke/src/base/SwapChain.cs index d87e461..aa916b1 100644 --- a/vke/src/base/SwapChain.cs +++ b/vke/src/base/SwapChain.cs @@ -5,6 +5,7 @@ using System; using Vulkan; using static Vulkan.Vk; +using static Vulkan.Utils; namespace vke { /// @@ -56,7 +57,7 @@ namespace vke { : 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++) { @@ -120,7 +121,7 @@ namespace vke { } 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 (); @@ -129,11 +130,11 @@ namespace vke { 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]; @@ -155,7 +156,7 @@ namespace vke { Create (); return -1; } - Utils.CheckResult (res); + CheckResult (res); return (int)currentImageIndex; } diff --git a/vke/src/base/VulkanContext.cs b/vke/src/base/VulkanContext.cs new file mode 100644 index 0000000..df6d2fe --- /dev/null +++ b/vke/src/base/VulkanContext.cs @@ -0,0 +1,254 @@ +// Copyright (c) 2021 Jean-Philippe Bruyère +// +// 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 windows = new Dictionary(); + /** 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 + } +}