Win32 vulkan window

This commit is contained in:
Jorijn van der Graaf 2026-02-24 02:32:37 +01:00
commit b5e69c90fa
12 changed files with 950 additions and 85 deletions

View file

@ -117,6 +117,40 @@ export namespace Crafter {
return types;
}
template <typename... Shaders>
constexpr static std::vector<VkDescriptorPoolSize> GetPoolSizesCombined(const std::span<const DescriptorSetLayoutVulkan> shaders) {
std::vector<VkDescriptorPoolSize> types;
for(const DescriptorSetLayoutVulkan& shader : shaders) {
for (const VkDescriptorSetLayoutBinding& binding : shader.descriptors) {
for(VkDescriptorPoolSize& type : types) {
if(type.type == binding.descriptorType) {
type.descriptorCount += binding.descriptorCount;
goto inner;
}
}
types.emplace_back(binding.descriptorType, binding.descriptorCount);
inner:;
}
}
([&] {
for (const VkDescriptorSetLayoutBinding& binding : Shaders::descriptors) {
for(VkDescriptorPoolSize& type : types) {
if(type.type == binding.descriptorType) {
type.descriptorCount += binding.descriptorCount;
goto inner2;
}
}
types.emplace_back(binding.descriptorType, binding.descriptorCount);
inner2:;
}
}(),
...);
return types;
}
public:
void BuildPool(std::span<const VkDescriptorPoolSize> poolSizes, std::span<const VkDescriptorSetLayout> setLayouts) {

View file

@ -115,7 +115,7 @@ export namespace Crafter {
}
};
template <std::uint32_t GeneralShader, std::uint32_t ClosestHitShader, std::uint32_t AnyHitShader, std::uint32_t IntersectionShader>
template <std::uint32_t GeneralShader, std::uint32_t ClosestHitShader, std::uint32_t AnyHitShader, std::uint32_t IntersectionShader>
struct ShaderGroup {
static constexpr std::uint32_t generalShader = GeneralShader;
static constexpr std::uint32_t closestHitShader = ClosestHitShader;
@ -135,7 +135,7 @@ export namespace Crafter {
inline static VkStridedDeviceAddressRegionKHR hitRegion;
inline static VkStridedDeviceAddressRegionKHR callableRegion;
static void Init(VkCommandBuffer cmd, std::span<VkDescriptorSetLayout> setLayouts) {
static void Init(VkCommandBuffer cmd, const std::span<const VkDescriptorSetLayout> setLayouts) {
VkPipelineLayoutCreateInfo pipelineLayoutInfo {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = static_cast<std::uint32_t>(setLayouts.size()),
@ -176,7 +176,7 @@ export namespace Crafter {
hitRegion.stride = sbtStride;
hitRegion.deviceAddress = AlignUp(missRegion.deviceAddress + missRegion.size, VulkanDevice::rayTracingProperties.shaderGroupBaseAlignment);
hitRegion.size = GetGroupCount<VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR>(groupIndexSeq) * sbtStride;
hitRegion.size = (GetGroupCount<VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR>(groupIndexSeq) * sbtStride) + (GetGroupCount<VK_SHADER_STAGE_ANY_HIT_BIT_KHR>(groupIndexSeq) * sbtStride);
std::size_t bufferSize = hitRegion.deviceAddress + hitRegion.size;
sbtBuffer.Create(VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferSize);
@ -199,7 +199,7 @@ export namespace Crafter {
VkRayTracingShaderGroupTypeKHR groupType;
if constexpr(groupTemplate::generalShader != VK_SHADER_UNUSED_KHR) {
groupType = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
} else if constexpr(groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR) {
} else if constexpr(groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR || groupTemplate::anyHitShader != VK_SHADER_UNUSED_KHR) {
groupType = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR;
} else {
static_assert(
@ -237,6 +237,11 @@ export namespace Crafter {
if constexpr(shaderTemplate::_stage == stage) {
count++;
}
} else if constexpr(groupTemplate::anyHitShader != VK_SHADER_UNUSED_KHR) {
using shaderTemplate = std::tuple_element_t<groupTemplate::anyHitShader, Shaders>;
if constexpr(shaderTemplate::_stage == stage) {
count++;
}
} else {
static_assert(
groupTemplate::generalShader != VK_SHADER_UNUSED_KHR ||
@ -267,6 +272,12 @@ export namespace Crafter {
std::memcpy(sbtBuffer.value + offset, shaderHandles.data() + index * VulkanDevice::rayTracingProperties.shaderGroupHandleSize, VulkanDevice::rayTracingProperties.shaderGroupHandleSize);
offset += sbtStride;
}
} else if constexpr(groupTemplate::anyHitShader != VK_SHADER_UNUSED_KHR) {
using shaderTemplate = std::tuple_element_t<groupTemplate::anyHitShader, Shaders>;
if constexpr(shaderTemplate::_stage == stage) {
std::memcpy(sbtBuffer.value + offset, shaderHandles.data() + index * VulkanDevice::rayTracingProperties.shaderGroupHandleSize, VulkanDevice::rayTracingProperties.shaderGroupHandleSize);
offset += sbtStride;
}
} else {
static_assert(
groupTemplate::generalShader != VK_SHADER_UNUSED_KHR ||
@ -283,6 +294,7 @@ export namespace Crafter {
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_MISS_BIT_KHR>(sbtStride, offset), ...);
offset = AlignUp(offset, VulkanDevice::rayTracingProperties.shaderGroupBaseAlignment);
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR>(sbtStride, offset), ...);
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_ANY_HIT_BIT_KHR>(sbtStride, offset), ...);
}
};
}

View file

@ -20,7 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
module;
#ifdef CRAFTER_GRAPHICS_VULKAN
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_wayland.h>
#endif
export module Crafter.Graphics:VulkanDevice;
#ifdef CRAFTER_GRAPHICS_VULKAN

View file

@ -40,6 +40,7 @@ module;
#include <wayland-client-protocol.h>
#endif
#ifdef CRAFTER_GRAPHICS_VULKAN
#ifndef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@ -61,6 +62,9 @@ module;
#include <wayland-client-protocol.h>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_wayland.h>
#else
#include <vulkan/vulkan.h>
#endif
#endif
export module Crafter.Graphics:Window;
@ -278,7 +282,7 @@ export namespace Crafter {
// Command buffer submission and execution
VkSemaphore renderComplete;
};
#ifndef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32
class WindowVulkan final : public Window, public WindowKeyboard, public WindowMouse, public WindowTitle {
public:
WindowVulkan(std::uint32_t width, std::uint32_t height);
@ -412,5 +416,63 @@ export namespace Crafter {
VkStridedDeviceAddressRegionKHR hitRegion;
VkStridedDeviceAddressRegionKHR callableRegion;
};
#else
class WindowVulkan final : public Window, public WindowKeyboard, public WindowMouse, public WindowTitle {
public:
WindowVulkan(std::uint32_t width, std::uint32_t height);
WindowVulkan(std::uint32_t width, std::uint32_t height, const std::string_view title);
~WindowVulkan();
Event<void> onRender;
std::vector<VkDescriptorSet> descriptorsRt;
void Render();
void QueueRender();
void Resize(std::uint32_t width, std::uint32_t height);
void StartSync() override;
void StartUpdate() override;
void StopUpdate() override;
void SetTitle(const std::string_view title) override;
VkCommandBuffer StartInit();
void FinishInit();
template <typename Pipeline>
void SetPipelineRT() {
rtPipeline = Pipeline::pipeline;
rtPipelineLayout = Pipeline::pipelineLayout;
raygenRegion = Pipeline::raygenRegion;
missRegion = Pipeline::missRegion;
hitRegion = Pipeline::hitRegion;
callableRegion = Pipeline::callableRegion;
}
void SetPipelineRT(PipelineRTVulkan& pipeline) {
rtPipeline = pipeline.pipeline;
rtPipelineLayout = pipeline.pipelineLayout;
raygenRegion = pipeline.raygenRegion;
missRegion = pipeline.missRegion;
hitRegion = pipeline.hitRegion;
callableRegion = pipeline.callableRegion;
}
void CreateSwapchain();
static constexpr std::uint32_t numFrames = 3;
VkSurfaceKHR vulkanSurface = VK_NULL_HANDLE;
VkSwapchainKHR swapChain = VK_NULL_HANDLE;
VkFormat colorFormat;
VkColorSpaceKHR colorSpace;
VkImage images[numFrames];
VkImageView imageViews[numFrames];
std::thread thread;
VkCommandBuffer drawCmdBuffers[numFrames];
VkSubmitInfo submitInfo;
Semaphores semaphores;
uint32_t currentBuffer = 0;
VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkPipeline rtPipeline;
VkPipelineLayout rtPipelineLayout;
VkStridedDeviceAddressRegionKHR raygenRegion;
VkStridedDeviceAddressRegionKHR missRegion;
VkStridedDeviceAddressRegionKHR hitRegion;
VkStridedDeviceAddressRegionKHR callableRegion;
};
#endif
#endif
}