This commit is contained in:
Jörg Wollenschläger 2016-04-02 16:22:24 +09:00
Родитель 4fda327c1b
Коммит 42438ea39a
13 изменённых файлов: 1157 добавлений и 4 удалений

Просмотреть файл

@ -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")]

900
Samples/MiniTri/Sample.cs Normal file
Просмотреть файл

@ -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(&currentBackBufferIndexCopy)
};
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>

Двоичные данные
Samples/MiniTri/frag.spv Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -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>

Двоичные данные
Samples/MiniTri/vert.spv Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -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>