Skip to content

Commit

Permalink
Part 2 UI (#1)
Browse files Browse the repository at this point in the history
* start ui

* ui start
  • Loading branch information
JensKrumsieck committed Sep 18, 2023
1 parent 8322bb4 commit bec642b
Show file tree
Hide file tree
Showing 12 changed files with 298 additions and 17 deletions.
10 changes: 10 additions & 0 deletions RaytracingVulkan.UI/App.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="RaytracingVulkan.UI.App"
RequestedThemeVariant="Default">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->

<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>
24 changes: 24 additions & 0 deletions RaytracingVulkan.UI/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;

namespace RaytracingVulkan.UI;

public partial class App : Application
{
public readonly VkContext VkContext = new();
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}

public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
}

base.OnFrameworkInitializationCompleted();
}
}
14 changes: 14 additions & 0 deletions RaytracingVulkan.UI/MainWindow.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:RaytracingVulkan.UI.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="RaytracingVulkan.UI.MainWindow"
x:DataType="viewModels:MainViewModel"
Title="RaytracingVulkan.UI">
<Design.DataContext>
<viewModels:MainViewModel/>
</Design.DataContext>
<Image Source="{Binding Image}" x:Name="Image" Width="500" Height="500"/>
</Window>
24 changes: 24 additions & 0 deletions RaytracingVulkan.UI/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Threading;
using RaytracingVulkan.UI.ViewModels;

namespace RaytracingVulkan.UI;

public partial class MainWindow : Window
{
private readonly MainViewModel _viewModel = new();

public MainWindow()
{
InitializeComponent();
DataContext = _viewModel;
}

public override void Render(DrawingContext context)
{
base.Render(context);
_viewModel.Render();
Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Render);
}
}
21 changes: 21 additions & 0 deletions RaytracingVulkan.UI/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Avalonia;
using System;

namespace RaytracingVulkan.UI;

class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);

// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace();
}
32 changes: 32 additions & 0 deletions RaytracingVulkan.UI/RaytracingVulkan.UI.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>


<ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.2"/>
<PackageReference Include="Avalonia.Desktop" Version="11.0.2"/>
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.2"/>
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.2"/>
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.2"/>
<PackageReference Include="Microsoft.Toolkit.Mvvm" Version="7.1.2" />
</ItemGroup>


<ItemGroup>
<ProjectReference Include="..\RaytracingVulkan\RaytracingVulkan.csproj" />
</ItemGroup>


<ItemGroup>
<ProjectReference Include="..\RaytracingVulkan\RaytracingVulkan.csproj" />
</ItemGroup>
</Project>
93 changes: 93 additions & 0 deletions RaytracingVulkan.UI/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System;
using System.Diagnostics;
using Avalonia;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Silk.NET.Vulkan;

namespace RaytracingVulkan.UI.ViewModels;

public unsafe partial class MainViewModel : ObservableObject, IDisposable
{
[ObservableProperty] private WriteableBitmap _image;

private readonly VkContext _context = (Application.Current as App)!.VkContext;

private Stopwatch VulkanStopWatch = new();
private readonly DescriptorPool _descriptorPool;
private readonly DescriptorSet _descriptorSet;
private readonly DescriptorSetLayout _setLayout;
private readonly PipelineLayout _pipelineLayout;
private readonly Pipeline _pipeline;

private readonly CommandBuffer _cmd;

private readonly VkImage _vkImage;
private readonly VkBuffer _vkBuffer;

private readonly void* _mappedData;

public MainViewModel()
{
//pipeline creation
var poolSizes = new DescriptorPoolSize[] {new() {Type = DescriptorType.StorageImage, DescriptorCount = 1000}};
_descriptorPool = _context.CreateDescriptorPool(poolSizes);
var binding = new DescriptorSetLayoutBinding
{
Binding = 0,
DescriptorCount = 1,
DescriptorType = DescriptorType.StorageImage,
StageFlags = ShaderStageFlags.ComputeBit
};
_setLayout = _context.CreateDescriptorSetLayout(new[] {binding});
_descriptorSet = _context.AllocateDescriptorSet(_descriptorPool, _setLayout);

var shaderModule = _context.LoadShaderModule("./assets/shaders/raytracing.comp.spv");
_pipelineLayout = _context.CreatePipelineLayout(_setLayout);
_pipeline = _context.CreateComputePipeline(_pipelineLayout, shaderModule);
var sz = 2000u;
//image creation
_vkImage = new VkImage(_context, sz, sz, Format.B8G8R8A8Unorm,ImageUsageFlags.StorageBit | ImageUsageFlags.TransferDstBit | ImageUsageFlags.TransferSrcBit);
_vkImage.TransitionLayoutImmediate(ImageLayout.General);
_context.UpdateDescriptorSetImage(ref _descriptorSet, _vkImage.GetImageInfo(), DescriptorType.StorageImage, 0);

_image = new WriteableBitmap(new PixelSize((int) sz, (int) sz), new Vector(96, 96), PixelFormat.Bgra8888);

//we don't need it anymore
_context.DestroyShaderModule(shaderModule);
_cmd = _context.AllocateCommandBuffer();
_vkBuffer = new VkBuffer(_context, _vkImage.Width * _vkImage.Height * 4, BufferUsageFlags.TransferDstBit,
MemoryPropertyFlags.HostCachedBit | MemoryPropertyFlags.HostCoherentBit |
MemoryPropertyFlags.HostVisibleBit);
_vkBuffer.MapMemory(ref _mappedData);
}
public void Dispose()
{
_vkBuffer.UnmapMemory();
_context.DestroyDescriptorPool(_descriptorPool);
_context.DestroyDescriptorSetLayout(_setLayout);
_context.DestroyPipelineLayout(_pipelineLayout);
_context.DestroyPipeline(_pipeline);
_image.Dispose();
GC.SuppressFinalize(this);
}

public void Render()
{
//execute compute shader
_context.BeginCommandBuffer(_cmd);
_vkImage.TransitionLayout(_cmd, ImageLayout.General);
_context.BindComputePipeline(_cmd, _pipeline);
_context.BindComputeDescriptorSet(_cmd, _descriptorSet, _pipelineLayout);
_context.Dispatch(_cmd, _vkImage.Width/32, _vkImage.Height/32, 1);
_vkImage.TransitionLayout(_cmd, ImageLayout.TransferSrcOptimal);
_vkImage.CopyToBuffer(_cmd, _vkBuffer.Buffer);
_context.EndCommandBuffer(_cmd);
_context.WaitForQueue();

using var buffer = _image.Lock();
var size = _vkImage.Width * _vkImage.Height * 4;
System.Buffer.MemoryCopy(_mappedData, (void*) buffer.Address, size, size);
}
}
18 changes: 18 additions & 0 deletions RaytracingVulkan.UI/app.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<!-- This manifest is used on Windows only.
Don't remove it as it might cause problems with window transparency and embeded controls.
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
<assemblyIdentity version="1.0.0.0" name="RaytracingVulkan.UI.Desktop"/>

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on
and is designed to work with. Uncomment the appropriate elements
and Windows will automatically select the most compatible environment. -->

