Add triangle sample
This commit is contained in:
Родитель
4fda327c1b
Коммит
42438ea39a
|
@ -0,0 +1,2 @@
|
|||
glslangValidator.exe -V MiniTri.frag
|
||||
glslangValidator.exe -V MiniTri.vert
|
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{96426D44-3995-44F5-85C0-901027203313}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MiniTri</RootNamespace>
|
||||
<AssemblyName>MiniTri</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject>MiniTri.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="SharpDX, Version=3.0.2.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpDX.3.0.2\lib\net45\SharpDX.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="SharpDX.Desktop, Version=3.0.2.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpDX.Desktop.3.0.2\lib\net45\SharpDX.Desktop.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="SharpVulkan">
|
||||
<HintPath>..\..\Bin\SharpVulkan.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Sample.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="frag.spv">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
<None Include="vert.spv">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) 2016 Jörg Wollenschläger
|
||||
//
|
||||
// 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.
|
||||
|
||||
#version 400
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
|
||||
layout (location = 0) in vec3 Color;
|
||||
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(Color, 1);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2016 Jörg Wollenschläger
|
||||
//
|
||||
// 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.
|
||||
|
||||
#version 400
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
|
||||
layout (location = 0) in vec3 Position;
|
||||
layout (location = 1) in vec3 ColorIn;
|
||||
|
||||
layout (location = 0) out vec3 ColorOut;
|
||||
|
||||
void main()
|
||||
{
|
||||
ColorOut = ColorIn;
|
||||
gl_Position = vec4(Position, 1);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2016 Jörg Wollenschläger
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace MiniTri
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
[STAThread]
|
||||
private static void Main()
|
||||
{
|
||||
using (var sample = new Sample())
|
||||
{
|
||||
sample.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("MiniTri")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("MiniTri")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("96426d44-3995-44f5-85c0-901027203313")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,900 @@
|
|||
// Copyright (c) 2016 Jörg Wollenschläger
|
||||
//
|
||||
// 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.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using SharpDX;
|
||||
using SharpDX.Text;
|
||||
using SharpDX.Windows;
|
||||
|
||||
namespace MiniTri
|
||||
{
|
||||
using SharpVulkan;
|
||||
|
||||
public unsafe class Sample : IDisposable
|
||||
{
|
||||
private readonly bool validate = false;
|
||||
|
||||
private readonly Form form;
|
||||
|
||||
private Instance instance;
|
||||
private PhysicalDevice physicalDevice;
|
||||
private Queue queue;
|
||||
private Device device;
|
||||
private DebugReportCallback debugReportCallback;
|
||||
private DebugReportCallbackDelegate debugReport;
|
||||
|
||||
private Surface surface;
|
||||
private Swapchain swapchain;
|
||||
private Format backBufferFormat;
|
||||
private Image[] backBuffers;
|
||||
private ImageView[] backBufferViews;
|
||||
private uint currentBackBufferIndex;
|
||||
private Image depthStencilBuffer;
|
||||
private ImageView depthStencilView;
|
||||
|
||||
private CommandPool commandPool;
|
||||
private CommandBuffer commandBuffer;
|
||||
private CommandBuffer setupCommanBuffer;
|
||||
|
||||
private PipelineLayout pipelineLayout;
|
||||
private Pipeline pipeline;
|
||||
private RenderPass renderPass;
|
||||
private Framebuffer[] framebuffers;
|
||||
|
||||
private Buffer vertexBuffer;
|
||||
private DeviceMemory vertexBufferMemory;
|
||||
private VertexInputAttributeDescription[] vertexAttributes;
|
||||
private VertexInputBindingDescription[] vertexBindings;
|
||||
|
||||
public Sample()
|
||||
{
|
||||
form = new RenderForm("SharpVulkan - Vulkan Sample");
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
Debugger.Launch();
|
||||
Initialize();
|
||||
RenderLoop.Run(form, Draw);
|
||||
}
|
||||
|
||||
protected virtual void Initialize()
|
||||
{
|
||||
CreateInstance();
|
||||
CreateSurface();
|
||||
CreateDevice();
|
||||
CreateCommandBuffer();
|
||||
|
||||
CreateSwapchain();
|
||||
CreateBackBufferViews();
|
||||
|
||||
CreateVertexBuffer();
|
||||
CreateRenderPass();
|
||||
CreatePipelineLayout();
|
||||
CreatePipeline();
|
||||
CreateFramebuffers();
|
||||
}
|
||||
|
||||
protected virtual void CreateInstance()
|
||||
{
|
||||
var applicationInfo = new ApplicationInfo
|
||||
{
|
||||
StructureType = StructureType.ApplicationInfo,
|
||||
EngineVersion = 0,
|
||||
ApiVersion = Vulkan.ApiVersion
|
||||
};
|
||||
|
||||
var enabledLayerNames = new []
|
||||
{
|
||||
Marshal.StringToHGlobalAnsi("VK_LAYER_LUNARG_standard_validation"),
|
||||
};
|
||||
|
||||
var enabledExtensionNames = new []
|
||||
{
|
||||
Marshal.StringToHGlobalAnsi("VK_KHR_surface"),
|
||||
Marshal.StringToHGlobalAnsi("VK_KHR_win32_surface"),
|
||||
Marshal.StringToHGlobalAnsi("VK_EXT_debug_report"),
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
fixed (void* enabledLayerNamesPointer = &enabledLayerNames[0])
|
||||
fixed (void* enabledExtensionNamesPointer = &enabledExtensionNames[0])
|
||||
{
|
||||
var instanceCreateInfo = new InstanceCreateInfo
|
||||
{
|
||||
StructureType = StructureType.InstanceCreateInfo,
|
||||
ApplicationInfo = new IntPtr(&applicationInfo),
|
||||
EnabledExtensionCount = (uint)enabledExtensionNames.Length,
|
||||
EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer),
|
||||
};
|
||||
|
||||
if (validate)
|
||||
{
|
||||
instanceCreateInfo.EnabledLayerCount = (uint)enabledLayerNames.Length;
|
||||
instanceCreateInfo.EnabledLayerNames = new IntPtr(enabledLayerNamesPointer);
|
||||
}
|
||||
|
||||
instance = Vulkan.CreateInstance(ref instanceCreateInfo);
|
||||
}
|
||||
|
||||
if (validate)
|
||||
{
|
||||
var createDebugReportCallbackName = Encoding.ASCII.GetBytes("vkCreateDebugReportCallbackEXT");
|
||||
fixed (byte* createDebugReportCallbackNamePointer = &createDebugReportCallbackName[0])
|
||||
{
|
||||
var createDebugReportCallback = Marshal.GetDelegateForFunctionPointer<CreateDebugReportCallbackDelegate>(instance.GetProcAddress(createDebugReportCallbackNamePointer));
|
||||
|
||||
debugReport = DebugReport;
|
||||
var createInfo = new DebugReportCallbackCreateInfo
|
||||
{
|
||||
StructureType = StructureType.DebugReportCallbackCreateInfo,
|
||||
Flags = (uint)(DebugReportFlags.Error | DebugReportFlags.Warning | DebugReportFlags.PerformanceWarning),
|
||||
Callback = Marshal.GetFunctionPointerForDelegate(debugReport)
|
||||
};
|
||||
createDebugReportCallback(instance, ref createInfo, null, out debugReportCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach (var enabledExtensionName in enabledExtensionNames)
|
||||
Marshal.FreeHGlobal(enabledExtensionName);
|
||||
|
||||
foreach (var enabledLayerName in enabledLayerNames)
|
||||
Marshal.FreeHGlobal(enabledLayerName);
|
||||
}
|
||||
|
||||
physicalDevice = instance.PhysicalDevices[0];
|
||||
|
||||
var props = physicalDevice.QueueFamilyProperties;
|
||||
}
|
||||
|
||||
private static RawBool DebugReport(DebugReportFlags flags, DebugReportObjectType objectType, ulong @object, PointerSize location, int messageCode, string layerPrefix, string message, IntPtr userData)
|
||||
{
|
||||
Debug.WriteLine($"{flags}: {message} ([{messageCode}] {layerPrefix})");
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual void CreateDevice()
|
||||
{
|
||||
uint queuePriorities = 0;
|
||||
var queueCreateInfo = new DeviceQueueCreateInfo
|
||||
{
|
||||
StructureType = StructureType.DeviceQueueCreateInfo,
|
||||
QueueFamilyIndex = 0,
|
||||
QueueCount = 1,
|
||||
QueuePriorities = new IntPtr(&queuePriorities)
|
||||
};
|
||||
|
||||
var enabledLayerNames = new[]
|
||||
{
|
||||
Marshal.StringToHGlobalAnsi("VK_LAYER_LUNARG_standard_validation"),
|
||||
};
|
||||
|
||||
var enabledExtensionNames = new[]
|
||||
{
|
||||
Marshal.StringToHGlobalAnsi("VK_KHR_swapchain"),
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
fixed (void* enabledLayerNamesPointer = &enabledLayerNames[0])
|
||||
fixed (void* enabledExtensionNamesPointer = &enabledExtensionNames[0])
|
||||
{
|
||||
var deviceCreateInfo = new DeviceCreateInfo
|
||||
{
|
||||
StructureType = StructureType.DeviceCreateInfo,
|
||||
QueueCreateInfoCount = 1,
|
||||
QueueCreateInfos = new IntPtr(&queueCreateInfo),
|
||||
EnabledExtensionCount = (uint)enabledExtensionNames.Length,
|
||||
EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer)
|
||||
};
|
||||
|
||||
if (validate)
|
||||
{
|
||||
deviceCreateInfo.EnabledLayerCount = (uint)enabledLayerNames.Length;
|
||||
deviceCreateInfo.EnabledLayerNames = new IntPtr(enabledLayerNamesPointer);
|
||||
}
|
||||
|
||||
device = physicalDevice.CreateDevice(ref deviceCreateInfo);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach (var enabledExtensionName in enabledExtensionNames)
|
||||
Marshal.FreeHGlobal(enabledExtensionName);
|
||||
|
||||
foreach (var enabledLayerName in enabledLayerNames)
|
||||
Marshal.FreeHGlobal(enabledLayerName);
|
||||
}
|
||||
|
||||
var queueNodeIndex = physicalDevice.QueueFamilyProperties.
|
||||
Where((properties, index) => (properties.QueueFlags & QueueFlags.Graphics) != 0 && physicalDevice.GetSurfaceSupport((uint)index, surface)).
|
||||
Select((properties, index) => index).First();
|
||||
|
||||
queue = device.GetQueue(0, (uint)queueNodeIndex);
|
||||
}
|
||||
|
||||
protected virtual void CreateSurface()
|
||||
{
|
||||
var surfaceCreateInfo = new Win32SurfaceCreateInfo
|
||||
{
|
||||
StructureType = StructureType.Win32SurfaceCreateInfo,
|
||||
InstanceHandle = Process.GetCurrentProcess().Handle,
|
||||
WindowHandle = form.Handle,
|
||||
};
|
||||
surface = instance.CreateWin32Surface(surfaceCreateInfo);
|
||||
}
|
||||
|
||||
protected virtual void CreateSwapchain()
|
||||
{
|
||||
// surface format
|
||||
var surfaceFormats = physicalDevice.GetSurfaceFormats(surface);
|
||||
if (surfaceFormats.Length == 1 && surfaceFormats[0].Format == Format.Undefined)
|
||||
{
|
||||
backBufferFormat = Format.B8G8R8A8UNorm;
|
||||
}
|
||||
else
|
||||
{
|
||||
backBufferFormat = surfaceFormats[0].Format;
|
||||
}
|
||||
|
||||
SurfaceCapabilities surfaceCapabilities;
|
||||
physicalDevice.GetSurfaceCapabilities(surface, out surfaceCapabilities);
|
||||
|
||||
// Buffer count
|
||||
uint desiredImageCount = surfaceCapabilities.MinImageCount + 1;
|
||||
if (surfaceCapabilities.MaxImageCount > 0 && desiredImageCount > surfaceCapabilities.MaxImageCount)
|
||||
{
|
||||
desiredImageCount = surfaceCapabilities.MaxImageCount;
|
||||
}
|
||||
|
||||
// Transform
|
||||
SurfaceTransformFlags preTransform;
|
||||
if ((surfaceCapabilities.SupportedTransforms & SurfaceTransformFlags.Identity) != 0)
|
||||
{
|
||||
preTransform = SurfaceTransformFlags.Identity;
|
||||
}
|
||||
else
|
||||
{
|
||||
preTransform = surfaceCapabilities.CurrentTransform;
|
||||
}
|
||||
|
||||
// Present mode
|
||||
var presentModes = physicalDevice.GetSurfacePresentModes(surface);
|
||||
|
||||
var swapChainPresentMode = PresentMode.Fifo;
|
||||
if (presentModes.Contains(PresentMode.Mailbox))
|
||||
swapChainPresentMode = PresentMode.Mailbox;
|
||||
else if (presentModes.Contains(PresentMode.Immediate))
|
||||
swapChainPresentMode = PresentMode.Immediate;
|
||||
|
||||
// Create swapchain
|
||||
var swapchainCreateInfo = new SwapchainCreateInfo
|
||||
{
|
||||
StructureType = StructureType.SwapchainCreateInfo,
|
||||
Surface = surface,
|
||||
ImageSharingMode = SharingMode.Exclusive,
|
||||
ImageExtent = new Extent2D((uint)form.ClientSize.Width, (uint)form.ClientSize.Height),
|
||||
ImageArrayLayers = 1,
|
||||
ImageFormat = backBufferFormat,
|
||||
ImageColorSpace = ColorSpace.SRgbNonlinear,
|
||||
ImageUsage = ImageUsageFlags.ColorAttachment,
|
||||
PresentMode = swapChainPresentMode,
|
||||
CompositeAlpha = CompositeAlphaFlags.Opaque,
|
||||
MinImageCount = desiredImageCount,
|
||||
PreTransform = preTransform,
|
||||
Clipped = true
|
||||
// OldSwapchain =
|
||||
};
|
||||
swapchain = device.CreateSwapchain(ref swapchainCreateInfo);
|
||||
|
||||
// Initialize swapchain image layout
|
||||
backBuffers = device.GetSwapchainImages(swapchain);
|
||||
foreach (var image in backBuffers)
|
||||
{
|
||||
SetImageLayout(image, ImageAspectFlags.Color, ImageLayout.Undefined, ImageLayout.PresentSource);
|
||||
}
|
||||
Flush();
|
||||
}
|
||||
|
||||
protected virtual void CreateBackBufferViews()
|
||||
{
|
||||
|
||||
backBufferViews = new ImageView[backBuffers.Length];
|
||||
|
||||
for (var i = 0; i < backBuffers.Length; i++)
|
||||
{
|
||||
var createInfo = new ImageViewCreateInfo
|
||||
{
|
||||
StructureType = StructureType.ImageViewCreateInfo,
|
||||
ViewType = ImageViewType.Image2D,
|
||||
Format = backBufferFormat,
|
||||
Image = backBuffers[i],
|
||||
Components = ComponentMapping.Identity,
|
||||
SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1)
|
||||
};
|
||||
|
||||
backBufferViews[i] = device.CreateImageView(ref createInfo);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void CreateCommandBuffer()
|
||||
{
|
||||
// Command pool
|
||||
var commandPoolCreateInfo = new CommandPoolCreateInfo
|
||||
{
|
||||
StructureType = StructureType.CommandPoolCreateInfo,
|
||||
QueueFamilyIndex = 0,
|
||||
Flags = CommandPoolCreateFlags.ResetCommandBuffer
|
||||
};
|
||||
commandPool = device.CreateCommandPool(ref commandPoolCreateInfo);
|
||||
|
||||
// Command buffer
|
||||
var commandBufferAllocationInfo = new CommandBufferAllocateInfo
|
||||
{
|
||||
StructureType = StructureType.CommandBufferAllocateInfo,
|
||||
Level = CommandBufferLevel.Primary,
|
||||
CommandPool = commandPool,
|
||||
CommandBufferCount = 1
|
||||
};
|
||||
CommandBuffer commandBuffer;
|
||||
device.AllocateCommandBuffers(ref commandBufferAllocationInfo, &commandBuffer);
|
||||
this.commandBuffer = commandBuffer;
|
||||
}
|
||||
|
||||
private void CreateVertexBuffer()
|
||||
{
|
||||
var vertices = new[,]
|
||||
{
|
||||
{ 0.0f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f },
|
||||
{ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f },
|
||||
{ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f },
|
||||
};
|
||||
|
||||
var createInfo = new BufferCreateInfo
|
||||
{
|
||||
StructureType = StructureType.BufferCreateInfo,
|
||||
Usage = BufferUsageFlags.VertexBuffer,
|
||||
Size = (ulong)(sizeof(float) * vertices.Length)
|
||||
};
|
||||
vertexBuffer = device.CreateBuffer(ref createInfo);
|
||||
|
||||
MemoryRequirements memoryRequirements;
|
||||
device.GetBufferMemoryRequirements(vertexBuffer, out memoryRequirements);
|
||||
|
||||
if (memoryRequirements.Size == 0)
|
||||
return;
|
||||
|
||||
var allocateInfo = new MemoryAllocateInfo
|
||||
{
|
||||
StructureType = StructureType.MemoryAllocateInfo,
|
||||
AllocationSize = memoryRequirements.Size,
|
||||
MemoryTypeIndex = MemoryTypeFromProperties(memoryRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible)
|
||||
};
|
||||
vertexBufferMemory = device.AllocateMemory(ref allocateInfo);
|
||||
|
||||
var mapped = device.MapMemory(vertexBufferMemory, 0, (ulong)createInfo.Size, MemoryMapFlags.None);
|
||||
fixed (float* source = &vertices[0, 0]) Utilities.CopyMemory(mapped, new IntPtr(source), (int)createInfo.Size);
|
||||
device.UnmapMemory(vertexBufferMemory);
|
||||
|
||||
device.BindBufferMemory(vertexBuffer, vertexBufferMemory, 0);
|
||||
|
||||
vertexAttributes = new []
|
||||
{
|
||||
new VertexInputAttributeDescription { Binding = 0, Location = 0, Format = Format.R32G32B32SFloat, Offset = 0 },
|
||||
new VertexInputAttributeDescription { Binding = 0, Location = 1, Format = Format.R32G32B32SFloat, Offset = sizeof(float) * 3 },
|
||||
};
|
||||
|
||||
vertexBindings = new []
|
||||
{
|
||||
new VertexInputBindingDescription { Binding = 0, InputRate = VertexInputRate.Vertex, Stride = (uint)(sizeof(float) * vertices.GetLength(1)) }
|
||||
};
|
||||
}
|
||||
|
||||
private void CreateRenderPass()
|
||||
{
|
||||
var colorAttachmentReference = new AttachmentReference { Attachment = 0, Layout = ImageLayout.ColorAttachmentOptimal };
|
||||
var depthStencilAttachmentReference = new AttachmentReference { Attachment = 1, Layout = ImageLayout.DepthStencilAttachmentOptimal };
|
||||
|
||||
var subpass = new SubpassDescription
|
||||
{
|
||||
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||
ColorAttachmentCount = 1,
|
||||
ColorAttachments = new IntPtr(&colorAttachmentReference),
|
||||
};
|
||||
|
||||
var attachments = new[]
|
||||
{
|
||||
new AttachmentDescription
|
||||
{
|
||||
Format = backBufferFormat,
|
||||
Samples = SampleCountFlags.Sample1,
|
||||
LoadOperation = AttachmentLoadOperation.Load,
|
||||
StoreOperation = AttachmentStoreOperation.Store,
|
||||
StencilLoadOperation = AttachmentLoadOperation.DontCare,
|
||||
StencilStoreOperation = AttachmentStoreOperation.DontCare,
|
||||
InitialLayout = ImageLayout.ColorAttachmentOptimal,
|
||||
FinalLayout = ImageLayout.ColorAttachmentOptimal
|
||||
},
|
||||
};
|
||||
|
||||
fixed (AttachmentDescription* attachmentsPointer = &attachments[0])
|
||||
{
|
||||
var createInfo = new RenderPassCreateInfo
|
||||
{
|
||||
StructureType = StructureType.RenderPassCreateInfo,
|
||||
AttachmentCount = (uint)attachments.Length,
|
||||
Attachments = new IntPtr(attachmentsPointer),
|
||||
SubpassCount = 1,
|
||||
Subpasses = new IntPtr(&subpass)
|
||||
};
|
||||
|
||||
renderPass = device.CreateRenderPass(ref createInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateFramebuffers()
|
||||
{
|
||||
framebuffers = new Framebuffer[backBuffers.Length];
|
||||
for (int i = 0; i < backBuffers.Length; i++)
|
||||
{
|
||||
var attachment = backBufferViews[i];
|
||||
var createInfo = new FramebufferCreateInfo
|
||||
{
|
||||
StructureType = StructureType.FramebufferCreateInfo,
|
||||
RenderPass = renderPass,
|
||||
AttachmentCount = 1,
|
||||
Attachments = new IntPtr(&attachment),
|
||||
Width = (uint)form.ClientSize.Width,
|
||||
Height = (uint)form.ClientSize.Height,
|
||||
Layers = 1
|
||||
};
|
||||
framebuffers[i] = device.CreateFramebuffer(ref createInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreatePipelineLayout()
|
||||
{
|
||||
// We don't need any descriptors, since we don't use any resources/uniforms
|
||||
var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo { StructureType = StructureType.DescriptorSetLayoutCreateInfo };
|
||||
var descriptorSetLayout = device.CreateDescriptorSetLayout(ref descriptorSetLayoutCreateInfo);
|
||||
|
||||
var createInfo = new PipelineLayoutCreateInfo { StructureType = StructureType.PipelineLayoutCreateInfo };
|
||||
pipelineLayout = device.CreatePipelineLayout(ref createInfo);
|
||||
|
||||
// Destroy temporary layout
|
||||
device.DestroyDescriptorSetLayout(descriptorSetLayout);
|
||||
}
|
||||
|
||||
private void CreatePipeline()
|
||||
{
|
||||
var dynamicStates = new [] { DynamicState.Viewport, DynamicState.Scissor };
|
||||
|
||||
var entryPointName = System.Text.Encoding.UTF8.GetBytes("main\0");
|
||||
|
||||
fixed (byte* entryPointNamePointer = &entryPointName[0])
|
||||
fixed (DynamicState* dynamicStatesPointer = &dynamicStates[0])
|
||||
fixed (VertexInputAttributeDescription* vertexAttibutesPointer = &vertexAttributes[0])
|
||||
fixed (VertexInputBindingDescription* vertexBindingsPointer = &vertexBindings[0])
|
||||
{
|
||||
var dynamicState = new PipelineDynamicStateCreateInfo
|
||||
{
|
||||
StructureType = StructureType.PipelineDynamicStateCreateInfo,
|
||||
DynamicStateCount = (uint)dynamicStates.Length,
|
||||
DynamicStates = new IntPtr(dynamicStatesPointer)
|
||||
};
|
||||
|
||||
var viewportState = new PipelineViewportStateCreateInfo
|
||||
{
|
||||
StructureType = StructureType.PipelineViewportStateCreateInfo,
|
||||
ScissorCount = 1,
|
||||
ViewportCount = 1,
|
||||
};
|
||||
|
||||
var vertexInputState = new PipelineVertexInputStateCreateInfo
|
||||
{
|
||||
StructureType = StructureType.PipelineVertexInputStateCreateInfo,
|
||||
VertexAttributeDescriptionCount = (uint)vertexAttributes.Length,
|
||||
VertexAttributeDescriptions = new IntPtr(vertexAttibutesPointer),
|
||||
VertexBindingDescriptionCount = (uint)vertexBindings.Length,
|
||||
VertexBindingDescriptions = new IntPtr(vertexBindingsPointer),
|
||||
};
|
||||
|
||||
var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo
|
||||
{
|
||||
StructureType = StructureType.PipelineInputAssemblyStateCreateInfo,
|
||||
Topology = PrimitiveTopology.TriangleList
|
||||
};
|
||||
|
||||
var rasterizerState = new PipelineRasterizationStateCreateInfo
|
||||
{
|
||||
StructureType = StructureType.PipelineRasterizationStateCreateInfo,
|
||||
PolygonMode = PolygonMode.Fill,
|
||||
CullMode = CullModeFlags.None,
|
||||
FrontFace = FrontFace.Clockwise,
|
||||
};
|
||||
|
||||
var colorBlendAttachment = new PipelineColorBlendAttachmentState { ColorWriteMask = ColorComponentFlags.R | ColorComponentFlags.G | ColorComponentFlags.B | ColorComponentFlags.A };
|
||||
var blendState = new PipelineColorBlendStateCreateInfo
|
||||
{
|
||||
StructureType = StructureType.PipelineColorBlendStateCreateInfo,
|
||||
AttachmentCount = 1,
|
||||
Attachments = new IntPtr(&colorBlendAttachment)
|
||||
};
|
||||
|
||||
var depthStencilState = new PipelineDepthStencilStateCreateInfo
|
||||
{
|
||||
StructureType = StructureType.PipelineDepthStencilStateCreateInfo,
|
||||
DepthTestEnable = false,
|
||||
DepthWriteEnable = true,
|
||||
DepthCompareOperation = CompareOperation.LessOrEqual,
|
||||
Back = new StencilOperationState { CompareOperation = CompareOperation.Always },
|
||||
Front = new StencilOperationState { CompareOperation = CompareOperation.Always }
|
||||
};
|
||||
|
||||
var shaderStages = new[]
|
||||
{
|
||||
new PipelineShaderStageCreateInfo
|
||||
{
|
||||
StructureType = StructureType.PipelineShaderStageCreateInfo,
|
||||
Name = new IntPtr(entryPointNamePointer),
|
||||
Stage = ShaderStageFlags.Vertex,
|
||||
Module = CreateVertexShader()
|
||||
},
|
||||
new PipelineShaderStageCreateInfo
|
||||
{
|
||||
StructureType = StructureType.PipelineShaderStageCreateInfo,
|
||||
Name = new IntPtr(entryPointNamePointer),
|
||||
Stage = ShaderStageFlags.Fragment,
|
||||
Module = CreateFragmentShader()
|
||||
}
|
||||
};
|
||||
|
||||
fixed (PipelineShaderStageCreateInfo* shaderStagesPointer = &shaderStages[0])
|
||||
{
|
||||
var createInfo = new GraphicsPipelineCreateInfo
|
||||
{
|
||||
StructureType = StructureType.GraphicsPipelineCreateInfo,
|
||||
Layout = pipelineLayout,
|
||||
DynamicState = new IntPtr(&dynamicState),
|
||||
ViewportState = new IntPtr(&viewportState),
|
||||
VertexInputState = new IntPtr(&vertexInputState),
|
||||
InputAssemblyState = new IntPtr(&inputAssemblyState),
|
||||
RasterizationState = new IntPtr(&rasterizerState),
|
||||
ColorBlendState = new IntPtr(&blendState),
|
||||
DepthStencilState = new IntPtr(&depthStencilState),
|
||||
StageCount = (uint)shaderStages.Length,
|
||||
Stages = new IntPtr(shaderStagesPointer),
|
||||
RenderPass = renderPass
|
||||
};
|
||||
pipeline = device.CreateGraphicsPipelines(PipelineCache.Null, 1, &createInfo);
|
||||
}
|
||||
|
||||
foreach (var shaderStage in shaderStages)
|
||||
{
|
||||
device.DestroyShaderModule(shaderStage.Module);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ShaderModule CreateVertexShader()
|
||||
{
|
||||
var bytes = File.ReadAllBytes("vert.spv");
|
||||
return CreateShaderModule(bytes);
|
||||
}
|
||||
|
||||
private ShaderModule CreateFragmentShader()
|
||||
{
|
||||
var bytes = File.ReadAllBytes("frag.spv");
|
||||
return CreateShaderModule(bytes);
|
||||
}
|
||||
|
||||
private ShaderModule CreateShaderModule(byte[] shaderCode)
|
||||
{
|
||||
fixed (byte* codePointer = &shaderCode[0])
|
||||
{
|
||||
var createInfo = new ShaderModuleCreateInfo
|
||||
{
|
||||
StructureType = StructureType.ShaderModuleCreateInfo,
|
||||
CodeSize = shaderCode.Length,
|
||||
Code = new IntPtr(codePointer)
|
||||
};
|
||||
return device.CreateShaderModule(ref createInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private uint MemoryTypeFromProperties(uint typeBits, MemoryPropertyFlags memoryProperties)
|
||||
{
|
||||
PhysicalDeviceMemoryProperties physicalDeviceMemoryProperties;
|
||||
physicalDevice.GetMemoryProperties(out physicalDeviceMemoryProperties);
|
||||
for (uint i = 0; i < physicalDeviceMemoryProperties.MemoryTypeCount; i++)
|
||||
{
|
||||
if ((typeBits & 1) == 1)
|
||||
{
|
||||
// Type is available, does it match user properties?
|
||||
var memoryType = *((MemoryType*)&physicalDeviceMemoryProperties.MemoryTypes + i);
|
||||
if ((memoryType.PropertyFlags & memoryProperties) == memoryProperties)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
typeBits >>= 1;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
protected virtual void Draw()
|
||||
{
|
||||
var semaphoreCreateInfo = new SemaphoreCreateInfo { StructureType = StructureType.SemaphoreCreateInfo };
|
||||
var presentCompleteSemaphore = device.CreateSemaphore(ref semaphoreCreateInfo);
|
||||
|
||||
try
|
||||
{
|
||||
// Get the index of the next available swapchain image
|
||||
currentBackBufferIndex = device.AcquireNextImage(this.swapchain, ulong.MaxValue, presentCompleteSemaphore, Fence.Null);
|
||||
}
|
||||
catch (SharpVulkanException e) when (e.Result == Result.ErrorOutOfDate)
|
||||
{
|
||||
// TODO: Handle resize and retry draw
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
// Record drawing command buffer
|
||||
var beginInfo = new CommandBufferBeginInfo { StructureType = StructureType.CommandBufferBeginInfo };
|
||||
commandBuffer.Begin(ref beginInfo);
|
||||
DrawInternal();
|
||||
commandBuffer.End();
|
||||
|
||||
// Submit
|
||||
var drawCommandBuffer = commandBuffer;
|
||||
var pipelineStageFlags = PipelineStageFlags.BottomOfPipe;
|
||||
var submitInfo = new SubmitInfo
|
||||
{
|
||||
StructureType = StructureType.SubmitInfo,
|
||||
WaitSemaphoreCount = 1,
|
||||
WaitSemaphores = new IntPtr(&presentCompleteSemaphore),
|
||||
WaitDstStageMask = new IntPtr(&pipelineStageFlags),
|
||||
CommandBufferCount = 1,
|
||||
CommandBuffers = new IntPtr(&drawCommandBuffer),
|
||||
};
|
||||
queue.Submit(1, &submitInfo, Fence.Null);
|
||||
|
||||
// Present
|
||||
var swapchain = this.swapchain;
|
||||
var currentBackBufferIndexCopy = currentBackBufferIndex;
|
||||
var presentInfo = new PresentInfo
|
||||
{
|
||||
StructureType = StructureType.PresentInfo,
|
||||
SwapchainCount = 1,
|
||||
Swapchains = new IntPtr(&swapchain),
|
||||
ImageIndices = new IntPtr(¤tBackBufferIndexCopy)
|
||||
};
|
||||
queue.Present(ref presentInfo);
|
||||
|
||||
// Wait
|
||||
queue.WaitIdle();
|
||||
|
||||
// Cleanup
|
||||
device.DestroySemaphore(presentCompleteSemaphore);
|
||||
}
|
||||
|
||||
private void DrawInternal()
|
||||
{
|
||||
// Post-present transition
|
||||
var memoryBarrier = new ImageMemoryBarrier
|
||||
{
|
||||
StructureType = StructureType.ImageMemoryBarrier,
|
||||
Image = backBuffers[currentBackBufferIndex],
|
||||
SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
|
||||
OldLayout = ImageLayout.PresentSource,
|
||||
NewLayout = ImageLayout.ColorAttachmentOptimal,
|
||||
SourceAccessMask = AccessFlags.MemoryRead,
|
||||
DestinationAccessMask = AccessFlags.ColorAttachmentWrite
|
||||
};
|
||||
commandBuffer.PipelineBarrier(PipelineStageFlags.TopOfPipe, PipelineStageFlags.TopOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier);
|
||||
|
||||
// Clear render target
|
||||
var clearRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 0, 0, 1);
|
||||
commandBuffer.ClearColorImage(backBuffers[currentBackBufferIndex], ImageLayout.TransferDestinationOptimal, new RawColor4(1, 0, 1, 1), 1, &clearRange);
|
||||
|
||||
// Begin render pass
|
||||
var renderPassBeginInfo = new RenderPassBeginInfo
|
||||
{
|
||||
StructureType = StructureType.RenderPassBeginInfo,
|
||||
RenderPass = renderPass,
|
||||
Framebuffer = framebuffers[currentBackBufferIndex],
|
||||
RenderArea = new Rect2D(0, 0, (uint)form.ClientSize.Width, (uint)form.ClientSize.Height),
|
||||
};
|
||||
commandBuffer.BeginRenderPass(ref renderPassBeginInfo, SubpassContents.Inline);
|
||||
|
||||
// Bind pipeline
|
||||
commandBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline);
|
||||
|
||||
// Set viewport and scissor
|
||||
var viewport = new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height);
|
||||
commandBuffer.SetViewport(0, 1, &viewport);
|
||||
|
||||
var scissor = new Rect2D(0, 0, (uint)form.ClientSize.Width, (uint)form.ClientSize.Height);
|
||||
commandBuffer.SetScissor(0, 1, &scissor);
|
||||
|
||||
// Bind vertex buffer
|
||||
var vertexBufferCopy = vertexBuffer;
|
||||
ulong offset = 0;
|
||||
commandBuffer.BindVertexBuffers(0, 1, &vertexBufferCopy, &offset);
|
||||
|
||||
// Draw vertices
|
||||
commandBuffer.Draw(3, 1, 0, 0);
|
||||
|
||||
// End render pass
|
||||
commandBuffer.EndRenderPass();
|
||||
|
||||
// Pre-present transition
|
||||
memoryBarrier = new ImageMemoryBarrier
|
||||
{
|
||||
StructureType = StructureType.ImageMemoryBarrier,
|
||||
Image = backBuffers[currentBackBufferIndex],
|
||||
SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
|
||||
OldLayout = ImageLayout.ColorAttachmentOptimal,
|
||||
NewLayout = ImageLayout.PresentSource,
|
||||
SourceAccessMask = AccessFlags.ColorAttachmentWrite,
|
||||
DestinationAccessMask = AccessFlags.MemoryRead
|
||||
};
|
||||
commandBuffer.PipelineBarrier(PipelineStageFlags.AllCommands, PipelineStageFlags.BottomOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier);
|
||||
}
|
||||
|
||||
private void SetImageLayout(Image image, ImageAspectFlags imageAspect, ImageLayout oldLayout, ImageLayout newLayout)
|
||||
{
|
||||
if (setupCommanBuffer == CommandBuffer.Null)
|
||||
{
|
||||
// Create command buffer
|
||||
CommandBuffer setupCommandBuffer;
|
||||
var allocateInfo = new CommandBufferAllocateInfo
|
||||
{
|
||||
StructureType = StructureType.CommandBufferAllocateInfo,
|
||||
CommandPool = commandPool,
|
||||
Level = CommandBufferLevel.Primary,
|
||||
CommandBufferCount = 1,
|
||||
};
|
||||
device.AllocateCommandBuffers(ref allocateInfo, &setupCommandBuffer);
|
||||
setupCommanBuffer = setupCommandBuffer;
|
||||
|
||||
// Begin command buffer
|
||||
var inheritanceInfo = new CommandBufferInheritanceInfo { StructureType = StructureType.CommandBufferInheritanceInfo };
|
||||
var beginInfo = new CommandBufferBeginInfo
|
||||
{
|
||||
StructureType = StructureType.CommandBufferBeginInfo,
|
||||
InheritanceInfo = new IntPtr(&inheritanceInfo)
|
||||
};
|
||||
setupCommanBuffer.Begin(ref beginInfo);
|
||||
}
|
||||
|
||||
var imageMemoryBarrier = new ImageMemoryBarrier
|
||||
{
|
||||
StructureType = StructureType.ImageMemoryBarrier,
|
||||
OldLayout = oldLayout,
|
||||
NewLayout = newLayout,
|
||||
Image = image,
|
||||
SubresourceRange = new ImageSubresourceRange(imageAspect, 0, 1, 0, 1)
|
||||
};
|
||||
|
||||
switch (newLayout)
|
||||
{
|
||||
case ImageLayout.TransferDestinationOptimal:
|
||||
imageMemoryBarrier.DestinationAccessMask = AccessFlags.TransferRead;
|
||||
break;
|
||||
case ImageLayout.ColorAttachmentOptimal:
|
||||
imageMemoryBarrier.DestinationAccessMask = AccessFlags.ColorAttachmentWrite;
|
||||
break;
|
||||
case ImageLayout.DepthStencilAttachmentOptimal:
|
||||
imageMemoryBarrier.DestinationAccessMask = AccessFlags.DepthStencilAttachmentWrite;
|
||||
break;
|
||||
case ImageLayout.ShaderReadOnlyOptimal:
|
||||
imageMemoryBarrier.DestinationAccessMask = AccessFlags.ShaderRead | AccessFlags.InputAttachmentRead;
|
||||
break;
|
||||
}
|
||||
|
||||
var sourceStages = PipelineStageFlags.TopOfPipe;
|
||||
var destinationStages = PipelineStageFlags.TopOfPipe;
|
||||
|
||||
setupCommanBuffer.PipelineBarrier(sourceStages, destinationStages, DependencyFlags.None, 0, null, 0, null, 1, &imageMemoryBarrier);
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
if (this.setupCommanBuffer == CommandBuffer.Null)
|
||||
return;
|
||||
|
||||
var setupCommanBuffer = this.setupCommanBuffer;
|
||||
|
||||
this.setupCommanBuffer.End();
|
||||
|
||||
var submitInfo = new SubmitInfo
|
||||
{
|
||||
StructureType = StructureType.SubmitInfo,
|
||||
CommandBufferCount = 1,
|
||||
CommandBuffers = new IntPtr(&setupCommanBuffer)
|
||||
};
|
||||
|
||||
queue.Submit(1, &submitInfo, Fence.Null);
|
||||
|
||||
queue.WaitIdle();
|
||||
|
||||
device.FreeCommandBuffers(commandPool, 1, &setupCommanBuffer);
|
||||
|
||||
this.setupCommanBuffer = CommandBuffer.Null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
device.WaitIdle();
|
||||
|
||||
device.FreeMemory(vertexBufferMemory);
|
||||
device.DestroyBuffer(vertexBuffer);
|
||||
|
||||
foreach (var framebuffer in framebuffers)
|
||||
device.DestroyFramebuffer(framebuffer);
|
||||
|
||||
device.DestroyRenderPass(renderPass);
|
||||
device.DestroyPipeline(pipeline);
|
||||
device.DestroyPipelineLayout(pipelineLayout);
|
||||
|
||||
var commandBufferCopy = commandBuffer;
|
||||
device.FreeCommandBuffers(commandPool, 1, &commandBufferCopy);
|
||||
device.DestroyCommandPool(commandPool);
|
||||
|
||||
foreach (var backBufferView in backBufferViews)
|
||||
device.DestroyImageView(backBufferView);
|
||||
|
||||
device.DestroySwapchain(swapchain);
|
||||
instance.DestroySurface(surface);
|
||||
|
||||
device.Destroy();
|
||||
|
||||
if (debugReportCallback != DebugReportCallback.Null)
|
||||
{
|
||||
var destroyDebugReportCallbackName = Encoding.ASCII.GetBytes("vkDestroyDebugReportCallbackEXT");
|
||||
fixed (byte* destroyDebugReportCallbackNamePointer = &destroyDebugReportCallbackName[0])
|
||||
{
|
||||
var destroyDebugReportCallback = Marshal.GetDelegateForFunctionPointer<DestroyDebugReportCallbackDelegate>(instance.GetProcAddress(destroyDebugReportCallbackNamePointer));
|
||||
destroyDebugReportCallback(instance, debugReportCallback, null);
|
||||
}
|
||||
}
|
||||
instance.Destroy();
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)]
|
||||
private unsafe delegate RawBool DebugReportCallbackDelegate(DebugReportFlags flags, DebugReportObjectType objectType, ulong @object, PointerSize location, int messageCode, string layerPrefix, string message, IntPtr userData);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
private unsafe delegate Result CreateDebugReportCallbackDelegate(Instance instance, ref DebugReportCallbackCreateInfo createInfo, AllocationCallbacks* allocator, out DebugReportCallback callback);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
private unsafe delegate Result DestroyDebugReportCallbackDelegate(Instance instance, DebugReportCallback debugReportCallback, AllocationCallbacks* allocator);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/></startup></configuration>
|
Двоичный файл не отображается.
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="SharpDX" version="3.0.2" targetFramework="net452" />
|
||||
<package id="SharpDX.Desktop" version="3.0.2" targetFramework="net452" />
|
||||
</packages>
|
Двоичный файл не отображается.
|
@ -0,0 +1,22 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniTri", "MiniTri\MiniTri.csproj", "{96426D44-3995-44F5-85C0-901027203313}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{96426D44-3995-44F5-85C0-901027203313}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{96426D44-3995-44F5-85C0-901027203313}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{96426D44-3995-44F5-85C0-901027203313}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{96426D44-3995-44F5-85C0-901027203313}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -9,24 +9,24 @@
|
|||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SharpVulkan</RootNamespace>
|
||||
<AssemblyName>SharpVulkan</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<OutputPath>$(SolutionDir)\Bin\</OutputPath>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
|
|
Загрузка…
Ссылка в новой задаче