123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826 |
- using System;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Numerics;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using Avalonia;
- using Avalonia.Threading;
- using Silk.NET.Vulkan;
- using SilkNetDemo;
- using Buffer = System.Buffer;
- using Image = Silk.NET.Vulkan.Image;
- namespace GpuInterop.VulkanDemo;
- unsafe class VulkanContent : IDisposable
- {
- private readonly VulkanContext _context;
- private ShaderModule _vertShader;
- private ShaderModule _fragShader;
- private PipelineLayout _pipelineLayout;
- private RenderPass _renderPass;
- private Pipeline _pipeline;
- private DescriptorSetLayout _descriptorSetLayout;
- private Silk.NET.Vulkan.Buffer _vertexBuffer;
- private DeviceMemory _vertexBufferMemory;
- private Silk.NET.Vulkan.Buffer _indexBuffer;
- private DeviceMemory _indexBufferMemory;
- private Silk.NET.Vulkan.Buffer _uniformBuffer;
- private DeviceMemory _uniformBufferMemory;
- private Framebuffer _framebuffer;
- private Image _depthImage;
- private DeviceMemory _depthImageMemory;
- private ImageView _depthImageView;
- public VulkanContent(VulkanContext context)
- {
- _context = context;
- var name = typeof(VulkanContent).Assembly.GetManifestResourceNames().First(x => x.Contains("teapot.bin"));
- using (var sr = new BinaryReader(typeof(VulkanContent).Assembly.GetManifestResourceStream(name)!))
- {
- var buf = new byte[sr.ReadInt32()];
- sr.Read(buf, 0, buf.Length);
- var points = new float[buf.Length / 4];
- Buffer.BlockCopy(buf, 0, points, 0, buf.Length);
- buf = new byte[sr.ReadInt32()];
- sr.Read(buf, 0, buf.Length);
- _indices = new ushort[buf.Length / 2];
- Buffer.BlockCopy(buf, 0, _indices, 0, buf.Length);
- _points = new Vertex[points.Length / 3];
- for (var primitive = 0; primitive < points.Length / 3; primitive++)
- {
- var srci = primitive * 3;
- _points[primitive] = new Vertex
- {
- Position = new Vector3(points[srci], points[srci + 1], points[srci + 2])
- };
- }
- for (int i = 0; i < _indices.Length; i += 3)
- {
- Vector3 a = _points[_indices[i]].Position;
- Vector3 b = _points[_indices[i + 1]].Position;
- Vector3 c = _points[_indices[i + 2]].Position;
- var normal = Vector3.Normalize(Vector3.Cross(c - b, a - b));
- _points[_indices[i]].Normal += normal;
- _points[_indices[i + 1]].Normal += normal;
- _points[_indices[i + 2]].Normal += normal;
- }
- for (int i = 0; i < _points.Length; i++)
- {
- _points[i].Normal = Vector3.Normalize(_points[i].Normal);
- _maxY = Math.Max(_maxY, _points[i].Position.Y);
- _minY = Math.Min(_minY, _points[i].Position.Y);
- }
- }
- var api = _context.Api;
- var device = _context.Device;
- var vertShaderData = GetShader(false);
- var fragShaderData = GetShader(true);
- fixed (byte* ptr = vertShaderData)
- {
- var shaderCreateInfo = new ShaderModuleCreateInfo()
- {
- SType = StructureType.ShaderModuleCreateInfo,
- CodeSize = (nuint)vertShaderData.Length,
- PCode = (uint*)ptr,
- };
- api.CreateShaderModule(device, shaderCreateInfo, null, out _vertShader);
- }
- fixed (byte* ptr = fragShaderData)
- {
- var shaderCreateInfo = new ShaderModuleCreateInfo()
- {
- SType = StructureType.ShaderModuleCreateInfo,
- CodeSize = (nuint)fragShaderData.Length,
- PCode = (uint*)ptr,
- };
- api.CreateShaderModule(device, shaderCreateInfo, null, out _fragShader);
- }
- CreateBuffers();
- }
- private byte[] GetShader(bool fragment)
- {
- var name = typeof(VulkanContent).Assembly.GetManifestResourceNames()
- .First(x => x.Contains((fragment ? "frag" : "vert") + ".spirv"));
- using (var sr = typeof(VulkanContent).Assembly.GetManifestResourceStream(name)!)
- {
- using (var mem = new MemoryStream())
- {
- sr.CopyTo(mem);
- return mem.ToArray();
- }
- }
- }
- private PixelSize? _previousImageSize = PixelSize.Empty;
-
- public void Render(VulkanImage image,
- double yaw, double pitch, double roll, double disco)
- {
- var api = _context.Api;
-
- if (image.Size != _previousImageSize)
- CreateTemporalObjects(image.Size);
- _previousImageSize = image.Size;
-
- var model = Matrix4x4.CreateFromYawPitchRoll((float)yaw, (float)pitch, (float)roll);
- var vertexConstant = new VertexPushConstant()
- {
- Disco = (float)disco,
- MinY = _minY,
- MaxY = _maxY,
- Model = model,
- Time = (float)(St.Elapsed.Ticks % (TimeSpan.TicksPerSecond * 40) / (double)TimeSpan.TicksPerSecond)
- };
- var commandBuffer = _context.Pool.CreateCommandBuffer();
- commandBuffer.BeginRecording();
- _colorAttachment!.TransitionLayout(commandBuffer.InternalHandle,
- ImageLayout.Undefined, AccessFlags.None,
- ImageLayout.ColorAttachmentOptimal, AccessFlags.ColorAttachmentWriteBit);
- var commandBufferHandle = new CommandBuffer(commandBuffer.Handle);
- api.CmdSetViewport(commandBufferHandle, 0, 1,
- new Viewport()
- {
- Width = (float)image.Size.Width,
- Height = (float)image.Size.Height,
- MaxDepth = 1,
- MinDepth = 0,
- X = 0,
- Y = 0
- });
- var scissor = new Rect2D
- {
- Extent = new Extent2D((uint?)image.Size.Width, (uint?)image.Size.Height)
- };
- api.CmdSetScissor(commandBufferHandle, 0, 1, &scissor);
- var clearValues = new ClearValue[]
- {
- new() { Color = new ClearColorValue { Float32_0 = 1, Float32_1 = 0, Float32_2 = 0, Float32_3 = 0.1f } },
- new() { DepthStencil = new ClearDepthStencilValue { Depth = 1, Stencil = 0 } }
- };
- fixed (ClearValue* clearValue = clearValues)
- {
- var beginInfo = new RenderPassBeginInfo()
- {
- SType = StructureType.RenderPassBeginInfo,
- RenderPass = _renderPass,
- Framebuffer = _framebuffer,
- RenderArea = new Rect2D(new Offset2D(0, 0), new Extent2D((uint?)image.Size.Width, (uint?)image.Size.Height)),
- ClearValueCount = (uint)clearValues.Length,
- PClearValues = clearValue
- };
- api.CmdBeginRenderPass(commandBufferHandle, beginInfo, SubpassContents.Inline);
- }
- api.CmdBindPipeline(commandBufferHandle, PipelineBindPoint.Graphics, _pipeline);
- var dset = _descriptorSet;
- api.CmdBindDescriptorSets(commandBufferHandle, PipelineBindPoint.Graphics,
- _pipelineLayout,0,1, &dset, null);
- api.CmdPushConstants(commandBufferHandle, _pipelineLayout, ShaderStageFlags.VertexBit | ShaderStageFlags.FragmentBit, 0,
- (uint)Marshal.SizeOf<VertexPushConstant>(), &vertexConstant);
- api.CmdBindVertexBuffers(commandBufferHandle, 0, 1, _vertexBuffer, 0);
- api.CmdBindIndexBuffer(commandBufferHandle, _indexBuffer, 0, IndexType.Uint16);
- api.CmdDrawIndexed(commandBufferHandle, (uint)_indices.Length, 1, 0, 0, 0);
-
- api.CmdEndRenderPass(commandBufferHandle);
-
- _colorAttachment.TransitionLayout(commandBuffer.InternalHandle, ImageLayout.TransferSrcOptimal, AccessFlags.TransferReadBit);
- image.TransitionLayout(commandBuffer.InternalHandle, ImageLayout.TransferDstOptimal, AccessFlags.TransferWriteBit);
-
-
- var srcBlitRegion = new ImageBlit
- {
- SrcOffsets = new ImageBlit.SrcOffsetsBuffer
- {
- Element0 = new Offset3D(0, 0, 0),
- Element1 = new Offset3D(image.Size.Width, image.Size.Height, 1),
- },
- DstOffsets = new ImageBlit.DstOffsetsBuffer
- {
- Element0 = new Offset3D(0, 0, 0),
- Element1 = new Offset3D(image.Size.Width, image.Size.Height, 1),
- },
- SrcSubresource =
- new ImageSubresourceLayers
- {
- AspectMask = ImageAspectFlags.ColorBit,
- BaseArrayLayer = 0,
- LayerCount = 1,
- MipLevel = 0
- },
- DstSubresource = new ImageSubresourceLayers
- {
- AspectMask = ImageAspectFlags.ColorBit,
- BaseArrayLayer = 0,
- LayerCount = 1,
- MipLevel = 0
- }
- };
- api.CmdBlitImage(commandBuffer.InternalHandle, _colorAttachment.InternalHandle,
- ImageLayout.TransferSrcOptimal,
- image.InternalHandle, ImageLayout.TransferDstOptimal, 1, srcBlitRegion, Filter.Linear);
-
- commandBuffer.Submit();
- }
- public unsafe void Dispose()
- {
- if (_isInit)
- {
- var api = _context.Api;
- var device = _context.Device;
- DestroyTemporalObjects();
- api.DestroyShaderModule(device, _vertShader, null);
- api.DestroyShaderModule(device, _fragShader, null);
- api.DestroyBuffer(device, _vertexBuffer, null);
- api.FreeMemory(device, _vertexBufferMemory, null);
- api.DestroyBuffer(device, _indexBuffer, null);
- api.FreeMemory(device, _indexBufferMemory, null);
-
-
- }
- _isInit = false;
- }
- public unsafe void DestroyTemporalObjects()
- {
- if (_isInit)
- {
- if (_renderPass.Handle != 0)
- {
- var api = _context.Api;
- var device = _context.Device;
- api.FreeDescriptorSets(_context.Device, _context.DescriptorPool, new[] { _descriptorSet });
-
- api.DestroyImageView(device, _depthImageView, null);
- api.DestroyImage(device, _depthImage, null);
- api.FreeMemory(device, _depthImageMemory, null);
- api.DestroyFramebuffer(device, _framebuffer, null);
- api.DestroyPipeline(device, _pipeline, null);
- api.DestroyPipelineLayout(device, _pipelineLayout, null);
- api.DestroyRenderPass(device, _renderPass, null);
- api.DestroyDescriptorSetLayout(device, _descriptorSetLayout, null);
-
- api.DestroyBuffer(device, _uniformBuffer, null);
- api.FreeMemory(device, _uniformBufferMemory, null);
- _colorAttachment?.Dispose();
- _colorAttachment = null;
- _depthImage = default;
- _depthImageView = default;
- _depthImageView = default;
- _framebuffer = default;
- _pipeline = default;
- _renderPass = default;
- _pipelineLayout = default;
- _descriptorSetLayout = default;
- _uniformBuffer = default;
- _uniformBufferMemory = default;
- }
- }
- }
- private unsafe void CreateDepthAttachment(PixelSize size)
- {
- var imageCreateInfo = new ImageCreateInfo
- {
- SType = StructureType.ImageCreateInfo,
- ImageType = ImageType.Type2D,
- Format = Format.D32Sfloat,
- Extent =
- new Extent3D((uint?)size.Width,
- (uint?)size.Height, 1),
- MipLevels = 1,
- ArrayLayers = 1,
- Samples = SampleCountFlags.Count1Bit,
- Tiling = ImageTiling.Optimal,
- Usage = ImageUsageFlags.DepthStencilAttachmentBit,
- SharingMode = SharingMode.Exclusive,
- InitialLayout = ImageLayout.Undefined,
- Flags = ImageCreateFlags.CreateMutableFormatBit
- };
- var api = _context.Api;
- var device = _context.Device;
- api
- .CreateImage(device, imageCreateInfo, null, out _depthImage).ThrowOnError();
- api.GetImageMemoryRequirements(device, _depthImage,
- out var memoryRequirements);
- var memoryAllocateInfo = new MemoryAllocateInfo
- {
- SType = StructureType.MemoryAllocateInfo,
- AllocationSize = memoryRequirements.Size,
- MemoryTypeIndex = (uint)FindSuitableMemoryTypeIndex(api,
- _context.PhysicalDevice,
- memoryRequirements.MemoryTypeBits, MemoryPropertyFlags.DeviceLocalBit)
- };
- api.AllocateMemory(device, memoryAllocateInfo, null,
- out _depthImageMemory).ThrowOnError();
- api.BindImageMemory(device, _depthImage, _depthImageMemory, 0);
- var componentMapping = new ComponentMapping(
- ComponentSwizzle.R,
- ComponentSwizzle.G,
- ComponentSwizzle.B,
- ComponentSwizzle.A);
- var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.DepthBit,
- 0, 1, 0, 1);
- var imageViewCreateInfo = new ImageViewCreateInfo
- {
- SType = StructureType.ImageViewCreateInfo,
- Image = _depthImage,
- ViewType = ImageViewType.Type2D,
- Format = Format.D32Sfloat,
- Components = componentMapping,
- SubresourceRange = subresourceRange
- };
- api
- .CreateImageView(device, imageViewCreateInfo, null, out _depthImageView)
- .ThrowOnError();
- }
- private unsafe void CreateTemporalObjects(PixelSize size)
- {
- DestroyTemporalObjects();
-
- var view = Matrix4x4.CreateLookAt(new Vector3(25, 25, 25), new Vector3(), new Vector3(0, -1, 0));
- var projection =
- Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.PI / 4), (float)size.Width / size.Height,
- 0.01f, 1000);
-
- _colorAttachment = new VulkanImage(_context, (uint)Format.R8G8B8A8Unorm, size, false, Array.Empty<string>());
- CreateDepthAttachment(size);
- var api = _context.Api;
- var device = _context.Device;
-
- // create renderpasses
- var colorAttachment = new AttachmentDescription()
- {
- Format = Format.R8G8B8A8Unorm,
- Samples = SampleCountFlags.Count1Bit,
- LoadOp = AttachmentLoadOp.Clear,
- StoreOp = AttachmentStoreOp.Store,
- InitialLayout = ImageLayout.Undefined,
- FinalLayout = ImageLayout.ColorAttachmentOptimal,
- StencilLoadOp = AttachmentLoadOp.DontCare,
- StencilStoreOp = AttachmentStoreOp.DontCare
- };
- var depthAttachment = new AttachmentDescription()
- {
- Format = Format.D32Sfloat,
- Samples = SampleCountFlags.Count1Bit,
- LoadOp = AttachmentLoadOp.Clear,
- StoreOp = AttachmentStoreOp.DontCare,
- InitialLayout = ImageLayout.Undefined,
- FinalLayout = ImageLayout.DepthStencilAttachmentOptimal,
- StencilLoadOp = AttachmentLoadOp.DontCare,
- StencilStoreOp = AttachmentStoreOp.DontCare
- };
- var subpassDependency = new SubpassDependency()
- {
- SrcSubpass = Vk.SubpassExternal,
- DstSubpass = 0,
- SrcStageMask = PipelineStageFlags.ColorAttachmentOutputBit,
- SrcAccessMask = 0,
- DstStageMask = PipelineStageFlags.ColorAttachmentOutputBit,
- DstAccessMask = AccessFlags.ColorAttachmentWriteBit
- };
- var colorAttachmentReference = new AttachmentReference()
- {
- Attachment = 0, Layout = ImageLayout.ColorAttachmentOptimal
- };
- var depthAttachmentReference = new AttachmentReference()
- {
- Attachment = 1, Layout = ImageLayout.DepthStencilAttachmentOptimal
- };
- var subpassDescription = new SubpassDescription()
- {
- PipelineBindPoint = PipelineBindPoint.Graphics,
- ColorAttachmentCount = 1,
- PColorAttachments = &colorAttachmentReference,
- PDepthStencilAttachment = &depthAttachmentReference
- };
- var attachments = new[] { colorAttachment, depthAttachment };
- fixed (AttachmentDescription* atPtr = attachments)
- {
- var renderPassCreateInfo = new RenderPassCreateInfo()
- {
- SType = StructureType.RenderPassCreateInfo,
- AttachmentCount = (uint)attachments.Length,
- PAttachments = atPtr,
- SubpassCount = 1,
- PSubpasses = &subpassDescription,
- DependencyCount = 1,
- PDependencies = &subpassDependency
- };
- api.CreateRenderPass(device, renderPassCreateInfo, null, out _renderPass).ThrowOnError();
- // create framebuffer
- var frameBufferAttachments = new[] { new ImageView(_colorAttachment.ViewHandle), _depthImageView };
- fixed (ImageView* frAtPtr = frameBufferAttachments)
- {
- var framebufferCreateInfo = new FramebufferCreateInfo()
- {
- SType = StructureType.FramebufferCreateInfo,
- RenderPass = _renderPass,
- AttachmentCount = (uint)frameBufferAttachments.Length,
- PAttachments = frAtPtr,
- Width = (uint)size.Width,
- Height = (uint)size.Height,
- Layers = 1
- };
- api.CreateFramebuffer(device, framebufferCreateInfo, null, out _framebuffer).ThrowOnError();
- }
- }
- // Create pipeline
- var pname = Marshal.StringToHGlobalAnsi("main");
- var vertShaderStageInfo = new PipelineShaderStageCreateInfo()
- {
- SType = StructureType.PipelineShaderStageCreateInfo,
- Stage = ShaderStageFlags.VertexBit,
- Module = _vertShader,
- PName = (byte*)pname,
- };
- var fragShaderStageInfo = new PipelineShaderStageCreateInfo()
- {
- SType = StructureType.PipelineShaderStageCreateInfo,
- Stage = ShaderStageFlags.FragmentBit,
- Module = _fragShader,
- PName = (byte*)pname,
- };
- var stages = new[] { vertShaderStageInfo, fragShaderStageInfo };
- var bindingDescription = Vertex.VertexInputBindingDescription;
- var attributeDescription = Vertex.VertexInputAttributeDescription;
- fixed (VertexInputAttributeDescription* attrPtr = attributeDescription)
- {
- var vertextInputInfo = new PipelineVertexInputStateCreateInfo()
- {
- SType = StructureType.PipelineVertexInputStateCreateInfo,
- VertexAttributeDescriptionCount = (uint)attributeDescription.Length,
- VertexBindingDescriptionCount = 1,
- PVertexAttributeDescriptions = attrPtr,
- PVertexBindingDescriptions = &bindingDescription
- };
- var inputAssembly = new PipelineInputAssemblyStateCreateInfo()
- {
- SType = StructureType.PipelineInputAssemblyStateCreateInfo,
- Topology = PrimitiveTopology.TriangleList,
- PrimitiveRestartEnable = false
- };
- var viewport = new Viewport()
- {
- X = 0,
- Y = 0,
- Width = (float)size.Width,
- Height = (float)size.Height,
- MinDepth = 0,
- MaxDepth = 1
- };
- var scissor = new Rect2D()
- {
- Offset = new Offset2D(0, 0), Extent = new Extent2D((uint)viewport.Width, (uint)viewport.Height)
- };
- var pipelineViewPortCreateInfo = new PipelineViewportStateCreateInfo()
- {
- SType = StructureType.PipelineViewportStateCreateInfo,
- ViewportCount = 1,
- PViewports = &viewport,
- ScissorCount = 1,
- PScissors = &scissor
- };
- var rasterizerStateCreateInfo = new PipelineRasterizationStateCreateInfo()
- {
- SType = StructureType.PipelineRasterizationStateCreateInfo,
- DepthClampEnable = false,
- RasterizerDiscardEnable = false,
- PolygonMode = PolygonMode.Fill,
- LineWidth = 1,
- CullMode = CullModeFlags.None,
- DepthBiasEnable = false
- };
- var multisampleStateCreateInfo = new PipelineMultisampleStateCreateInfo()
- {
- SType = StructureType.PipelineMultisampleStateCreateInfo,
- SampleShadingEnable = false,
- RasterizationSamples = SampleCountFlags.Count1Bit
- };
- var depthStencilCreateInfo = new PipelineDepthStencilStateCreateInfo()
- {
- SType = StructureType.PipelineDepthStencilStateCreateInfo,
- StencilTestEnable = false,
- DepthCompareOp = CompareOp.Less,
- DepthTestEnable = true,
- DepthWriteEnable = true,
- DepthBoundsTestEnable = false,
- };
- var colorBlendAttachmentState = new PipelineColorBlendAttachmentState()
- {
- ColorWriteMask = ColorComponentFlags.ABit |
- ColorComponentFlags.RBit |
- ColorComponentFlags.GBit |
- ColorComponentFlags.BBit,
- BlendEnable = false
- };
- var colorBlendState = new PipelineColorBlendStateCreateInfo()
- {
- SType = StructureType.PipelineColorBlendStateCreateInfo,
- LogicOpEnable = false,
- AttachmentCount = 1,
- PAttachments = &colorBlendAttachmentState
- };
- var dynamicStates = new DynamicState[] { DynamicState.Viewport, DynamicState.Scissor };
- fixed (DynamicState* states = dynamicStates)
- {
- var dynamicStateCreateInfo = new PipelineDynamicStateCreateInfo()
- {
- SType = StructureType.PipelineDynamicStateCreateInfo,
- DynamicStateCount = (uint)dynamicStates.Length,
- PDynamicStates = states
- };
- var vertexPushConstantRange = new PushConstantRange()
- {
- Offset = 0,
- Size = (uint)Marshal.SizeOf<VertexPushConstant>(),
- StageFlags = ShaderStageFlags.VertexBit
- };
- var fragPushConstantRange = new PushConstantRange()
- {
- //Offset = vertexPushConstantRange.Size,
- Size = (uint)Marshal.SizeOf<VertexPushConstant>(),
- StageFlags = ShaderStageFlags.FragmentBit
- };
- var layoutBindingInfo = new DescriptorSetLayoutBinding
- {
- Binding = 0,
- StageFlags = ShaderStageFlags.VertexBit,
- DescriptorCount = 1,
- DescriptorType = DescriptorType.UniformBuffer,
- };
- var layoutInfo = new DescriptorSetLayoutCreateInfo
- {
- SType = StructureType.DescriptorSetLayoutCreateInfo,
- BindingCount = 1,
- PBindings = &layoutBindingInfo
- };
-
- api.CreateDescriptorSetLayout(device, &layoutInfo, null, out _descriptorSetLayout).ThrowOnError();
-
- var projView = view * projection;
- VulkanBufferHelper.AllocateBuffer<UniformBuffer>(_context, BufferUsageFlags.UniformBufferBit,
- out _uniformBuffer,
- out _uniformBufferMemory, new[]
- {
- new UniformBuffer
- {
- Projection = projView
- }
- });
-
- var descriptorSetLayout = _descriptorSetLayout;
- var descriptorCreateInfo = new DescriptorSetAllocateInfo
- {
- SType = StructureType.DescriptorSetAllocateInfo,
- DescriptorPool = _context.DescriptorPool,
- DescriptorSetCount = 1,
- PSetLayouts = &descriptorSetLayout
- };
- api.AllocateDescriptorSets(device, &descriptorCreateInfo, out _descriptorSet).ThrowOnError();
- var descriptorBufferInfo = new DescriptorBufferInfo
- {
- Buffer = _uniformBuffer,
- Range = (ulong)Unsafe.SizeOf<UniformBuffer>(),
- };
- var descriptorWrite = new WriteDescriptorSet
- {
- SType = StructureType.WriteDescriptorSet,
- DstSet = _descriptorSet,
- DescriptorType = DescriptorType.UniformBuffer,
- DescriptorCount = 1,
- PBufferInfo = &descriptorBufferInfo,
- };
- api.UpdateDescriptorSets(device, 1, &descriptorWrite, 0, null);
-
- var constants = new[] { vertexPushConstantRange, fragPushConstantRange };
- fixed (PushConstantRange* constant = constants)
- {
- var setLayout = _descriptorSetLayout;
- var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
- {
- SType = StructureType.PipelineLayoutCreateInfo,
- PushConstantRangeCount = (uint)constants.Length,
- PPushConstantRanges = constant,
- SetLayoutCount = 1,
- PSetLayouts = &setLayout
- };
- api.CreatePipelineLayout(device, pipelineLayoutCreateInfo, null, out _pipelineLayout)
- .ThrowOnError();
- }
- fixed (PipelineShaderStageCreateInfo* stPtr = stages)
- {
- var pipelineCreateInfo = new GraphicsPipelineCreateInfo()
- {
- SType = StructureType.GraphicsPipelineCreateInfo,
- StageCount = 2,
- PStages = stPtr,
- PVertexInputState = &vertextInputInfo,
- PInputAssemblyState = &inputAssembly,
- PViewportState = &pipelineViewPortCreateInfo,
- PRasterizationState = &rasterizerStateCreateInfo,
- PMultisampleState = &multisampleStateCreateInfo,
- PDepthStencilState = &depthStencilCreateInfo,
- PColorBlendState = &colorBlendState,
- PDynamicState = &dynamicStateCreateInfo,
- Layout = _pipelineLayout,
- RenderPass = _renderPass,
- Subpass = 0,
- BasePipelineHandle = _pipeline.Handle != 0 ? _pipeline : new Pipeline(),
- BasePipelineIndex = _pipeline.Handle != 0 ? 0 : -1
- };
- api.CreateGraphicsPipelines(device, new PipelineCache(), 1, &pipelineCreateInfo, null,
- out _pipeline).ThrowOnError();
- }
- }
- }
- Marshal.FreeHGlobal(pname);
- _isInit = true;
- }
- private unsafe void CreateBuffers()
- {
- VulkanBufferHelper.AllocateBuffer<Vertex>(_context, BufferUsageFlags.VertexBufferBit, out _vertexBuffer,
- out _vertexBufferMemory, _points);
- VulkanBufferHelper.AllocateBuffer<ushort>(_context, BufferUsageFlags.IndexBufferBit, out _indexBuffer,
- out _indexBufferMemory, _indices);
- }
- private static int FindSuitableMemoryTypeIndex(Vk api, PhysicalDevice physicalDevice, uint memoryTypeBits,
- MemoryPropertyFlags flags)
- {
- api.GetPhysicalDeviceMemoryProperties(physicalDevice, out var properties);
- for (var i = 0; i < properties.MemoryTypeCount; i++)
- {
- var type = properties.MemoryTypes[i];
- if ((memoryTypeBits & (1 << i)) != 0 && type.PropertyFlags.HasFlag(flags)) return i;
- }
- return -1;
- }
- [StructLayout(LayoutKind.Sequential, Pack = 4)]
- private struct Vertex
- {
- public Vector3 Position;
- public Vector3 Normal;
- public static unsafe VertexInputBindingDescription VertexInputBindingDescription
- {
- get
- {
- return new VertexInputBindingDescription()
- {
- Binding = 0,
- Stride = (uint)Marshal.SizeOf<Vertex>(),
- InputRate = VertexInputRate.Vertex
- };
- }
- }
- public static unsafe VertexInputAttributeDescription[] VertexInputAttributeDescription
- {
- get
- {
- return new VertexInputAttributeDescription[]
- {
- new VertexInputAttributeDescription
- {
- Binding = 0,
- Location = 0,
- Format = Format.R32G32B32Sfloat,
- Offset = (uint)Marshal.OffsetOf<Vertex>("Position")
- },
- new VertexInputAttributeDescription
- {
- Binding = 0,
- Location = 1,
- Format = Format.R32G32B32Sfloat,
- Offset = (uint)Marshal.OffsetOf<Vertex>("Normal")
- }
- };
- }
- }
- }
- private readonly Vertex[] _points;
- private readonly ushort[] _indices;
- private readonly float _minY;
- private readonly float _maxY;
- static Stopwatch St = Stopwatch.StartNew();
- private bool _isInit;
- private VulkanImage? _colorAttachment;
- private DescriptorSet _descriptorSet;
- [StructLayout(LayoutKind.Sequential, Pack = 4)]
- private struct VertexPushConstant
- {
- public float MaxY;
- public float MinY;
- public float Time;
- public float Disco;
- public Matrix4x4 Model;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 4)]
- private struct UniformBuffer
- {
- public Matrix4x4 Projection;
- }
- }
|