<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
</assembly>
6 changes: 6 additions & 0 deletions RaytracingVulkan.sln
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RaytracingVulkan", "RaytracingVulkan\RaytracingVulkan.csproj", "{483FEA20-C27C-4569-8113-48B1FFA917D9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RaytracingVulkan.UI", "RaytracingVulkan.UI\RaytracingVulkan.UI.csproj", "{719D6130-96F8-4C1D-9003-EADE59A1EB29}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -12,5 +14,9 @@ Global
{483FEA20-C27C-4569-8113-48B1FFA917D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{483FEA20-C27C-4569-8113-48B1FFA917D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{483FEA20-C27C-4569-8113-48B1FFA917D9}.Release|Any CPU.Build.0 = Release|Any CPU
{719D6130-96F8-4C1D-9003-EADE59A1EB29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{719D6130-96F8-4C1D-9003-EADE59A1EB29}.Debug|Any CPU.Build.0 = Debug|Any CPU
{719D6130-96F8-4C1D-9003-EADE59A1EB29}.Release|Any CPU.ActiveCfg = Release|Any CPU
{719D6130-96F8-4C1D-9003-EADE59A1EB29}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
2 changes: 1 addition & 1 deletion RaytracingVulkan/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

//image creation
var image = new VkImage(ctx, 500, 500, Format.R8G8B8A8Unorm,ImageUsageFlags.StorageBit | ImageUsageFlags.TransferDstBit | ImageUsageFlags.TransferSrcBit);
image.TransitionLayout(ImageLayout.General);
image.TransitionLayoutImmediate(ImageLayout.General);
var imageInfo = image.GetImageInfo();
ctx.UpdateDescriptorSetImage(ref descriptorSet, imageInfo, DescriptorType.StorageImage, 0);

Expand Down
26 changes: 21 additions & 5 deletions RaytracingVulkan/VkContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ public VkContext()
}

public Result SubmitMainQueue(SubmitInfo submitInfo, Fence fence) => _vk.QueueSubmit(_mainQueue, 1, submitInfo, fence);
private Result WaitForQueue() => _vk.QueueWaitIdle(_mainQueue);
public CommandBuffer BeginSingleTimeCommands()
public Result WaitForQueue() => _vk.QueueWaitIdle(_mainQueue);

public CommandBuffer AllocateCommandBuffer()
{
var allocInfo = new CommandBufferAllocateInfo
{
Expand All @@ -164,15 +164,20 @@ public CommandBuffer BeginSingleTimeCommands()
Level = CommandBufferLevel.Primary
};
_vk.AllocateCommandBuffers(_device, allocInfo, out var commandBuffer);
return commandBuffer;
}

public void BeginCommandBuffer(CommandBuffer commandBuffer)
{
var beginInfo = new CommandBufferBeginInfo
{
SType = StructureType.CommandBufferBeginInfo,
Flags = CommandBufferUsageFlags.None
};
_vk.BeginCommandBuffer(commandBuffer, beginInfo);
return commandBuffer; }
}

public void EndSingleTimeCommands(CommandBuffer cmd)
public void EndCommandBuffer(CommandBuffer cmd)
{
_vk.EndCommandBuffer(cmd);
var submitInfo = new SubmitInfo
Expand All @@ -182,6 +187,17 @@ public void EndSingleTimeCommands(CommandBuffer cmd)
PCommandBuffers = &cmd
};
SubmitMainQueue(submitInfo, default);
}

public CommandBuffer BeginSingleTimeCommands()
{
var commandBuffer = AllocateCommandBuffer();
BeginCommandBuffer(commandBuffer);
return commandBuffer; }

public void EndSingleTimeCommands(CommandBuffer cmd)
{
EndCommandBuffer(cmd);
WaitForQueue();
_vk.FreeCommandBuffers(_device, _commandPool, 1, cmd);
}
Expand Down

0 comments on commit bec642b

Please sign in to comment.