namespace MeshShader {
class Program : SampleBase {
-#if DEBUG
- /*public override string[] EnabledLayers =>
- new string[] {
- "VK_LAYER_KHRONOS_validation"
- };*/
-
-#endif
public override string[] EnabledInstanceExtensions => new string[] {
Ext.I.VK_KHR_get_physical_device_properties2,
Ext.I.VK_EXT_debug_utils,
Ext.D.VK_KHR_swapchain,
Ext.D.VK_KHR_spirv_1_4,
Ext.D.VK_EXT_mesh_shader
- //"VK_NV_mesh_shader"
};
- protected override void configureEnabledFeatures(VkPhysicalDeviceFeatures available_features, ref VkPhysicalDeviceFeatures enabled_features)
- {
- base.configureEnabledFeatures(available_features, ref enabled_features);
-
-
- }
- vke.DebugUtils.Messenger dbgmsg;
protected override void selectPhysicalDevice () {
PhysicalDeviceCollection phys = instance.GetAvailablePhysicalDevice ();
phy = instance.GetAvailablePhysicalDevice ().FirstOrDefault (p => p.Properties.deviceType == VkPhysicalDeviceType.DiscreteGpu && p.HasSwapChainSupport);
Console.WriteLine($"Using gpu: {phy.Properties.deviceName}");
- dbgmsg = new vke.DebugUtils.Messenger (instance,
- VkDebugUtilsMessageTypeFlagsEXT.PerformanceEXT | VkDebugUtilsMessageTypeFlagsEXT.ValidationEXT | VkDebugUtilsMessageTypeFlagsEXT.GeneralEXT,
- VkDebugUtilsMessageSeverityFlagsEXT.InfoEXT |
- VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT |
- VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT |
- VkDebugUtilsMessageSeverityFlagsEXT.VerboseEXT);
-
VkPhysicalDeviceFeatures2 phyFeat2 = VkPhysicalDeviceFeatures2.New;
VkPhysicalDeviceMeshShaderFeaturesEXT meshFeat = VkPhysicalDeviceMeshShaderFeaturesEXT.New;
float rotX, rotY, zoom = 1f;
HostBuffer<Matrix4x4> uboMVPmatrix; //a host mappable buffer for mvp matrice.
-
DescriptorPool descriptorPool;
DescriptorSet descriptorSet;//descriptor set for the mvp matrice.
protected override void initVulkan () {
base.initVulkan ();
-
+ uboMVPmatrix = new HostBuffer<Matrix4x4> (dev, VkBufferUsageFlags.UniformBuffer, 1, true);
descriptorPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer));
using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false)) {
- //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.Layout = new PipelineLayout (dev);
- //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.Layout = new PipelineLayout (dev,
+ new DescriptorSetLayout (dev, new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.MeshEXT, VkDescriptorType.UniformBuffer)));
cfg.RenderPass = new RenderPass (dev, swapChain.ColorFormat, cfg.Samples);
- //configuration of vertex bindings and attributes
- //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.MeshEXT, "#shaders.main.mesh.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);
+ descriptorSet = descriptorPool.Allocate (pipeline.Layout.DescriptorSetLayouts[0]);
+ DescriptorSetWrites uboUpdate = new DescriptorSetWrites (descriptorSet, pipeline.Layout.DescriptorSetLayouts[0]);
+ 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);
//view update override, see base method for more informations.
public override void UpdateView () {
- /*uboMVPmatrix.AsSpan()[0] =
+ 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 ();*/
+ base.UpdateView ();
}
protected override void onMouseMove (double xPos, double yPos) {
double diffX = lastMouseX - xPos;
cmds[i].SetViewport (swapChain.Width, swapChain.Height);
cmds[i].SetScissor (swapChain.Width, swapChain.Height);
- //cmds[i].BindDescriptorSet (pipeline.Layout, descriptorSet);
+ cmds[i].BindDescriptorSet (pipeline.Layout, descriptorSet);
cmds[i].BindPipeline (pipeline);
//the descriptor pool
descriptorPool.Dispose ();
//resources have to be explicityly disposed.
- //uboMVPmatrix.Dispose ();
- dbgmsg?.Dispose ();
+ uboMVPmatrix.Dispose ();
}
}
-
-#extension GL_EXT_mesh_shader : require
+#version 450
+
+#extension GL_NV_mesh_shader : require
layout(local_size_x = 1) in;
layout(triangles, max_vertices = 3, max_primitives = 1) out;
{
vec4 color;
} v_out[]; // [max_vertices]
-
+
+layout (binding = 0) uniform UBO
+{
+ mat4 mvp;
+};
float scale = 0.95;
-const vec3 vertices[3] = {vec3(-1,-1,0), vec3(0,1,0), vec3(1,-1,0)};
+const vec4 vertices[3] =
+{
+ vec4(-1,-1,0,1),
+ vec4(0,1,0,1),
+ vec4(1,-1,0,1)
+};
const vec3 colors[3] = {vec3(1.0,0.0,0.0), vec3(0.0,1.0,0.0), vec3(0.0,0.0,1.0)};
void main()
{
- vec4 pos = vec4(vertices[0] * scale, 1.0);
- // GL->VK conventions...
- pos.y = -pos.y; pos.z = (pos.z + pos.w) / 2.0;
- gl_MeshVerticesEXT[0].gl_Position = pos;
-
- pos = vec4(vertices[1] * scale, 1.0);
- pos.y = -pos.y; pos.z = (pos.z + pos.w) / 2.0;
- gl_MeshVerticesEXT[1].gl_Position = pos;
-
- pos = vec4(vertices[2] * scale, 1.0);
- pos.y = -pos.y; pos.z = (pos.z + pos.w) / 2.0;
- gl_MeshVerticesEXT[2].gl_Position = pos;
-
+ gl_MeshVerticesNV[0].gl_Position = mvp * vertices[0];
+ gl_MeshVerticesNV[1].gl_Position = mvp * vertices[1];
+ gl_MeshVerticesNV[2].gl_Position = mvp * vertices[2];
v_out[0].color = vec4(colors[0], 1.0);
v_out[1].color = vec4(colors[1], 1.0);
v_out[2].color = vec4(colors[2], 1.0);
+ gl_PrimitiveIndicesNV[0] = 0;
+ gl_PrimitiveIndicesNV[1] = 1;
+ gl_PrimitiveIndicesNV[2] = 2;
- gl_PrimitiveIndicesEXT[0] = 0;
- gl_PrimitiveIndicesEXT[1] = 1;
- gl_PrimitiveIndicesEXT[2] = 2;
-
- gl_PrimitiveCountEXT = 1;
-
- SetMeshOutputsEXT(3,1);
+ gl_PrimitiveCountNV = 1;
}
\ No newline at end of file