]> O.S.I.I.S - jp/vke.net.git/commitdiff
test compute rasterization
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 28 Mar 2023 09:31:27 +0000 (11:31 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 28 Mar 2023 09:31:27 +0000 (11:31 +0200)
23 files changed:
.vscode/launch.json
.vscode/tasks.json
samples/DynamicRendering/DynamicRendering.csproj [new file with mode: 0644]
samples/DynamicRendering/main.cs [new file with mode: 0644]
samples/DynamicRendering/shaders/main.frag [new file with mode: 0644]
samples/DynamicRendering/shaders/main.vert [new file with mode: 0644]
samples/FillTests/FillTests.csproj [new file with mode: 0644]
samples/FillTests/main.cs [new file with mode: 0644]
samples/FillTests/shaders/contour.frag [new file with mode: 0644]
samples/FillTests/shaders/contour.vert [new file with mode: 0644]
samples/FillTests/shaders/main.frag [new file with mode: 0644]
samples/FillTests/shaders/main.vert [new file with mode: 0644]
samples/FillTests/shaders/simpletexture.frag [new file with mode: 0644]
samples/FillTests/shaders/test.comp [new file with mode: 0644]
samples/MeshShader/main.cs
samples/Triangle/main.cs
samples/common/SampleBase.cs
samples/compute/main.cs
samples/compute/stroker.cs
samples/compute/test.cs
vke.net.sln
vke/src/base/GraphicPipeline.cs
vke/src/base/RenderPass.cs

index f0d49edb6b9e979dec3d37729dab299efb2063f2..4a31790b4a6d9218c4c05fd7b4dcebef0845fc55 100644 (file)
                        "stopAtEntry": false,
                        "console": "internalConsole"
                },
+               {
+                       "name": ".NET Core Launch (FillTests)",
+                       "type": "coreclr",
+                       "request": "launch",
+                       "preLaunchTask": "build FillTests",
+                       "program": "${workspaceFolder}/build/Debug/netcoreapp3.1/FillTests",
+                       "args": [],
+                       "cwd": "${workspaceFolder}/build/Debug/netcoreapp3.1/",
+                       "stopAtEntry": false,
+                       "console": "internalConsole"
+               },
+               {
+                       "name": ".NET Core Launch (DynamicRendering)",
+                       "type": "coreclr",
+                       "request": "launch",
+                       "preLaunchTask": "build DynamicRendering",
+                       "program": "${workspaceFolder}/build/Debug/netcoreapp3.1/DynamicRendering",
+                       "args": [],
+                       "cwd": "${workspaceFolder}/build/Debug/netcoreapp3.1/",
+                       "stopAtEntry": false,
+                       "console": "internalConsole"
+               },
                {
                        "name": ".NET Core Launch (MeshShader)",
                        "type": "coreclr",
                        "args": [],
                        "cwd": "${workspaceFolder}/build/Debug/netcoreapp3.1/",
                        "stopAtEntry": false,
-                       "console": "internalConsole"
+                       "console": "internalConsole",
+                       "env": {
+                               "VK_ICD_FILENAMES": "/opt/share/vulkan/icd.d/radeon_icd.x86_64.json",
+                               "RADV_PERFTEST": "rt,ext_ms",
+                               "LD_LIBARY_PATH": "/opt/lib/x86_64-linux-gnu/"
+                       }
                },
                {
                        "name": ".NET Core Launch (ExternalMemmories)",
index e1657dd6488e071cfaa745847f4ddc9e487ea87e..d7522d2088126b118e20db9f24dce03570f9c1e4 100644 (file)
                        ],
                        "problemMatcher": "$msCompile"
                },
