aboutsummaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2019-04-26 01:53:07 +0200
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2019-04-26 01:53:07 +0200
commit568219e7719bfaf076ba23b539dd6ee7f647e273 (patch)
tree5b06297bb69dc2d511917f5d22f967028aa01077
parent01ea60eb8fc7b7a30f388f7be6e7c401ee94e441 (diff)
pipeline cache
-rw-r--r--samples/deferred/EnvironmentPipeline.cs4
-rw-r--r--samples/deferred/main.cs10
-rw-r--r--samples/pbrSashaWillem/EnvironmentPipeline.cs4
-rw-r--r--samples/pbrSashaWillem/PbrPipeline.cs4
-rw-r--r--vke/src/ComputePipeline.cs9
-rw-r--r--vke/src/DescriptorPool.cs6
-rw-r--r--vke/src/GraphicPipeline.cs10
-rw-r--r--vke/src/GraphicPipelineConfig.cs2
-rw-r--r--vke/src/Pipeline.cs5
-rw-r--r--vke/src/PipelineCache.cs114
-rw-r--r--vke/src/SpecializationConstant.cs20
11 files changed, 163 insertions, 25 deletions
diff --git a/samples/deferred/EnvironmentPipeline.cs b/samples/deferred/EnvironmentPipeline.cs
index 68128cc..909ee4a 100644
--- a/samples/deferred/EnvironmentPipeline.cs
+++ b/samples/deferred/EnvironmentPipeline.cs
@@ -17,8 +17,8 @@ namespace CVKL {
public int debugMip = 0;
public int debugFace = 0;
- public EnvironmentCube (DescriptorSet dsSkybox, PipelineLayout plLayout, Queue staggingQ, RenderPass renderPass)
- : base (renderPass, "EnvCube pipeline") {
+ public EnvironmentCube (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)) {
diff --git a/samples/deferred/main.cs b/samples/deferred/main.cs
index 1b1d720..db60521 100644
--- a/samples/deferred/main.cs
+++ b/samples/deferred/main.cs
@@ -79,6 +79,7 @@ namespace deferred {
DescriptorSetLayout descLayoutMain, descLayoutTextures, descLayoutGBuff;
DescriptorSet dsMain, dsGBuff;
+ PipelineCache pipelineCache;
Pipeline gBuffPipeline, composePipeline, toneMappingPipeline, debugPipeline;
HostBuffer uboMats;
@@ -97,6 +98,8 @@ namespace deferred {
const int SP_TONE_MAPPING = 3;
Program () {
+ pipelineCache = new PipelineCache (dev);
+
camera = new Camera (Utils.DegreesToRadians (45f), 1f, 0.1f, 16f);
init ();
@@ -205,7 +208,7 @@ namespace deferred {
cfg.multisampleState.sampleShadingEnable = true;
cfg.multisampleState.minSampleShading = 0.5f;
}
-
+ cfg.Cache = pipelineCache;
cfg.Layout = new PipelineLayout (dev, descLayoutMain, descLayoutTextures, descLayoutGBuff);
cfg.Layout.AddPushConstants (
new VkPushConstantRange (VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf<Matrix4x4> ()),
@@ -544,6 +547,10 @@ namespace deferred {
camera.Type = Camera.CamType.FirstPerson;
Console.WriteLine ($"camera type = {camera.Type}");
break;
+ case Key.S:
+ pipelineCache.Save ();
+ Console.WriteLine ($"Pipeline Cache saved.");
+ break;
default:
base.onKeyDown (key, scanCode, modifiers);
return;
@@ -579,6 +586,7 @@ namespace deferred {
envCube.Dispose ();
descriptorPool.Dispose ();
+ pipelineCache.Dispose ();
}
}
diff --git a/samples/pbrSashaWillem/EnvironmentPipeline.cs b/samples/pbrSashaWillem/EnvironmentPipeline.cs
index c12aa6e..010d21d 100644
--- a/samples/pbrSashaWillem/EnvironmentPipeline.cs
+++ b/samples/pbrSashaWillem/EnvironmentPipeline.cs
@@ -18,8 +18,8 @@ namespace CVKL {
public int debugMip = -1;
public int debugFace = 0;
- public EnvironmentCube (DescriptorSet dsSkybox, PipelineLayout plLayout, Queue staggingQ, RenderPass renderPass)
- : base (renderPass, "EnvCube pipeline") {
+ public EnvironmentCube (DescriptorSet dsSkybox, PipelineLayout plLayout, Queue staggingQ, RenderPass renderPass, PipelineCache pipelineCache = null)
+ : base (renderPass, pipelineCache, "EnvCube pipeline") {
using (CommandPool cmdPool = new CommandPool (staggingQ.Dev, staggingQ.index)) {
diff --git a/samples/pbrSashaWillem/PbrPipeline.cs b/samples/pbrSashaWillem/PbrPipeline.cs
index b7df5a1..20a8ae1 100644
--- a/samples/pbrSashaWillem/PbrPipeline.cs
+++ b/samples/pbrSashaWillem/PbrPipeline.cs
@@ -40,8 +40,8 @@ namespace CVKL {
public PbrModel2 model;
public EnvironmentCube envCube;
- public PBRPipeline (Queue staggingQ, RenderPass renderPass, Image uiImage) :
- base (renderPass, "pbr pipeline") {
+ 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),
diff --git a/vke/src/ComputePipeline.cs b/vke/src/ComputePipeline.cs
index 323006a..e57a7d0 100644
--- a/vke/src/ComputePipeline.cs
+++ b/vke/src/ComputePipeline.cs
@@ -33,12 +33,12 @@ namespace CVKL {
public string SpirVPath;
#region CTORS
- public ComputePipeline (Device dev, string name = "compute pipeline") : base (dev, name) {
+ public ComputePipeline (Device dev, PipelineCache cache = null, string name = "compute pipeline") : base (dev, cache, name) {
}
/// <summary>
- /// Create a new Pipeline with supplied RenderPass
+ /// Create a new Pipeline with supplied PipelineLayout
/// </summary>
- public ComputePipeline (PipelineLayout layout, string spirvPath, string name = "pipeline") : base(layout.Dev, name)
+ public ComputePipeline (PipelineLayout layout, string spirvPath, PipelineCache cache = null, string name = "pipeline") : base(layout.Dev, cache, name)
{
SpirVPath = spirvPath;
this.layout = layout;
@@ -50,6 +50,7 @@ namespace CVKL {
public override void Activate () {
if (state != ActivableState.Activated) {
layout.Activate ();
+ Cache?.Activate ();
using (ShaderInfo shader = new ShaderInfo (VkShaderStageFlags.Compute, SpirVPath)) {
VkComputePipelineCreateInfo info = VkComputePipelineCreateInfo.New ();
@@ -58,7 +59,7 @@ namespace CVKL {
info.basePipelineHandle = 0;
info.basePipelineIndex = 0;
- Utils.CheckResult (Vk.vkCreateComputePipelines (Dev.VkDev, VkPipelineCache.Null, 1, ref info, IntPtr.Zero, out handle));
+ Utils.CheckResult (Vk.vkCreateComputePipelines (Dev.VkDev, Cache == null ? VkPipelineCache.Null : Cache.handle, 1, ref info, IntPtr.Zero, out handle));
Dev.DestroyShaderModule (info.stage.module);
}
diff --git a/vke/src/DescriptorPool.cs b/vke/src/DescriptorPool.cs
index 05c1685..bd5a3d8 100644
--- a/vke/src/DescriptorPool.cs
+++ b/vke/src/DescriptorPool.cs
@@ -29,7 +29,7 @@ using VK;
using static VK.Vk;
namespace CVKL {
- public class DescriptorPool : Activable {
+ public sealed class DescriptorPool : Activable {
internal VkDescriptorPool handle;
public readonly uint MaxSets;
@@ -72,7 +72,7 @@ namespace CVKL {
Allocate (ds);
return ds;
}
- public unsafe void Allocate (DescriptorSet descriptorSet) {
+ public void Allocate (DescriptorSet descriptorSet) {
VkDescriptorSetAllocateInfo allocInfo = VkDescriptorSetAllocateInfo.New();
allocInfo.descriptorPool = handle;
allocInfo.descriptorSetCount = (uint)descriptorSet.descriptorSetLayouts.Count;
@@ -104,7 +104,7 @@ namespace CVKL {
#region IDisposable Support
protected override void Dispose (bool disposing) {
if (!disposing)
- System.Diagnostics.Debug.WriteLine ("VKE DescriptorPool disposed by finalizer");
+ System.Diagnostics.Debug.WriteLine ($"CVKL DescriptorPool '{name}' disposed by finalizer");
if (state == ActivableState.Activated)
vkDestroyDescriptorPool (Dev.VkDev, handle, IntPtr.Zero);
base.Dispose (disposing);
diff --git a/vke/src/GraphicPipeline.cs b/vke/src/GraphicPipeline.cs
index 5a84eb1..562e4fa 100644
--- a/vke/src/GraphicPipeline.cs
+++ b/vke/src/GraphicPipeline.cs
@@ -35,15 +35,14 @@ namespace CVKL {
public VkSampleCountFlags Samples => RenderPass.Samples;
#region CTORS
- protected GraphicPipeline (RenderPass renderPass, string name = "graphic pipeline") : base(renderPass.Dev, name) {
+ protected GraphicPipeline (RenderPass renderPass, PipelineCache cache = null, string name = "graphic pipeline") : base(renderPass.Dev, cache, name) {
RenderPass = renderPass;
-
handle.SetDebugMarkerName (Dev, name);
}
/// <summary>
/// Create a new Pipeline with supplied RenderPass
/// </summary>
- public GraphicPipeline (GraphicPipelineConfig cfg, string name = "graphic pipeline") : this (cfg.RenderPass, name)
+ public GraphicPipeline (GraphicPipelineConfig cfg, string name = "graphic pipeline") : this (cfg.RenderPass, cfg.Cache, name)
{
layout = cfg.Layout;
@@ -58,6 +57,7 @@ namespace CVKL {
if (state != ActivableState.Activated) {
Layout.Activate ();
RenderPass.Activate ();
+ Cache?.Activate ();
List<VkPipelineShaderStageCreateInfo> shaderStages = new List<VkPipelineShaderStageCreateInfo> ();
foreach (ShaderInfo shader in cfg.shaders)
@@ -92,7 +92,7 @@ namespace CVKL {
info.pStages = shaderStages.Pin ();
info.subpass = cfg.SubpassIndex;
- Utils.CheckResult (vkCreateGraphicsPipelines (Dev.VkDev, VkPipelineCache.Null, 1, ref info, IntPtr.Zero, out handle));
+ 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);
@@ -124,7 +124,7 @@ namespace CVKL {
protected override void Dispose (bool disposing) {
if (disposing) {
- if (state == ActivableState.Activated)
+ if (state == ActivableState.Activated)
RenderPass.Dispose ();
}else
System.Diagnostics.Debug.WriteLine ("GraphicPipeline disposed by finalizer");
diff --git a/vke/src/GraphicPipelineConfig.cs b/vke/src/GraphicPipelineConfig.cs
index 31d9d7d..000da1a 100644
--- a/vke/src/GraphicPipelineConfig.cs
+++ b/vke/src/GraphicPipelineConfig.cs
@@ -34,7 +34,7 @@ namespace CVKL {
public uint SubpassIndex;
public PipelineLayout Layout;
public RenderPass RenderPass;
-
+ public PipelineCache Cache;
public VkPipelineBindPoint bindPoint = VkPipelineBindPoint.Graphics;
public VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = VkPipelineInputAssemblyStateCreateInfo.New();
public VkPipelineRasterizationStateCreateInfo rasterizationState = VkPipelineRasterizationStateCreateInfo.New();
diff --git a/vke/src/Pipeline.cs b/vke/src/Pipeline.cs
index 4eba418..9a6b3aa 100644
--- a/vke/src/Pipeline.cs
+++ b/vke/src/Pipeline.cs
@@ -31,6 +31,7 @@ namespace CVKL {
public abstract class Pipeline : Activable {
protected VkPipeline handle;
protected PipelineLayout layout;
+ protected PipelineCache Cache;
public VkPipeline Handle => handle;
public PipelineLayout Layout => layout;
@@ -38,7 +39,8 @@ namespace CVKL {
protected readonly VkPipelineBindPoint bindPoint;
#region CTORS
- protected Pipeline (Device dev, string name = "custom pipeline") : base(dev, name) {
+ protected Pipeline (Device dev, PipelineCache cache = null, string name = "custom pipeline") : base(dev, name) {
+ this.Cache = cache;
}
#endregion
@@ -52,6 +54,7 @@ namespace CVKL {
if (state == ActivableState.Activated) {
if (disposing) {
layout.Dispose ();
+ Cache?.Dispose ();
} else
System.Diagnostics.Debug.WriteLine ($"Pipeline '{name}' disposed by finalizer");
diff --git a/vke/src/PipelineCache.cs b/vke/src/PipelineCache.cs
new file mode 100644
index 0000000..879dda6
--- /dev/null
+++ b/vke/src/PipelineCache.cs
@@ -0,0 +1,114 @@
+//
+// SpecializationConstant.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// Copyright (c) 2019 jp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using VK;
+
+using static VK.Vk;
+
+namespace CVKL {
+ public sealed class PipelineCache : Activable {
+ internal VkPipelineCache handle;
+ readonly string globalConfigPath;
+ readonly string cacheFile;
+
+ #region CTOR
+ public PipelineCache (Device dev, string cacheFile = "pipelines.bin", string name = "pipeline cache") : base(dev, name) {
+ string configRoot = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.UserProfile), ".config");
+ string appName = Assembly.GetEntryAssembly ().GetName ().Name;
+ globalConfigPath = Path.Combine (configRoot, appName);
+
+ if (!Directory.Exists (globalConfigPath))
+ Directory.CreateDirectory (globalConfigPath);
+
+ this.cacheFile = cacheFile;
+
+ Activate ();
+ }
+ #endregion
+
+ public override void Activate () {
+ string path = Path.Combine (globalConfigPath, cacheFile);
+
+ if (state != ActivableState.Activated) {
+ VkPipelineCacheCreateInfo info = VkPipelineCacheCreateInfo.New ();
+
+ if (File.Exists (path)) {
+ using (FileStream fs = File.Open (path, FileMode.Open)) {
+ using (BinaryReader br = new BinaryReader (fs)) {
+ int length = (int)br.BaseStream.Length;
+ info.pInitialData = Marshal.AllocHGlobal (length);
+ info.initialDataSize = (UIntPtr)br.BaseStream.Length;
+ Marshal.Copy(br.ReadBytes (length),0, info.pInitialData, length);
+ }
+ }
+ }
+
+ Utils.CheckResult (vkCreatePipelineCache (Dev.VkDev, ref info, IntPtr.Zero, out handle));
+
+ if (info.pInitialData != IntPtr.Zero)
+ Marshal.FreeHGlobal (info.pInitialData);
+ }
+ base.Activate ();
+ }
+
+ protected override VkDebugMarkerObjectNameInfoEXT DebugMarkerInfo => throw new NotImplementedException ();
+
+ public void Save () {
+ if (state != ActivableState.Activated)
+ return;
+ string path = Path.Combine (globalConfigPath, cacheFile);
+
+ if (File.Exists (path))
+ File.Delete (path);
+
+ UIntPtr dataSize;
+ Utils.CheckResult (vkGetPipelineCacheData (Dev.VkDev, handle, out dataSize, IntPtr.Zero));
+ byte[] pData = new byte[(int)dataSize];
+ Utils.CheckResult (vkGetPipelineCacheData (Dev.VkDev, handle, out dataSize, pData.Pin ()));
+ pData.Unpin ();
+
+ using (FileStream fs = File.Open (path, FileMode.CreateNew))
+ using (BinaryWriter br = new BinaryWriter (fs))
+ br.Write (pData, 0, (int)dataSize);
+ }
+
+
+ #region IDisposable Support
+ protected override void Dispose (bool disposing) {
+ if (!disposing)
+ System.Diagnostics.Debug.WriteLine ($"CVKL PipelineCache '{name}' disposed by finalizer");
+ if (state == ActivableState.Activated)
+ vkDestroyPipelineCache (Dev.VkDev, handle, IntPtr.Zero);
+ base.Dispose (disposing);
+ }
+ #endregion
+
+ }
+}
diff --git a/vke/src/SpecializationConstant.cs b/vke/src/SpecializationConstant.cs
index adb51d9..b1ecd9e 100644
--- a/vke/src/SpecializationConstant.cs
+++ b/vke/src/SpecializationConstant.cs
@@ -28,7 +28,10 @@ using System.Collections.Generic;
using System.Runtime.InteropServices;
using VK;
-namespace CVKL {
+namespace CVKL {
+ /// <summary>
+ /// Hold shader specialization constant value and type
+ /// </summary>
public class SpecializationConstant<T> : SpecializationConstant {
T val;
IntPtr ptr = IntPtr.Zero;
@@ -48,9 +51,15 @@ namespace CVKL {
public unsafe override void WriteTo (IntPtr ptr) {
this.ptr = ptr;
- if (typeof(T) == typeof(float)) {
- float val = Convert.ToSingle(Value);
- System.Buffer.MemoryCopy (&val, ptr.ToPointer (), 4, 4);
+ if (typeof (T) == typeof (float)) {
+ float v = Convert.ToSingle (Value);
+ System.Buffer.MemoryCopy (&v, ptr.ToPointer (), 4, 4);
+ } else if (typeof (T) == typeof (int) || typeof (T) == typeof (uint)) {
+ Marshal.WriteInt32 (ptr, Convert.ToInt32 (val));
+ } else if (typeof (T) == typeof (long) || typeof (T) == typeof (ulong)) {
+ Marshal.WriteInt64 (ptr, Convert.ToInt64 (val));
+ } else if (typeof (T) == typeof (byte)) {
+ Marshal.WriteByte (ptr, Convert.ToByte (val));
}
}
}
@@ -63,6 +72,9 @@ namespace CVKL {
public abstract void WriteTo (IntPtr ptr);
}
+ /// <summary>
+ /// Specialization constant infos, must be disposed after pipeline creation
+ /// </summary>
public class SpecializationInfo : IDisposable {
IntPtr pData;
VkSpecializationMapEntry[] entries;