From: Jean-Philippe Bruyère Date: Mon, 4 Aug 2025 13:04:28 +0000 (+0200) Subject: ShaderObject test ok, CreateSwapchain virtual meth in vkWindow, divers wip X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=refs%2Fheads%2FfillTest2;p=jp%2Fvke.net.git ShaderObject test ok, CreateSwapchain virtual meth in vkWindow, divers wip --- diff --git a/.vscode/launch.json b/.vscode/launch.json index ee0e702..66bb370 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -43,6 +43,17 @@ "stopAtEntry": false, "console": "internalConsole" }, + { + "name": ".NET Core Launch (FramebufferFetchTests)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build FramebufferFetchTests", + "program": "${workspaceFolder}/build/Debug/net6/FramebufferFetchTests", + "args": [], + "cwd": "${workspaceFolder}/build/Debug/net6/", + "stopAtEntry": false, + "console": "internalConsole" + }, { "name": ".NET Core Launch (ShaderObject)", "type": "coreclr", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index e501b27..1a6ebbb 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -58,6 +58,19 @@ "problemMatcher": "$msCompile" }, { + "label": "build FramebufferFetchTests", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/samples/FramebufferFetchTests/FramebufferFetchTests.csproj", + "/property:GenerateFullPaths=true", + "/property:SolutionDir=${workspaceFolder}/", + "/property:Configuration=Debug", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, { "label": "build ShaderObject", "command": "dotnet", "type": "process", diff --git a/Directory.Build.props b/Directory.Build.props index 7efe3e3..2f8c399 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ $(SolutionDir)build\$(Configuration)\ 0.2.0 $(SpirVTasksReleaseVersion) - 0.3.0 + 0.3.4 $(VkeReleaseVersion)-beta true false diff --git a/addons/gltfLoader/glTFLoader.cs b/addons/gltfLoader/glTFLoader.cs index d73b841..2a8d6f5 100644 --- a/addons/gltfLoader/glTFLoader.cs +++ b/addons/gltfLoader/glTFLoader.cs @@ -330,7 +330,6 @@ namespace vke.glTF { dev.WaitIdle (); cmd.Free (); - } return meshes.ToArray (); diff --git a/samples/DistanceFieldFontTest/Program.cs b/samples/DistanceFieldFontTest/Program.cs index 31990cd..7443d90 100644 --- a/samples/DistanceFieldFontTest/Program.cs +++ b/samples/DistanceFieldFontTest/Program.cs @@ -17,7 +17,7 @@ namespace DistanceFieldFontTest { SwapChain.PREFERED_FORMAT = VkFormat.B8g8r8a8Unorm; #if DEBUG Instance.VALIDATION = true; - Instance.RENDER_DOC_CAPTURE = true; + //Instance.RENDER_DOC_CAPTURE = true; #endif using (Program vke = new Program ()) { vke.Run (); diff --git a/samples/DistanceFieldFontTest/shaders/main.vert b/samples/DistanceFieldFontTest/shaders/main.vert index 3b395bf..8d0061d 100644 --- a/samples/DistanceFieldFontTest/shaders/main.vert +++ b/samples/DistanceFieldFontTest/shaders/main.vert @@ -4,7 +4,7 @@ #extension GL_ARB_shading_language_420pack : enable layout (location = 0) in vec3 inPos; -layout (location = 1) in vec3 inColor; +layout (location = 1) in vec2 inUV; layout (binding = 0) uniform UBO { @@ -13,7 +13,7 @@ layout (binding = 0) uniform UBO mat4 modelMatrix; } ubo; -layout (location = 0) out vec3 outColor; +layout (location = 0) out vec2 outUV; out gl_PerVertex { @@ -23,6 +23,6 @@ out gl_PerVertex void main() { - outColor = inColor; + outUV = inUV; gl_Position = ubo.projectionMatrix * ubo.viewMatrix * ubo.modelMatrix * vec4(inPos.xyz, 1.0); } diff --git a/samples/ExtendedDynamic/ExtendedDynamic.csproj b/samples/ExtendedDynamic/ExtendedDynamic.csproj new file mode 100644 index 0000000..672fb5a --- /dev/null +++ b/samples/ExtendedDynamic/ExtendedDynamic.csproj @@ -0,0 +1,5 @@ + + + false + + diff --git a/samples/ExtendedDynamic/README.md b/samples/ExtendedDynamic/README.md new file mode 100644 index 0000000..8bdcb08 --- /dev/null +++ b/samples/ExtendedDynamic/README.md @@ -0,0 +1,153 @@ +# Shaders +For this tutorials we'll need a `vertex` and a `fragment` shaders. Vulkan need them to be compiled into [SPIR-V](https://www.khronos.org/spir/). Install the [Vulkan Sdk](https://www.lunarg.com/vulkan-sdk/) and after building it, ensure the `VULKAN_SDK` environment variable points to its binary subdir. +```bash +export VULKAN_SDK=/VulkanSDK/1.2.176.1/x86_64 +``` +To enable automatic shader compilation during build, add the [SpirVTasks package](https://www.nuget.org/packages/SpirVTasks/) and a generic **GLSLShader** item globing a full directory. +```xml + + + + + + +``` +See [SpirVTasks documentation](https://github.com/jpbruyere/vke.net/tree/master/SpirVTasks) for more informations. + +# 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)); +``` +# Configuring pipelines + +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 +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))); +``` +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 +``` +# Adding the shaders +Add both vertex and fragment shaders to the globbed directory of your `.csproj` + +##### triangle.vert +```glsl +#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); +} +``` +##### triangle.frag +```glsl +#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); +} +``` + +Shaders will be compiled into spir-v automatically during build by the `SpirVTasks`. The resulting shaders will be 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.triangle.vert.spv"); +cfg.AddShader (dev, VkShaderStageFlags.Fragment, "#shaders.triangle.frag.spv"); +``` +Because native ShaderModule used during pipeline creation may be distroyed once the pipeline is created, The PipelineConfig class implement the +'IDisposable' interface to release those pointers automaticaly. + +# Creating the pipeline +Once the pipeline configuration is complete, we use it to effectively create and activate a new 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); +``` +# Descriptor allocation +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]); +``` +# Descriptor update + +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); +``` + +# Updating the view + +Override the `UpdateView` method of the `VkWindow` class to update view related stuff like matrices. + +```csharp +public override void UpdateView () { + mvp = Matrix4x4.Create ... + uboMats.Update (mvp, (uint)Marshal.SizeOf ()); + base.UpdateView (); +} +``` +This method is called at least once before the rendering loop just after 'OnResize'. +Then, it is triggered in the render loop each time the `updateViewRequested` field of `VkWindow` is set to 'true', +don't forget to reset `updateViewRequested` to 'false' or call the `base.UpdateView()` which will reset this boolean. + +In a typical application, the mouse movements will set `updateViewRequested` to true. +```csharp +protected override void onMouseMove (double xPos, double yPos) { + updateViewRequested = true; +``` diff --git a/samples/ExtendedDynamic/main.cs b/samples/ExtendedDynamic/main.cs new file mode 100644 index 0000000..db57f71 --- /dev/null +++ b/samples/ExtendedDynamic/main.cs @@ -0,0 +1,217 @@ +// 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; + +//the traditional triangle sample +namespace FillTests { + class Program : SampleBase { + static void Main (string[] args) { +#if DEBUG + Instance.VALIDATION = true; + Instance.VK_MINOR = 3; +#endif + using (Program vke = new Program ()) { + vke.Run (); + } + } + public override string[] EnabledDeviceExtensions => new string[] + { + Ext.D.VK_KHR_swapchain, + Ext.D.VK_EXT_extended_dynamic_state, + Ext.D.VK_EXT_vertex_input_dynamic_state, + Ext.D.VK_EXT_extended_dynamic_state3 + }; + IntPtr deviceCreationPNextChain = IntPtr.Zero; + public override IntPtr DeviceCreationPNext => deviceCreationPNextChain; + + 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 uboMVPmatrix; //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 () { + + using (PinnedObjects pctx = new PinnedObjects ()) { + VkPhysicalDeviceExtendedDynamicStateFeaturesEXT dynFeat = new VkPhysicalDeviceExtendedDynamicStateFeaturesEXT(true); + dynFeat.extendedDynamicState = VkBool32.True; + + deviceCreationPNextChain = dynFeat.Pin(pctx); + + 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. + uboMVPmatrix = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, 1, 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. + //Because 'ShaderInfo' instantiate temporary native ShaderModule, the GraphicPipelineConfig + //class implement 'IDisposable' interface to dispose those modules once the pipeline(s) is created. + 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))); + + cfg.dynamicStates.Add(VkDynamicState.PrimitiveTopology); + + //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, uboMVPmatrix.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); + } + + protected override void createSwapchain() + { + swapChain = new SwapChain (presentQueue as PresentQueue, Width, Height, SwapChain.PREFERED_FORMAT, VkPresentModeKHR.FifoRelaxedKHR); + swapChain.Activate (); + } + //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() { + 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); + + Vk.vkCmdSetPrimitiveTopology(cmds[i].Handle, VkPrimitiveTopology.PointList); + + 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 (); + + updateViewRequested = true; + + 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 (); + uboMVPmatrix.Dispose (); + } + } + + base.Dispose (disposing); + } + } +} diff --git a/samples/ExtendedDynamic/shaders/main.frag b/samples/ExtendedDynamic/shaders/main.frag new file mode 100644 index 0000000..85aeb08 --- /dev/null +++ b/samples/ExtendedDynamic/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/ExtendedDynamic/shaders/main.vert b/samples/ExtendedDynamic/shaders/main.vert new file mode 100644 index 0000000..40a3796 --- /dev/null +++ b/samples/ExtendedDynamic/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/FillTests/shaders/contour.comp b/samples/FillTests/shaders/contour.comp new file mode 100644 index 0000000..df30fc6 --- /dev/null +++ b/samples/FillTests/shaders/contour.comp @@ -0,0 +1,29 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (set = 0, binding = 0, r32ui) uniform uimage2D img; + +layout(push_constant) uniform PushConsts { + vec2 p0; + vec2 p1; + uint primID; + uint contourID; +}; + + +layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + +void main() +{ + float yDiff = p1.y - p0.y; + float xDiff = p1.y - p0.y; + float m = yDiff / xDiff; + float b = p0.y - p0.x * m; + float y = p0.y + gl_GlobalInvocationID.x; + + float x = (y - b) / m; + + imageAtomicAdd(img, ivec2(floor(x), floor(y)), primID); +} diff --git a/samples/FramebufferFetchTests/FramebufferFetchTests.csproj b/samples/FramebufferFetchTests/FramebufferFetchTests.csproj new file mode 100644 index 0000000..672fb5a --- /dev/null +++ b/samples/FramebufferFetchTests/FramebufferFetchTests.csproj @@ -0,0 +1,5 @@ + + + false + + diff --git a/samples/FramebufferFetchTests/README.md b/samples/FramebufferFetchTests/README.md new file mode 100644 index 0000000..8bdcb08 --- /dev/null +++ b/samples/FramebufferFetchTests/README.md @@ -0,0 +1,153 @@ +# Shaders +For this tutorials we'll need a `vertex` and a `fragment` shaders. Vulkan need them to be compiled into [SPIR-V](https://www.khronos.org/spir/). Install the [Vulkan Sdk](https://www.lunarg.com/vulkan-sdk/) and after building it, ensure the `VULKAN_SDK` environment variable points to its binary subdir. +```bash +export VULKAN_SDK=/VulkanSDK/1.2.176.1/x86_64 +``` +To enable automatic shader compilation during build, add the [SpirVTasks package](https://www.nuget.org/packages/SpirVTasks/) and a generic **GLSLShader** item globing a full directory. +```xml + + + + + + +``` +See [SpirVTasks documentation](https://github.com/jpbruyere/vke.net/tree/master/SpirVTasks) for more informations. + +# 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)); +``` +# Configuring pipelines + +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 +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))); +``` +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 +``` +# Adding the shaders +Add both vertex and fragment shaders to the globbed directory of your `.csproj` + +##### triangle.vert +```glsl +#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); +} +``` +##### triangle.frag +```glsl +#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); +} +``` + +Shaders will be compiled into spir-v automatically during build by the `SpirVTasks`. The resulting shaders will be 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.triangle.vert.spv"); +cfg.AddShader (dev, VkShaderStageFlags.Fragment, "#shaders.triangle.frag.spv"); +``` +Because native ShaderModule used during pipeline creation may be distroyed once the pipeline is created, The PipelineConfig class implement the +'IDisposable' interface to release those pointers automaticaly. + +# Creating the pipeline +Once the pipeline configuration is complete, we use it to effectively create and activate a new 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); +``` +# Descriptor allocation +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]); +``` +# Descriptor update + +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); +``` + +# Updating the view + +Override the `UpdateView` method of the `VkWindow` class to update view related stuff like matrices. + +```csharp +public override void UpdateView () { + mvp = Matrix4x4.Create ... + uboMats.Update (mvp, (uint)Marshal.SizeOf ()); + base.UpdateView (); +} +``` +This method is called at least once before the rendering loop just after 'OnResize'. +Then, it is triggered in the render loop each time the `updateViewRequested` field of `VkWindow` is set to 'true', +don't forget to reset `updateViewRequested` to 'false' or call the `base.UpdateView()` which will reset this boolean. + +In a typical application, the mouse movements will set `updateViewRequested` to true. +```csharp +protected override void onMouseMove (double xPos, double yPos) { + updateViewRequested = true; +``` diff --git a/samples/FramebufferFetchTests/main.cs b/samples/FramebufferFetchTests/main.cs new file mode 100644 index 0000000..87cac12 --- /dev/null +++ b/samples/FramebufferFetchTests/main.cs @@ -0,0 +1,225 @@ +// 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; + +//the traditional triangle sample +namespace FillTests { + class Program : SampleBase { + static void Main (string[] args) { +#if DEBUG + Instance.VALIDATION = true; + Instance.VK_MINOR = 3; +#endif + SwapChain.PREFERED_FORMAT = VkFormat.B8g8r8a8Srgb; + SwapChain.IMAGES_USAGE = VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.AttachmentFeedbackLoopEXT; + using (Program vke = new Program ()) { + vke.Run (); + } + } + public override string[] EnabledDeviceExtensions => new string[] + { + Ext.D.VK_KHR_swapchain, + Ext.D.VK_EXT_attachment_feedback_loop_layout, + }; + + 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 uboMVPmatrix; //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. + uboMVPmatrix = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, 1, 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. + //Because 'ShaderInfo' instantiate temporary native ShaderModule, the GraphicPipelineConfig + //class implement 'IDisposable' interface to dispose those modules once the pipeline(s) is created. + 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 = createRenderPass(); + + //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, uboMVPmatrix.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); + } + RenderPass createRenderPass() { + RenderPass rp = new RenderPass (dev, VkSampleCountFlags.SampleCount1); + rp.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) }); + + SubPass subpass0 = new SubPass (); + subpass0.AddColorReference (0, VkImageLayout.AttachmentFeedbackLoopOptimalEXT); + + rp.AddAttachment (swapChain.ColorFormat, VkImageLayout.PresentSrcKHR, VkSampleCountFlags.SampleCount1, VkAttachmentLoadOp.Load, VkAttachmentStoreOp.Store, VkImageLayout.AttachmentFeedbackLoopOptimalEXT); + + rp.AddSubpass (subpass0); + + rp.AddDependency (Vk.SubpassExternal, 0, + VkPipelineStageFlags.BottomOfPipe, VkPipelineStageFlags.ColorAttachmentOutput, + VkAccessFlags.MemoryRead, VkAccessFlags.ColorAttachmentWrite); + rp.AddDependency (0, Vk.SubpassExternal, + VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.BottomOfPipe, + VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.MemoryRead); + + return rp; + } + protected override void createSwapchain() + { + swapChain = new SwapChain (presentQueue as PresentQueue, Width, Height, SwapChain.PREFERED_FORMAT, VkPresentModeKHR.MailboxKHR); + swapChain.Activate (); + } + + //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() { + 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 (); + + updateViewRequested = true; + + 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 (); + uboMVPmatrix.Dispose (); + } + } + + base.Dispose (disposing); + } + } +} diff --git a/samples/FramebufferFetchTests/shaders/main.frag b/samples/FramebufferFetchTests/shaders/main.frag new file mode 100644 index 0000000..dc070cb --- /dev/null +++ b/samples/FramebufferFetchTests/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 = outFragColor + vec4(inColor, 1.0); +} \ No newline at end of file diff --git a/samples/FramebufferFetchTests/shaders/main.vert b/samples/FramebufferFetchTests/shaders/main.vert new file mode 100644 index 0000000..40a3796 --- /dev/null +++ b/samples/FramebufferFetchTests/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/ShaderObject/main.cs b/samples/ShaderObject/main.cs index e8e74a0..6d52c93 100644 --- a/samples/ShaderObject/main.cs +++ b/samples/ShaderObject/main.cs @@ -14,14 +14,32 @@ namespace ShaderObjectSample { class Program : SampleBase { public override string[] EnabledDeviceExtensions => new string[] { Ext.D.VK_KHR_swapchain, - Ext.D.VK_EXT_shader_object + Ext.D.VK_EXT_shader_object, + Ext.D.VK_KHR_dynamic_rendering, + Ext.D.VK_EXT_extended_dynamic_state, + Ext.D.VK_EXT_vertex_input_dynamic_state, + Ext.D.VK_KHR_maintenance2, + Ext.D.VK_KHR_create_renderpass2, + Ext.D.VK_KHR_depth_stencil_resolve }; - static void Main (string[] args) { + public override string[] EnabledInstanceExtensions => new string[] { + Ext.I.VK_EXT_debug_utils, + }; + protected override void configureEnabledFeatures(VkPhysicalDeviceFeatures available_features, ref VkPhysicalDeviceFeatures enabled_features) + { + enabled_features.fillModeNonSolid = available_features.fillModeNonSolid; + } + + + static void Main(string[] args) + { + Instance.VK_MINOR = 3; #if DEBUG Instance.VALIDATION = true; #endif - using (Program vke = new Program ()) { - vke.Run (); + using (Program vke = new Program()) + { + vke.Run(); } } @@ -46,9 +64,12 @@ namespace ShaderObjectSample { DescriptorPool descriptorPool; DescriptorSet descriptorSet;//descriptor set for the mvp matrice. + PipelineLayout pipelineLayout; + + //FrameBuffers frameBuffers; //the frame buffer collection coupled to the swapchain images + //GraphicPipeline pipeline; //the triangle rendering pipeline - FrameBuffers frameBuffers; //the frame buffer collection coupled to the swapchain images - GraphicPipeline pipeline; //the triangle rendering pipeline + LinkedShaderObjects shaders; //triangle vertices (position + color per vertex) and indices. Vertex[] vertices = { @@ -58,22 +79,70 @@ namespace ShaderObjectSample { }; ushort[] indices = new ushort[] { 0, 1, 2 }; - protected override void initVulkan () { - base.initVulkan (); + IntPtr deviceCreationPNext = IntPtr.Zero; + public override IntPtr DeviceCreationPNext => deviceCreationPNext; + + + + protected override void selectPhysicalDevice() + { + base.selectPhysicalDevice(); + + VkPhysicalDeviceFeatures2 phyFeat2 = VkPhysicalDeviceFeatures2.New; + using (var dynRenderingFeat = new PNext()) + { + using (var shadObjFeat = new PNext(dynRenderingFeat)) + { + phyFeat2.pNext = shadObjFeat; + Vk.vkGetPhysicalDeviceFeatures2(phy.Handle, ref phyFeat2); + + Console.WriteLine($"ShaderObject Support:\t{shadObjFeat.Val.shaderObject}"); + Console.WriteLine($"Dynamic Rendering Support:\t{dynRenderingFeat.Val.dynamicRendering}"); + + } + } + } + vke.DebugUtils.Messenger dbgmsg; + + protected override void initVulkan() + { + using (PinnedObjects pctx = new PinnedObjects()) + { + VkPhysicalDeviceShaderObjectFeaturesEXT shadObjFeat = new VkPhysicalDeviceShaderObjectFeaturesEXT(true); + VkPhysicalDeviceDynamicRenderingFeatures dynRenderFeat = new VkPhysicalDeviceDynamicRenderingFeatures(true); + shadObjFeat.shaderObject = VkBool32.True; + shadObjFeat.pNext = dynRenderFeat.Pin(pctx); + deviceCreationPNext = shadObjFeat.Pin(pctx); + base.initVulkan(); + } + dbgmsg = new vke.DebugUtils.Messenger (instance, VkDebugUtilsMessageTypeFlagsEXT.PerformanceEXT | VkDebugUtilsMessageTypeFlagsEXT.ValidationEXT | VkDebugUtilsMessageTypeFlagsEXT.GeneralEXT, + VkDebugUtilsMessageSeverityFlagsEXT.InfoEXT | + VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT | + VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT | + VkDebugUtilsMessageSeverityFlagsEXT.VerboseEXT); + + + DescriptorSetLayout dsLayout = new DescriptorSetLayout(dev, new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer)); - DescriptorSetLayout dsLayout = new DescriptorSetLayout (dev, new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer)); ShaderObject vertexShader = new ShaderObject(dev, VkShaderStageFlags.Vertex, VkShaderStageFlags.Fragment, dsLayout); vertexShader.FileName = "#shaders.main.vert.spv"; - - vertexShader.Activate(); - - - vbo = new HostBuffer (dev, VkBufferUsageFlags.VertexBuffer, vertices); - ibo = new HostBuffer (dev, VkBufferUsageFlags.IndexBuffer, indices); - - uboMVPmatrix = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, 1, true); - - descriptorPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer)); + + ShaderObject fragmentShader = new ShaderObject(dev, VkShaderStageFlags.Fragment, 0, dsLayout); + fragmentShader.FileName = "#shaders.main.frag.spv"; + + shaders = new LinkedShaderObjects(vertexShader, fragmentShader); + shaders.Activate(); + + pipelineLayout = new PipelineLayout(dev, dsLayout); + pipelineLayout.Activate(); + + + vbo = new HostBuffer(dev, VkBufferUsageFlags.VertexBuffer, vertices); + ibo = new HostBuffer(dev, VkBufferUsageFlags.IndexBuffer, indices); + + uboMVPmatrix = new HostBuffer(dev, VkBufferUsageFlags.UniformBuffer, 1, true); + + descriptorPool = new DescriptorPool(dev, 1, new VkDescriptorPoolSize(VkDescriptorType.UniformBuffer)); /* cfg.AddVertexBinding (0); @@ -84,10 +153,10 @@ namespace ShaderObjectSample { ); */ - 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); + descriptorSet = descriptorPool.Allocate(dsLayout); + DescriptorSetWrites uboUpdate = new DescriptorSetWrites(descriptorSet, dsLayout); + uboUpdate.Write(dev, uboMVPmatrix.Descriptor); + cmds = cmdPool.AllocateCommandBuffer(swapChain.ImageCount); } //view update override, see base method for more informations. @@ -113,40 +182,150 @@ namespace ShaderObjectSample { } } - void buildCommandBuffers() { + + public static void GetDelegate(VkDevice dev, string name, ref IntPtr ptr) + { + GCHandle gCHandle = GCHandle.Alloc(System.Text.Encoding.UTF8.GetBytes(name + "\0"), GCHandleType.Pinned); + IntPtr intPtr = Vk.vkGetDeviceProcAddr(dev, gCHandle.AddrOfPinnedObject()); + if (!(intPtr == IntPtr.Zero)) + { + ptr = intPtr; + } + + gCHandle.Free(); + } + void buildCommandBuffers() + { cmdPool.Reset (VkCommandPoolResetFlags.ReleaseResources); - for (int i = 0; i < swapChain.ImageCount; ++i) { - FrameBuffer fb = frameBuffers[i]; - cmds[i].Start (); + for (int i = 0; i < swapChain.ImageCount; ++i) + buildCommandBuffer(cmds[i], i); + } + public class RenderingInfo + { + List attachments = new List(); + VkRenderingInfo info; + public RenderingInfo(VkRect2D renderArea) + { + info.renderArea = renderArea; + info.layerCount = 1; + } + public void AddAttachment ( + VkImageView imageView, + VkAttachmentLoadOp loadOp = VkAttachmentLoadOp.Clear, + VkAttachmentStoreOp storeOp = VkAttachmentStoreOp.Store, + VkImageLayout imageLayout = VkImageLayout.ColorAttachmentOptimal, + VkClearValue clearValue = default + ) { + attachments.Add (new VkRenderingAttachmentInfo { + imageView = imageView, + imageLayout = imageLayout, + loadOp = loadOp, + storeOp = storeOp, + clearValue = clearValue + }); + } + public void Begin(CommandBuffer cmd) + { + VkRenderingInfo i = info; + i.pColorAttachments = attachments; + Vk.vkCmdBeginRendering(cmd.Handle, ref i);// ref renderingInfo); + } + } + + void buildCommandBuffer(PrimaryCommandBuffer cmd, int imageIndex) { + //FrameBuffer fb = frameBuffers[i]; + cmd.Start (); + swapChain.images[imageIndex].SetLayout(cmd, VkImageAspectFlags.Color, VkImageLayout.ColorAttachmentOptimal); + + /*VkRenderingAttachmentInfo colorAttachment = VkRenderingAttachmentInfo.New; + colorAttachment.clearValue = new VkClearValue(0, 0, 0); + colorAttachment.imageLayout = VkImageLayout.ColorAttachmentOptimal; + colorAttachment.loadOp = VkAttachmentLoadOp.Clear; + colorAttachment.storeOp = VkAttachmentStoreOp.Store; + colorAttachment.imageView = swapChain.images[imageIndex].Descriptor.imageView; + + VkRenderingInfo renderingInfo = VkRenderingInfo.New; + renderingInfo.renderArea = new VkRect2D(swapChain.Width, swapChain.Height); + renderingInfo.pColorAttachments = colorAttachment; + renderingInfo.layerCount = 1;*/ + + RenderingInfo ri = new RenderingInfo(new VkRect2D(swapChain.Width, swapChain.Height)); + ri.AddAttachment(swapChain.images[imageIndex].Descriptor.imageView); + ri.Begin(cmd); + + //colorAttachment.clearValue + // New structures are used to define the attachments used in dynamic rendering + /* VkRenderingAttachmentInfo colorAttachment = new VkRenderingAttachmentInfo(VkImageLayout.ColorAttachmentOptimal, VkImageLayout.Undefined, VkAttachmentLoadOp.Clear, + VkAttachmentStoreOp.Store, new VkClearValue(0, 0, 0)); + colorAttachment.imageView = swapChain.images[i].Descriptor.imageView; - pipeline.RenderPass.Begin (cmds[i], fb); - cmds[i].SetViewport (swapChain.Width, swapChain.Height); - cmds[i].SetScissor (swapChain.Width, swapChain.Height); + VkRenderingInfo renderingInfo = VkRenderingInfo.New; + renderingInfo.renderArea = new VkRect2D(swapChain.Width, swapChain.Height); + renderingInfo.pColorAttachments = colorAttachment; + renderingInfo.layerCount = 1;*/ + /*IntPtr test = IntPtr.Zero; + GetDelegate(dev.Handle, "vkCmdBeginRendering", ref test); - cmds[i].BindDescriptorSet (pipeline.Layout, descriptorSet); + Vk.vkCmdBeginRendering(cmd.Handle, ref renderingInfo);*/ - cmds[i].BindPipeline (pipeline); + //cmd.SetViewport (swapChain.Width, swapChain.Height); + //cmd.SetScissor (swapChain.Width, swapChain.Height); - cmds[i].BindVertexBuffer (vbo); - cmds[i].BindIndexBuffer (ibo, VkIndexType.Uint16); - cmds[i].DrawIndexed ((uint)indices.Length); + cmd.SetCullMode(VkCullModeFlags.None); + cmd.SetFrontFace(VkFrontFace.Clockwise); + cmd.SetDepthTestEnable(false); + cmd.SetPrimitiveTopology(VkPrimitiveTopology.TriangleList); + cmd.SetPrimitiveRestartEnable(false); + cmd.SetPolygonModeEXT(VkPolygonMode.Fill); + cmd.SetStencilTestEnable(false); + cmd.SetRasterizerDiscardEnable(false); - pipeline.RenderPass.End (cmds[i]); + cmd.SetDepthWriteEnable(false); + cmd.SetDepthBiasEnable(false); + cmd.SetRasterizationSamplesEXT(VkSampleCountFlags.SampleCount1); + cmd.SetSampleMaskEXT(VkSampleCountFlags.SampleCount1, 0xFF); + cmd.SetAlphaToCoverageEnableEXT(false); + cmd.SetColorBlendEnableEXT(0, false); - cmds[i].End (); + cmd.SetColorWriteMaskEXT(0, 0xf); + cmd.SetViewport(new VkViewport { width = swapChain.Width, height = swapChain.Height }); + cmd.SetScissor(new VkRect2D (swapChain.Width, swapChain.Height)); + + cmd.SetLineWidth(1.0f); + + VkVertexInputBindingDescription2EXT vxBindingDesc = new VkVertexInputBindingDescription2EXT( + 0, (uint)Marshal.SizeOf(), VkVertexInputRate.Vertex, 1); + + VkVertexInputAttributeDescription2EXT[] vxAttribDesc = { + new VkVertexInputAttributeDescription2EXT(0, 0, VkFormat.R32g32b32Sfloat, 0), + new VkVertexInputAttributeDescription2EXT(1, 0, VkFormat.R32g32b32Sfloat, 12) + }; + + using (PinnedObjects pctx = new PinnedObjects()) { + Vk.vkCmdSetVertexInputEXT(cmd.Handle, 1, vxBindingDesc.Pin(pctx), (uint)vxAttribDesc.Length, vxAttribDesc.Pin(pctx)); + + cmd.BindDescriptorSet (pipelineLayout, descriptorSet); + cmd.BindVertexBuffer (vbo); + cmd.BindIndexBuffer (ibo, VkIndexType.Uint16); + + + Vk.vkCmdBindShadersEXT(cmd.Handle, shaders.Count, shaders.Stages.Pin(pctx), shaders.ShaderHandles.Pin(pctx)); } + + cmd.DrawIndexed ((uint)indices.Length); + + Vk.vkCmdEndRendering(cmd.Handle); + swapChain.images[imageIndex].SetLayout(cmd, VkImageAspectFlags.Color, VkImageLayout.PresentSrcKHR); + + cmd.End (); + } protected override void OnResize () { base.OnResize (); - updateViewRequested = true; - - frameBuffers?.Dispose(); - frameBuffers = pipeline.RenderPass.CreateFrameBuffers(swapChain); - buildCommandBuffers (); } //clean up @@ -155,15 +334,18 @@ namespace ShaderObjectSample { 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 (); + //pipeline.Dispose (); //frame buffers are automatically activated on creation as for resources, so it requests an explicit call to dispose. - frameBuffers?.Dispose(); + //frameBuffers?.Dispose(); + shaders.Dispose(); + pipelineLayout.Dispose(); //the descriptor pool descriptorPool.Dispose (); //resources have to be explicityly disposed. vbo.Dispose (); ibo.Dispose (); uboMVPmatrix.Dispose (); + dbgmsg.Dispose(); } } diff --git a/samples/Textured/shaders/main.vert b/samples/Textured/shaders/main.vert index 3b395bf..8d0061d 100644 --- a/samples/Textured/shaders/main.vert +++ b/samples/Textured/shaders/main.vert @@ -4,7 +4,7 @@ #extension GL_ARB_shading_language_420pack : enable layout (location = 0) in vec3 inPos; -layout (location = 1) in vec3 inColor; +layout (location = 1) in vec2 inUV; layout (binding = 0) uniform UBO { @@ -13,7 +13,7 @@ layout (binding = 0) uniform UBO mat4 modelMatrix; } ubo; -layout (location = 0) out vec3 outColor; +layout (location = 0) out vec2 outUV; out gl_PerVertex { @@ -23,6 +23,6 @@ out gl_PerVertex void main() { - outColor = inColor; + outUV = inUV; gl_Position = ubo.projectionMatrix * ubo.viewMatrix * ubo.modelMatrix * vec4(inPos.xyz, 1.0); } diff --git a/samples/Triangle/main.cs b/samples/Triangle/main.cs index 2646543..a48d8de 100644 --- a/samples/Triangle/main.cs +++ b/samples/Triangle/main.cs @@ -15,6 +15,7 @@ namespace FillTests { #if DEBUG Instance.VALIDATION = true; #endif + SwapChain.PREFERED_FORMAT = VkFormat.B8g8r8a8Srgb; using (Program vke = new Program ()) { vke.Run (); } diff --git a/samples/deferred/DeferredPbrRenderer.cs b/samples/deferred/DeferredPbrRenderer.cs index e37deb4..075bc6e 100644 --- a/samples/deferred/DeferredPbrRenderer.cs +++ b/samples/deferred/DeferredPbrRenderer.cs @@ -232,8 +232,6 @@ namespace deferred { new VkDescriptorSetLayoutBinding (2, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//normals + AO new VkDescriptorSetLayoutBinding (3, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment));//Pos + depth - - using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, NUM_SAMPLES)) { cfg.rasterizationState.cullMode = VkCullModeFlags.Back; if (NUM_SAMPLES != VkSampleCountFlags.SampleCount1) { diff --git a/samples/deferred/main.cs b/samples/deferred/main.cs index ecdc687..faeaca9 100644 --- a/samples/deferred/main.cs +++ b/samples/deferred/main.cs @@ -34,7 +34,7 @@ namespace deferred { Deferred (string name = "VkCrowWindow", uint _width = 800, uint _height = 600, bool vSync = false) : base (name, _width, _height, vSync) { } - public override string[] EnabledInstanceExtensions => new string[] { + public override string[] EnabledInstanceExtensions => new string[] { Ext.I.VK_EXT_debug_utils, }; diff --git a/vke.net.sln b/vke.net.sln index 7a04fd8..7e4752b 100644 --- a/vke.net.sln +++ b/vke.net.sln @@ -1,4 +1,5 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 + +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30104.148 MinimumVisualStudioVersion = 10.0.40219.1 @@ -56,94 +57,458 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FillTests", "samples\FillTe EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShaderObject", "samples\ShaderObject\ShaderObject.csproj", "{1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FramebufferFetchTests", "samples\FramebufferFetchTests\FramebufferFetchTests.csproj", "{EF207B32-8BDA-4D97-B536-183C07EA7769}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExtendedDynamic", "samples\ExtendedDynamic\ExtendedDynamic.csproj", "{8D6CAB7C-E739-4C49-9EF3-97E949633B46}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution BuildPackages|Any CPU = BuildPackages|Any CPU + BuildPackages|x64 = BuildPackages|x64 + BuildPackages|x86 = BuildPackages|x86 Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 ReleaseSpirVTasks|Any CPU = ReleaseSpirVTasks|Any CPU + ReleaseSpirVTasks|x64 = ReleaseSpirVTasks|x64 + ReleaseSpirVTasks|x86 = ReleaseSpirVTasks|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Debug|x64.ActiveCfg = Debug|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Debug|x64.Build.0 = Debug|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Debug|x86.ActiveCfg = Debug|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Debug|x86.Build.0 = Debug|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Release|x64.ActiveCfg = Release|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Release|x64.Build.0 = Release|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Release|x86.ActiveCfg = Release|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Release|x86.Build.0 = Release|Any CPU {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Release|Any CPU {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.ReleaseSpirVTasks|Any CPU.Build.0 = Release|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU {642726F4-0592-4846-8EAF-A5D1964C85A7}.BuildPackages|Any CPU.ActiveCfg = Release|Any CPU {642726F4-0592-4846-8EAF-A5D1964C85A7}.BuildPackages|Any CPU.Build.0 = Release|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {642726F4-0592-4846-8EAF-A5D1964C85A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {642726F4-0592-4846-8EAF-A5D1964C85A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.Debug|x64.ActiveCfg = Debug|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.Debug|x64.Build.0 = Debug|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.Debug|x86.ActiveCfg = Debug|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.Debug|x86.Build.0 = Debug|Any CPU {642726F4-0592-4846-8EAF-A5D1964C85A7}.Release|Any CPU.ActiveCfg = Release|Any CPU {642726F4-0592-4846-8EAF-A5D1964C85A7}.Release|Any CPU.Build.0 = Release|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.Release|x64.ActiveCfg = Release|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.Release|x64.Build.0 = Release|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.Release|x86.ActiveCfg = Release|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.Release|x86.Build.0 = Release|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {642726F4-0592-4846-8EAF-A5D1964C85A7}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.BuildPackages|Any CPU.ActiveCfg = Release|Any CPU {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.BuildPackages|Any CPU.Build.0 = Release|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Debug|x64.ActiveCfg = Debug|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Debug|x64.Build.0 = Debug|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Debug|x86.ActiveCfg = Debug|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Debug|x86.Build.0 = Debug|Any CPU {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Release|Any CPU.ActiveCfg = Release|Any CPU {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Release|Any CPU.Build.0 = Release|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Release|x64.ActiveCfg = Release|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Release|x64.Build.0 = Release|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Release|x86.ActiveCfg = Release|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Release|x86.Build.0 = Release|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.BuildPackages|Any CPU.ActiveCfg = Release|Any CPU {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.BuildPackages|Any CPU.Build.0 = Release|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Debug|x64.ActiveCfg = Debug|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Debug|x64.Build.0 = Debug|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Debug|x86.ActiveCfg = Debug|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Debug|x86.Build.0 = Debug|Any CPU {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Release|Any CPU.ActiveCfg = Release|Any CPU {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Release|Any CPU.Build.0 = Release|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Release|x64.ActiveCfg = Release|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Release|x64.Build.0 = Release|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Release|x86.ActiveCfg = Release|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Release|x86.Build.0 = Release|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.BuildPackages|Any CPU.ActiveCfg = Release|Any CPU {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.BuildPackages|Any CPU.Build.0 = Release|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Debug|x64.ActiveCfg = Debug|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Debug|x64.Build.0 = Debug|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Debug|x86.ActiveCfg = Debug|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Debug|x86.Build.0 = Debug|Any CPU {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Release|Any CPU.ActiveCfg = Release|Any CPU {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Release|Any CPU.Build.0 = Release|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Release|x64.ActiveCfg = Release|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Release|x64.Build.0 = Release|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Release|x86.ActiveCfg = Release|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.Release|x86.Build.0 = Release|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Debug|x64.ActiveCfg = Debug|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Debug|x64.Build.0 = Debug|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Debug|x86.ActiveCfg = Debug|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Debug|x86.Build.0 = Debug|Any CPU {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Release|Any CPU.ActiveCfg = Release|Any CPU {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Release|Any CPU.Build.0 = Release|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Release|x64.ActiveCfg = Release|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Release|x64.Build.0 = Release|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Release|x86.ActiveCfg = Release|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Release|x86.Build.0 = Release|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Debug|x64.ActiveCfg = Debug|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Debug|x64.Build.0 = Debug|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Debug|x86.ActiveCfg = Debug|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Debug|x86.Build.0 = Debug|Any CPU {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Release|Any CPU.ActiveCfg = Release|Any CPU {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Release|Any CPU.Build.0 = Release|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Release|x64.ActiveCfg = Release|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Release|x64.Build.0 = Release|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Release|x86.ActiveCfg = Release|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.Release|x86.Build.0 = Release|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {124152F8-FAE6-4D4B-87B9-6074DD365E9B}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {1B2DF710-E500-49E5-8802-EBA71A05E827}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1B2DF710-E500-49E5-8802-EBA71A05E827}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.Debug|x64.ActiveCfg = Debug|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.Debug|x64.Build.0 = Debug|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.Debug|x86.ActiveCfg = Debug|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.Debug|x86.Build.0 = Debug|Any CPU {1B2DF710-E500-49E5-8802-EBA71A05E827}.Release|Any CPU.ActiveCfg = Release|Any CPU {1B2DF710-E500-49E5-8802-EBA71A05E827}.Release|Any CPU.Build.0 = Release|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.Release|x64.ActiveCfg = Release|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.Release|x64.Build.0 = Release|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.Release|x86.ActiveCfg = Release|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.Release|x86.Build.0 = Release|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {1B2DF710-E500-49E5-8802-EBA71A05E827}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Debug|x64.ActiveCfg = Debug|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Debug|x64.Build.0 = Debug|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Debug|x86.ActiveCfg = Debug|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Debug|x86.Build.0 = Debug|Any CPU {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Release|Any CPU.ActiveCfg = Release|Any CPU {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Release|Any CPU.Build.0 = Release|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Release|x64.ActiveCfg = Release|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Release|x64.Build.0 = Release|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Release|x86.ActiveCfg = Release|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Release|x86.Build.0 = Release|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {77437C6D-28B5-4798-96CA-68F987770D65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {77437C6D-28B5-4798-96CA-68F987770D65}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.Debug|x64.ActiveCfg = Debug|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.Debug|x64.Build.0 = Debug|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.Debug|x86.ActiveCfg = Debug|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.Debug|x86.Build.0 = Debug|Any CPU {77437C6D-28B5-4798-96CA-68F987770D65}.Release|Any CPU.ActiveCfg = Release|Any CPU {77437C6D-28B5-4798-96CA-68F987770D65}.Release|Any CPU.Build.0 = Release|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.Release|x64.ActiveCfg = Release|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.Release|x64.Build.0 = Release|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.Release|x86.ActiveCfg = Release|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.Release|x86.Build.0 = Release|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {77437C6D-28B5-4798-96CA-68F987770D65}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {8185163E-A67C-4C0E-8548-67E2A9F16309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8185163E-A67C-4C0E-8548-67E2A9F16309}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.Debug|x64.ActiveCfg = Debug|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.Debug|x64.Build.0 = Debug|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.Debug|x86.ActiveCfg = Debug|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.Debug|x86.Build.0 = Debug|Any CPU {8185163E-A67C-4C0E-8548-67E2A9F16309}.Release|Any CPU.ActiveCfg = Release|Any CPU {8185163E-A67C-4C0E-8548-67E2A9F16309}.Release|Any CPU.Build.0 = Release|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.Release|x64.ActiveCfg = Release|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.Release|x64.Build.0 = Release|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.Release|x86.ActiveCfg = Release|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.Release|x86.Build.0 = Release|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {8185163E-A67C-4C0E-8548-67E2A9F16309}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Debug|x64.ActiveCfg = Debug|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Debug|x64.Build.0 = Debug|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Debug|x86.ActiveCfg = Debug|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Debug|x86.Build.0 = Debug|Any CPU {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Release|Any CPU.ActiveCfg = Release|Any CPU {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Release|Any CPU.Build.0 = Release|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Release|x64.ActiveCfg = Release|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Release|x64.Build.0 = Release|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Release|x86.ActiveCfg = Release|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.Release|x86.Build.0 = Release|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {D9A41382-444E-44ED-B638-3D8F06F2FBC2}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Debug|x64.ActiveCfg = Debug|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Debug|x64.Build.0 = Debug|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Debug|x86.ActiveCfg = Debug|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Debug|x86.Build.0 = Debug|Any CPU {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Release|Any CPU.ActiveCfg = Release|Any CPU {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Release|Any CPU.Build.0 = Release|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Release|x64.ActiveCfg = Release|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Release|x64.Build.0 = Release|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Release|x86.ActiveCfg = Release|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Release|x86.Build.0 = Release|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Debug|x64.ActiveCfg = Debug|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Debug|x64.Build.0 = Debug|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Debug|x86.ActiveCfg = Debug|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Debug|x86.Build.0 = Debug|Any CPU {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Release|Any CPU.ActiveCfg = Release|Any CPU {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Release|Any CPU.Build.0 = Release|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Release|x64.ActiveCfg = Release|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Release|x64.Build.0 = Release|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Release|x86.ActiveCfg = Release|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.Release|x86.Build.0 = Release|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {85CD9813-E182-4ED1-8D2C-38467657BEF3}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.BuildPackages|x86.Build.0 = BuildPackages|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}.Debug|x64.ActiveCfg = Debug|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.Debug|x64.Build.0 = Debug|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.Debug|x86.ActiveCfg = Debug|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.Debug|x86.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}.Release|x64.ActiveCfg = Release|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.Release|x64.Build.0 = Release|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.Release|x86.ActiveCfg = Release|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.Release|x86.Build.0 = Release|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {CF8755E1-9E8B-4AD2-A7D1-D66D797004AD}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Debug|x64.ActiveCfg = Debug|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Debug|x64.Build.0 = Debug|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Debug|x86.ActiveCfg = Debug|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Debug|x86.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 + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Release|x64.ActiveCfg = Release|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Release|x64.Build.0 = Release|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Release|x86.ActiveCfg = Release|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.Release|x86.Build.0 = Release|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {5787D082-7E4E-4B18-9C69-529CBC4F105E}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.BuildPackages|x86.Build.0 = BuildPackages|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}.Debug|x64.ActiveCfg = Debug|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.Debug|x64.Build.0 = Debug|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.Debug|x86.ActiveCfg = Debug|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.Debug|x86.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}.Release|x64.ActiveCfg = Release|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.Release|x64.Build.0 = Release|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.Release|x86.ActiveCfg = Release|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.Release|x86.Build.0 = Release|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {3A0E5765-911E-4451-9715-ED55095D6C39}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.BuildPackages|x86.Build.0 = BuildPackages|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}.Debug|x64.ActiveCfg = Debug|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.Debug|x64.Build.0 = Debug|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.Debug|x86.ActiveCfg = Debug|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.Debug|x86.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}.Release|x64.ActiveCfg = Release|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.Release|x64.Build.0 = Release|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.Release|x86.ActiveCfg = Release|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.Release|x86.Build.0 = Release|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.BuildPackages|x64.ActiveCfg = BuildPackages|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.BuildPackages|x64.Build.0 = BuildPackages|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.BuildPackages|x86.ActiveCfg = BuildPackages|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.BuildPackages|x86.Build.0 = BuildPackages|Any CPU {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.Debug|x64.ActiveCfg = Debug|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.Debug|x64.Build.0 = Debug|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.Debug|x86.ActiveCfg = Debug|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.Debug|x86.Build.0 = Debug|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.Release|x64.ActiveCfg = Release|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.Release|x64.Build.0 = Release|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.Release|x86.ActiveCfg = Release|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.Release|x86.Build.0 = Release|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.ReleaseSpirVTasks|x64.ActiveCfg = ReleaseSpirVTasks|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.ReleaseSpirVTasks|x64.Build.0 = ReleaseSpirVTasks|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.ReleaseSpirVTasks|x86.ActiveCfg = ReleaseSpirVTasks|Any CPU + {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371}.ReleaseSpirVTasks|x86.Build.0 = ReleaseSpirVTasks|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.BuildPackages|Any CPU.ActiveCfg = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.BuildPackages|Any CPU.Build.0 = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.BuildPackages|x64.ActiveCfg = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.BuildPackages|x64.Build.0 = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.BuildPackages|x86.ActiveCfg = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.BuildPackages|x86.Build.0 = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Debug|x64.ActiveCfg = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Debug|x64.Build.0 = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Debug|x86.ActiveCfg = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Debug|x86.Build.0 = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Release|Any CPU.Build.0 = Release|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Release|x64.ActiveCfg = Release|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Release|x64.Build.0 = Release|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Release|x86.ActiveCfg = Release|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.Release|x86.Build.0 = Release|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.ReleaseSpirVTasks|Any CPU.Build.0 = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.ReleaseSpirVTasks|x64.ActiveCfg = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.ReleaseSpirVTasks|x64.Build.0 = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.ReleaseSpirVTasks|x86.ActiveCfg = Debug|Any CPU + {EF207B32-8BDA-4D97-B536-183C07EA7769}.ReleaseSpirVTasks|x86.Build.0 = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.BuildPackages|Any CPU.ActiveCfg = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.BuildPackages|Any CPU.Build.0 = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.BuildPackages|x64.ActiveCfg = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.BuildPackages|x64.Build.0 = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.BuildPackages|x86.ActiveCfg = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.BuildPackages|x86.Build.0 = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Debug|x64.ActiveCfg = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Debug|x64.Build.0 = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Debug|x86.ActiveCfg = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Debug|x86.Build.0 = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Release|Any CPU.Build.0 = Release|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Release|x64.ActiveCfg = Release|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Release|x64.Build.0 = Release|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Release|x86.ActiveCfg = Release|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.Release|x86.Build.0 = Release|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.ReleaseSpirVTasks|Any CPU.Build.0 = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.ReleaseSpirVTasks|x64.ActiveCfg = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.ReleaseSpirVTasks|x64.Build.0 = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.ReleaseSpirVTasks|x86.ActiveCfg = Debug|Any CPU + {8D6CAB7C-E739-4C49-9EF3-97E949633B46}.ReleaseSpirVTasks|x86.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -166,6 +531,8 @@ Global {3A0E5765-911E-4451-9715-ED55095D6C39} = {16439374-B8DB-4643-8116-EB3358B49A12} {273C88AE-D095-4CF9-8D6F-D7ABE3E9C8D3} = {16439374-B8DB-4643-8116-EB3358B49A12} {1B63D92E-7C54-41DA-9BCA-AC0C53F3D371} = {16439374-B8DB-4643-8116-EB3358B49A12} + {EF207B32-8BDA-4D97-B536-183C07EA7769} = {16439374-B8DB-4643-8116-EB3358B49A12} + {8D6CAB7C-E739-4C49-9EF3-97E949633B46} = {16439374-B8DB-4643-8116-EB3358B49A12} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1360F94D-CF3C-4121-A8D7-E227F41668F1} diff --git a/vke/src/VkWindow.cs b/vke/src/VkWindow.cs index 4acbc1b..8dfa69c 100644 --- a/vke/src/VkWindow.cs +++ b/vke/src/VkWindow.cs @@ -176,9 +176,7 @@ namespace vke { //activate the device to have effective queues created accordingly to what's available dev.Activate (DeviceCreationPNext, enabledFeatures, EnabledDeviceExtensions); - swapChain = new SwapChain (presentQueue as PresentQueue, Width, Height, SwapChain.PREFERED_FORMAT, - VSync ? VkPresentModeKHR.FifoKHR : VkPresentModeKHR.ImmediateKHR); - swapChain.Activate (); + createSwapchain(); Width = swapChain.Width; Height = swapChain.Height; @@ -217,7 +215,14 @@ namespace vke { protected virtual void createQueues () { presentQueue = new PresentQueue (dev, VkQueueFlags.Graphics, hSurf); } - + /// + /// Override this method for custom swapchain creation and activation. + /// + protected virtual void createSwapchain() { + swapChain = new SwapChain (presentQueue as PresentQueue, Width, Height, SwapChain.PREFERED_FORMAT, + VSync ? VkPresentModeKHR.FifoKHR : VkPresentModeKHR.ImmediateKHR); + swapChain.Activate (); + } /// /// Main render method called each frame. get next swapchain image, process resize if needed, submit and present to the presentQueue. /// Wait QueueIdle after presenting. @@ -235,10 +240,8 @@ namespace vke { drawFence.Wait (); drawFence.Reset (); - presentQueue.Submit (cmds[idx], swapChain.nextImgAvail, drawComplete[idx], drawFence); + presentQueue.Submit (cmds[idx], swapChain.ConsumeNextImgSemaphore(), drawComplete[idx], drawFence); presentQueue.Present (swapChain, drawComplete[idx]); - - swapChain.semaphoresQueue.Enqueue(swapChain.nextImgAvail); //presentQueue.WaitIdle (); } diff --git a/vke/src/base/CommandBuffer.cs b/vke/src/base/CommandBuffer.cs index aaad0f5..fab96e0 100644 --- a/vke/src/base/CommandBuffer.cs +++ b/vke/src/base/CommandBuffer.cs @@ -95,65 +95,73 @@ namespace vke { /// - secondary command buffers, which can be executed by primary command buffers, and which are not directly submitted to queues. /// Command buffer are not derived from activable, because their state is retained by the pool which create them. /// - public abstract class CommandBuffer { + public abstract class CommandBuffer + { public enum States { Init, Record, Executable, Pending, Invalid }; - protected CommandPool pool; - protected VkCommandBuffer handle; + protected CommandPool pool; + protected VkCommandBuffer handle; - public VkCommandBuffer Handle => handle; + public VkCommandBuffer Handle => handle; public Device Device => pool?.Dev;//this help - //public States State { get; internal set; } + //public States State { get; internal set; } - internal CommandBuffer (VkDevice _dev, CommandPool _pool, VkCommandBuffer _buff) - { - pool = _pool; - handle = _buff; + internal CommandBuffer(VkDevice _dev, CommandPool _pool, VkCommandBuffer _buff) + { + pool = _pool; + handle = _buff; //State = States.Init; - } + } /// /// Put the command buffer in the executable state if no errors are present in the recording. /// - public void End () { - CheckResult (vkEndCommandBuffer (handle)); - } - /// - /// Update dynamic viewport state - /// - public void SetViewport (float width, float height, float x = 0f, float y = 0f, float minDepth = 0.0f, float maxDepth = 1.0f) { - VkViewport viewport = new VkViewport { + public void End() + { + CheckResult(vkEndCommandBuffer(handle)); + } + /// + /// Update dynamic viewport state + /// + public void SetViewport(float width, float height, float x = 0f, float y = 0f, float minDepth = 0.0f, float maxDepth = 1.0f) + { + VkViewport viewport = new VkViewport + { x = x, y = y, - height = height, - width = width, - minDepth = minDepth, - maxDepth = maxDepth, - }; - vkCmdSetViewport (handle, 0, 1, ref viewport); - } - /// - /// Update dynamic scissor state - /// - public void SetScissor (uint width, uint height, int offsetX = 0, int offsetY = 0) { - VkRect2D scissor = new VkRect2D (offsetX, offsetY, width, height); - vkCmdSetScissor (handle, 0, 1, ref scissor); - } + height = height, + width = width, + minDepth = minDepth, + maxDepth = maxDepth, + }; + vkCmdSetViewport(handle, 0, 1, ref viewport); + } + /// + /// Update dynamic scissor state + /// + public void SetScissor(uint width, uint height, int offsetX = 0, int offsetY = 0) + { + VkRect2D scissor = new VkRect2D(offsetX, offsetY, width, height); + vkCmdSetScissor(handle, 0, 1, ref scissor); + } //TODO:update generator to handle float array in this command - public void SetBlendConstants (float r, float g, float b, float a) + public void SetBlendConstants(float r, float g, float b, float a) { throw new NotImplementedException(); //vkCmdSetBlendConstants(handle, ); } - public void BindPipeline (Pipeline pipeline, VkPipelineBindPoint bindPoint) { - vkCmdBindPipeline (handle, bindPoint, pipeline.Handle); - } - public void Dispatch (uint groupCountX, uint groupCountY = 1, uint groupCountZ = 1) { - vkCmdDispatch (handle, groupCountX, groupCountY, groupCountZ); + public void BindPipeline(Pipeline pipeline, VkPipelineBindPoint bindPoint) + { + vkCmdBindPipeline(handle, bindPoint, pipeline.Handle); + } + public void Dispatch(uint groupCountX, uint groupCountY = 1, uint groupCountZ = 1) + { + vkCmdDispatch(handle, groupCountX, groupCountY, groupCountZ); } - public void BindPipeline (Pipeline pl) { - pl.Bind (this); + public void BindPipeline(Pipeline pl) + { + pl.Bind(this); } /// /// bind pipeline and descriptor set with default pipeline layout @@ -161,82 +169,181 @@ namespace vke { /// pipeline to bind /// descriptor set /// first set to bind - public void BindPipeline (Pipeline pl, DescriptorSet ds, uint firstset = 0) { - pl.Bind (this); - pl.BindDescriptorSet (this, ds, firstset); - } - public void BindDescriptorSet (PipelineLayout pipelineLayout, DescriptorSet descriptorSet, uint firstSet = 0) { - vkCmdBindDescriptorSets (handle, VkPipelineBindPoint.Graphics, pipelineLayout.handle, firstSet, 1, ref descriptorSet.handle, 0, IntPtr.Zero); - } - public void BindDescriptorSet (VkPipelineBindPoint bindPoint, PipelineLayout pipelineLayout, DescriptorSet descriptorSet, uint firstSet = 0) { - vkCmdBindDescriptorSets (handle, bindPoint, pipelineLayout.handle, firstSet, 1, ref descriptorSet.handle, 0, IntPtr.Zero); - } - public void BindDescriptorSets (VkPipelineBindPoint bindPoint, PipelineLayout pipelineLayout, uint firstSet,params DescriptorSet[] descriptorSets) { - vkCmdBindDescriptorSets (handle, bindPoint, pipelineLayout.handle, firstSet, (uint)descriptorSets.Length, descriptorSets.Pin (), 0, IntPtr.Zero); - descriptorSets.Unpin (); - } - public void BindVertexBuffer (Buffer vertices, uint binding = 0, ulong offset = 0) { - vkCmdBindVertexBuffers (handle, binding, 1, ref vertices.handle, ref offset); - } - public void BindIndexBuffer (Buffer indices, VkIndexType indexType = VkIndexType.Uint32, ulong offset = 0) { - vkCmdBindIndexBuffer (handle, indices.handle, offset, indexType); - } - public void DrawIndexed (uint indexCount, uint instanceCount = 1, uint firstIndex = 0, int vertexOffset = 0, uint firstInstance = 0) { - vkCmdDrawIndexed (Handle, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); - } - public void Draw (uint vertexCount, uint instanceCount = 1, uint firstVertex = 0, uint firstInstance = 0) { - vkCmdDraw (Handle, vertexCount, instanceCount, firstVertex, firstInstance); - } - public void PushConstant (PipelineLayout pipelineLayout, VkShaderStageFlags stageFlags, Object data, uint offset = 0) { - vkCmdPushConstants (handle, pipelineLayout.handle, stageFlags, offset, (uint)Marshal.SizeOf (data), data.Pin ()); - data.Unpin (); - } - public void PushConstant (Pipeline pipeline, object obj, int rangeIndex = 0, uint offset = 0) { - PushConstant (pipeline.Layout, pipeline.Layout.PushConstantRanges[rangeIndex].stageFlags, obj, offset); - } - public void PushConstant (PipelineLayout pipelineLayout, VkShaderStageFlags stageFlags, uint size, Object data, uint offset = 0) { - vkCmdPushConstants (handle, pipelineLayout.handle, stageFlags, offset, size, data.Pin ()); - data.Unpin (); - } - public void SetMemoryBarrier (VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, - VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkDependencyFlags dependencyFlags = VkDependencyFlags.ByRegion) { + public void BindPipeline(Pipeline pl, DescriptorSet ds, uint firstset = 0) + { + pl.Bind(this); + pl.BindDescriptorSet(this, ds, firstset); + } + public void BindDescriptorSet(PipelineLayout pipelineLayout, DescriptorSet descriptorSet, uint firstSet = 0) + { + vkCmdBindDescriptorSets(handle, VkPipelineBindPoint.Graphics, pipelineLayout.handle, firstSet, 1, ref descriptorSet.handle, 0, IntPtr.Zero); + } + public void BindDescriptorSet(VkPipelineBindPoint bindPoint, PipelineLayout pipelineLayout, DescriptorSet descriptorSet, uint firstSet = 0) + { + vkCmdBindDescriptorSets(handle, bindPoint, pipelineLayout.handle, firstSet, 1, ref descriptorSet.handle, 0, IntPtr.Zero); + } + public void BindDescriptorSets(VkPipelineBindPoint bindPoint, PipelineLayout pipelineLayout, uint firstSet, params DescriptorSet[] descriptorSets) + { + vkCmdBindDescriptorSets(handle, bindPoint, pipelineLayout.handle, firstSet, (uint)descriptorSets.Length, descriptorSets.Pin(), 0, IntPtr.Zero); + descriptorSets.Unpin(); + } + public void BindVertexBuffer(Buffer vertices, uint binding = 0, ulong offset = 0) + { + vkCmdBindVertexBuffers(handle, binding, 1, ref vertices.handle, ref offset); + } + public void BindIndexBuffer(Buffer indices, VkIndexType indexType = VkIndexType.Uint32, ulong offset = 0) + { + vkCmdBindIndexBuffer(handle, indices.handle, offset, indexType); + } + public void DrawIndexed(uint indexCount, uint instanceCount = 1, uint firstIndex = 0, int vertexOffset = 0, uint firstInstance = 0) + { + vkCmdDrawIndexed(Handle, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); + } + public void Draw(uint vertexCount, uint instanceCount = 1, uint firstVertex = 0, uint firstInstance = 0) + { + vkCmdDraw(Handle, vertexCount, instanceCount, firstVertex, firstInstance); + } + public void PushConstant(PipelineLayout pipelineLayout, VkShaderStageFlags stageFlags, Object data, uint offset = 0) + { + vkCmdPushConstants(handle, pipelineLayout.handle, stageFlags, offset, (uint)Marshal.SizeOf(data), data.Pin()); + data.Unpin(); + } + public void PushConstant(Pipeline pipeline, object obj, int rangeIndex = 0, uint offset = 0) + { + PushConstant(pipeline.Layout, pipeline.Layout.PushConstantRanges[rangeIndex].stageFlags, obj, offset); + } + public void PushConstant(PipelineLayout pipelineLayout, VkShaderStageFlags stageFlags, uint size, Object data, uint offset = 0) + { + vkCmdPushConstants(handle, pipelineLayout.handle, stageFlags, offset, size, data.Pin()); + data.Unpin(); + } + public void SetMemoryBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, + VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkDependencyFlags dependencyFlags = VkDependencyFlags.ByRegion) + { VkMemoryBarrier memoryBarrier = default; memoryBarrier.srcAccessMask = srcAccessMask; memoryBarrier.dstAccessMask = dstAccessMask; - Vk.vkCmdPipelineBarrier (Handle, srcStageMask, dstStageMask, + Vk.vkCmdPipelineBarrier(Handle, srcStageMask, dstStageMask, dependencyFlags, 1, ref memoryBarrier, 0, IntPtr.Zero, 0, IntPtr.Zero); } - public void BeginRegion (string name, float r = 1f, float g = 0.1f, float b=0.1f, float a = 1f) { + 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 = default; - info.pMarkerName = name.Pin (); + info.pMarkerName = name.Pin(); info.color.X = r; info.color.Y = g; info.color.Z = b; info.color.W = a; - vkCmdDebugMarkerBeginEXT (Handle, ref info); - name.Unpin (); + vkCmdDebugMarkerBeginEXT(Handle, ref info); + name.Unpin(); } - public void InsertDebugMarker (string name, float r = 1f, float g = 0.1f, float b=0.1f, float a = 1f) { + 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 = default; - info.pMarkerName = name.Pin (); + info.pMarkerName = name.Pin(); info.color.X = r; info.color.Y = g; info.color.Z = b; info.color.W = a; - vkCmdDebugMarkerInsertEXT (Handle, ref info); - name.Unpin (); + vkCmdDebugMarkerInsertEXT(Handle, ref info); + name.Unpin(); } - public void EndRegion () { + public void EndRegion() + { if (Device.debugUtilsEnabled) - vkCmdDebugMarkerEndEXT (Handle); + vkCmdDebugMarkerEndEXT(Handle); } - public void Free () { - pool.FreeCommandBuffers (this); - } - } + public void Free() + { + pool.FreeCommandBuffers(this); + } + public void SetCullMode(VkCullModeFlags cullMode) + { + Vk.vkCmdSetCullMode(Handle, cullMode); + } + public void SetFrontFace(VkFrontFace frontFace) + { + Vk.vkCmdSetFrontFace(Handle, frontFace); + } + public void SetDepthTestEnable(VkBool32 enable) + { + Vk.vkCmdSetDepthTestEnable(Handle, enable); + } + public void SetPrimitiveTopology(VkPrimitiveTopology topology) + { + Vk.vkCmdSetPrimitiveTopology(Handle, topology); + } + public void SetPrimitiveRestartEnable(VkBool32 enable) + { + Vk.vkCmdSetPrimitiveRestartEnable(Handle, enable); + } + public void SetPolygonModeEXT(VkPolygonMode mode) + { + Vk.vkCmdSetPolygonModeEXT(Handle, mode); + } + public void SetStencilTestEnable(VkBool32 enable) + { + Vk.vkCmdSetStencilTestEnable(Handle, enable); + } + public void SetRasterizerDiscardEnable(VkBool32 enable) + { + Vk.vkCmdSetRasterizerDiscardEnable(Handle, enable); + } + public void SetDepthWriteEnable(VkBool32 enable) + { + Vk.vkCmdSetDepthWriteEnable(Handle, enable); + } + public void SetDepthBiasEnable(VkBool32 enable) + { + Vk.vkCmdSetDepthBiasEnable(Handle, enable); + } + public void SetRasterizationSamplesEXT(VkSampleCountFlags count) + { + Vk.vkCmdSetRasterizationSamplesEXT(Handle, count); + } + public void SetSampleMaskEXT(VkSampleCountFlags count, uint mask = 0xFF) + { + Vk.vkCmdSetSampleMaskEXT(Handle, count, mask); + } + public void SetAlphaToCoverageEnableEXT(VkBool32 enable) + { + Vk.vkCmdSetAlphaToCoverageEnableEXT(Handle, enable); + } + public void SetColorBlendEnableEXT(uint firstAttachment, params VkBool32[] enable) + { + Vk.vkCmdSetColorBlendEnableEXT(Handle, firstAttachment, (uint)enable.Length, enable.Pin()); + enable.Unpin(); + } + public void SetColorWriteMaskEXT(uint firstAttachment, params uint[] flags) + { + Vk.vkCmdSetColorWriteMaskEXT(Handle, firstAttachment, (uint)flags.Length, flags.Pin()); + flags.Unpin(); + } + public void SetColorWriteMaskEXT(uint firstAttachment, params VkColorComponentFlags[] flags) + { + Vk.vkCmdSetColorWriteMaskEXT(Handle, firstAttachment, (uint)flags.Length, flags.Pin()); + flags.Unpin(); + } + public void SetViewport(params VkViewport[] viewports) + { + Vk.vkCmdSetViewportWithCount(Handle, (uint)viewports.Length, viewports.Pin()); + viewports.Unpin(); + } + public void SetScissor(params VkRect2D[] scissors) + { + Vk.vkCmdSetScissorWithCount(Handle, (uint)scissors.Length, scissors.Pin()); + scissors.Unpin(); + } + + + + public void SetLineWidth(float width) { + Vk.vkCmdSetLineWidth(Handle, width); + } + } } diff --git a/vke/src/base/Device.cs b/vke/src/base/Device.cs index 2dee8bd..7ad6b37 100644 --- a/vke/src/base/Device.cs +++ b/vke/src/base/Device.cs @@ -81,6 +81,8 @@ namespace vke { deviceCreateInfo.enabledExtensionCount = (uint)deviceExtensions.Count; deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.Pin (); } + + deviceCreateInfo.pNext = pNext; CheckResult (vkCreateDevice (phy.Handle, ref deviceCreateInfo, IntPtr.Zero, out dev)); diff --git a/vke/src/base/QueryPool.cs b/vke/src/base/QueryPool.cs index 0a3dc06..788acb5 100644 --- a/vke/src/base/QueryPool.cs +++ b/vke/src/base/QueryPool.cs @@ -26,11 +26,17 @@ namespace vke { public void Write (PrimaryCommandBuffer cmd, uint query, VkPipelineStageFlags stageFlags = VkPipelineStageFlags.BottomOfPipe) { vkCmdWriteTimestamp (cmd.Handle, stageFlags, handle, query); } - public void Start (PrimaryCommandBuffer cmd, VkPipelineStageFlags stageFlags = VkPipelineStageFlags.BottomOfPipe) { - vkCmdResetQueryPool(cmd.Handle, handle, 0, 2); - vkCmdWriteTimestamp (cmd.Handle, stageFlags, handle, 0); + public void Reset(PrimaryCommandBuffer cmd) + { + Vk.vkCmdResetQueryPool(cmd.Handle, handle, 0u, 2u); + } + + public void Start(PrimaryCommandBuffer cmd, VkPipelineStageFlags stageFlags = VkPipelineStageFlags.BottomOfPipe) + { + Vk.vkCmdWriteTimestamp(cmd.Handle, stageFlags, handle, 0u); } - public void End (PrimaryCommandBuffer cmd, VkPipelineStageFlags stageFlags = VkPipelineStageFlags.BottomOfPipe) { + + public void End (PrimaryCommandBuffer cmd, VkPipelineStageFlags stageFlags = VkPipelineStageFlags.BottomOfPipe) { vkCmdWriteTimestamp (cmd.Handle, stageFlags, handle, 1); } public float ElapsedMiliseconds { @@ -40,52 +46,56 @@ namespace vke { } } } - public class PipelineStatisticsQueryPool : QueryPool { + + public class PipelineStatisticsQueryPool : QueryPool + { public readonly VkQueryPipelineStatisticFlags[] RequestedStats; #region CTORS - public PipelineStatisticsQueryPool (Device device, VkQueryPipelineStatisticFlags statisticFlags, uint count = 1) - : base (device, VkQueryType.PipelineStatistics, statisticFlags, count) + public PipelineStatisticsQueryPool(Device device, VkQueryPipelineStatisticFlags statisticFlags, uint count = 1) + : base(device, VkQueryType.PipelineStatistics, statisticFlags, count) { - List requests = new List (); - - if (statisticFlags.HasFlag (VkQueryPipelineStatisticFlags.InputAssemblyVertices)) - requests.Add (VkQueryPipelineStatisticFlags.InputAssemblyVertices); - if (statisticFlags.HasFlag (VkQueryPipelineStatisticFlags.InputAssemblyPrimitives)) - requests.Add (VkQueryPipelineStatisticFlags.InputAssemblyPrimitives); - if (statisticFlags.HasFlag (VkQueryPipelineStatisticFlags.VertexShaderInvocations)) - requests.Add (VkQueryPipelineStatisticFlags.VertexShaderInvocations); - if (statisticFlags.HasFlag (VkQueryPipelineStatisticFlags.GeometryShaderInvocations)) - requests.Add (VkQueryPipelineStatisticFlags.GeometryShaderInvocations); - if (statisticFlags.HasFlag (VkQueryPipelineStatisticFlags.GeometryShaderPrimitives)) - requests.Add (VkQueryPipelineStatisticFlags.GeometryShaderPrimitives); - if (statisticFlags.HasFlag (VkQueryPipelineStatisticFlags.ClippingInvocations)) - requests.Add (VkQueryPipelineStatisticFlags.ClippingInvocations); - if (statisticFlags.HasFlag (VkQueryPipelineStatisticFlags.ClippingPrimitives)) - requests.Add (VkQueryPipelineStatisticFlags.ClippingPrimitives); - if (statisticFlags.HasFlag (VkQueryPipelineStatisticFlags.FragmentShaderInvocations)) - requests.Add (VkQueryPipelineStatisticFlags.FragmentShaderInvocations); - if (statisticFlags.HasFlag (VkQueryPipelineStatisticFlags.TessellationControlShaderPatches)) - requests.Add (VkQueryPipelineStatisticFlags.TessellationControlShaderPatches); - if (statisticFlags.HasFlag (VkQueryPipelineStatisticFlags.TessellationEvaluationShaderInvocations)) - requests.Add (VkQueryPipelineStatisticFlags.TessellationEvaluationShaderInvocations); - if (statisticFlags.HasFlag (VkQueryPipelineStatisticFlags.ComputeShaderInvocations)) - requests.Add (VkQueryPipelineStatisticFlags.ComputeShaderInvocations); - - RequestedStats = requests.ToArray (); + List requests = new List(); + + if (statisticFlags.HasFlag(VkQueryPipelineStatisticFlags.InputAssemblyVertices)) + requests.Add(VkQueryPipelineStatisticFlags.InputAssemblyVertices); + if (statisticFlags.HasFlag(VkQueryPipelineStatisticFlags.InputAssemblyPrimitives)) + requests.Add(VkQueryPipelineStatisticFlags.InputAssemblyPrimitives); + if (statisticFlags.HasFlag(VkQueryPipelineStatisticFlags.VertexShaderInvocations)) + requests.Add(VkQueryPipelineStatisticFlags.VertexShaderInvocations); + if (statisticFlags.HasFlag(VkQueryPipelineStatisticFlags.GeometryShaderInvocations)) + requests.Add(VkQueryPipelineStatisticFlags.GeometryShaderInvocations); + if (statisticFlags.HasFlag(VkQueryPipelineStatisticFlags.GeometryShaderPrimitives)) + requests.Add(VkQueryPipelineStatisticFlags.GeometryShaderPrimitives); + if (statisticFlags.HasFlag(VkQueryPipelineStatisticFlags.ClippingInvocations)) + requests.Add(VkQueryPipelineStatisticFlags.ClippingInvocations); + if (statisticFlags.HasFlag(VkQueryPipelineStatisticFlags.ClippingPrimitives)) + requests.Add(VkQueryPipelineStatisticFlags.ClippingPrimitives); + if (statisticFlags.HasFlag(VkQueryPipelineStatisticFlags.FragmentShaderInvocations)) + requests.Add(VkQueryPipelineStatisticFlags.FragmentShaderInvocations); + if (statisticFlags.HasFlag(VkQueryPipelineStatisticFlags.TessellationControlShaderPatches)) + requests.Add(VkQueryPipelineStatisticFlags.TessellationControlShaderPatches); + if (statisticFlags.HasFlag(VkQueryPipelineStatisticFlags.TessellationEvaluationShaderInvocations)) + requests.Add(VkQueryPipelineStatisticFlags.TessellationEvaluationShaderInvocations); + if (statisticFlags.HasFlag(VkQueryPipelineStatisticFlags.ComputeShaderInvocations)) + requests.Add(VkQueryPipelineStatisticFlags.ComputeShaderInvocations); + + RequestedStats = requests.ToArray(); resultLength = (uint)requests.Count; - Activate (); + Activate(); } #endregion - public void Begin (PrimaryCommandBuffer cmd, uint query = 0) { - vkCmdBeginQuery (cmd.Handle, handle, query, VkQueryControlFlags.Precise); + public void Begin(PrimaryCommandBuffer cmd, uint query = 0) + { + vkCmdBeginQuery(cmd.Handle, handle, query, VkQueryControlFlags.Precise); } - public void End (PrimaryCommandBuffer cmd, uint query = 0) { - vkCmdEndQuery (cmd.Handle, handle, query); + public void End(PrimaryCommandBuffer cmd, uint query = 0) + { + vkCmdEndQuery(cmd.Handle, handle, query); } } diff --git a/vke/src/base/ShaderObject.cs b/vke/src/base/ShaderObject.cs index 3cae8ce..d38785d 100644 --- a/vke/src/base/ShaderObject.cs +++ b/vke/src/base/ShaderObject.cs @@ -11,124 +11,229 @@ using static Vulkan.Utils; using System.IO; using System.Runtime.InteropServices; -namespace vke { +namespace vke +{ /// /// Collection of FrameBuffers, useful to handle multiple framebuffers for a swapchain. /// - public class ShaderObjects : Collection, IDisposable + public class LinkedShaderObjects : Activable { - //public Framebuffer this[int index] => Items[index]; + List shaders; + internal IEnumerable shaderHandles = null; + internal IEnumerable shaderStages = null; - public void Dispose() + public IEnumerable ShaderHandles => shaderHandles; + public IEnumerable Stages => shaderStages; + public uint Count => (uint)shaderHandles?.Count(); + //public IEnumerable Layouts => shaders?.Count > 0 ? shaders[0].DescriptorSetLayouts.ToArray() : null; + + #region CTORS + public LinkedShaderObjects(params ShaderObject[] shaderObjects) : base(shaderObjects[0].Dev) + { + shaders = new List(shaderObjects); + } + #endregion + + public override void Activate() { - foreach (ShaderObject fb in Items) - fb.Dispose(); - ClearItems(); + if (state != ActivableState.Activated) + { + List infos = new List(); + foreach (ShaderObject lso in shaders) + { + VkShaderCreateInfoEXT info = lso.getCreateInfo(); + info.flags |= VkShaderCreateFlagsEXT.LinkStageEXT; + infos.Add(info); + } + + //shaderHandles = new VkShaderEXT[shaders.Count]; + + IntPtr handles = Marshal.AllocHGlobal (Marshal.SizeOf () * (int)shaders.Count); + + //CheckResult(vkCreateShadersEXT(Dev.Handle, (uint)infos.Count, infos.PinPointer(), IntPtr.Zero, shaderHandles.Pin())); + VkResult res = vkCreateShadersEXT(Dev.Handle, (uint)infos.Count, infos.PinPointer(), IntPtr.Zero, handles); + //shaderHandles.Unpin(); + + VkShaderEXT[] hnds = new VkShaderEXT [shaders.Count]; + + for (int i = 0; i < shaders.Count; i++) + hnds [i] = (ulong) Marshal.ReadIntPtr (handles + i * Marshal.SizeOf ()); + + Marshal.FreeHGlobal (handles); + + + shaderHandles = hnds; + shaderStages = infos.Select(i => (uint)i.stage).ToArray(); + + foreach (VkShaderCreateInfoEXT lsoci in infos) + { + lsoci.pCode.Unpin(); + lsoci.Dispose(); + } + } + + base.Activate(); + } + protected override VkDebugUtilsObjectNameInfoEXT DebugUtilsInfo => new VkDebugUtilsObjectNameInfoEXT (VkObjectType.ShaderEXT, (ulong)shaderHandles?.FirstOrDefault().Handle); + + #region IDisposable Support + protected override void Dispose(bool disposing) + { + if (state == ActivableState.Activated) + { + if (disposing) + { + foreach (ShaderObject lso in shaders) + { + foreach (DescriptorSetLayout dsl in lso.DescriptorSetLayouts) + dsl.Dispose(); + } + } + else + System.Diagnostics.Debug.WriteLine("VKE Activable ShaderObject disposed by finalizer"); + + foreach (VkShaderEXT hnd in shaderHandles) + vkDestroyShaderEXT(Dev.Handle, hnd, IntPtr.Zero); + + shaderHandles = null; + shaderStages = null; + } + else if (disposing) + System.Diagnostics.Debug.WriteLine("Calling dispose on unactive ShaderObject"); + + base.Dispose(disposing); } + #endregion } - public sealed class ShaderObject : Activable { - internal VkShaderEXT handle; + + public sealed class ShaderObject : Activable + { + internal VkShaderEXT handle; public VkShaderEXT Handle => handle; public string FileName; + public string EntryPoint = "main"; public VkShaderStageFlags Stage; public VkShaderStageFlags NextStage; public VkShaderCreateFlagsEXT Flags = VkShaderCreateFlagsEXT.LinkStageEXT; - public List DescriptorSetLayouts = new List (); - public List PushConstantRanges = new List (); + public List DescriptorSetLayouts = new List(); + public List PushConstantRanges = new List(); protected override VkDebugUtilsObjectNameInfoEXT DebugUtilsInfo - => new VkDebugUtilsObjectNameInfoEXT (VkObjectType.ShaderEXT, handle.Handle); + => new VkDebugUtilsObjectNameInfoEXT(VkObjectType.ShaderEXT, handle.Handle); #region CTORS - public ShaderObject (Device device, VkShaderStageFlags stage, VkShaderStageFlags nextStage) : base (device) { + public ShaderObject(Device device, VkShaderStageFlags stage, VkShaderStageFlags nextStage = 0) : base(device) + { Stage = stage; NextStage = nextStage; } - public ShaderObject (Device device, VkShaderStageFlags stage, VkShaderStageFlags nextStage, VkPushConstantRange pushConstantRange, params DescriptorSetLayout[] descriptorSetLayouts) - : this (device, stage, nextStage, descriptorSetLayouts) { - PushConstantRanges.Add (pushConstantRange); + public ShaderObject(Device device, VkShaderStageFlags stage, VkShaderStageFlags nextStage, VkPushConstantRange pushConstantRange, params DescriptorSetLayout[] descriptorSetLayouts) + : this(device, stage, nextStage, descriptorSetLayouts) + { + PushConstantRanges.Add(pushConstantRange); } - public ShaderObject (Device device, VkShaderStageFlags stage, VkShaderStageFlags nextStage, VkPushConstantRange[] pushConstantRanges, params DescriptorSetLayout[] descriptorSetLayouts) - : this (device, stage, nextStage, descriptorSetLayouts) { + public ShaderObject(Device device, VkShaderStageFlags stage, VkShaderStageFlags nextStage, VkPushConstantRange[] pushConstantRanges, params DescriptorSetLayout[] descriptorSetLayouts) + : this(device, stage, nextStage, descriptorSetLayouts) + { foreach (VkPushConstantRange pcr in pushConstantRanges) - PushConstantRanges.Add (pcr); + PushConstantRanges.Add(pcr); } - public ShaderObject (Device device, VkShaderStageFlags stage, VkShaderStageFlags nextStage, params DescriptorSetLayout[] descriptorSetLayouts) - :this (device, stage, nextStage) { + public ShaderObject(Device device, VkShaderStageFlags stage, VkShaderStageFlags nextStage, params DescriptorSetLayout[] descriptorSetLayouts) + : this(device, stage, nextStage) + { if (descriptorSetLayouts.Length > 0) - DescriptorSetLayouts.AddRange (descriptorSetLayouts); - } + DescriptorSetLayouts.AddRange(descriptorSetLayouts); + } #endregion - public void AddPushConstants (params VkPushConstantRange[] pushConstantRanges) { + public void AddPushConstants(params VkPushConstantRange[] pushConstantRanges) + { foreach (VkPushConstantRange pcr in pushConstantRanges) - PushConstantRanges.Add (pcr); + PushConstantRanges.Add(pcr); } - uint[] getCode(out UIntPtr shaderSize) { - using (Stream stream = Helpers.GetStreamFromPath (FileName)) { - using (BinaryReader br = new BinaryReader (stream)) { - byte[] shaderCode = br.ReadBytes ((int)stream.Length); + uint[] getCode(out UIntPtr shaderSize) + { + using (Stream stream = Helpers.GetStreamFromPath(FileName)) + { + using (BinaryReader br = new BinaryReader(stream)) + { + byte[] shaderCode = br.ReadBytes((int)stream.Length); shaderSize = (UIntPtr)shaderCode.Length; - ReadOnlySpan tmp = MemoryMarshal.Cast (shaderCode); + ReadOnlySpan tmp = MemoryMarshal.Cast(shaderCode); return tmp.ToArray(); } } } - public override void Activate () { - if (state != ActivableState.Activated) { - foreach (DescriptorSetLayout dsl in DescriptorSetLayouts) - dsl.Activate (); + internal VkShaderCreateInfoEXT getCreateInfo() + { + foreach (DescriptorSetLayout dsl in DescriptorSetLayouts) + dsl.Activate(); - - VkShaderCreateInfoEXT info = default; - info.flags = VkShaderCreateFlagsEXT.LinkStageEXT; - info.stage = VkShaderStageFlags.Vertex; - info.stage = VkShaderStageFlags.Fragment; - info.codeType = VkShaderCodeTypeEXT.SpirvEXT; + VkShaderCreateInfoEXT info = VkShaderCreateInfoEXT.New; + info.flags = Flags; + info.stage = Stage; + info.nextStage = NextStage; + info.codeType = VkShaderCodeTypeEXT.SpirvEXT; + info.pName = EntryPoint; - uint[] code = getCode(out UIntPtr codeSize); - info.codeSize = codeSize; - info.pCode = code.PinPointer(); + uint[] code = getCode(out UIntPtr codeSize); + info.codeSize = codeSize; + info.pCode = code.PinPointer(); - VkDescriptorSetLayout[] dsls = DescriptorSetLayouts.Select (dsl => dsl.handle).ToArray (); + VkDescriptorSetLayout[] dsls = DescriptorSetLayouts.Select(dsl => dsl.handle).ToArray(); - if (dsls.Length > 0) { - info.pSetLayouts = dsls; - } - if (PushConstantRanges.Count > 0) { - info.pPushConstantRanges = PushConstantRanges; - } - CheckResult (vkCreateShadersEXT (Dev.Handle, 1, ref info, IntPtr.Zero, out handle)); + if (dsls.Length > 0) + { + info.pSetLayouts = dsls; + } + if (PushConstantRanges.Count > 0) + { + info.pPushConstantRanges = PushConstantRanges; + } + return info; + } - code.Unpin(); + public override void Activate() + { + if (state != ActivableState.Activated) + { + VkShaderCreateInfoEXT info = getCreateInfo(); + CheckResult(vkCreateShadersEXT(Dev.Handle, 1, ref info, IntPtr.Zero, out handle)); + info.pCode.Unpin(); info.Dispose(); } - base.Activate (); + base.Activate(); } - public override string ToString () { - return string.Format ($"{base.ToString ()}[0x{handle.Handle.ToString("x")}]"); + public override string ToString() + { + return string.Format($"{base.ToString()}[0x{handle.Handle.ToString("x")}]"); } #region IDisposable Support - protected override void Dispose (bool disposing) { - if (state == ActivableState.Activated) { - if (disposing) { + protected override void Dispose(bool disposing) + { + if (state == ActivableState.Activated) + { + if (disposing) + { foreach (DescriptorSetLayout dsl in DescriptorSetLayouts) - dsl.Dispose (); - } else - System.Diagnostics.Debug.WriteLine ("VKE Activable ShaderObject disposed by finalizer"); + dsl.Dispose(); + } + else + System.Diagnostics.Debug.WriteLine("VKE Activable ShaderObject disposed by finalizer"); - vkDestroyShaderEXT (Dev.Handle, handle, IntPtr.Zero); - }else if (disposing) - System.Diagnostics.Debug.WriteLine ("Calling dispose on unactive ShaderObject"); + vkDestroyShaderEXT(Dev.Handle, handle, IntPtr.Zero); + } + else if (disposing) + System.Diagnostics.Debug.WriteLine("Calling dispose on unactive ShaderObject"); - base.Dispose (disposing); + base.Dispose(disposing); } #endregion } diff --git a/vke/src/base/SwapChain.cs b/vke/src/base/SwapChain.cs index 08b6d88..82684ec 100644 --- a/vke/src/base/SwapChain.cs +++ b/vke/src/base/SwapChain.cs @@ -33,7 +33,7 @@ namespace vke { PresentQueue presentQueue; public Queue semaphoresQueue = new Queue(); - public VkSemaphore nextImgAvail; + VkSemaphore nextImgAvail; public Image[] images; protected override VkDebugUtilsObjectNameInfoEXT DebugUtilsInfo @@ -166,6 +166,14 @@ namespace vke { CheckResult (res); return (int)currentImageIndex; } + /// + /// Return semaphore used for last call to vkAcquireNextImageKHR and requeue it for later use. May be call only once. + /// + /// semaphore used for last call to vkAcquireNextImageKHR + public VkSemaphore ConsumeNextImgSemaphore() { + semaphoresQueue.Enqueue(nextImgAvail); + return nextImgAvail; + } void _destroy () { for (int i = 0; i < ImageCount; i++) { diff --git a/vke/vke.csproj b/vke/vke.csproj index 5ff69a0..c21ca1b 100644 --- a/vke/vke.csproj +++ b/vke/vke.csproj @@ -48,7 +48,7 @@ - +