+               {
+                       "label": "build FillTests",
+                       "command": "dotnet",
+                       "type": "process",
+                       "args": [
+                               "build",
+                               "${workspaceFolder}/samples/FillTests/FillTests.csproj",
+                               "/property:GenerateFullPaths=true",
+                               "/property:SolutionDir=${workspaceFolder}/",
+                               "/property:Configuration=Debug",
+                               "/consoleloggerparameters:NoSummary"
+                       ],
+                       "problemMatcher": "$msCompile"
+               },
+               {
+                       "label": "build DynamicRendering",
+                       "command": "dotnet",
+                       "type": "process",
+                       "args": [
+                               "build",
+                               "${workspaceFolder}/samples/DynamicRendering/DynamicRendering.csproj",
+                               "/property:GenerateFullPaths=true",
+                               "/property:SolutionDir=${workspaceFolder}/",
+                               "/property:Configuration=Debug",
+                               "/consoleloggerparameters:NoSummary"
+                       ],
+                       "problemMatcher": "$msCompile"
+               },
                {
                        "label": "build MeshShader",
                        "command": "dotnet",
diff --git a/samples/DynamicRendering/DynamicRendering.csproj b/samples/DynamicRendering/DynamicRendering.csproj
new file mode 100644 (file)
index 0000000..672fb5a
--- /dev/null
@@ -0,0 +1,5 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <IncludeDefaultNoneItems>false</IncludeDefaultNoneItems>
+  </PropertyGroup>
+</Project>
diff --git a/samples/DynamicRendering/main.cs b/samples/DynamicRendering/main.cs
new file mode 100644 (file)
index 0000000..beb4bc5
--- /dev/null
@@ -0,0 +1,161 @@
+// Copyright (c) 2023  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using System;
+using System.Numerics;
+using System.Runtime.InteropServices;
+using vke;
+using Vulkan;
+using Glfw;
+
+//the traditional triangle sample with dynamic rendeging aithout framebuffers
+namespace FillTests {
+       class Program : SampleBase {
+               static void Main (string[] args) {
+#if DEBUG
+                       Instance.VALIDATION = true;
+#endif
+                       using (Program vke = new Program ()) {
+                               vke.Run ();
+                       }
+               }
+               public override string[] EnabledInstanceExtensions => new string[]
+               {
+                       Ext.I.VK_KHR_get_physical_device_properties2
+               };
+               public override string[] EnabledDeviceExtensions => new string[]
+               {
+                       Ext.D.VK_KHR_swapchain,
+                       Ext.D.VK_KHR_dynamic_rendering,
+                       Ext.D.VK_KHR_depth_stencil_resolve,
+               };
+
+               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);
+                       }
+               }
+
+               HostBuffer ibo;     //a host mappable buffer to hold the indices.
+               HostBuffer vbo;     //a host mappable buffer to hold vertices.
+               HostBuffer<Matrix4x4> uboMVPmatrix; //a host mappable buffer for mvp matrice.
+
+               DescriptorPool descriptorPool;
+               DescriptorSet descriptorSet;//descriptor set for the mvp matrice.
+               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 ();
+
+                       vbo = new HostBuffer<Vertex> (dev, VkBufferUsageFlags.VertexBuffer, vertices);
+                       ibo = new HostBuffer<ushort> (dev, VkBufferUsageFlags.IndexBuffer, indices);
+                       uboMVPmatrix = new HostBuffer<Matrix4x4> (dev, VkBufferUsageFlags.UniformBuffer, 1, true);
+
+                       descriptorPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer));
+
+                       using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false)) {
+                               cfg.Layout = new PipelineLayout (dev,
+                                       new DescriptorSetLayout (dev, new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer)));
+                               cfg.AddVertexBinding<Vertex> (0);
+                               cfg.AddVertexAttributes (0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat);//position + color
+
+                               cfg.AddShaders (
+                                       new ShaderInfo (dev, VkShaderStageFlags.Vertex, "#shaders.main.vert.spv"),
+                                       new ShaderInfo (dev, VkShaderStageFlags.Fragment, "#shaders.main.frag.spv")
+                               );
+
+                               pipeline = new GraphicPipeline (dev, cfg);
+                       }
+
+                       descriptorSet = descriptorPool.Allocate (pipeline.Layout.DescriptorSetLayouts[0]);
+
+                       DescriptorSetWrites uboUpdate = new DescriptorSetWrites (descriptorSet, pipeline.Layout.DescriptorSetLayouts[0]);
+                       uboUpdate.Write (dev, uboMVPmatrix.Descriptor);
+
+                       cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount);
+               }
+
+               //view update override, see base method for more informations.
+               public override void UpdateView () {
+                       uboMVPmatrix.AsSpan()[0] =
+                               Matrix4x4.CreateFromAxisAngle (Vector3.UnitY, rotY) *
+                               Matrix4x4.CreateFromAxisAngle (Vector3.UnitX, rotX) *
+                               Matrix4x4.CreateTranslation (0, 0, -3f * zoom) *
+                               Helpers.CreatePerspectiveFieldOfView (Helpers.DegreesToRadians (45f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
+
+                       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(PrimaryCommandBuffer cmd) {
+                       cmd.Start ();
+
+                       cmd.SetViewport (swapChain.Width, swapChain.Height);
+                       cmd.SetScissor (swapChain.Width, swapChain.Height);
+
+                       cmd.BindDescriptorSet (pipeline.Layout, descriptorSet);
+
+                       cmd.BindPipeline (pipeline);
+
+                       cmd.BindVertexBuffer (vbo);
+                       cmd.BindIndexBuffer (ibo, VkIndexType.Uint16);
+                       cmd.DrawIndexed ((uint)indices.Length);
+
+                       cmd.End ();
+               }
+
+               protected override void OnResize () {
+                       base.OnResize ();
+
+                       updateViewRequested = true;
+
+                       cmdPool.Reset (VkCommandPoolResetFlags.ReleaseResources);
+
+                       for (int i = 0; i < swapChain.ImageCount; ++i)
+                               buildCommandBuffers (cmds[i]);
+               }
+               //clean up
+               protected override void Dispose (bool disposing) {
+                       dev.WaitIdle ();
+                       if (disposing) {
+                               if (!isDisposed) {
+                                       pipeline.Dispose ();
+                                       descriptorPool.Dispose ();
+                                       vbo.Dispose ();
+                                       ibo.Dispose ();
+                                       uboMVPmatrix.Dispose ();
+                               }
+                       }
+
+                       base.Dispose (disposing);
+               }
+       }
+}
diff --git a/samples/DynamicRendering/shaders/main.frag b/samples/DynamicRendering/shaders/main.frag
new file mode 100644 (file)
index 0000000..85aeb08
--- /dev/null
@@ -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/DynamicRendering/shaders/main.vert b/samples/DynamicRendering/shaders/main.vert
new file mode 100644 (file)
index 0000000..40a3796
--- /dev/null
@@ -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/FillTests/FillTests.csproj b/samples/FillTests/FillTests.csproj
new file mode 100644 (file)
index 0000000..672fb5a
--- /dev/null
@@ -0,0 +1,5 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <IncludeDefaultNoneItems>false</IncludeDefaultNoneItems>
+  </PropertyGroup>
+</Project>
diff --git a/samples/FillTests/main.cs b/samples/FillTests/main.cs
new file mode 100644 (file)
index 0000000..4c8abf6
--- /dev/null
@@ -0,0 +1,261 @@
+// Copyright (c) 2023  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using System;
+using System.Numerics;
+using System.Runtime.InteropServices;
+using vke;
+using Vulkan;
+using Glfw;
+
+namespace FillTests {
+
+       class Program : SampleBase {
+               static void Main (string[] args) {
+#if DEBUG
+                       Instance.VALIDATION = true;
+                       Instance.RENDER_DOC_CAPTURE = true;
+#endif
+                       using (Program vke = new Program ()) {
+                               vke.Run ();
+                       }
+               }
+
+
+               FrameBuffers frameBuffers;      //the frame buffer collection coupled to the swapchain images
+               FrameBuffer fbContour;
+               
+               [StructLayout(LayoutKind.Sequential)]
+               struct Vertex {
+                       Vector2 position;
+                       UInt32 contourID;
+                       public Vertex (float x, float y, UInt32 _contourID) {
+                               position = new Vector2 (x, y);
+                               contourID = _contourID;
+                       }
+               }
+                               //triangle vertices (position + color per vertex) and indices.
+               /*Vertex[] vertices = {
+                       new Vertex (10.0f, 210.0f,  1),
+                       new Vertex (100.0f, 220.0f,  1),
+                       new Vertex (50.0f,  270.0f,  1),
+                       new Vertex (10.0f, 210.0f,  1),
+               };*/
+               /*Vertex[] vertices = {
+                       new Vertex (100.0f, 210.0f,  1),
+                       new Vertex (200.0f, 120.0f,  1),
+                       new Vertex (350.0f,  270.0f,  1),
+                       new Vertex (150.0f, 310.0f,  1),
+                       new Vertex (100.0f, 210.0f,  1)
+               };*/
+               Vertex[] vertices = {
+                       new Vertex (100.0f, 100.0f,  1),
+                       new Vertex (500.0f, 400.0f,  1),
+                       new Vertex (450.0f,  150.0f,  1),
+                       new Vertex (120.0f, 420.0f,  1),
+                       new Vertex (100.0f, 100.0f,  1)
+               };
+               HostBuffer vbo;
+               GraphicPipeline plContours;
+               GraphicPipeline plFSQ;
+               ComputePipeline plComp;
+               DescriptorPool descriptorPool;
+               DescriptorSet dsComp, dsFSQ;//descriptor set for the mvp matrice.
+               vke.Image imgContour, imgColor;
+
+               VkFormat rastFormat = VkFormat.B8g8r8a8Uint;
+               const VkSampleCountFlags contourSamplesCount = VkSampleCountFlags.SampleCount1;
+
+
+               protected override void initVulkan () {
+                       base.initVulkan ();
+
+                       UpdateFrequency = 1;
+
+                       vbo = new HostBuffer<Vertex> (dev, VkBufferUsageFlags.VertexBuffer, vertices);
+                       vbo.SetName("vbo");
+
+                       using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.LineStrip, contourSamplesCount, false)) {
+                               cfg.Layout = new PipelineLayout (dev,
+                                       new VkPushConstantRange (VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf<Vector2>()));
+                               cfg.RenderPass = new RenderPass (dev, contourSamplesCount);
+                               cfg.RenderPass.AddAttachment(rastFormat, VkImageLayout.General, contourSamplesCount, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.Store, VkImageLayout.General);
+                               cfg.RenderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
+                               cfg.RenderPass.AddSubpass(new SubPass (VkImageLayout.ColorAttachmentOptimal));
+                               cfg.RenderPass.AddDependency (Vk.SubpassExternal, 0,
+                                       VkPipelineStageFlags.ComputeShader, VkPipelineStageFlags.ColorAttachmentOutput,
+                                       VkAccessFlags.MemoryRead, VkAccessFlags.ColorAttachmentWrite);
+                               cfg.RenderPass.AddDependency (0, Vk.SubpassExternal,
+                                       VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.ComputeShader,
+                                       VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.MemoryWrite);                         
+                               
+
+                               cfg.AddVertexBinding<Vertex> (0);
+                               cfg.AddVertexAttributes (0, VkFormat.R32g32Sfloat, VkFormat.R32Uint);//position + color
+                               cfg.AddShaders (
+                                       new ShaderInfo (dev, VkShaderStageFlags.Vertex, "#shaders.contour.vert.spv"),
+                                       new ShaderInfo (dev, VkShaderStageFlags.Fragment, "#shaders.contour.frag.spv")
+                               );
+                               plContours = new GraphicPipeline (cfg);
+                       }
+
+                       //uboMVPmatrix = new HostBuffer<Matrix4x4> (dev, VkBufferUsageFlags.UniformBuffer, 1, true);
+
+                       descriptorPool = new DescriptorPool (dev, 2,
+                               new VkDescriptorPoolSize (VkDescriptorType.StorageImage, 2),
+                               new VkDescriptorPoolSize (VkDescriptorType.CombinedImageSampler, 1)
+                       );
+
+                       
+                       using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, contourSamplesCount, false)) {
+                               cfg.Layout = new PipelineLayout (dev, new DescriptorSetLayout(dev, 
+                                       new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)));
+                               cfg.RenderPass = new RenderPass (dev, swapChain.ColorFormat, VkSampleCountFlags.SampleCount1);
+                               cfg.RenderPass.ClearValues[0] = new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) };
+                               cfg.AddVertexBinding<Vertex> (0);
+                               cfg.AddVertexAttributes (0, VkFormat.R32g32Sfloat, VkFormat.R32g32b32Sfloat);//position + color
+                               cfg.AddShaders (
+                                       new ShaderInfo (dev, VkShaderStageFlags.Vertex, "#vke.FullScreenQuad.vert.spv"),
+                                       new ShaderInfo (dev, VkShaderStageFlags.Fragment, "#shaders.simpletexture.frag.spv")
+                               );
+                               plFSQ = new GraphicPipeline (cfg);
+                       }
+
+               
+                       plComp = new ComputePipeline (
+                               new PipelineLayout (dev,
+                                       new VkPushConstantRange (VkShaderStageFlags.Compute, sizeof (float)),
+                                        new DescriptorSetLayout(dev, 
+                                       new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Compute, VkDescriptorType.StorageImage),
+                                       new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Compute, VkDescriptorType.StorageImage))),
+                               "#shaders.test.comp.spv");
+
+                       dsComp = descriptorPool.Allocate (plComp.Layout.DescriptorSetLayouts[0]);
+                       dsFSQ =  descriptorPool.Allocate (plFSQ.Layout.DescriptorSetLayouts[0]);
+
+                       cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount);
+               }
+
+               //view update override, see base method for more informations.
+               public override void UpdateView () {
+
+                       base.UpdateView ();
+               }
+               protected override void onMouseMove (double xPos, double yPos) {
+
+               }
+
+               void stroke() {
+                       PrimaryCommandBuffer cmd = cmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);
+                       
+                       imgContour.SetLayout(cmd, VkImageAspectFlags.Color, VkImageLayout.ColorAttachmentOptimal);
+
+                       plContours.RenderPass.Begin (cmd, fbContour);
+
+                       cmd.SetViewport (swapChain.Width, swapChain.Height);
+                       cmd.SetScissor (swapChain.Width, swapChain.Height);
+                       //cmd.BindDescriptorSet (pipeline.Layout, descriptorSet);
+
+                       cmd.BindPipeline (plContours);
+                       cmd.PushConstant (plContours.Layout, VkShaderStageFlags.Vertex, new Vector2(swapChain.Width, swapChain.Height));
+
+                       cmd.BindVertexBuffer (vbo);
+                       cmd.Draw ((uint)vertices.Length);
+
+                       plContours.RenderPass.End (cmd);
+
+                       imgContour.SetLayout(cmd, VkImageAspectFlags.Color,VkImageLayout.ColorAttachmentOptimal, VkImageLayout.General);
+                       imgColor.SetLayout(cmd, VkImageAspectFlags.Color, VkImageLayout.General);
+
+                       cmd.BindPipeline(plComp, VkPipelineBindPoint.Compute);
+                       plComp.BindDescriptorSet(cmd,dsComp);
+                       
+                       cmd.Dispatch(swapChain.Height);
+
+                       this.presentQueue.EndSubmitAndWait(cmd, true);
+               }
+               void buildCommandBuffer(PrimaryCommandBuffer cmd, FrameBuffer fb) {
+                               cmd.Start ();
+
+                               imgColor.SetLayout(cmd, VkImageAspectFlags.Color, VkImageLayout.ColorAttachmentOptimal);
+
+                               plFSQ.RenderPass.Begin (cmd, fb);
+
+                               cmd.BindPipeline (plFSQ);
+                               cmd.SetViewport (swapChain.Width, swapChain.Height);
+                               cmd.SetScissor (swapChain.Width, swapChain.Height);
+                               cmd.BindDescriptorSet (plFSQ.Layout, dsFSQ);
+
+                               cmd.Draw (3);
+
+                               plFSQ.RenderPass.End (cmd);
+
+                               cmd.End ();
+               }               
+               void buildCommandBuffers() {
+                       cmdPool.Reset (VkCommandPoolResetFlags.ReleaseResources);
+
+                       stroke();
+
+                       for (int i = 0; i < swapChain.ImageCount; ++i) {
+                               buildCommandBuffer(cmds[i], frameBuffers[i]);
+                       }
+               }
+               public override void Update()
+               {
+                       dev.WaitIdle();
+                       stroke();
+               }
+               protected override void OnResize () {
+                       base.OnResize ();
+
+                       updateViewRequested = true;
+
+                       frameBuffers?.Dispose();
+                       frameBuffers = plFSQ.RenderPass.CreateFrameBuffers(swapChain);
+
+                       imgContour?.Dispose();
+                       imgContour = new vke.Image (dev, rastFormat, VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.Storage, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, contourSamplesCount);
+                       imgContour.CreateView();
+
+                       fbContour = new FrameBuffer(plContours.RenderPass, swapChain.Width, swapChain.Height, 1, imgContour);
+
+                       imgColor?.Dispose();
+                       imgColor = new vke.Image (dev, VkFormat.R8g8b8a8Unorm, VkImageUsageFlags.Sampled | VkImageUsageFlags.Storage, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, contourSamplesCount);
+                       imgColor.CreateSampler();
+                       imgColor.CreateView();
+
+
+                       DescriptorSetWrites compUpdate = new DescriptorSetWrites (dsComp, plComp.Layout.DescriptorSetLayouts[0]);
+                       imgColor.Descriptor.imageLayout = VkImageLayout.General;
+                       imgContour.Descriptor.imageLayout = VkImageLayout.General;
+                       compUpdate.Write (dev, imgContour.Descriptor, imgColor.Descriptor);
+
+                       DescriptorSetWrites fsqUpdate = new DescriptorSetWrites (dsFSQ, plFSQ.Layout.DescriptorSetLayouts[0]);
+                       imgColor.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
+                       fsqUpdate.Write (dev, imgColor.Descriptor);
+
+                       buildCommandBuffers ();
+                       
+               }
+               //clean up
+               protected override void Dispose (bool disposing) {
+                       dev.WaitIdle ();
+                       if (disposing) {
+                               if (!isDisposed) {
+                                       plContours.Dispose();
+                                       plComp.Dispose ();
+                                       plFSQ.Dispose();
+                                       imgContour?.Dispose();
+                                       imgColor?.Dispose();
+                                       frameBuffers?.Dispose();
+                                       fbContour.Dispose();
+                                       descriptorPool.Dispose ();
+                                       vbo.Dispose ();
+                               }
+                       }
+
+                       base.Dispose (disposing);
+               }
+       }
+}
diff --git a/samples/FillTests/shaders/contour.frag b/samples/FillTests/shaders/contour.frag
new file mode 100644 (file)
index 0000000..631e45a
--- /dev/null
@@ -0,0 +1,12 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in flat uint inContourID;
+layout (location = 0) out uvec4 outFragColor;
+
+void main() 
+{
+  outFragColor = uvec4(1u << gl_PrimitiveID, inContourID, 0, 1);
+}
\ No newline at end of file
diff --git a/samples/FillTests/shaders/contour.vert b/samples/FillTests/shaders/contour.vert
new file mode 100644 (file)
index 0000000..e38ef7b
--- /dev/null
@@ -0,0 +1,23 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec2 inPos;
+layout (location = 1) in uint inContourID;
+
+layout(push_constant) uniform PushConsts {
+    vec2 size;
+};
+
+out gl_PerVertex 
+{
+    vec4 gl_Position;   
+};
+
+layout (location = 0) out flat uint outContourID;
+
+void main() 
+{      
+    gl_Position = vec4(inPos.xy * vec2(2) / size - vec2(1), 0.0, 1.0);
+}
diff --git a/samples/FillTests/shaders/main.frag b/samples/FillTests/shaders/main.frag
new file mode 100644 (file)
index 0000000..85aeb08
--- /dev/null
@@ -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/FillTests/shaders/main.vert b/samples/FillTests/shaders/main.vert
new file mode 100644 (file)
index 0000000..40a3796
--- /dev/null
@@ -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/FillTests/shaders/simpletexture.frag b/samples/FillTests/shaders/simpletexture.frag
new file mode 100644 (file)
index 0000000..a081876
--- /dev/null
@@ -0,0 +1,15 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (set = 0, binding = 0) uniform sampler2D samplerColor;
+
+layout (location = 0) in       vec2 inUV;
+
+layout (location = 0) out      vec4 outFragColor;
+
+void main()
+{    
+       outFragColor = texture(samplerColor, inUV);
+}
diff --git a/samples/FillTests/shaders/test.comp b/samples/FillTests/shaders/test.comp
new file mode 100644 (file)
index 0000000..c68fc0d
--- /dev/null
@@ -0,0 +1,65 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (set = 0, binding = 0, rgba8ui) readonly uniform uimage2D inputImage;
+layout (set = 0, binding = 1, rgba8) writeonly uniform image2D outputImage;
+
+layout(push_constant) uniform PushConsts {
+    float halfWidth;
+};
+
+
+layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+
+void main()
+{
+    int count=0;
+    ivec2 is = imageSize(inputImage);
+    int c = 0;
+    uint[64] contourStates;
+    for(int i=0; i<contourStates.length(); i++) {
+        contourStates[i]=0;
+    }
+    
+    int start = -1;
+    for(int i=0; i<is.x; i++) {
+        ivec2 uv = ivec2(i, gl_GlobalInvocationID.x);
+        uvec4 ct = imageLoad(inputImage, uv);
+        uint contourID = ct.g;
+        uint primID = ct.r;
+
+        if (primID > 0) {
+            imageStore(outputImage, uv, vec4(1.f,0.f,0.f,1.f));
+
+            uint lastState = contourStates[contourID];
+            contourStates[contourID] = contourStates[contourID] | primID;
+
+            if (contourStates[contourID] != lastState) {
+                uint bc = bitCount(contourStates[contourID]);
+                if ((bc % 2) != 0) {
+                    if (start >= 0) {
+                        for(int j=start; j<i; j++) {
+                            imageStore(outputImage, ivec2(j, gl_GlobalInvocationID.x), vec4(0.f,1.f,0.f,1.f));
+                        }
+                    }
+                    start = i + 1;
+                } else {
+                    if (start >= 0) {
+                        for(int j=start; j<i; j++) {
+                            imageStore(outputImage, ivec2(j, gl_GlobalInvocationID.x), vec4(0.f,0.f,1.f,1.f));
+                        }
+                    }
+                    start = -1;
+                }
+            }
+            
+        } else {
+            imageStore(outputImage, uv, vec4(0.f,0.f,0.f,1.f));
+        }
+
+        
+    }
+
+}
index 5625588c382a788d911fad310dc8305a1c754b41..1c4f446a0cbedb3bd8c1c10cb2ac6586dd45e708 100644 (file)
@@ -14,7 +14,7 @@ namespace MeshShader {
        class Program : SampleBase {
                public override string[] EnabledInstanceExtensions => new string[] {
                        Ext.I.VK_KHR_get_physical_device_properties2,
-                       Ext.I.VK_EXT_debug_utils,
+                       //Ext.I.VK_EXT_debug_utils,
                };
                public override string[] EnabledDeviceExtensions => new string[] {
                        Ext.D.VK_KHR_swapchain,
@@ -74,7 +74,7 @@ namespace MeshShader {
 
                        uboMVPmatrix = new HostBuffer<Matrix4x4> (dev, VkBufferUsageFlags.UniformBuffer, 1, true);
                        descriptorPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer));
-                       using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false)) {
+                       using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount8, false)) {
                                cfg.Layout = new PipelineLayout (dev,
                                        new DescriptorSetLayout (dev, new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.MeshEXT, VkDescriptorType.UniformBuffer)));
                                cfg.RenderPass = new RenderPass (dev, swapChain.ColorFormat, cfg.Samples);
