"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)",
],
"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",
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <IncludeDefaultNoneItems>false</IncludeDefaultNoneItems>
+ </PropertyGroup>
+</Project>
--- /dev/null
+// 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);
+ }
+ }
+}
--- /dev/null
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec3 inColor;
+layout (location = 0) out vec4 outFragColor;
+
+void main()
+{
+ outFragColor = vec4(inColor, 1.0);
+}
\ No newline at end of file
--- /dev/null
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec3 inPos;
+layout (location = 1) in vec3 inColor;
+
+layout (binding = 0) uniform UBO
+{
+ mat4 mvp;
+};
+
+layout (location = 0) out vec3 outColor;
+
+out gl_PerVertex
+{
+ vec4 gl_Position;
+};
+
+
+void main()
+{
+ outColor = inColor;
+ gl_Position = mvp * vec4(inPos.xyz, 1.0);
+}
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <IncludeDefaultNoneItems>false</IncludeDefaultNoneItems>
+ </PropertyGroup>
+</Project>
--- /dev/null
+// 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);
+ }
+ }
+}
--- /dev/null
+#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
--- /dev/null
+#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);
+}
--- /dev/null
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec3 inColor;
+layout (location = 0) out vec4 outFragColor;
+
+void main()
+{
+ outFragColor = vec4(inColor, 1.0);
+}
\ No newline at end of file
--- /dev/null
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec3 inPos;
+layout (location = 1) in vec3 inColor;
+
+layout (binding = 0) uniform UBO
+{
+ mat4 mvp;
+};
+
+layout (location = 0) out vec3 outColor;
+
+out gl_PerVertex
+{
+ vec4 gl_Position;
+};
+
+
+void main()
+{
+ outColor = inColor;
+ gl_Position = mvp * vec4(inPos.xyz, 1.0);
+}
--- /dev/null
+#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);
+}
--- /dev/null
+#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));
+ }
+
+
+ }
+
+}
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,
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);
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 ();
{
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
}
}
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 {
Instance instance;
PhysicalDevice phy;
Device dev;
+ DescriptorSetLayout dsLayout;
Queue computeQ;
- HostBuffer inBuff, outBuff;
- DescriptorPool dsPool;
- DescriptorSetLayout dsLayout;
- DescriptorSet dset;
ComputePipeline plCompute;
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)
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 ();
plCompute.Dispose ();
dsLayout.Dispose ();
- dsPool.Dispose ();
-
- inBuff.Dispose ();
- outBuff.Dispose ();
dev.Dispose ();
instance.Dispose ();
bool rebuildBuffers = false;
void buildCommandBuffers() {
- cmdPool.Reset (VkCommandPoolResetFlags.ReleaseResources);
+ cmdPool.Reset ();
for (int i = 0; i < swapChain.ImageCount; ++i) {
FrameBuffer fb = frameBuffers[i];
using System;
+using System.Numerics;
using System.Runtime.InteropServices;
-using CVKL;
-using VK;
+using Glfw;
+using Vulkan;
+using vke;
using System.Linq;
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 ();
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);
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;
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
{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
{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}
/// <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>
/// </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;
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;
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");
/// 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);