diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2019-08-26 21:18:10 +0200 |
|---|---|---|
| committer | j-p <jp_bruyere@hotmail.com> | 2019-08-28 11:32:06 +0200 |
| commit | 9db72a724f14fcbae966a548f268dbee3b0055d7 (patch) | |
| tree | 1a821a6a994f3d2c6597b57bfe2f5ddfd0aa6c8d | |
| parent | 8a8b76927ee1b5477001e62379baf546d2fae978 (diff) | |
separate pbr pass and final tonemaping in 2 renderpass to be able to insert computation stages, and maybe more
28 files changed, 663 insertions, 227 deletions
diff --git a/VK/Delegates.cs b/VK/Delegates.cs index d524d73..d400542 100644 --- a/VK/Delegates.cs +++ b/VK/Delegates.cs @@ -32,9 +32,9 @@ namespace VK VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope); - public unsafe delegate void PFN_vkVoidFunction(); + public delegate void PFN_vkVoidFunction(); - public unsafe delegate VkBool32 PFN_vkDebugReportCallbackEXT( + public delegate VkBool32 PFN_vkDebugReportCallbackEXT( VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, ulong @object, @@ -44,7 +44,7 @@ namespace VK IntPtr pMessage, IntPtr pUserData); - public unsafe delegate VkBool32 PFN_vkDebugUtilsMessengerCallbackEXT ( + public delegate VkBool32 PFN_vkDebugUtilsMessengerCallbackEXT ( VkDebugUtilsMessageSeverityFlagsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, IntPtr pCallbackData, diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props index 8e85c1e..20c3076 100644 --- a/samples/Directory.Build.props +++ b/samples/Directory.Build.props @@ -30,7 +30,7 @@ </ItemGroup> <ItemGroup> - <PackageReference Include="Vulkan" Version="0.1.3" /> + <PackageReference Include="Vulkan" Version="0.1.4-beta" /> </ItemGroup> <ItemGroup> diff --git a/samples/Textured/main.cs b/samples/Textured/main.cs index 3308290..f14e5b8 100644 --- a/samples/Textured/main.cs +++ b/samples/Textured/main.cs @@ -10,7 +10,7 @@ namespace TextureSample { static void Main (string[] args) { Instance.VALIDATION = true; Instance.DEBUG_UTILS = true; - Instance.RENDER_DOC_CAPTURE = true; + //Instance.RENDER_DOC_CAPTURE = true; using (Program vke = new Program ()) { vke.Run (); } @@ -64,21 +64,8 @@ namespace TextureSample { "data/textures/tex256.jpg", }; - DebugReport dbgReport; - CVKL.DebugUtils.Messenger msg; - - Program () : base () { - - msg = new CVKL.DebugUtils.Messenger (instance); - - if (Instance.DEBUG_UTILS) - dbgReport = new DebugReport (instance, - VkDebugReportFlagsEXT.DebugEXT| - VkDebugReportFlagsEXT.ErrorEXT | - VkDebugReportFlagsEXT.WarningEXT | - VkDebugReportFlagsEXT.PerformanceWarningEXT | - VkDebugReportFlagsEXT.InformationEXT); - + Program () : base () { + loadTexture (imgPathes[currentImgIndex]); vbo = new GPUBuffer<float> (presentQueue, cmdPool, VkBufferUsageFlags.VertexBuffer, vertices); @@ -121,8 +108,7 @@ namespace TextureSample { void buildCommandBuffers () { for (int i = 0; i < swapChain.ImageCount; ++i) { cmds[i]?.Free (); - cmds[i] = cmdPool.AllocateCommandBuffer (); - cmds[i].Start (); + cmds[i] = cmdPool.AllocateAndStart (); recordDraw (cmds[i], frameBuffers[i]); @@ -265,8 +251,6 @@ namespace TextureSample { vbo.Dispose (); ibo.Dispose (); uboMats.Dispose (); - dbgReport?.Dispose (); - msg?.Dispose (); } } diff --git a/samples/Triangle/main.cs b/samples/Triangle/main.cs index 9a6b397..6640ec5 100644 --- a/samples/Triangle/main.cs +++ b/samples/Triangle/main.cs @@ -11,6 +11,7 @@ namespace Triangle { static void Main (string[] args) { //Instance.RENDER_DOC_CAPTURE = true; Instance.VALIDATION = true; + Instance.DEBUG_UTILS = true; using (Program vke = new Program ()) { vke.Run (); diff --git a/samples/compute/compute.csproj b/samples/compute/compute.csproj index e1734ff..3f93177 100644 --- a/samples/compute/compute.csproj +++ b/samples/compute/compute.csproj @@ -5,6 +5,6 @@ </PropertyGroup> <ItemGroup> - <Compile Include="delaunay.cs" /> + <Compile Include="test.cs" /> </ItemGroup> </Project>
\ No newline at end of file diff --git a/samples/compute/test.cs b/samples/compute/test.cs index a9aa578..7037613 100644 --- a/samples/compute/test.cs +++ b/samples/compute/test.cs @@ -9,6 +9,14 @@ namespace test { VkPhysicalDeviceFeatures enabledFeatures = default (VkPhysicalDeviceFeatures); string[] enabledExtensions = { Ext.D.VK_KHR_swapchain }; + static void Main (string[] args) { + Instance.VALIDATION = true; + //Instance.DEBUG_UTILS = true; + + using (Program vke = new Program ()) + vke.Run (); + } + Instance instance; PhysicalDevice phy; Device dev; @@ -33,13 +41,13 @@ namespace test { instance = new Instance (); #if DEBUG - dbgReport = new DebugReport (instance, + /*dbgReport = new DebugReport (instance, VkDebugReportFlagsEXT.ErrorEXT | VkDebugReportFlagsEXT.DebugEXT | VkDebugReportFlagsEXT.WarningEXT | VkDebugReportFlagsEXT.PerformanceWarningEXT - ); + );*/ #endif phy = instance.GetAvailablePhysicalDevice ().FirstOrDefault (); @@ -117,14 +125,9 @@ namespace test { dev.Dispose (); #if DEBUG - dbgReport.Dispose (); + dbgReport?.Dispose (); #endif instance.Dispose (); } - - static void Main (string[] args) { - using (Program vke = new Program ()) - vke.Run (); - } } } diff --git a/samples/deferred/deferred.csproj b/samples/deferred/deferred.csproj index 4a034f6..5758c39 100644 --- a/samples/deferred/deferred.csproj +++ b/samples/deferred/deferred.csproj @@ -33,5 +33,8 @@ <ItemGroup> <PackageReference Include="Crow.VK" Version="0.9.0-beta" /> </ItemGroup> - + + <ItemGroup> + <Folder Include="shaders\" /> + </ItemGroup> </Project>
\ No newline at end of file diff --git a/samples/deferred/deferredPbrRenderer.cs b/samples/deferred/deferredPbrRenderer.cs index f88dffe..39ce23a 100644 --- a/samples/deferred/deferredPbrRenderer.cs +++ b/samples/deferred/deferredPbrRenderer.cs @@ -7,13 +7,11 @@ using VK; namespace deferred { public class DeferredPbrRenderer : IDisposable { Device dev; - SwapChain swapChain; - public PresentQueue presentQueue; - - public static int MAX_MATERIAL_COUNT = 8; + Queue gQueue; + public static int MAX_MATERIAL_COUNT = 4; public static VkSampleCountFlags NUM_SAMPLES = VkSampleCountFlags.SampleCount1; public static VkFormat HDR_FORMAT = VkFormat.R16g16b16a16Sfloat; - public static VkFormat MRT_FORMAT = VkFormat.R16g16b16a16Sfloat; + public static VkFormat MRT_FORMAT = VkFormat.R32g32b32a32Sfloat; public static bool TEXTURE_ARRAY; public enum DebugView { @@ -35,14 +33,14 @@ namespace deferred { public int debugMip = 0; public int debugFace = 0; const float lightMoveSpeed = 0.1f; + public float exposure = 2.0f; + public float gamma = 1.2f; public struct Matrices { public Matrix4x4 projection; public Matrix4x4 model; public Matrix4x4 view; public Vector4 camPos; - public float exposure; - public float gamma; public float prefilteredCubeMipLevels; public float scaleIBLAmbient; } @@ -52,9 +50,17 @@ namespace deferred { public Matrix4x4 mvp; } + struct BloomPushCsts { + readonly Vector2 texSize; + public int dir; + public BloomPushCsts(uint width, uint height, int dir) { + this.texSize = new Vector2 (width, height); + this.dir = dir; + } + }; + + public Matrices matrices = new Matrices { - gamma = 1.2f, - exposure = 2.0f, scaleIBLAmbient = 0.5f, }; public Light[] lights = { @@ -62,21 +68,21 @@ namespace deferred { position = new Vector4(2.5f,5.5f,2,0f), color = new Vector4(1,0.8f,0.8f,1) }, - new Light { + /*new Light { position = new Vector4(-2.5f,5.5f,2,0f), color = new Vector4(0.8f,0.8f,1,1) - } + }*/ }; - Framebuffer[] frameBuffers; - Image gbColorRough, gbEmitMetal, gbN_AO, gbPos, hdrImg; + Framebuffer frameBuffer; + public Image gbColorRough, gbEmitMetal, gbN_AO, gbPos, hdrImgResolved, hdrImgMS;//, downSamp, downSamp2; DescriptorPool descriptorPool; DescriptorSetLayout descLayoutMain, descLayoutTextures, descLayoutGBuff; DescriptorSet dsMain, dsGBuff; public PipelineCache pipelineCache; - Pipeline gBuffPipeline, composePipeline, toneMappingPipeline, debugPipeline; + Pipeline gBuffPipeline, composePipeline, debugPipeline; public HostBuffer uboMatrices { get; private set; } public HostBuffer<Light> uboLights { get; private set; } @@ -89,31 +95,39 @@ namespace deferred { public BoundingBox modelAABB; + public VkSemaphore DrawComplete; + const int SP_SKYBOX = 0; const int SP_MODELS = 1; const int SP_COMPOSE = 2; - const int SP_TONE_MAPPING = 3; + //const int SP_TONE_MAPPING = 3; string cubemapPath; + uint width, height; - public DeferredPbrRenderer (Device dev, SwapChain swapChain, PresentQueue presentQueue, string cubemapPath, float nearPlane, float farPlane) { - this.dev = dev; - this.swapChain = swapChain; - this.presentQueue = presentQueue; + public DeferredPbrRenderer (Queue gQueue, string cubemapPath, uint width, uint height, float nearPlane, float farPlane) { + this.gQueue = gQueue; + this.dev = gQueue.Dev; this.cubemapPath = cubemapPath; + this.width = width; + this.height = height; + + DrawComplete = dev.CreateSemaphore(); + pipelineCache = new PipelineCache (dev); - descriptorPool = new DescriptorPool (dev, 3, + descriptorPool = new DescriptorPool (dev, 5, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer, 3), - new VkDescriptorPoolSize (VkDescriptorType.CombinedImageSampler, 5), - new VkDescriptorPoolSize (VkDescriptorType.InputAttachment, 5) + new VkDescriptorPoolSize (VkDescriptorType.CombinedImageSampler, 6), + new VkDescriptorPoolSize (VkDescriptorType.InputAttachment, 5), + new VkDescriptorPoolSize (VkDescriptorType.StorageImage, 4) ); uboMatrices = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, matrices, true); uboLights = new HostBuffer<Light> (dev, VkBufferUsageFlags.UniformBuffer, lights, true); #if WITH_SHADOWS - shadowMapRenderer = new ShadowMapRenderer (dev, this); + shadowMapRenderer = new ShadowMapRenderer (gQueue, this); #endif init (nearPlane, farPlane); @@ -122,13 +136,14 @@ namespace deferred { void init_renderpass () { renderPass = new RenderPass (dev, NUM_SAMPLES); - renderPass.AddAttachment (swapChain.ColorFormat, VkImageLayout.PresentSrcKHR, VkSampleCountFlags.SampleCount1);//swapchain image + renderPass.AddAttachment (HDR_FORMAT, VkImageLayout.ColorAttachmentOptimal, VkSampleCountFlags.SampleCount1);//final outpout renderPass.AddAttachment (dev.GetSuitableDepthFormat (), VkImageLayout.DepthStencilAttachmentOptimal, NUM_SAMPLES); - renderPass.AddAttachment (swapChain.ColorFormat, VkImageLayout.ColorAttachmentOptimal, NUM_SAMPLES, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.DontCare);//GBuff0 (color + roughness) and final color before resolve + renderPass.AddAttachment (VkFormat.R8g8b8a8Unorm, VkImageLayout.ColorAttachmentOptimal, NUM_SAMPLES, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.DontCare);//GBuff0 (color + roughness) and final color before resolve renderPass.AddAttachment (VkFormat.R8g8b8a8Unorm, VkImageLayout.ColorAttachmentOptimal, NUM_SAMPLES, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.DontCare);//GBuff1 (emit + metal) renderPass.AddAttachment (MRT_FORMAT, VkImageLayout.ColorAttachmentOptimal, NUM_SAMPLES, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.DontCare);//GBuff2 (normals + AO) renderPass.AddAttachment (MRT_FORMAT, VkImageLayout.ColorAttachmentOptimal, NUM_SAMPLES, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.DontCare);//GBuff3 (Pos + depth) - renderPass.AddAttachment (HDR_FORMAT, VkImageLayout.ColorAttachmentOptimal, NUM_SAMPLES);//hdr color + if (NUM_SAMPLES != VkSampleCountFlags.SampleCount1) + renderPass.AddAttachment (HDR_FORMAT, VkImageLayout.ColorAttachmentOptimal, NUM_SAMPLES);//hdr color multisampled renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) }); renderPass.ClearValues.Add (new VkClearValue { depthStencil = new VkClearDepthStencilValue (1.0f, 0) }); @@ -136,30 +151,35 @@ namespace deferred { renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) }); renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) }); renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) }); - renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) }); + if (NUM_SAMPLES != VkSampleCountFlags.SampleCount1) + renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) }); + + uint mainHdr = NUM_SAMPLES == VkSampleCountFlags.SampleCount1 ? 0u : 6u; - SubPass[] subpass = { new SubPass (), new SubPass (), new SubPass (), new SubPass () }; + SubPass[] subpass = { new SubPass (), new SubPass (), new SubPass ()}; //skybox - subpass[SP_SKYBOX].AddColorReference (6, VkImageLayout.ColorAttachmentOptimal); + subpass[SP_SKYBOX].AddColorReference (mainHdr, VkImageLayout.ColorAttachmentOptimal); //models subpass[SP_MODELS].AddColorReference (new VkAttachmentReference (2, VkImageLayout.ColorAttachmentOptimal), new VkAttachmentReference (3, VkImageLayout.ColorAttachmentOptimal), new VkAttachmentReference (4, VkImageLayout.ColorAttachmentOptimal), new VkAttachmentReference (5, VkImageLayout.ColorAttachmentOptimal)); subpass[SP_MODELS].SetDepthReference (1, VkImageLayout.DepthStencilAttachmentOptimal); - subpass[SP_MODELS].AddPreservedReference (0); + subpass[SP_MODELS].AddPreservedReference (mainHdr); //compose - subpass[SP_COMPOSE].AddColorReference (6, VkImageLayout.ColorAttachmentOptimal); + subpass[SP_COMPOSE].AddColorReference (mainHdr, VkImageLayout.ColorAttachmentOptimal); subpass[SP_COMPOSE].AddInputReference (new VkAttachmentReference (2, VkImageLayout.ShaderReadOnlyOptimal), new VkAttachmentReference (3, VkImageLayout.ShaderReadOnlyOptimal), new VkAttachmentReference (4, VkImageLayout.ShaderReadOnlyOptimal), new VkAttachmentReference (5, VkImageLayout.ShaderReadOnlyOptimal)); - //tone mapping - subpass[SP_TONE_MAPPING].AddColorReference ((NUM_SAMPLES == VkSampleCountFlags.SampleCount1) ? 0u : 2u, VkImageLayout.ColorAttachmentOptimal); - subpass[SP_TONE_MAPPING].AddInputReference (new VkAttachmentReference (6, VkImageLayout.ShaderReadOnlyOptimal)); if (NUM_SAMPLES != VkSampleCountFlags.SampleCount1) - subpass[SP_TONE_MAPPING].AddResolveReference (0, VkImageLayout.ColorAttachmentOptimal); + subpass[SP_COMPOSE].AddResolveReference (0, VkImageLayout.ColorAttachmentOptimal); + //tone mapping + //subpass[SP_TONE_MAPPING].AddColorReference ((NUM_SAMPLES == VkSampleCountFlags.SampleCount1) ? 0u : 2u, VkImageLayout.ColorAttachmentOptimal); + //subpass[SP_TONE_MAPPING].AddInputReference (new VkAttachmentReference (6, VkImageLayout.ShaderReadOnlyOptimal)); + //if (NUM_SAMPLES != VkSampleCountFlags.SampleCount1) + //subpass[SP_TONE_MAPPING].AddResolveReference (0, VkImageLayout.ColorAttachmentOptimal); renderPass.AddSubpass (subpass); @@ -172,12 +192,24 @@ namespace deferred { renderPass.AddDependency (SP_MODELS, SP_COMPOSE, VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.FragmentShader, VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.ShaderRead); - renderPass.AddDependency (SP_COMPOSE, SP_TONE_MAPPING, - VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.FragmentShader, - VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.ShaderRead); - renderPass.AddDependency (SP_TONE_MAPPING, Vk.SubpassExternal, - VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.BottomOfPipe, - VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.MemoryRead); + //renderPass.AddDependency (SP_COMPOSE, Vk.SubpassExternal, + //VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.Transfer, + //VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.TransferRead); + //renderPass.AddDependency (SP_COMPOSE, SP_COMPOSE, + //VkPipelineStageFlags.Transfer, VkPipelineStageFlags.ComputeShader, + //VkAccessFlags.TransferWrite, VkAccessFlags.ShaderRead); + //renderPass.AddDependency (Vk.SubpassExternal, SP_TONE_MAPPING, + // VkPipelineStageFlags.ComputeShader, VkPipelineStageFlags.FragmentShader, + // VkAccessFlags.ShaderWrite, VkAccessFlags.ShaderRead); + //renderPass.AddDependency (SP_SKYBOX, SP_TONE_MAPPING, + //VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.FragmentShader, + //VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.ShaderRead); + renderPass.AddDependency (SP_COMPOSE, Vk.SubpassExternal, + VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.Transfer, + VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.TransferRead); + //renderPass.AddDependency (SP_TONE_MAPPING, Vk.SubpassExternal, + //VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.BottomOfPipe, + //VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.MemoryRead); } void init (float nearPlane, float farPlane) { @@ -196,6 +228,7 @@ namespace deferred { if (TEXTURE_ARRAY) { descLayoutMain.Bindings.Add (new VkDescriptorSetLayoutBinding (7, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler));//texture array + //descLayoutMain.Bindings.Add (new VkDescriptorSetLayoutBinding (8, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler));//down sampled hdr } else { descLayoutTextures = new DescriptorSetLayout (dev, new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler), @@ -210,8 +243,8 @@ namespace deferred { new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//color + roughness new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//emit + metal new VkDescriptorSetLayoutBinding (2, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//normals + AO - new VkDescriptorSetLayoutBinding (3, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//Pos + depth - new VkDescriptorSetLayoutBinding (4, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment));//hdr + new VkDescriptorSetLayoutBinding (3, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment));//Pos + depth + GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, NUM_SAMPLES); @@ -276,15 +309,15 @@ namespace deferred { cfg.shaders[1] = new ShaderInfo (VkShaderStageFlags.Fragment, "shaders/show_gbuff.frag.spv"); cfg.SubpassIndex = SP_COMPOSE; debugPipeline = new GraphicPipeline (cfg); - //TONE MAPPING - cfg.shaders[1] = new ShaderInfo (VkShaderStageFlags.Fragment, "shaders/tone_mapping.frag.spv"); - cfg.SubpassIndex = SP_TONE_MAPPING; - toneMappingPipeline = new GraphicPipeline (cfg); + ////TONE MAPPING + //cfg.shaders[1] = new ShaderInfo (VkShaderStageFlags.Fragment, "shaders/tone_mapping.frag.spv"); + //cfg.SubpassIndex = SP_TONE_MAPPING; + //toneMappingPipeline = new GraphicPipeline (cfg); dsMain = descriptorPool.Allocate (descLayoutMain); dsGBuff = descriptorPool.Allocate (descLayoutGBuff); - envCube = new EnvironmentCube (cubemapPath, dsMain, gBuffPipeline.Layout, presentQueue, renderPass); + envCube = new EnvironmentCube (cubemapPath, dsMain, gBuffPipeline.Layout, gQueue, renderPass); matrices.prefilteredCubeMipLevels = envCube.prefilterCube.CreateInfo.mipLevels; @@ -300,6 +333,24 @@ namespace deferred { dsMainWrite = new DescriptorSetWrites (dsMain, descLayoutMain.Bindings[6]); dsMainWrite.Write (dev, shadowMapRenderer.shadowMap.Descriptor); #endif + init_blur (); + } + + ComputePipeline plBlur; + DescriptorSetLayout dsLayoutBlur; + DescriptorSet dsetPing, dsetPong; + + void init_blur () { + dsLayoutBlur = new DescriptorSetLayout (dev, + new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Compute, VkDescriptorType.StorageImage), + new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Compute, VkDescriptorType.StorageImage) + ); + plBlur = new ComputePipeline ( + new PipelineLayout (dev, new VkPushConstantRange (VkShaderStageFlags.Compute, (uint)Marshal.SizeOf<BloomPushCsts>()), dsLayoutBlur), + "shaders/computeTest.comp.spv"); + + dsetPing = descriptorPool.Allocate (dsLayoutBlur); + dsetPong = descriptorPool.Allocate (dsLayoutBlur); } public void LoadModel (Queue transferQ, string path) { @@ -329,16 +380,16 @@ namespace deferred { modelAABB = model.DefaultScene.AABB; } + public void buildCommandBuffers (CommandBuffer cmd) { + //downSamp.SetLayout (cmd, VkImageAspectFlags.Color, + //VkAccessFlags.ShaderWrite, VkAccessFlags.TransferWrite, + //VkImageLayout.General, VkImageLayout.TransferDstOptimal, + //VkPipelineStageFlags.ComputeShader, VkPipelineStageFlags.Transfer); - public void buildCommandBuffers (CommandBuffer cmd, int imageIndex) { - recordDraw (cmd, frameBuffers[imageIndex]); - } + renderPass.Begin (cmd, frameBuffer); - void recordDraw (CommandBuffer cmd, Framebuffer fb) { - renderPass.Begin (cmd, fb); - - cmd.SetViewport (fb.Width, fb.Height); - cmd.SetScissor (fb.Width, fb.Height); + cmd.SetViewport (frameBuffer.Width, frameBuffer.Height); + cmd.SetScissor (frameBuffer.Width, frameBuffer.Height); cmd.BindDescriptorSet (gBuffPipeline.Layout, dsMain); @@ -350,6 +401,7 @@ namespace deferred { model.Bind (cmd); model.DrawAll (cmd, gBuffPipeline.Layout); } + renderPass.BeginSubPass (cmd); cmd.BindDescriptorSet (composePipeline.Layout, dsGBuff, 1); @@ -368,11 +420,55 @@ namespace deferred { cmd.Draw (3, 1, 0, 0); - renderPass.BeginSubPass (cmd); - toneMappingPipeline.Bind (cmd); - cmd.Draw (3, 1, 0, 0); + //renderPass.BeginSubPass (cmd); + + //toneMappingPipeline.Bind (cmd); + //cmd.Draw (3, 1, 0, 0); renderPass.End (cmd); + + /*downSamp.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.ShaderReadOnlyOptimal, VkImageLayout.TransferDstOptimal, + VkPipelineStageFlags.FragmentShader, VkPipelineStageFlags.Transfer);*/ + + /*===== + hdrImg.SetLayout (cmd, VkImageAspectFlags.Color, + VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.TransferRead, + VkImageLayout.ColorAttachmentOptimal, VkImageLayout.TransferSrcOptimal, + VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.Transfer); + + hdrImg.BlitTo (cmd, downSamp); + + hdrImg.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.TransferSrcOptimal, VkImageLayout.ColorAttachmentOptimal, + VkPipelineStageFlags.Transfer, VkPipelineStageFlags.ColorAttachmentOutput); + =========*/ + + /* + downSamp.SetLayout (cmd, VkImageAspectFlags.Color, + VkAccessFlags.TransferWrite, VkAccessFlags.MemoryRead, + VkImageLayout.TransferDstOptimal, VkImageLayout.General, + VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader); + + plBlur.Bind (cmd); + BloomPushCsts pcBloom = new BloomPushCsts (downSamp.Width, downSamp.Height, 0); + + + plBlur.BindDescriptorSet (cmd, dsetPing); + cmd.PushConstant (plBlur.Layout, VkShaderStageFlags.Compute, pcBloom); + cmd.Dispatch (downSamp.Width / 16, downSamp.Height / 16); + + plBlur.BindDescriptorSet (cmd, dsetPong); + cmd.PushConstant (plBlur.Layout, VkShaderStageFlags.Compute, 1, (uint)Marshal.SizeOf<Vector2> ()); + cmd.Dispatch (downSamp.Width / 16, downSamp.Height / 16); + */ + + /*====== + downSamp.SetLayout (cmd, VkImageAspectFlags.Color, + VkAccessFlags.ShaderWrite, VkAccessFlags.ShaderRead, + VkImageLayout.General, VkImageLayout.ShaderReadOnlyOptimal, + VkPipelineStageFlags.ComputeShader, VkPipelineStageFlags.FragmentShader); + =======*/ + + } public void MoveLight (Vector4 dir) { @@ -384,7 +480,7 @@ namespace deferred { #region update public void UpdateView (Camera camera) { - camera.AspectRatio = (float)swapChain.Width / swapChain.Height; + camera.AspectRatio = (float)width / height; matrices.projection = camera.Projection; matrices.view = camera.View; @@ -400,79 +496,104 @@ namespace deferred { uboMatrices.Update (matrices, (uint)Marshal.SizeOf<Matrices> ()); } -#endregion + #endregion + + const int blurScale = 4; void createGBuff () { gbColorRough?.Dispose (); gbEmitMetal?.Dispose (); gbN_AO?.Dispose (); gbPos?.Dispose (); - hdrImg?.Dispose (); + hdrImgResolved?.Dispose (); + hdrImgMS?.Dispose (); + + //downSamp?.Dispose (); + //downSamp2?.Dispose (); + + hdrImgResolved = new Image (dev, HDR_FORMAT, VkImageUsageFlags.Sampled | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransferSrc, VkMemoryPropertyFlags.DeviceLocal, width, height, VkImageType.Image2D, VkSampleCountFlags.SampleCount1); + gbColorRough = new Image (dev, VkFormat.R8g8b8a8Unorm, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, width, height, VkImageType.Image2D, NUM_SAMPLES); + gbEmitMetal = new Image (dev, VkFormat.R8g8b8a8Unorm, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, width, height, VkImageType.Image2D, NUM_SAMPLES); + gbN_AO = new Image (dev, MRT_FORMAT, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, width, height, VkImageType.Image2D, NUM_SAMPLES); + gbPos = new Image (dev, MRT_FORMAT, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, width, height, VkImageType.Image2D, NUM_SAMPLES); + if (NUM_SAMPLES != VkSampleCountFlags.SampleCount1) + hdrImgMS = new Image (dev, HDR_FORMAT, VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, width, height, VkImageType.Image2D, NUM_SAMPLES); - gbColorRough = new Image (dev, swapChain.ColorFormat, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, NUM_SAMPLES); - gbEmitMetal = new Image (dev, VkFormat.R8g8b8a8Unorm, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, NUM_SAMPLES); - gbN_AO = new Image (dev, MRT_FORMAT, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, NUM_SAMPLES); - gbPos = new Image (dev, MRT_FORMAT, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, NUM_SAMPLES); - hdrImg = new Image (dev, HDR_FORMAT, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal | VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, NUM_SAMPLES); + //downSamp = new Image (dev, VkFormat.R16g16b16a16Sfloat, VkImageUsageFlags.TransferDst | VkImageUsageFlags.Storage | VkImageUsageFlags.Sampled, VkMemoryPropertyFlags.DeviceLocal, width / blurScale, height / blurScale, VkImageType.Image2D); + //downSamp2 = new Image (dev, VkFormat.R16g16b16a16Sfloat, VkImageUsageFlags.TransferDst | VkImageUsageFlags.Storage | VkImageUsageFlags.Sampled, VkMemoryPropertyFlags.DeviceLocal, width / blurScale, height / blurScale, VkImageType.Image2D); - gbColorRough.CreateView (); - gbColorRough.CreateSampler (); + gbColorRough.CreateView (); gbColorRough.CreateSampler (); gbColorRough.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; - gbEmitMetal.CreateView (); - gbEmitMetal.CreateSampler (); + gbEmitMetal.CreateView (); gbEmitMetal.CreateSampler (); gbEmitMetal.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; - gbN_AO.CreateView (); - gbN_AO.CreateSampler (); + gbN_AO.CreateView (); gbN_AO.CreateSampler (); gbN_AO.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; - gbPos.CreateView (); - gbPos.CreateSampler (); + gbPos.CreateView (); gbPos.CreateSampler (); gbPos.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; - hdrImg.CreateView (); - hdrImg.CreateSampler (); - hdrImg.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; + hdrImgResolved.CreateView (); hdrImgResolved.CreateSampler (); + hdrImgResolved.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; + + hdrImgMS?.CreateView (); + + //downSamp.CreateView (); downSamp.CreateSampler (); + //downSamp.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; + //downSamp2.CreateView (); downSamp2.CreateSampler (); + //downSamp2.Descriptor.imageLayout = VkImageLayout.General; DescriptorSetWrites uboUpdate = new DescriptorSetWrites (descLayoutGBuff); uboUpdate.Write (dev, dsGBuff, gbColorRough.Descriptor, gbEmitMetal.Descriptor, gbN_AO.Descriptor, - gbPos.Descriptor, - hdrImg.Descriptor); + gbPos.Descriptor); + //uboUpdate = new DescriptorSetWrites (dsMain, descLayoutMain.Bindings[8]); + //uboUpdate.Write (dev, downSamp.Descriptor); + + //uboUpdate = new DescriptorSetWrites (dsetPing, dsLayoutBlur); + //downSamp.Descriptor.imageLayout = VkImageLayout.General; + //uboUpdate.Write (dev, downSamp.Descriptor, downSamp2.Descriptor); + //uboUpdate.Write (dev, dsetPong, downSamp2.Descriptor, downSamp.Descriptor); + gbColorRough.SetName ("GBuffColorRough"); gbEmitMetal.SetName ("GBuffEmitMetal"); gbN_AO.SetName ("GBuffN"); gbPos.SetName ("GBuffPos"); - hdrImg.SetName ("HDRimg"); + hdrImgResolved.SetName ("HDRimg resolved"); + hdrImgMS?.SetName ("HDRimg resolved"); + //downSamp.SetName ("HDRimgDownScaled"); + //downSamp2.SetName ("HDRimgDownScaled2"); } - public void Resize () { - if (frameBuffers != null) - for (int i = 0; i < swapChain.ImageCount; ++i) - frameBuffers[i]?.Dispose (); - + public void Resize (uint width, uint height) { + frameBuffer?.Dispose (); createGBuff (); - frameBuffers = new Framebuffer[swapChain.ImageCount]; - - for (int i = 0; i < swapChain.ImageCount; ++i) { - frameBuffers[i] = new Framebuffer (renderPass, swapChain.Width, swapChain.Height, new Image[] { - swapChain.images[i], null, gbColorRough, gbEmitMetal, gbN_AO, gbPos, hdrImg}); - } + frameBuffer = (NUM_SAMPLES == VkSampleCountFlags.SampleCount1) ? + new Framebuffer (renderPass, width, height, new Image[] { + hdrImgResolved, null, gbColorRough, gbEmitMetal, gbN_AO, gbPos}) : + new Framebuffer (renderPass, width, height, new Image[] { + hdrImgResolved, null, gbColorRough, gbEmitMetal, gbN_AO, gbPos, hdrImgMS}); } public void Dispose () { dev.WaitIdle (); - for (int i = 0; i < swapChain.ImageCount; ++i) - frameBuffers[i]?.Dispose (); + + frameBuffer?.Dispose (); gbColorRough.Dispose (); gbEmitMetal.Dispose (); gbN_AO.Dispose (); gbPos.Dispose (); - hdrImg.Dispose (); + hdrImgMS?.Dispose (); + hdrImgResolved.Dispose (); + + //downSamp.Dispose (); + //downSamp2.Dispose (); + //plBlur.Dispose (); + //dsLayoutBlur.Dispose (); gBuffPipeline.Dispose (); composePipeline.Dispose (); - toneMappingPipeline.Dispose (); + //toneMappingPipeline.Dispose (); debugPipeline?.Dispose (); descLayoutMain.Dispose (); @@ -489,6 +610,8 @@ namespace deferred { #endif descriptorPool.Dispose (); + + dev.DestroySemaphore (DrawComplete); } } } diff --git a/samples/deferred/main-crow.cs b/samples/deferred/main-crow.cs index 83170b7..9486259 100644 --- a/samples/deferred/main-crow.cs +++ b/samples/deferred/main-crow.cs @@ -166,7 +166,6 @@ namespace deferred { crow.Load ("#deferred.menu.crow").DataSource = this; - } protected override void recordDraw (CommandBuffer cmd, int imageIndex) { diff --git a/samples/deferred/main.cs b/samples/deferred/main.cs index 5e4c28f..f9653cc 100644 --- a/samples/deferred/main.cs +++ b/samples/deferred/main.cs @@ -8,14 +8,14 @@ namespace deferred { class Deferred : VkWindow { static void Main (string[] args) { - //Instance.VALIDATION = true; - //Instance.DEBUG_UTILS = true; - //Instance.RENDER_DOC_CAPTURE = true; + Instance.VALIDATION = true; + Instance.DEBUG_UTILS = true; + Instance.RENDER_DOC_CAPTURE = true; DeferredPbrRenderer.TEXTURE_ARRAY = true; - DeferredPbrRenderer.NUM_SAMPLES = VkSampleCountFlags.SampleCount1; - DeferredPbrRenderer.HDR_FORMAT = VkFormat.R32g32b32a32Sfloat; - DeferredPbrRenderer.MRT_FORMAT = VkFormat.R16g16b16a16Sfloat; + DeferredPbrRenderer.NUM_SAMPLES = VkSampleCountFlags.SampleCount2; + DeferredPbrRenderer.HDR_FORMAT = VkFormat.R16g16b16a16Sfloat; + DeferredPbrRenderer.MRT_FORMAT = VkFormat.R32g32b32a32Sfloat; PbrModelTexArray.TEXTURE_DIM = 1024; @@ -24,6 +24,11 @@ namespace deferred { } } + public override string[] EnabledDeviceExtensions => new string[] { + Ext.D.VK_KHR_swapchain, + Ext.D.VK_EXT_debug_marker + }; + protected override void configureEnabledFeatures (VkPhysicalDeviceFeatures available_features, ref VkPhysicalDeviceFeatures enabled_features) { base.configureEnabledFeatures (available_features, ref enabled_features); @@ -37,6 +42,7 @@ namespace deferred { protected override void createQueues () { base.createQueues (); transferQ = new Queue (dev, VkQueueFlags.Transfer); + computeQ = new Queue (dev, VkQueueFlags.Compute); } string[] cubemapPathes = { "data/textures/papermill.ktx", @@ -57,30 +63,87 @@ namespace deferred { int curModelIndex = 0; bool reloadModel; - Queue transferQ; + Queue transferQ, computeQ; DeferredPbrRenderer renderer; - CVKL.DebugUtils.Messenger dbgmsg; - Deferred () : base() { + GraphicPipeline plToneMap; + Framebuffer[] frameBuffers; + DescriptorPool descriptorPool; + DescriptorSetLayout dsLayout; + DescriptorSet descriptorSet; + - if (Instance.DEBUG_UTILS) - dbgmsg = new CVKL.DebugUtils.Messenger (instance, VkDebugReportFlagsEXT.InformationEXT); + Deferred () : base("deferred", 1024, 1024) { camera = new Camera (Utils.DegreesToRadians (45f), 1f, 0.1f, 16f); camera.SetPosition (0, 0, 2); - renderer = new DeferredPbrRenderer (dev, swapChain, presentQueue, cubemapPathes[2], camera.NearPlane, camera.FarPlane); + renderer = new DeferredPbrRenderer (presentQueue, cubemapPathes[2], swapChain.Width, swapChain.Height, camera.NearPlane, camera.FarPlane); renderer.LoadModel (transferQ, modelPathes[curModelIndex]); camera.Model = Matrix4x4.CreateScale (1f / Math.Max (Math.Max (renderer.modelAABB.Width, renderer.modelAABB.Height), renderer.modelAABB.Depth)); + init_final_pl (); + } + + void init_final_pl() { + descriptorPool = new DescriptorPool (dev, 1, + new VkDescriptorPoolSize (VkDescriptorType.CombinedImageSampler, 1) + ); + + GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, DeferredPbrRenderer.NUM_SAMPLES); + + cfg.Layout = new PipelineLayout (dev, + new VkPushConstantRange (VkShaderStageFlags.Fragment, 2 * sizeof (float)), + new DescriptorSetLayout (dev, 0, + new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler) + //new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler) + )); + + cfg.RenderPass = new RenderPass (dev, swapChain.ColorFormat, DeferredPbrRenderer.NUM_SAMPLES); + + cfg.AddShader (VkShaderStageFlags.Vertex, "shaders/FullScreenQuad.vert.spv"); + cfg.AddShader (VkShaderStageFlags.Fragment, "shaders/tone_mapping.frag.spv"); + + plToneMap = new GraphicPipeline (cfg); + + descriptorSet = descriptorPool.Allocate (cfg.Layout.DescriptorSetLayouts[0]); } + CommandBuffer cmdPbr; + void buildCommandBuffers () { + cmdPbr?.Free (); + cmdPbr = cmdPool.AllocateAndStart (); + renderer.buildCommandBuffers (cmdPbr); + cmdPbr.End (); + for (int i = 0; i < swapChain.ImageCount; ++i) { cmds[i]?.Free (); cmds[i] = cmdPool.AllocateAndStart (); - renderer.buildCommandBuffers (cmds[i], i); + + renderer.hdrImgResolved.SetLayout (cmds[i], VkImageAspectFlags.Color, VkImageLayout.ColorAttachmentOptimal, VkImageLayout.ShaderReadOnlyOptimal, + VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.FragmentShader); + + plToneMap.RenderPass.Begin (cmds[i], frameBuffers[i]); + + cmds[i].SetViewport (frameBuffers[i].Width, frameBuffers[i].Height); + cmds[i].SetScissor (frameBuffers[i].Width, frameBuffers[i].Height); + + plToneMap.Bind (cmds[i]); + plToneMap.BindDescriptorSet (cmds[i], descriptorSet); + + cmds[i].PushConstant (plToneMap.Layout, VkShaderStageFlags.Fragment, 2 * sizeof(float), new float[] { renderer.exposure, renderer.gamma }, 0); + + cmds[i].Draw (3, 1, 0, 0); + + plToneMap.RenderPass.End (cmds[i]); + + renderer.hdrImgResolved.SetLayout (cmds[i], VkImageAspectFlags.Color, + VkAccessFlags.ShaderRead, VkAccessFlags.ColorAttachmentWrite, + VkImageLayout.ShaderReadOnlyOptimal, VkImageLayout.ColorAttachmentOptimal, + VkPipelineStageFlags.FragmentShader, VkPipelineStageFlags.ColorAttachmentOutput); + cmds[i].End (); } } @@ -112,10 +175,51 @@ namespace deferred { } } + protected override void render () { + int idx = swapChain.GetNextImage (); + if (idx < 0) { + OnResize (); + return; + } + + if (cmds[idx] == null) + return; + + presentQueue.Submit (cmdPbr, swapChain.presentComplete, renderer.DrawComplete); + + presentQueue.Submit (cmds[idx], renderer.DrawComplete, drawComplete[idx]); + presentQueue.Present (swapChain, drawComplete[idx]); + + presentQueue.WaitIdle (); + } protected override void OnResize () { + dev.WaitIdle (); + UpdateView (); - renderer.Resize (); + renderer.Resize (swapChain.Width, swapChain.Height); + + if (frameBuffers != null) + for (int i = 0; i < swapChain.ImageCount; ++i) + frameBuffers[i]?.Dispose (); + + frameBuffers = new Framebuffer[swapChain.ImageCount]; + + for (int i = 0; i < swapChain.ImageCount; ++i) { + frameBuffers[i] = new Framebuffer (plToneMap.RenderPass, swapChain.Width, swapChain.Height, + (plToneMap.Samples == VkSampleCountFlags.SampleCount1) ? new Image[] { + swapChain.images[i], + } : new Image[] { + null, + swapChain.images[i] + }); + } + + DescriptorSetWrites uboUpdate = new DescriptorSetWrites (plToneMap.Layout.DescriptorSetLayouts[0]); + uboUpdate.Write (dev, descriptorSet, renderer.hdrImgResolved.Descriptor); + buildCommandBuffers (); + + dev.WaitIdle (); } #region Mouse and keyboard @@ -235,15 +339,15 @@ namespace deferred { break; case Key.F2: if (modifiers.HasFlag (Modifier.Shift)) - renderer.matrices.exposure -= 0.3f; + renderer.exposure -= 0.3f; else - renderer.matrices.exposure += 0.3f; + renderer.exposure += 0.3f; break; case Key.F3: if (modifiers.HasFlag (Modifier.Shift)) - renderer.matrices.gamma -= 0.1f; + renderer.gamma -= 0.1f; else - renderer.matrices.gamma += 0.1f; + renderer.gamma += 0.1f; break; case Key.F4: if (camera.Type == Camera.CamType.FirstPerson) @@ -276,7 +380,6 @@ namespace deferred { if (disposing) { if (!isDisposed) { renderer.Dispose (); - dbgmsg?.Dispose (); } } base.Dispose (disposing); diff --git a/samples/deferred/shaders/bloom.comp b/samples/deferred/shaders/bloom.comp new file mode 100644 index 0000000..b0e00f0 --- /dev/null +++ b/samples/deferred/shaders/bloom.comp @@ -0,0 +1,61 @@ +#version 450 + +layout (local_size_x = 16, local_size_y = 16) in; +layout (binding = 0, rgba16) uniform readonly image2D inputImage; +layout (binding = 1, rgba16) uniform image2D resultImage; + +layout(push_constant) uniform PushConsts { + vec2 texSize; + int dir; +} pc; + +void main(void) +{ + // From the OpenGL Super bible + const float weights[] = float[](0.0024499299678342, + 0.0043538453346397, + 0.0073599963704157, + 0.0118349786570722, + 0.0181026699707781, + 0.0263392293891488, + 0.0364543006660986, + 0.0479932050577658, + 0.0601029809166942, + 0.0715974486241365, + 0.0811305381519717, + 0.0874493212267511, + 0.0896631113333857, + 0.0874493212267511, + 0.0811305381519717, + 0.0715974486241365, + 0.0601029809166942, + 0.0479932050577658, + 0.0364543006660986, + 0.0263392293891488, + 0.0181026699707781, + 0.0118349786570722, + 0.0073599963704157, + 0.0043538453346397, + 0.0024499299678342); + + + const float blurScale = 0.003; + const float blurStrength = 1.0; + + float ar = 1.0; + // Aspect ratio for vertical blur pass + if (pc.dir == 1) + ar = pc.texSize.y / pc.texSize.x; + + vec2 P = gl_GlobalInvocationID.yx - vec2(0, (weights.length() >> 1) * ar * blurScale); + + vec4 color = vec4(0.0); + for (int i = 0; i < weights.length(); i++) + { + vec2 dv = vec2(0.0, i * blurScale) * ar; + color += imageLoad (inputImage, ivec2(P + dv)) * weights[i] * blurStrength; + } + + //imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), color); + imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), vec4(1,0,0,1)); +}
\ No newline at end of file diff --git a/samples/deferred/shaders/bloom.frag b/samples/deferred/shaders/bloom.frag new file mode 100644 index 0000000..c3bf402 --- /dev/null +++ b/samples/deferred/shaders/bloom.frag @@ -0,0 +1,63 @@ +#version 450 + +layout (binding = 0) uniform sampler2D samplerColor0; +layout (binding = 1) uniform sampler2D samplerColor1; + +layout (location = 0) in vec2 inUV; + +layout (location = 0) out vec4 outColor; + +layout (constant_id = 0) const int dir = 0; + +void main(void) +{ + // From the OpenGL Super bible + const float weights[] = float[](0.0024499299678342, + 0.0043538453346397, + 0.0073599963704157, + 0.0118349786570722, + 0.0181026699707781, + 0.0263392293891488, + 0.0364543006660986, + 0.0479932050577658, + 0.0601029809166942, + 0.0715974486241365, + 0.0811305381519717, + 0.0874493212267511, + 0.0896631113333857, + 0.0874493212267511, + 0.0811305381519717, + 0.0715974486241365, + 0.0601029809166942, + 0.0479932050577658, + 0.0364543006660986, + 0.0263392293891488, + 0.0181026699707781, + 0.0118349786570722, + 0.0073599963704157, + 0.0043538453346397, + 0.0024499299678342); + + + const float blurScale = 0.003; + const float blurStrength = 1.0; + + float ar = 1.0; + // Aspect ratio for vertical blur pass + if (dir == 1) + { + vec2 ts = textureSize(samplerColor1, 0); + ar = ts.y / ts.x; + } + + vec2 P = inUV.yx - vec2(0, (weights.length() >> 1) * ar * blurScale); + + vec4 color = vec4(0.0); + for (int i = 0; i < weights.length(); i++) + { + vec2 dv = vec2(0.0, i * blurScale) * ar; + color += texture(samplerColor1, P + dv) * weights[i] * blurStrength; + } + + outColor = color; +}
\ No newline at end of file diff --git a/samples/deferred/shaders/compose_with_shadows.frag b/samples/deferred/shaders/compose_with_shadows.frag index d8ad270..4247393 100644 --- a/samples/deferred/shaders/compose_with_shadows.frag +++ b/samples/deferred/shaders/compose_with_shadows.frag @@ -7,8 +7,6 @@ layout (set = 0, binding = 0) uniform UBO { mat4 model; mat4 view; vec4 camPos; - float exposure; - float gamma; float prefilteredCubeMipLevels; float scaleIBLAmbient; } ubo; @@ -252,14 +250,16 @@ void main() vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs); vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV); // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law) + vec3 color = NdotL * lights[i].color.rgb * (diffuseContrib + specContrib); + + #if SHADOW vec4 shadowClip = lights[i].mvp * vec4(pos, 1); float shadowFactor = filterPCF(shadowClip, i); - - - vec3 color = NdotL * lights[i].color.rgb * (diffuseContrib + specContrib); - // Calculate lighting contribution from image based lighting source (IBL) colors += shadowFactor * (color + getIBLContribution(pbrInputs, n, reflection)); + #else + colors += color + getIBLContribution(pbrInputs, n, reflection); + #endif } @@ -267,11 +267,11 @@ void main() const float u_OcclusionStrength = 1.0f; - const float u_EmissiveFactor = 1.0f; + const float u_EmissiveFactor = 3.0f; //AO is in the alpha channel of the normalAttachment colors = mix(colors, colors * subpassLoad(samplerN_AO, gl_SampleID).a, u_OcclusionStrength); - colors += emissive; + colors += emissive * u_EmissiveFactor; outColor = vec4(colors, baseColor.a); }
\ No newline at end of file diff --git a/samples/deferred/shaders/tone_mapping.frag b/samples/deferred/shaders/tone_mapping.frag index 187d672..fddf0c4 100644 --- a/samples/deferred/shaders/tone_mapping.frag +++ b/samples/deferred/shaders/tone_mapping.frag @@ -2,16 +2,13 @@ #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable -layout (set = 0, binding = 0) uniform UBO { - mat4 projection; - mat4 model; - mat4 view; - vec4 camPos; - float exposure; - float gamma; -} ubo; +layout(push_constant) uniform PushConsts { + float exposure; + float gamma; +} pc; -layout (input_attachment_index = 0, set = 1, binding = 4) uniform subpassInputMS samplerHDR; +layout (set = 0, binding = 0) uniform sampler2D samplerHDR; +//layout (set = 0, binding = 1) uniform sampler2D bloom; layout (location = 0) in vec2 inUV; layout (location = 0) out vec4 outColor; @@ -30,9 +27,9 @@ vec3 Uncharted2Tonemap(vec3 color) vec3 tonemap(vec3 color) { - vec3 outcol = Uncharted2Tonemap(color.rgb * ubo.exposure); + vec3 outcol = Uncharted2Tonemap(color.rgb * pc.exposure); outcol = outcol * (1.0f / Uncharted2Tonemap(vec3(11.2f))); - return pow(outcol, vec3(1.0f / ubo.gamma)); + return pow(outcol, vec3(1.0f / pc.gamma)); } vec3 SRGBtoLINEAR(vec3 srgbIn) @@ -48,13 +45,22 @@ vec3 SRGBtoLINEAR(vec3 srgbIn) return srgbIn; #endif //MANUAL_SRGB } - + void main() { - vec4 hdrColor = subpassLoad(samplerHDR, gl_SampleID); + //vec4 hdrColor = texelFetch (samplerHDR, ivec2(inUV), gl_SampleID); + vec4 hdrColor = texture (samplerHDR, inUV); outColor = vec4(SRGBtoLINEAR(tonemap(hdrColor.rgb)), hdrColor.a); - /* - vec3 mapped = vec3(1.0) - exp(-hdrColor.rgb * ubo.exposure); - mapped = pow(mapped, vec3(1.0 / ubo.gamma)); + + + //outColor = texture (bloom, inUV); + + /*float lum = (0.299*hdrColor.r + 0.587*hdrColor.g + 0.114*hdrColor.b); + if (lum<1.0) + discard; + outColor = vec4(SRGBtoLINEAR(tonemap(hdrColor.rgb)), hdrColor.a);;*/ + +/* vec3 mapped = vec3(1.0) - exp(-hdrColor.rgb * pc.exposure); + mapped = pow(mapped, vec3(1.0 / pc.gamma)); outColor = vec4(mapped, hdrColor.a);*/ }
\ No newline at end of file diff --git a/samples/deferred/shadowMapRenderer.cs b/samples/deferred/shadowMapRenderer.cs index 7b86f81..e41b0b3 100644 --- a/samples/deferred/shadowMapRenderer.cs +++ b/samples/deferred/shadowMapRenderer.cs @@ -13,6 +13,7 @@ using static deferred.DeferredPbrRenderer; namespace deferred { public class ShadowMapRenderer : IDisposable { Device dev; + Queue gQueue; public static uint SHADOWMAP_SIZE = 4096; public static VkFormat SHADOWMAP_FORMAT = VkFormat.D32SfloatS8Uint; @@ -35,9 +36,10 @@ namespace deferred { DescriptorSet dsShadow; DeferredPbrRenderer renderer; - public ShadowMapRenderer (Device dev, DeferredPbrRenderer renderer, float farPlane = 16f) { + public ShadowMapRenderer (Queue gQueue, DeferredPbrRenderer renderer, float farPlane = 16f) { this.lightFarPlane = farPlane; - this.dev = dev; + this.gQueue = gQueue; + this.dev = gQueue.Dev; this.renderer = renderer; descriptorPool = new DescriptorPool (dev, 1, @@ -78,7 +80,7 @@ namespace deferred { cfg.Layout = new PipelineLayout (dev, descLayoutShadow); cfg.Layout.AddPushConstants ( - new VkPushConstantRange (VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf<Matrix4x4> ()) + new VkPushConstantRange (VkShaderStageFlags.Vertex|VkShaderStageFlags.Geometry, (uint)Marshal.SizeOf<Matrix4x4> ()) ); cfg.AddVertexBinding<PbrModel.Vertex> (0); @@ -139,7 +141,7 @@ namespace deferred { shadowPass.End (cmd); - renderer.presentQueue.EndSubmitAndWait (cmd); + gQueue.EndSubmitAndWait (cmd); updateShadowMap = false; } diff --git a/samples/pbr/pbr.csproj b/samples/pbr/pbr.csproj index 71696f8..274e32a 100644 --- a/samples/pbr/pbr.csproj +++ b/samples/pbr/pbr.csproj @@ -15,5 +15,5 @@ <LogicalName>deferred.%(Filename)%(Extension)</LogicalName> </EmbeddedResource> </ItemGroup> - + </Project> diff --git a/samples/pbr/shaders/pbr_khr.frag b/samples/pbr/shaders/pbr_khr.frag index 9564e00..1f8e056 100644 --- a/samples/pbr/shaders/pbr_khr.frag +++ b/samples/pbr/shaders/pbr_khr.frag @@ -7,7 +7,7 @@ #extension GL_ARB_shading_language_420pack : enable #define MANUAL_SRGB 0 -#define DEBUG 0 +#define DEBUG 1 struct Material { vec4 baseColorFactor; @@ -177,8 +177,7 @@ vec3 getIBLContribution(PBRInfo pbrInputs, vec3 n, vec3 reflection) vec3 diffuse = diffuseLight * pbrInputs.diffuseColor; vec3 specular = specularLight * (pbrInputs.specularColor * brdf.x + brdf.y); - // For presentation, this allows us to disable IBL terms - // For presentation, this allows us to disable IBL terms + // For presentation, this allows us to disable IBL terms diffuse *= ubo.scaleIBLAmbient; specular *= ubo.scaleIBLAmbient; diff --git a/vke/CVKL.csproj b/vke/CVKL.csproj index a5bf978..8577539 100644 --- a/vke/CVKL.csproj +++ b/vke/CVKL.csproj @@ -1,10 +1,8 @@ <Project Sdk="Microsoft.NET.Sdk"> <Import Project="$(RootDirectory)netfx.props" /> <PropertyGroup> - <Copyright></Copyright> - <AssemblyVersion>0.1.5</AssemblyVersion> + <AssemblyVersion>0.1.6</AssemblyVersion> <Description>C# vulkan library with IDispose model and references counting</Description> - <Company></Company> <Product>CVKL</Product> <PackageId>CVKL</PackageId> <PackageTags>C# vulkan game library compute glfw</PackageTags> @@ -45,7 +43,7 @@ </ItemGroup> <ItemGroup> <PackageReference Include="glTF2Loader" Version="1.1.3-alpha" /> - <PackageReference Include="Vulkan" Version="0.1.3" /> + <PackageReference Include="Vulkan" Version="0.1.4-beta" /> </ItemGroup> <ItemGroup> <None Remove="shaders\**\*.frag;shaders\**\*.vert;shaders\**\*.comp;shaders\**\*.geom" /> diff --git a/vke/shaders/deffered/tone_mapping.frag b/vke/shaders/deffered/tone_mapping.frag index 187d672..d4053a7 100644 --- a/vke/shaders/deffered/tone_mapping.frag +++ b/vke/shaders/deffered/tone_mapping.frag @@ -12,6 +12,7 @@ layout (set = 0, binding = 0) uniform UBO { } ubo; layout (input_attachment_index = 0, set = 1, binding = 4) uniform subpassInputMS samplerHDR; +layout (set = 0, binding = 8) uniform sampler2D downSamp; layout (location = 0) in vec2 inUV; layout (location = 0) out vec4 outColor; diff --git a/vke/src/VkWindow.cs b/vke/src/VkWindow.cs index d9d1cf8..7ab566f 100644 --- a/vke/src/VkWindow.cs +++ b/vke/src/VkWindow.cs @@ -51,6 +51,8 @@ namespace CVKL { protected CommandBuffer[] cmds; protected VkSemaphore[] drawComplete; + DebugReport dbgRepport; + protected uint fps; protected bool updateViewRequested = true, rebuildBuffers; protected double lastMouseX, lastMouseY; @@ -117,6 +119,15 @@ namespace CVKL { void initVulkan (bool vSync) { instance = new Instance (); + if (Instance.DEBUG_UTILS) { + //dbgmsg = new CVKL.DebugUtils.Messenger (instance); + dbgRepport = new DebugReport (instance, + VkDebugReportFlagsEXT.ErrorEXT + | VkDebugReportFlagsEXT.WarningEXT + | VkDebugReportFlagsEXT.PerformanceWarningEXT + ); + } + hSurf = instance.CreateSurface (hWin); phy = instance.GetAvailablePhysicalDevice ().Where (p => p.HasSwapChainSupport).FirstOrDefault (); @@ -329,10 +340,10 @@ namespace CVKL { vkDestroySurfaceKHR (instance.Handle, hSurf, IntPtr.Zero); - cmdPool.Dispose (); - if (disposing) { + cmdPool.Dispose (); dev.Dispose (); + dbgRepport?.Dispose (); instance.Dispose (); } else Debug.WriteLine ("a VkWindow has not been correctly disposed"); diff --git a/vke/src/base/CommandBuffer.cs b/vke/src/base/CommandBuffer.cs index 7f64332..ffd61c6 100644 --- a/vke/src/base/CommandBuffer.cs +++ b/vke/src/base/CommandBuffer.cs @@ -116,7 +116,10 @@ namespace CVKL { vkCmdPushConstants (handle, pipelineLayout.handle, stageFlags, offset, (uint)Marshal.SizeOf (data), data.Pin ()); data.Unpin (); } - + 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 BeginRegion (string name, float r = 1f, float g = 0.1f, float b=0.1f, float a = 1f) { if (!Device.debugMarkersEnabled) return; diff --git a/vke/src/base/DebugReport.cs b/vke/src/base/DebugReport.cs index c4f1426..3bda80b 100644 --- a/vke/src/base/DebugReport.cs +++ b/vke/src/base/DebugReport.cs @@ -64,8 +64,13 @@ namespace CVKL { prefix = "DBUG"; break; } - - Console.WriteLine ("{0} {1}: {2}",prefix, messageCode, Marshal.PtrToStringAnsi(pMessage)); + try { + string msg = Marshal.PtrToStringAnsi (pMessage); + string[] tmp = msg.Split ('|'); + Console.WriteLine ($"{prefix}:{tmp[1]} |{Marshal.PtrToStringAnsi (pLayerPrefix)}({messageCode}){objectType}:{tmp[0]}"); + } catch (Exception ex) { + Console.WriteLine ("error parsing debug message: " + ex); + } Console.ForegroundColor = ConsoleColor.White; return VkBool32.False; } diff --git a/vke/src/base/DebugUtilsMessenger.cs b/vke/src/base/DebugUtilsMessenger.cs index 841b60e..b048c36 100644 --- a/vke/src/base/DebugUtilsMessenger.cs +++ b/vke/src/base/DebugUtilsMessenger.cs @@ -54,12 +54,16 @@ namespace CVKL.DebugUtils { // return VkBool32.False; //} - public Messenger (Instance instance, VkDebugReportFlagsEXT flags = VkDebugReportFlagsEXT.ErrorEXT | VkDebugReportFlagsEXT.WarningEXT) { + public Messenger (Instance instance, + VkDebugUtilsMessageTypeFlagsEXT typeMask = VkDebugUtilsMessageTypeFlagsEXT.ValidationEXT, + VkDebugUtilsMessageSeverityFlagsEXT severityMask = VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT | VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT) { + inst = instance; VkDebugUtilsMessengerCreateInfoEXT info = VkDebugUtilsMessengerCreateInfoEXT.New (); - info.messageType = VkDebugUtilsMessageTypeFlagsEXT.ValidationEXT | VkDebugUtilsMessageTypeFlagsEXT.GeneralEXT | VkDebugUtilsMessageTypeFlagsEXT.PerformanceEXT; - info.messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT | VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT | VkDebugUtilsMessageSeverityFlagsEXT.InfoEXT | VkDebugUtilsMessageSeverityFlagsEXT.VerboseEXT; + info.messageType = typeMask; + info.messageSeverity = severityMask; info.pfnUserCallback = Marshal.GetFunctionPointerForDelegate (onMessage); + info.pUserData = IntPtr.Zero; Utils.CheckResult (vkCreateDebugUtilsMessengerEXT (inst.VkInstance, ref info, IntPtr.Zero, out handle)); } diff --git a/vke/src/base/Device.cs b/vke/src/base/Device.cs index e45d45c..37dc91d 100644 --- a/vke/src/base/Device.cs +++ b/vke/src/base/Device.cs @@ -245,20 +245,25 @@ namespace CVKL { } public VkShaderModule LoadSPIRVShader (string filename) { - byte[] shaderCode = File.ReadAllBytes (filename); - ulong shaderSize = (ulong)shaderCode.Length; - unsafe { - // Create a new shader module that will be used for Pipeline creation - VkShaderModuleCreateInfo moduleCreateInfo = VkShaderModuleCreateInfo.New(); - moduleCreateInfo.codeSize = new UIntPtr (shaderSize); - moduleCreateInfo.pCode = shaderCode.Pin(); + VkShaderModule shaderModule; + using (Stream stream = StaticGetStreamFromPath (filename)) { + using (BinaryReader br = new BinaryReader (stream)) { + byte[] shaderCode = br.ReadBytes ((int)stream.Length); + ulong shaderSize = (ulong)shaderCode.Length; - Utils.CheckResult (vkCreateShaderModule (VkDev, ref moduleCreateInfo, IntPtr.Zero, out VkShaderModule shaderModule)); + // Create a new shader module that will be used for Pipeline creation + VkShaderModuleCreateInfo moduleCreateInfo = VkShaderModuleCreateInfo.New (); + moduleCreateInfo.codeSize = new UIntPtr (shaderSize); + moduleCreateInfo.pCode = shaderCode.Pin (); - shaderCode.Unpin (); + Utils.CheckResult (vkCreateShaderModule (VkDev, ref moduleCreateInfo, IntPtr.Zero, out shaderModule)); + + shaderCode.Unpin (); + } + + } + return shaderModule; - return shaderModule; - } } public static Stream StaticGetStreamFromPath (string path) { diff --git a/vke/src/base/Image.cs b/vke/src/base/Image.cs index 4e3c2d0..797eb84 100644 --- a/vke/src/base/Image.cs +++ b/vke/src/base/Image.cs @@ -51,6 +51,8 @@ namespace CVKL { public VkExtent3D Extent => info.extent; public VkFormat Format => info.format; public VkImage Handle => handle; + public uint Width => CreateInfo.extent.width; + public uint Height => CreateInfo.extent.height; protected override VkDebugMarkerObjectNameInfoEXT DebugMarkerInfo => new VkDebugMarkerObjectNameInfoEXT(VkDebugReportObjectTypeEXT.ImageEXT, handle.Handle); @@ -210,11 +212,9 @@ namespace CVKL { /// create host visible linear image without command from path /// </summary> public static Image Load (Device dev, - string path, VkFormat format = VkFormat.Undefined, bool reserveSpaceForMipmaps = true, + string path, VkImageUsageFlags usage = VkImageUsageFlags.Sampled, bool reserveSpaceForMipmaps = true, VkFormat format = VkFormat.Undefined, VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent, - VkImageTiling tiling = VkImageTiling.Linear, - VkImageType imageType = VkImageType.Image2D, - VkImageUsageFlags usage = VkImageUsageFlags.Sampled) { + VkImageTiling tiling = VkImageTiling.Linear, VkImageType imageType = VkImageType.Image2D) { if (format == VkFormat.Undefined) format = DefaultTextureFormat; @@ -412,11 +412,57 @@ namespace CVKL { }; SetLayout (cmdbuffer, oldImageLayout, newImageLayout, subresourceRange, srcStageMask, dstStageMask); } + public void SetLayout ( + CommandBuffer cmdbuffer, + VkImageAspectFlags aspectMask, + VkAccessFlags srcAccessMask, + VkAccessFlags dstAccessMask, + VkImageLayout oldImageLayout, + VkImageLayout newImageLayout, + VkPipelineStageFlags srcStageMask = VkPipelineStageFlags.AllCommands, + VkPipelineStageFlags dstStageMask = VkPipelineStageFlags.AllCommands) { + VkImageSubresourceRange subresourceRange = new VkImageSubresourceRange { + aspectMask = aspectMask, + baseMipLevel = 0, + levelCount = CreateInfo.mipLevels, + layerCount = CreateInfo.arrayLayers, + }; + SetLayout (cmdbuffer, srcAccessMask, dstAccessMask, oldImageLayout, newImageLayout, subresourceRange, srcStageMask, dstStageMask); + } + public void SetLayout ( + CommandBuffer cmdbuffer, + VkAccessFlags srcAccessMask, + VkAccessFlags dstAccessMask, + VkImageLayout oldImageLayout, + VkImageLayout newImageLayout, + VkImageSubresourceRange subresourceRange, + VkPipelineStageFlags srcStageMask = VkPipelineStageFlags.AllCommands, + VkPipelineStageFlags dstStageMask = VkPipelineStageFlags.AllCommands) { - // Create an image memory barrier for changing the layout of - // an image and put it into an active command buffer - // See chapter 11.4 "Image Layout" for details - public void SetLayout ( + VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New (); + imageMemoryBarrier.srcQueueFamilyIndex = Vk.QueueFamilyIgnored; + imageMemoryBarrier.dstQueueFamilyIndex = Vk.QueueFamilyIgnored; + imageMemoryBarrier.oldLayout = oldImageLayout; + imageMemoryBarrier.newLayout = newImageLayout; + imageMemoryBarrier.image = handle; + imageMemoryBarrier.subresourceRange = subresourceRange; + imageMemoryBarrier.srcAccessMask = srcAccessMask; + imageMemoryBarrier.dstAccessMask = dstAccessMask; + + Vk.vkCmdPipelineBarrier ( + cmdbuffer.Handle, + srcStageMask, + dstStageMask, + 0, + 0, IntPtr.Zero, + 0, IntPtr.Zero, + 1, ref imageMemoryBarrier); + + } + // Create an image memory barrier for changing the layout of + // an image and put it into an active command buffer + // See chapter 11.4 "Image Layout" for details + public void SetLayout ( CommandBuffer cmdbuffer, VkImageLayout oldImageLayout, VkImageLayout newImageLayout, @@ -566,7 +612,15 @@ namespace CVKL { SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.TransferSrcOptimal, VkImageLayout.ShaderReadOnlyOptimal, VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader); } - + public void BlitTo (CommandBuffer cmd, Image dest) { + VkImageBlit imageBlit = new VkImageBlit { + srcSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, info.arrayLayers, 0), + srcOffsets_1 = new VkOffset3D ((int)info.extent.width, (int)info.extent.height, 1), + dstSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, info.arrayLayers, 0), + dstOffsets_1 = new VkOffset3D ((int)dest.info.extent.width, (int)dest.info.extent.height, 1) + }; + vkCmdBlitImage (cmd.Handle, handle, VkImageLayout.TransferSrcOptimal, dest.handle, VkImageLayout.TransferDstOptimal, 1, ref imageBlit, VkFilter.Linear); + } public override string ToString () { return string.Format ($"{base.ToString ()}[0x{handle.Handle.ToString("x")}]"); } diff --git a/vke/src/base/Instance.cs b/vke/src/base/Instance.cs index cf583dc..d8a06d3 100644 --- a/vke/src/base/Instance.cs +++ b/vke/src/base/Instance.cs @@ -102,11 +102,11 @@ namespace CVKL { if (VALIDATION) { enabledLayerNames.Add (Strings.LayerValidation); - enabledLayerNames.Add (Strings.LayerValidation_old); + //enabledLayerNames.Add (Strings.LayerValidation_old); if (DEBUG_UTILS) { //if (ExtensionIsSupported(Strings.LayerValidation, Strings.VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) - instanceExtensions.Add (Strings.VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + //instanceExtensions.Add (Strings.VK_EXT_DEBUG_UTILS_EXTENSION_NAME); instanceExtensions.Add (Strings.VK_EXT_DEBUG_REPORT_EXTENSION_NAME); } diff --git a/vke/src/ktx.cs b/vke/src/ktx.cs index e449da2..cc68854 100644 --- a/vke/src/ktx.cs +++ b/vke/src/ktx.cs @@ -176,7 +176,7 @@ namespace KTX { else img.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal, - VkPipelineStageFlags.Transfer, VkPipelineStageFlags.TopOfPipe); + VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader); cmd.End (); diff --git a/vke/src/model/glTFLoader.cs b/vke/src/model/glTFLoader.cs index db9adf5..a841bf7 100644 --- a/vke/src/model/glTFLoader.cs +++ b/vke/src/model/glTFLoader.cs @@ -455,13 +455,13 @@ namespace CVKL { if (img.BufferView != null) {//load image from gltf buffer view GL.BufferView bv = gltf.BufferViews[(int)img.BufferView]; EnsureBufferIsLoaded (bv.Buffer); - vkimg = Image.Load (dev, bufferHandles[bv.Buffer].AddrOfPinnedObject () + bv.ByteOffset, (ulong)bv.ByteLength); + vkimg = Image.Load (dev, bufferHandles[bv.Buffer].AddrOfPinnedObject () + bv.ByteOffset, (ulong)bv.ByteLength, VkImageUsageFlags.TransferSrc); } else if (img.Uri.StartsWith ("data:", StringComparison.Ordinal)) {//load base64 encoded image Debug.WriteLine ("loading embedded image {0} : {1}", img.Name, img.MimeType); - vkimg = Image.Load (dev, glTFLoader.loadDataUri (img)); + vkimg = Image.Load (dev, glTFLoader.loadDataUri (img), VkImageUsageFlags.TransferSrc); } else { Debug.WriteLine ("loading image {0} : {1} : {2}", img.Name, img.MimeType, img.Uri);//load image from file path in uri - vkimg = Image.Load (dev, Path.Combine (baseDirectory, img.Uri)); + vkimg = Image.Load (dev, Path.Combine (baseDirectory, img.Uri), VkImageUsageFlags.TransferSrc); } imageBlit.srcOffsets_1 = new VkOffset3D ((int)vkimg.CreateInfo.extent.width, (int)vkimg.CreateInfo.extent.height, 1); @@ -469,8 +469,10 @@ namespace CVKL { cmd = cmdPool.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit); - vkimg.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.Undefined, VkImageLayout.TransferSrcOptimal, - VkPipelineStageFlags.BottomOfPipe, VkPipelineStageFlags.Transfer); + vkimg.SetLayout (cmd, VkImageAspectFlags.Color, + VkAccessFlags.HostWrite, VkAccessFlags.TransferRead, + VkImageLayout.Undefined, VkImageLayout.TransferSrcOptimal, + VkPipelineStageFlags.Host, VkPipelineStageFlags.Transfer); Vk.vkCmdBlitImage (cmd.Handle, vkimg.handle, VkImageLayout.TransferSrcOptimal, texArray.handle, VkImageLayout.TransferDstOptimal, 1, ref imageBlit, VkFilter.Linear); @@ -496,15 +498,21 @@ namespace CVKL { dstOffsets_1 = new VkOffset3D ((int)texDim >> i, (int)texDim >> i, 1) }; + texArray.SetLayout (cmd, + VkAccessFlags.TransferWrite, VkAccessFlags.TransferRead, + VkImageLayout.TransferDstOptimal, VkImageLayout.TransferSrcOptimal, mipSubRange, + VkPipelineStageFlags.Transfer, VkPipelineStageFlags.Transfer); + Vk.vkCmdBlitImage (cmd.Handle, texArray.handle, VkImageLayout.TransferSrcOptimal, texArray.handle, VkImageLayout.TransferDstOptimal, 1, ref imageBlit, VkFilter.Linear); - texArray.SetLayout (cmd, VkImageLayout.TransferDstOptimal, VkImageLayout.TransferSrcOptimal, mipSubRange, - VkPipelineStageFlags.Transfer, VkPipelineStageFlags.Transfer); + texArray.SetLayout (cmd, VkImageLayout.TransferSrcOptimal, VkImageLayout.ShaderReadOnlyOptimal, mipSubRange, + VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader); + mipSubRange.baseMipLevel = (uint)i; } - - texArray.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.TransferSrcOptimal, VkImageLayout.ShaderReadOnlyOptimal, - VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader); + mipSubRange.baseMipLevel = texArray.CreateInfo.mipLevels - 1; + texArray.SetLayout (cmd, VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal, mipSubRange, + VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader); cmd.End (); transferQ.Submit (cmd); |