index aabed923ace99d4574012bbe66d538b9c562b12b..c52f2923e2c7fe4a5a6674e724b0e23b20b496ab 100644 (file)
@@ -9,11 +9,11 @@ using Vulkan;
 using Glfw;
 
 //the traditional triangle sample
-namespace Triangle {
+namespace FillTests {
        class Program : SampleBase {
                static void Main (string[] args) {
 #if DEBUG
-                       Instance.VALIDATION = true;
+                       //Instance.VALIDATION = true;
 #endif
                        using (Program vke = new Program ()) {
                                vke.Run ();
index d6a3a641b3d3e755bb7c99f08f3bb48aedb81eaf..3564d29163779abdfb8c362652193627059d0632 100644 (file)
@@ -10,11 +10,11 @@ namespace vke
                {
                        base.initVulkan();
 #if DEBUG
-                       foreach (VkPhysicalDeviceToolProperties toolProp in phy.GetToolProperties()) {
+                       /*foreach (VkPhysicalDeviceToolProperties toolProp in phy.GetToolProperties()) {
                                Console.ForegroundColor = ConsoleColor.DarkYellow;
                                Console.WriteLine ($"Enabled Tool: {toolProp.name}({toolProp.version})");
                                Console.ResetColor ();
-                       }
+                       }*/
 #endif
                }
        }
index 29b244dcabf01eb313fd5db0d17d8e99a89f04f2..bb317f3c444beaf6e3a474042553456d3d6e6f3d 100644 (file)
@@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
 using System.Linq;
 using Vulkan;
 using vke;
+using System.Threading;
 
 //very simple compute example that just do an addition on every items of a random list of numbers.
 namespace SimpleCompute {
@@ -18,12 +19,9 @@ namespace SimpleCompute {
                Instance instance;
                PhysicalDevice phy;
                Device dev;
+               DescriptorSetLayout dsLayout;
                Queue computeQ;
 
-               HostBuffer inBuff, outBuff;
-               DescriptorPool dsPool;
-               DescriptorSetLayout dsLayout;
-               DescriptorSet dset;
 
                ComputePipeline plCompute;
 
@@ -49,10 +47,7 @@ namespace SimpleCompute {
 
                        createRandomDatas ();
 
-                       inBuff = new HostBuffer<int> (dev, VkBufferUsageFlags.StorageBuffer, datas);
-                       outBuff = new HostBuffer<uint> (dev, VkBufferUsageFlags.StorageBuffer, data_size);
 
-                       dsPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.StorageBuffer, 2));
                        dsLayout = new DescriptorSetLayout (dev,
                                new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Compute, VkDescriptorType.StorageBuffer),
                                new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Compute, VkDescriptorType.StorageBuffer)
@@ -60,27 +55,58 @@ namespace SimpleCompute {
 
                        plCompute = new ComputePipeline (new PipelineLayout (dev, dsLayout), "#shaders.compute.comp.spv" );
 
+               }
+               const int threadCount = 64;
+               object printMutex = new object();
+               void computeThread() {
+                       HostBuffer inBuff, outBuff;
+                       DescriptorPool dsPool;
+                       DescriptorSet dset;
+
+                       inBuff = new HostBuffer<int> (dev, VkBufferUsageFlags.StorageBuffer, datas);
+                       outBuff = new HostBuffer<uint> (dev, VkBufferUsageFlags.StorageBuffer, data_size);
+
+                       dsPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.StorageBuffer, 2));
                        dset = dsPool.Allocate (dsLayout);
                        DescriptorSetWrites dsUpdate = new DescriptorSetWrites (dset, dsLayout);
                        dsUpdate.Write (dev, inBuff.Descriptor, outBuff.Descriptor);
-               }
 
-               public void Run () {
                        using (CommandPool cmdPool = new CommandPool (dev, computeQ.qFamIndex)) {
                                PrimaryCommandBuffer cmd = cmdPool.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit);
                                plCompute.Bind (cmd);
                                plCompute.BindDescriptorSet (cmd, dset);
                                cmd.Dispatch (data_size * sizeof (int));
                                cmd.End ();
-
-                               computeQ.Submit (cmd);
+                               lock(computeQ)
+                                       computeQ.Submit (cmd);
                                computeQ.WaitIdle ();
                        }
+                       lock(printMutex)
+                               printResults (outBuff);
 
-                       printResults ();
+                       dsPool.Dispose ();
+                       inBuff.Dispose ();
+                       outBuff.Dispose ();
+                       finishedThread++;
+               }
+               volatile int finishedThread = 0;
+               void createThreads () {
+                       //Console.WriteLine ($"count down reset");
+                       for (int i = 0; i < threadCount; i++) {
+                               Thread t = new Thread (computeThread);
+                               t.IsBackground = true;
+                               t.Start ();
+                       }
                }
 
-               void printResults () {
+               public void Run () {
+                       createThreads();
+                       while (finishedThread < threadCount)
+                               Thread.Sleep(1);
+                       dev.WaitIdle();
+               }
+
+               void printResults (HostBuffer outBuff) {
                        int[] results = new int[data_size];
 
                        outBuff.Map ();
@@ -105,10 +131,6 @@ namespace SimpleCompute {
 
                        plCompute.Dispose ();
                        dsLayout.Dispose ();
-                       dsPool.Dispose ();
-
-                       inBuff.Dispose ();
-                       outBuff.Dispose ();
 
                        dev.Dispose ();
                        instance.Dispose ();
index 1a6e0a94b4fe7b1944357c0d309ec2542d6ec5ed..9a80a9a0248b49cef40c5b9e429a21ff6e9420fa 100644 (file)
@@ -147,7 +147,7 @@ namespace delaunay {
                bool rebuildBuffers = false;
 
                void buildCommandBuffers() {
-                       cmdPool.Reset (VkCommandPoolResetFlags.ReleaseResources);
+                       cmdPool.Reset ();
 
                        for (int i = 0; i < swapChain.ImageCount; ++i) {
                                FrameBuffer fb = frameBuffers[i];
index 80e66d46188cab22a6d9363b27487c4e5e46e2c2..5d1dbc6e3e939383680d9d56ca7f6ddb15b87712 100644 (file)
@@ -1,7 +1,9 @@
 using System;
+using System.Numerics;
 using System.Runtime.InteropServices;
-using CVKL;
-using VK;
+using Glfw;
+using Vulkan;
+using vke;
 using System.Linq;
 
 namespace test {
@@ -53,7 +55,8 @@ namespace test {
                        phy = instance.GetAvailablePhysicalDevice ().FirstOrDefault ();
                        dev = new Device (phy);
                        computeQ = new Queue (dev, VkQueueFlags.Compute);
-                       dev.Activate (enabledFeatures, enabledExtensions);
+
+                       dev.Activate (IntPtr.Zero, enabledFeatures, enabledExtensions);
 
                        datas = new float[data_size];
                        Random rnd = new Random ();
@@ -72,7 +75,7 @@ namespace test {
                                
                        plCompute = new ComputePipeline (
                                new PipelineLayout (dev, new VkPushConstantRange (VkShaderStageFlags.Compute, sizeof (int)), dsLayoutCompute),
-                               "#compute.computeTest.comp.spv" );
+                               "#shaders.computeTest.comp.spv" );
 
                        dsetPing = dsPool.Allocate (dsLayoutCompute);
                        dsetPong = dsPool.Allocate (dsLayoutCompute);
@@ -87,7 +90,7 @@ namespace test {
                public void Run () {
                        using (CommandPool cmdPool = new CommandPool (dev, computeQ.qFamIndex)) {
 
-                               CommandBuffer cmd = cmdPool.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit);
+                               PrimaryCommandBuffer cmd = cmdPool.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit);
 
                                bool pong = false;
 
index a366bbab9d214e3b31a7463a6581167d9ca63350..0219e5f3b0fc91f9017234258382e5555c9cd19e 100644 (file)
@@ -50,6 +50,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VulkanContext", "samples\Vu
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MeshShader", "samples\MeshShader\MeshShader.csproj", "{5787D082-7E4E-4B18-9C69-529CBC4F105E}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamicRendering", "samples\DynamicRendering\DynamicRendering.csproj", "{3A0E5765-911E-4451-9715-ED55095D6C39}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FillTests", "samples\FillTests\FillTests.csproj", "{273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}"
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                BuildPackages|Any CPU = BuildPackages|Any CPU
@@ -134,6 +138,22 @@ Global
                {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Debug|Any CPU.Build.0 = Debug|Any CPU
                {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Release|Any CPU.ActiveCfg = Release|Any CPU
                {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Release|Any CPU.Build.0 = Release|Any CPU
+               {3A0E5765-911E-4451-9715-ED55095D6C39}.BuildPackages|Any CPU.ActiveCfg = Debug|Any CPU
+               {3A0E5765-911E-4451-9715-ED55095D6C39}.BuildPackages|Any CPU.Build.0 = Debug|Any CPU
+               {3A0E5765-911E-4451-9715-ED55095D6C39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {3A0E5765-911E-4451-9715-ED55095D6C39}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {3A0E5765-911E-4451-9715-ED55095D6C39}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {3A0E5765-911E-4451-9715-ED55095D6C39}.Release|Any CPU.Build.0 = Release|Any CPU
+               {3A0E5765-911E-4451-9715-ED55095D6C39}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Debug|Any CPU
+               {3A0E5765-911E-4451-9715-ED55095D6C39}.ReleaseSpirVTasks|Any CPU.Build.0 = Debug|Any CPU
+               {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.BuildPackages|Any CPU.ActiveCfg = Debug|Any CPU
+               {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.BuildPackages|Any CPU.Build.0 = Debug|Any CPU
+               {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.Release|Any CPU.Build.0 = Release|Any CPU
+               {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Debug|Any CPU
+               {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.ReleaseSpirVTasks|Any CPU.Build.0 = Debug|Any CPU
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
@@ -153,6 +173,8 @@ Global
                {85CD9813-E182-4ED1-8D2C-38467657BEF3} = {16439374-B8DB-4643-8116-EB3358B49A12}
                {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD} = {16439374-B8DB-4643-8116-EB3358B49A12}
                {5787D082-7E4E-4B18-9C69-529CBC4F105E} = {16439374-B8DB-4643-8116-EB3358B49A12}
+               {3A0E5765-911E-4451-9715-ED55095D6C39} = {16439374-B8DB-4643-8116-EB3358B49A12}
+               {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3} = {16439374-B8DB-4643-8116-EB3358B49A12}
        EndGlobalSection
        GlobalSection(ExtensibilityGlobals) = postSolution
                SolutionGuid = {1360F94D-CF3C-4121-A8D7-E227F41668F1}
index c20cd1fc2c87da1061c99095f9a40edb3ea7a9e1..4e70340a476c2766fb4f1b9d6bd9a75ff07fdbdd 100644 (file)
@@ -21,7 +21,8 @@ namespace vke {
                /// <param name="renderPass">a managed Render pass that will be activated (if not already) during the pipeline creation.</param>
                /// <param name="cache">an optional pipeline cache to speed up pipeline creation.</param>
                /// <param name="name">an optionnal name that will be used by the debug utils extension if enabled.</param>
-               protected GraphicPipeline (RenderPass renderPass, PipelineCache cache = null, string name = "graphic pipeline") : base (renderPass.Dev, cache, name) {
+               protected GraphicPipeline (RenderPass renderPass, PipelineCache cache = null, string name = "graphic pipeline") :
+                       base (renderPass?.Dev, cache, name) {
                        RenderPass = renderPass;
                }
                /// <summary>
@@ -29,18 +30,23 @@ namespace vke {
                /// </summary>
                public GraphicPipeline (GraphicPipelineConfig cfg, string name = "graphic pipeline") : this (cfg.RenderPass, cfg.Cache, name) {
                        layout = cfg.Layout;
-
                        init (cfg);
                }
-
+               /// <summary>
+               /// Create a new Graphic Pipeline with Dynamic rendering (without RenderPass)
+               /// </summary>
+               public GraphicPipeline (Device dev, GraphicPipelineConfig cfg, string name = "graphic pipeline") : base (dev, cfg.Cache, name) {
+                       layout = cfg.Layout;
+                       init (cfg);
+               }
         #endregion
 
         public override void Activate () => throw new NotSupportedException ("Please initialize graphic pipeline through the init method");
 
                protected void init (GraphicPipelineConfig cfg) {
                        if (state != ActivableState.Activated) {
-                               Layout.Activate ();
-                               RenderPass.Activate ();
+                               Layout?.Activate ();
+                               RenderPass?.Activate ();
                                Cache?.Activate ();
 
                                bool enableTesselation = false;
@@ -79,8 +85,8 @@ namespace vke {
                                                viewportState.scissorCount = 1;
 
                                        VkGraphicsPipelineCreateInfo info = default;
-                                       info.renderPass = RenderPass.handle;
-                                       info.layout = Layout.handle;
+                                       info.renderPass = RenderPass == null ?  0 : RenderPass.handle;
+                                       info.layout = layout == null ? 0 : Layout.handle;
                                        info.pVertexInputState = vertInputInfo;
                                        info.pInputAssemblyState = cfg.inputAssemblyState;
                                        info.pRasterizationState = cfg.rasterizationState;
@@ -120,7 +126,7 @@ namespace vke {
                protected override void Dispose (bool disposing) {
                        if (disposing) {
                                if (state == ActivableState.Activated)
-                                       RenderPass.Dispose ();
+                                       RenderPass?.Dispose ();
                        } else
                                System.Diagnostics.Debug.WriteLine ("GraphicPipeline disposed by finalizer");
 
index b5a977d789f6078d86d6d1992c41d9e5e97deed2..91a56efd6380b093faaae4d943a0d92274197a2b 100644 (file)
@@ -36,20 +36,19 @@ namespace vke {
                /// Create renderpass with a single color attachment and a resolve one if needed
                /// </summary>
                public RenderPass (Device device, VkFormat colorFormat, VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1, VkAttachmentLoadOp loadOp = VkAttachmentLoadOp.Clear)
-                       : this (device) {
-                       Samples = samples;
-
-                       AddAttachment (colorFormat, (samples == VkSampleCountFlags.SampleCount1) ? VkImageLayout.PresentSrcKHR : VkImageLayout.ColorAttachmentOptimal, samples,
-                               loadOp, VkAttachmentStoreOp.Store);
+                       : this (device, samples) {
                        ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
 
                        SubPass subpass0 = new SubPass ();
                        subpass0.AddColorReference (0, VkImageLayout.ColorAttachmentOptimal);
 
                        if (samples != VkSampleCountFlags.SampleCount1) {
+                               AddAttachment (colorFormat, VkImageLayout.ColorAttachmentOptimal, samples, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.DontCare);
                                AddAttachment (colorFormat, VkImageLayout.PresentSrcKHR, VkSampleCountFlags.SampleCount1);
                                ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
                                subpass0.AddResolveReference (1, VkImageLayout.ColorAttachmentOptimal);
+                       } else {
+                               AddAttachment (colorFormat, VkImageLayout.PresentSrcKHR, samples, loadOp, VkAttachmentStoreOp.Store);
                        }
 
                        AddSubpass (subpass0);