public DebugDrawPipeline(Device dev, DescriptorSetLayout dsLayout, VkFormat colorFormat, VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1) : base(new RenderPass(dev, colorFormat), "Debug draw pipeline") { GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.LineList, samples); cfg.rasterizationState.lineWidth = 1.0f; cfg.RenderPass = RenderPass; cfg.Layout = new PipelineLayout(dev, dsLayout); cfg.Layout.AddPushConstants( new VkPushConstantRange(VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf <Matrix4x4> () * 2) ); cfg.AddVertexBinding(0, 6 * sizeof(float)); cfg.SetVertexAttributes(0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat); cfg.blendAttachments[0] = new VkPipelineColorBlendAttachmentState(true); cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/debug.vert.spv"); cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/debug.frag.spv"); layout = cfg.Layout; init(cfg); Vertices = new HostBuffer(dev, VkBufferUsageFlags.VertexBuffer, vboLength); Vertices.Map(); }
public EnvironmentCube(string cubemapPath, DescriptorSet dsSkybox, PipelineLayout plLayout, Queue staggingQ, RenderPass renderPass, PipelineCache cache = null) : base(renderPass, cache, "EnvCube pipeline") { using (CommandPool cmdPool = new CommandPool(staggingQ.Dev, staggingQ.index)) { vboSkybox = new GPUBuffer <float> (staggingQ, cmdPool, VkBufferUsageFlags.VertexBuffer, box_vertices); cubemap = KTX.KTX.Load(staggingQ, cmdPool, cubemapPath, VkImageUsageFlags.Sampled, VkMemoryPropertyFlags.DeviceLocal, true); cubemap.CreateView(VkImageViewType.Cube, VkImageAspectFlags.Color, 6, 0, cubemap.CreateInfo.mipLevels); cubemap.CreateSampler(VkSamplerAddressMode.ClampToEdge); cubemap.SetName("skybox Texture"); cubemap.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, renderPass.Samples, false); cfg.RenderPass = renderPass; cfg.Layout = plLayout; cfg.AddVertexBinding(0, 3 * sizeof(float)); cfg.AddVertexAttributes(0, VkFormat.R32g32b32Sfloat); cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/skybox.vert.spv"); cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/skybox.frag.spv"); cfg.multisampleState.rasterizationSamples = Samples; layout = cfg.Layout; init(cfg); generateBRDFLUT(staggingQ, cmdPool); generateCubemaps(staggingQ, cmdPool); } }
void generateBRDFLUT(Queue staggingQ, CommandPool cmdPool) { const VkFormat format = VkFormat.R16g16Sfloat; const int dim = 512; lutBrdf = new Image(Dev, format, VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.Sampled, VkMemoryPropertyFlags.DeviceLocal, dim, dim); lutBrdf.SetName("lutBrdf"); lutBrdf.CreateView(); lutBrdf.CreateSampler(VkSamplerAddressMode.ClampToEdge); GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false); cfg.Layout = new PipelineLayout(Dev, new DescriptorSetLayout(Dev)); cfg.RenderPass = new RenderPass(Dev); cfg.RenderPass.AddAttachment(format, VkImageLayout.ShaderReadOnlyOptimal); cfg.RenderPass.ClearValues.Add(new VkClearValue { color = new VkClearColorValue(0, 0, 0) }); cfg.RenderPass.AddSubpass(new SubPass(VkImageLayout.ColorAttachmentOptimal)); cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/genbrdflut.vert.spv"); cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/genbrdflut.frag.spv"); using (GraphicPipeline pl = new GraphicPipeline(cfg)) { using (Framebuffer fb = new Framebuffer(cfg.RenderPass, dim, dim, lutBrdf)) { CommandBuffer cmd = cmdPool.AllocateCommandBuffer(); cmd.Start(VkCommandBufferUsageFlags.OneTimeSubmit); pl.RenderPass.Begin(cmd, fb); cmd.SetViewport(dim, dim); cmd.SetScissor(dim, dim); pl.Bind(cmd); cmd.Draw(3, 1, 0, 0); pl.RenderPass.End(cmd); cmd.End(); staggingQ.Submit(cmd); staggingQ.WaitIdle(); cmd.Free(); } } lutBrdf.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; }
public static GraphicPipelineConfig CreateDefault(VkPrimitiveTopology topology = VkPrimitiveTopology.TriangleList, VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1, bool depthTestEnabled = true) { GraphicPipelineConfig cfg = new GraphicPipelineConfig(); cfg.inputAssemblyState.topology = topology; cfg.multisampleState.rasterizationSamples = samples; cfg.rasterizationState.polygonMode = VkPolygonMode.Fill; cfg.rasterizationState.cullMode = (uint)VkCullModeFlags.None; cfg.rasterizationState.frontFace = VkFrontFace.CounterClockwise; cfg.rasterizationState.depthClampEnable = False; cfg.rasterizationState.rasterizerDiscardEnable = False; cfg.rasterizationState.depthBiasEnable = False; cfg.rasterizationState.lineWidth = 1.0f; cfg.viewportState.viewportCount = 1; cfg.viewportState.scissorCount = 1; cfg.blendAttachments.Add(new VkPipelineColorBlendAttachmentState(false)); cfg.dynamicStates.Add(VkDynamicState.Viewport); cfg.dynamicStates.Add(VkDynamicState.Scissor); if (depthTestEnabled) { cfg.depthStencilState.depthTestEnable = True; cfg.depthStencilState.depthWriteEnable = True; cfg.depthStencilState.depthCompareOp = VkCompareOp.LessOrEqual; cfg.depthStencilState.depthBoundsTestEnable = False; cfg.depthStencilState.back.failOp = VkStencilOp.Keep; cfg.depthStencilState.back.passOp = VkStencilOp.Keep; cfg.depthStencilState.back.compareOp = VkCompareOp.Always; cfg.depthStencilState.stencilTestEnable = False; cfg.depthStencilState.front = cfg.depthStencilState.back; } return(cfg); }
public Image generateCubeMap(Queue staggingQ, CommandPool cmdPool, CBTarget target) { const float deltaPhi = (2.0f * (float)Math.PI) / 180.0f; const float deltaTheta = (0.5f * (float)Math.PI) / 64.0f; VkFormat format = VkFormat.R32g32b32a32Sfloat; uint dim = 64; if (target == CBTarget.PREFILTEREDENV) { format = VkFormat.R16g16b16a16Sfloat; dim = 512; } uint numMips = (uint)Math.Floor(Math.Log(dim, 2)) + 1; Image imgFbOffscreen = new Image(Dev, format, VkImageUsageFlags.TransferSrc | VkImageUsageFlags.ColorAttachment, VkMemoryPropertyFlags.DeviceLocal, dim, dim); imgFbOffscreen.SetName("offscreenfb"); imgFbOffscreen.CreateView(); Image cmap = new Image(Dev, format, VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled, VkMemoryPropertyFlags.DeviceLocal, dim, dim, VkImageType.Image2D, VkSampleCountFlags.SampleCount1, VkImageTiling.Optimal, numMips, 6, 1, VkImageCreateFlags.CubeCompatible); if (target == CBTarget.PREFILTEREDENV) { cmap.SetName("prefilterenvmap"); } else { cmap.SetName("irradianceCube"); } cmap.CreateView(VkImageViewType.Cube, VkImageAspectFlags.Color, 6, 0, numMips); cmap.CreateSampler(VkSamplerAddressMode.ClampToEdge); DescriptorPool dsPool = new DescriptorPool(Dev, 2, new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler)); DescriptorSetLayout dsLayout = new DescriptorSetLayout(Dev, new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)); GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false); cfg.Layout = new PipelineLayout(Dev, dsLayout); cfg.Layout.AddPushConstants( new VkPushConstantRange(VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, (uint)Marshal.SizeOf <Matrix4x4> () + 8)); cfg.RenderPass = new RenderPass(Dev); cfg.RenderPass.AddAttachment(format, VkImageLayout.ColorAttachmentOptimal); cfg.RenderPass.ClearValues.Add(new VkClearValue { color = new VkClearColorValue(0, 0, 0) }); cfg.RenderPass.AddSubpass(new SubPass(VkImageLayout.ColorAttachmentOptimal)); cfg.AddVertexBinding(0, 3 * sizeof(float)); cfg.AddVertexAttributes(0, VkFormat.R32g32b32Sfloat); cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/filtercube.vert.spv"); if (target == CBTarget.PREFILTEREDENV) { cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/prefilterenvmap.frag.spv"); } else { cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/irradiancecube.frag.spv"); } Matrix4x4[] matrices = { // POSITIVE_X Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Utils.DegreesToRadians(90)), // NEGATIVE_X Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Utils.DegreesToRadians(-90)), // POSITIVE_Y Matrix4x4.CreateRotationX(Utils.DegreesToRadians(-90)), // NEGATIVE_Y Matrix4x4.CreateRotationX(Utils.DegreesToRadians(90)), // POSITIVE_Z Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)), // NEGATIVE_Z Matrix4x4.CreateRotationZ(Utils.DegreesToRadians(180)) }; VkImageSubresourceRange subRes = new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, numMips, 0, 6); using (GraphicPipeline pl = new GraphicPipeline(cfg)) { DescriptorSet dset = dsPool.Allocate(dsLayout); DescriptorSetWrites dsUpdate = new DescriptorSetWrites(dsLayout); dsUpdate.Write(Dev, dset, cubemap.Descriptor); Dev.WaitIdle(); using (Framebuffer fb = new Framebuffer(pl.RenderPass, dim, dim, imgFbOffscreen)) { CommandBuffer cmd = cmdPool.AllocateCommandBuffer(); cmd.Start(VkCommandBufferUsageFlags.OneTimeSubmit); cmap.SetLayout(cmd, VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal, subRes); float roughness = 0; cmd.SetScissor(dim, dim); cmd.SetViewport((float)(dim), (float)dim); for (int m = 0; m < numMips; m++) { roughness = (float)m / ((float)numMips - 1f); for (int f = 0; f < 6; f++) { pl.RenderPass.Begin(cmd, fb); pl.Bind(cmd); float viewPortSize = (float)Math.Pow(0.5, m) * dim; cmd.SetViewport(viewPortSize, viewPortSize); cmd.PushConstant(pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, matrices[f] * Matrix4x4.CreatePerspectiveFieldOfView(Utils.DegreesToRadians(90), 1f, 0.1f, 512f)); if (target == CBTarget.IRRADIANCE) { cmd.PushConstant(pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaPhi, (uint)Marshal.SizeOf <Matrix4x4> ()); cmd.PushConstant(pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaTheta, (uint)Marshal.SizeOf <Matrix4x4> () + 4); } else { cmd.PushConstant(pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, roughness, (uint)Marshal.SizeOf <Matrix4x4> ()); cmd.PushConstant(pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, 64u, (uint)Marshal.SizeOf <Matrix4x4> () + 4); } cmd.BindDescriptorSet(pl.Layout, dset); cmd.BindVertexBuffer(vboSkybox); cmd.Draw(36); pl.RenderPass.End(cmd); imgFbOffscreen.SetLayout(cmd, VkImageAspectFlags.Color, VkImageLayout.ColorAttachmentOptimal, VkImageLayout.TransferSrcOptimal); VkImageCopy region = new VkImageCopy(); region.srcSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color, 1); region.dstSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color, 1, (uint)m, (uint)f); region.extent = new VkExtent3D { width = (uint)viewPortSize, height = (uint)viewPortSize, depth = 1 }; Vk.vkCmdCopyImage(cmd.Handle, imgFbOffscreen.Handle, VkImageLayout.TransferSrcOptimal, cmap.Handle, VkImageLayout.TransferDstOptimal, 1, region.Pin()); region.Unpin(); imgFbOffscreen.SetLayout(cmd, VkImageAspectFlags.Color, VkImageLayout.TransferSrcOptimal, VkImageLayout.ColorAttachmentOptimal); } } cmap.SetLayout(cmd, VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal, subRes); cmd.End(); staggingQ.Submit(cmd); staggingQ.WaitIdle(); cmd.Free(); } } cmap.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; dsLayout.Dispose(); imgFbOffscreen.Dispose(); dsPool.Dispose(); return(cmap); }
protected void init(GraphicPipelineConfig cfg) { if (state != ActivableState.Activated) { Layout.Activate(); RenderPass.Activate(); Cache?.Activate(); List <VkPipelineShaderStageCreateInfo> shaderStages = new List <VkPipelineShaderStageCreateInfo> (); foreach (ShaderInfo shader in cfg.shaders) { shaderStages.Add(shader.GetStageCreateInfo(Dev)); } VkPipelineColorBlendStateCreateInfo colorBlendInfo = VkPipelineColorBlendStateCreateInfo.New(); colorBlendInfo.attachmentCount = (uint)cfg.blendAttachments.Count; colorBlendInfo.pAttachments = cfg.blendAttachments.Pin(); VkPipelineDynamicStateCreateInfo dynStatesInfo = VkPipelineDynamicStateCreateInfo.New(); dynStatesInfo.dynamicStateCount = (uint)cfg.dynamicStates.Count; dynStatesInfo.pDynamicStates = cfg.dynamicStates.Pin(); VkPipelineVertexInputStateCreateInfo vertInputInfo = VkPipelineVertexInputStateCreateInfo.New(); vertInputInfo.vertexBindingDescriptionCount = (uint)cfg.vertexBindings.Count; vertInputInfo.pVertexBindingDescriptions = cfg.vertexBindings.Pin(); vertInputInfo.vertexAttributeDescriptionCount = (uint)cfg.vertexAttributes.Count; vertInputInfo.pVertexAttributeDescriptions = cfg.vertexAttributes.Pin(); VkGraphicsPipelineCreateInfo info = VkGraphicsPipelineCreateInfo.New(); info.renderPass = RenderPass.handle; info.layout = Layout.handle; info.pVertexInputState = vertInputInfo.Pin(); info.pInputAssemblyState = cfg.inputAssemblyState.Pin(); info.pRasterizationState = cfg.rasterizationState.Pin(); info.pColorBlendState = colorBlendInfo.Pin(); info.pMultisampleState = cfg.multisampleState.Pin(); info.pViewportState = cfg.viewportState.Pin(); info.pDepthStencilState = cfg.depthStencilState.Pin(); info.pDynamicState = dynStatesInfo.Pin(); info.stageCount = (uint)cfg.shaders.Count; info.pStages = shaderStages.Pin(); info.subpass = cfg.SubpassIndex; Utils.CheckResult(vkCreateGraphicsPipelines(Dev.VkDev, Cache == null ? VkPipelineCache.Null : Cache.handle, 1, ref info, IntPtr.Zero, out handle)); for (int i = 0; i < cfg.shaders.Count; i++) { Dev.DestroyShaderModule(shaderStages[i].module); } vertInputInfo.Unpin(); cfg.inputAssemblyState.Unpin(); cfg.rasterizationState.Unpin(); colorBlendInfo.Unpin(); cfg.multisampleState.Unpin(); cfg.viewportState.Unpin(); cfg.depthStencilState.Unpin(); dynStatesInfo.Unpin(); shaderStages.Unpin(); cfg.vertexAttributes.Unpin(); cfg.vertexBindings.Unpin(); cfg.dynamicStates.Unpin(); cfg.blendAttachments.Unpin(); } base.Activate(); }
/// <summary> /// Create a new Pipeline with supplied RenderPass /// </summary> public GraphicPipeline(GraphicPipelineConfig cfg, string name = "graphic pipeline") : this(cfg.RenderPass, cfg.Cache, name) { layout = cfg.Layout; init(cfg); }
public PBRPipeline(Queue staggingQ, RenderPass renderPass, Image uiImage, PipelineCache pipelineCache = null) : base(renderPass, pipelineCache, "pbr pipeline") { descriptorPool = new DescriptorPool(Dev, 2, new VkDescriptorPoolSize(VkDescriptorType.UniformBuffer, 2), new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler, 9) ); descLayoutMain = new DescriptorSetLayout(Dev, new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer), new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler), new VkDescriptorSetLayoutBinding(2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler), new VkDescriptorSetLayoutBinding(3, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler), new VkDescriptorSetLayoutBinding(4, VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer), new VkDescriptorSetLayoutBinding(5, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler));//ui image descLayoutTextures = new DescriptorSetLayout(Dev, new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler), new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler), new VkDescriptorSetLayoutBinding(2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler), new VkDescriptorSetLayoutBinding(3, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler), new VkDescriptorSetLayoutBinding(4, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler) ); GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, renderPass.Samples); cfg.Layout = new PipelineLayout(Dev, descLayoutMain, descLayoutTextures); cfg.Layout.AddPushConstants( new VkPushConstantRange(VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf <Matrix4x4> ()), new VkPushConstantRange(VkShaderStageFlags.Fragment, sizeof(int), 64) ); cfg.RenderPass = renderPass; cfg.AddVertexBinding <PbrModel2.Vertex> (0); cfg.AddVertexAttributes(0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat, VkFormat.R32g32Sfloat, VkFormat.R32g32Sfloat); cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/pbr.vert.spv"); cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/pbr_khr.frag.spv"); layout = cfg.Layout; init(cfg); dsMain = descriptorPool.Allocate(descLayoutMain); envCube = new EnvironmentCube(dsMain, layout, staggingQ, RenderPass); matrices.prefilteredCubeMipLevels = envCube.prefilterCube.CreateInfo.mipLevels; uboMats = new HostBuffer(Dev, VkBufferUsageFlags.UniformBuffer, matrices, true); string[] modelPathes = { "data/models/DamagedHelmet/glTF/DamagedHelmet.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Avocado/glTF/Avocado.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/BarramundiFish/glTF/BarramundiFish.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/BoomBoxWithAxes/glTF/BoomBoxWithAxes.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Box/glTF/Box.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/EnvironmentTest/glTF/EnvironmentTest.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/MetalRoughSpheres/glTF/MetalRoughSpheres.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/OrientationTest/glTF/OrientationTest.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Buggy/glTF/Buggy.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/2CylinderEngine/glTF-Embedded/2CylinderEngine.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/FlightHelmet/glTF/FlightHelmet.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/GearboxAssy/glTF/GearboxAssy.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Lantern/glTF/Lantern.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/SciFiHelmet/glTF/SciFiHelmet.gltf", "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Sponza/glTF/Sponza.gltf", "/mnt/devel/vkChess/data/chess.gltf" }; model = new PbrModel2(staggingQ, modelPathes[0], descLayoutTextures, AttachmentType.Color, AttachmentType.PhysicalProps, AttachmentType.Normal, AttachmentType.AmbientOcclusion, AttachmentType.Emissive); //model = new Model (Dev, presentQueue, "../data/models/icosphere.gltf"); //model = new Model (Dev, presentQueue, cmdPool, "../data/models/cube.gltf"); DescriptorSetWrites uboUpdate = new DescriptorSetWrites(descLayoutMain); uboUpdate.Write(Dev, dsMain, uboMats.Descriptor, envCube.irradianceCube.Descriptor, envCube.prefilterCube.Descriptor, envCube.lutBrdf.Descriptor, model.materialUBO.Descriptor, uiImage.Descriptor); }