Win32 vulkan window
This commit is contained in:
parent
415e523a45
commit
b5e69c90fa
12 changed files with 950 additions and 85 deletions
|
|
@ -6,17 +6,17 @@ import std;
|
||||||
import Crafter.Event;
|
import Crafter.Event;
|
||||||
import Crafter.Math;
|
import Crafter.Math;
|
||||||
|
|
||||||
typedef VulkanShader<"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR> Raygenspv;
|
typedef VulkanShaderConst<"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR> Raygenspv;
|
||||||
typedef VulkanShader<"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR> Closesthitspv;
|
typedef VulkanShaderConst<"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR> Closesthitspv;
|
||||||
typedef VulkanShader<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR> Misspv;
|
typedef VulkanShaderConst<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR> Misspv;
|
||||||
typedef std::tuple<Raygenspv, Misspv, Closesthitspv> AllShaders;
|
typedef std::tuple<Raygenspv, Misspv, Closesthitspv> AllShaders;
|
||||||
typedef std::tuple<
|
typedef std::tuple<
|
||||||
ShaderGroup<0, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>,
|
ShaderGroup<0, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>,
|
||||||
ShaderGroup<1, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>,
|
ShaderGroup<1, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>,
|
||||||
ShaderGroup<VK_SHADER_UNUSED_KHR, 2, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>
|
ShaderGroup<VK_SHADER_UNUSED_KHR, 2, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>
|
||||||
> ShaderGroups;
|
> ShaderGroups;
|
||||||
typedef PipelineRTVulkan<AllShaders, ShaderGroups> Pipeline;
|
typedef PipelineRTVulkanConst<AllShaders, ShaderGroups> Pipeline;
|
||||||
typedef DescriptorSetLayoutVulkan<1, {{
|
typedef DescriptorSetLayoutVulkanConst<1, {{
|
||||||
{
|
{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
|
.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
|
||||||
|
|
@ -24,7 +24,7 @@ typedef DescriptorSetLayoutVulkan<1, {{
|
||||||
.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR,
|
.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR,
|
||||||
},
|
},
|
||||||
}}> descriptorSetLayoutTlas;
|
}}> descriptorSetLayoutTlas;
|
||||||
typedef DescriptorSetLayoutVulkan<1, {{
|
typedef DescriptorSetLayoutVulkanConst<1, {{
|
||||||
{
|
{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||||
|
|
@ -42,7 +42,7 @@ int main() {
|
||||||
Closesthitspv::CreateShader();
|
Closesthitspv::CreateShader();
|
||||||
Misspv::CreateShader();
|
Misspv::CreateShader();
|
||||||
|
|
||||||
ShaderBindingTableVulkan<AllShaders>::Init();
|
ShaderBindingTableVulkanConst<AllShaders>::Init();
|
||||||
|
|
||||||
descriptorSetLayoutTlas::Init();
|
descriptorSetLayoutTlas::Init();
|
||||||
descriptorSetLayoutImage::Init();
|
descriptorSetLayoutImage::Init();
|
||||||
|
|
@ -56,12 +56,23 @@ int main() {
|
||||||
window.SetPipelineRT<Pipeline>();
|
window.SetPipelineRT<Pipeline>();
|
||||||
|
|
||||||
Mesh triangleMesh;
|
Mesh triangleMesh;
|
||||||
std::array<Vertex, 3> verts {{{-150, -150, 100}, {0, 150, 100}, {150, -150, 100}}};
|
std::array<Vector<float, 3, 3>, 3> verts {{{-150, -150, 100}, {0, 150, 100}, {150, -150, 100}}};
|
||||||
std::array<std::uint32_t, 3> index {{2,1,0}};
|
std::array<std::uint32_t, 3> index {{2,1,0}};
|
||||||
triangleMesh.Build(verts, index, cmd);
|
triangleMesh.Build(verts, index, cmd);
|
||||||
RenderingElement3DVulkan& el = RenderingElement3DVulkan::elements.emplace_back(triangleMesh);
|
|
||||||
|
RenderingElement3DVulkan renderer = {
|
||||||
|
.instance = {
|
||||||
|
.instanceCustomIndex = 0,
|
||||||
|
.mask = 0xFF,
|
||||||
|
.instanceShaderBindingTableRecordOffset = 0,
|
||||||
|
.flags = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR,
|
||||||
|
.accelerationStructureReference = triangleMesh.blasAddr
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
RenderingElement3DVulkan::elements.emplace_back(&renderer);
|
||||||
MatrixRowMajor<float, 4, 3, 1> transform = MatrixRowMajor<float, 4, 3, 1>::Identity();
|
MatrixRowMajor<float, 4, 3, 1> transform = MatrixRowMajor<float, 4, 3, 1>::Identity();
|
||||||
std::memcpy(el.instance.transform.matrix, transform.m, sizeof(transform.m));
|
std::memcpy(renderer.instance.transform.matrix, transform.m, sizeof(transform.m));
|
||||||
|
|
||||||
RenderingElement3DVulkan::tlases.resize(WindowVulkan::numFrames);
|
RenderingElement3DVulkan::tlases.resize(WindowVulkan::numFrames);
|
||||||
RenderingElement3DVulkan::BuildTLAS(cmd, 0);
|
RenderingElement3DVulkan::BuildTLAS(cmd, 0);
|
||||||
|
|
@ -135,7 +146,7 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
MatrixRowMajor<float, 4, 3, 1> transform = MatrixRowMajor<float, 4, 3, 1>::Translation(value, 0, 0);
|
MatrixRowMajor<float, 4, 3, 1> transform = MatrixRowMajor<float, 4, 3, 1>::Translation(value, 0, 0);
|
||||||
std::memcpy(el.instance.transform.matrix, transform.m, sizeof(transform.m));
|
std::memcpy(renderer.instance.transform.matrix, transform.m, sizeof(transform.m));
|
||||||
RenderingElement3DVulkan::BuildTLAS(window.drawCmdBuffers[window.currentBuffer], window.currentBuffer);
|
RenderingElement3DVulkan::BuildTLAS(window.drawCmdBuffers[window.currentBuffer], window.currentBuffer);
|
||||||
|
|
||||||
VkWriteDescriptorSetAccelerationStructureKHR writeDescriptorSetAccelerationStructure {
|
VkWriteDescriptorSetAccelerationStructureKHR writeDescriptorSetAccelerationStructure {
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,17 @@ import std;
|
||||||
import Crafter.Event;
|
import Crafter.Event;
|
||||||
import Crafter.Math;
|
import Crafter.Math;
|
||||||
|
|
||||||
typedef VulkanShader<"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR> Raygenspv;
|
typedef VulkanShaderConst<"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR> Raygenspv;
|
||||||
typedef VulkanShader<"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR> Closesthitspv;
|
typedef VulkanShaderConst<"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR> Closesthitspv;
|
||||||
typedef VulkanShader<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR> Misspv;
|
typedef VulkanShaderConst<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR> Misspv;
|
||||||
typedef std::tuple<Raygenspv, Misspv, Closesthitspv> AllShaders;
|
typedef std::tuple<Raygenspv, Misspv, Closesthitspv> AllShaders;
|
||||||
typedef std::tuple<
|
typedef std::tuple<
|
||||||
ShaderGroup<0, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>,
|
ShaderGroup<0, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>,
|
||||||
ShaderGroup<1, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>,
|
ShaderGroup<1, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>,
|
||||||
ShaderGroup<VK_SHADER_UNUSED_KHR, 2, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>
|
ShaderGroup<VK_SHADER_UNUSED_KHR, 2, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>
|
||||||
> ShaderGroups;
|
> ShaderGroups;
|
||||||
typedef PipelineRTVulkan<AllShaders, ShaderGroups> Pipeline;
|
typedef PipelineRTVulkanConst<AllShaders, ShaderGroups> Pipeline;
|
||||||
typedef DescriptorSetLayoutVulkan<2, {{
|
typedef DescriptorSetLayoutVulkanConst<3, {{
|
||||||
{
|
{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
|
.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
|
||||||
|
|
@ -28,6 +28,12 @@ typedef DescriptorSetLayoutVulkan<2, {{
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR,
|
.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.binding = 2,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR,
|
||||||
}
|
}
|
||||||
}}> descriptorSetLayout;
|
}}> descriptorSetLayout;
|
||||||
|
|
||||||
|
|
@ -39,7 +45,7 @@ int main() {
|
||||||
Raygenspv::CreateShader();
|
Raygenspv::CreateShader();
|
||||||
Closesthitspv::CreateShader();
|
Closesthitspv::CreateShader();
|
||||||
Misspv::CreateShader();
|
Misspv::CreateShader();
|
||||||
ShaderBindingTableVulkan<AllShaders>::Init();
|
ShaderBindingTableVulkanConst<AllShaders>::Init();
|
||||||
|
|
||||||
descriptorSetLayout::Init();
|
descriptorSetLayout::Init();
|
||||||
std::array<VkDescriptorSetLayout, 1> layouts {{descriptorSetLayout::layout}};
|
std::array<VkDescriptorSetLayout, 1> layouts {{descriptorSetLayout::layout}};
|
||||||
|
|
@ -51,12 +57,24 @@ int main() {
|
||||||
Pipeline::Init(cmd, layouts);
|
Pipeline::Init(cmd, layouts);
|
||||||
|
|
||||||
Mesh triangleMesh;
|
Mesh triangleMesh;
|
||||||
std::array<Vertex, 3> verts {{{-150, -150, 100}, {0, 150, 100}, {150, -150, 100}}};
|
std::array<Vector<float, 3, 3>, 3> verts {{{-150, -150, 100}, {0, 150, 100}, {150, -150, 100}}};
|
||||||
std::array<std::uint32_t, 3> index {{2,1,0}};
|
std::array<std::uint32_t, 3> index {{2,1,0}};
|
||||||
triangleMesh.Build(verts, index, cmd);
|
triangleMesh.Build(verts, index, cmd);
|
||||||
RenderingElement3DVulkan& el = RenderingElement3DVulkan::elements.emplace_back(triangleMesh);
|
|
||||||
|
RenderingElement3DVulkan renderer = {
|
||||||
|
.instance = {
|
||||||
|
.instanceCustomIndex = 0,
|
||||||
|
.mask = 0xFF,
|
||||||
|
.instanceShaderBindingTableRecordOffset = 0,
|
||||||
|
.flags = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR,
|
||||||
|
.accelerationStructureReference = triangleMesh.blasAddr
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
RenderingElement3DVulkan::elements.emplace_back(&renderer);
|
||||||
|
|
||||||
MatrixRowMajor<float, 4, 3, 1> transform = MatrixRowMajor<float, 4, 3, 1>::Identity();
|
MatrixRowMajor<float, 4, 3, 1> transform = MatrixRowMajor<float, 4, 3, 1>::Identity();
|
||||||
std::memcpy(el.instance.transform.matrix, transform.m, sizeof(transform.m));
|
std::memcpy(renderer.instance.transform.matrix, transform.m, sizeof(transform.m));
|
||||||
RenderingElement3DVulkan::tlases.resize(1);
|
RenderingElement3DVulkan::tlases.resize(1);
|
||||||
RenderingElement3DVulkan::BuildTLAS(cmd, 0);
|
RenderingElement3DVulkan::BuildTLAS(cmd, 0);
|
||||||
|
|
||||||
|
|
@ -71,7 +89,10 @@ int main() {
|
||||||
.pAccelerationStructures = &RenderingElement3DVulkan::tlases[0].accelerationStructure
|
.pAccelerationStructures = &RenderingElement3DVulkan::tlases[0].accelerationStructure
|
||||||
};
|
};
|
||||||
|
|
||||||
VkWriteDescriptorSet write[2] = {
|
VulkanBuffer<std::uint32_t, true, false, false> lightBuffer;
|
||||||
|
lightBuffer.Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 1);
|
||||||
|
|
||||||
|
VkWriteDescriptorSet write[3] = {
|
||||||
{
|
{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
.pNext = &writeDescriptorSetAccelerationStructure,
|
.pNext = &writeDescriptorSetAccelerationStructure,
|
||||||
|
|
@ -89,9 +110,19 @@ int main() {
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||||
.pImageInfo = &imageInfo
|
.pImageInfo = &imageInfo
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.dstSet = pool.sets[0],
|
||||||
|
.dstBinding = 2,
|
||||||
|
.dstArrayElement = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.pBufferInfo = &lightBuffer.descriptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
vkUpdateDescriptorSets(VulkanDevice::device, 2, write, 0, nullptr);
|
vkUpdateDescriptorSets(VulkanDevice::device, 3, write, 0, nullptr);
|
||||||
|
|
||||||
|
|
||||||
window.SetPipelineRT<Pipeline>();
|
window.SetPipelineRT<Pipeline>();
|
||||||
window.descriptorsRt = pool.sets;
|
window.descriptorsRt = pool.sets;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
{
|
{
|
||||||
"path":"../../project.json",
|
"path":"../../project.json",
|
||||||
"configuration":"lib-vulkan-debug"
|
"configuration":"lib-vulkan"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"shaders": [
|
"shaders": [
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ using namespace Crafter;
|
||||||
|
|
||||||
void Mesh::Build(std::span<Vector<float, 3, 3>> verticies, std::span<std::uint32_t> indicies, VkCommandBuffer cmd) {
|
void Mesh::Build(std::span<Vector<float, 3, 3>> verticies, std::span<std::uint32_t> indicies, VkCommandBuffer cmd) {
|
||||||
vertexBuffer.Resize(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, verticies.size());
|
vertexBuffer.Resize(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, verticies.size());
|
||||||
indexBuffer.Resize(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, indicies.size());
|
indexBuffer.Resize(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, indicies.size());
|
||||||
|
|
||||||
std::memcpy(vertexBuffer.value, verticies.data(), verticies.size() * sizeof(Vector<float, 3, 3>));
|
std::memcpy(vertexBuffer.value, verticies.data(), verticies.size() * sizeof(Vector<float, 3, 3>));
|
||||||
std::memcpy(indexBuffer.value, indicies.data(), indicies.size() * sizeof(std::uint32_t));
|
std::memcpy(indexBuffer.value, indicies.data(), indicies.size() * sizeof(std::uint32_t));
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
module;
|
module;
|
||||||
|
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include <vulkan/vulkan_wayland.h>
|
|
||||||
#include <vulkan/vk_enum_string_helper.h>
|
#include <vulkan/vk_enum_string_helper.h>
|
||||||
|
|
||||||
#define GET_EXTENSION_FUNCTION(_id) ((PFN_##_id)(vkGetInstanceProcAddr(instance, #_id)))
|
#define GET_EXTENSION_FUNCTION(_id) ((PFN_##_id)(vkGetInstanceProcAddr(instance, #_id)))
|
||||||
|
|
@ -35,7 +34,11 @@ using namespace Crafter;
|
||||||
const char* const instanceExtensionNames[] = {
|
const char* const instanceExtensionNames[] = {
|
||||||
"VK_EXT_debug_utils",
|
"VK_EXT_debug_utils",
|
||||||
"VK_KHR_surface",
|
"VK_KHR_surface",
|
||||||
|
#ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32
|
||||||
|
"VK_KHR_win32_surface"
|
||||||
|
#else
|
||||||
"VK_KHR_wayland_surface"
|
"VK_KHR_wayland_surface"
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
const char* const deviceExtensionNames[] = {
|
const char* const deviceExtensionNames[] = {
|
||||||
"VK_KHR_swapchain",
|
"VK_KHR_swapchain",
|
||||||
|
|
@ -246,11 +249,11 @@ void VulkanDevice::CreateDevice() {
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeature = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR};
|
VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeature = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR};
|
||||||
dynamicRenderingFeature.dynamicRendering = VK_TRUE;
|
dynamicRenderingFeature.dynamicRendering = VK_FALSE;
|
||||||
dynamicRenderingFeature.pNext = &deviceAccelerationStructureFeature;
|
dynamicRenderingFeature.pNext = &deviceAccelerationStructureFeature;
|
||||||
|
|
||||||
VkPhysicalDeviceMeshShaderFeaturesEXT ext_feature = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT};
|
VkPhysicalDeviceMeshShaderFeaturesEXT ext_feature = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT};
|
||||||
ext_feature.meshShader = VK_TRUE;
|
ext_feature.meshShader = VK_FALSE;
|
||||||
ext_feature.pNext = &dynamicRenderingFeature;
|
ext_feature.pNext = &dynamicRenderingFeature;
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures2 physical_features2 = {
|
VkPhysicalDeviceFeatures2 physical_features2 = {
|
||||||
|
|
@ -305,9 +308,9 @@ void VulkanDevice::CreateDevice() {
|
||||||
|
|
||||||
vkGetPhysicalDeviceMemoryProperties(physDevice, &memoryProperties);
|
vkGetPhysicalDeviceMemoryProperties(physDevice, &memoryProperties);
|
||||||
|
|
||||||
vkCmdDrawMeshTasksEXTProc = reinterpret_cast<PFN_vkCmdDrawMeshTasksEXT>(vkGetDeviceProcAddr(device, "vkCmdDrawMeshTasksEXT"));
|
// vkCmdDrawMeshTasksEXTProc = reinterpret_cast<PFN_vkCmdDrawMeshTasksEXT>(vkGetDeviceProcAddr(device, "vkCmdDrawMeshTasksEXT"));
|
||||||
vkCmdBeginRenderingKHRProc = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetInstanceProcAddr(instance, "vkCmdBeginRenderingKHR"));
|
// vkCmdBeginRenderingKHRProc = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetInstanceProcAddr(instance, "vkCmdBeginRenderingKHR"));
|
||||||
vkCmdEndRenderingKHRProc = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetInstanceProcAddr(instance, "vkCmdEndRenderingKHR"));
|
// vkCmdEndRenderingKHRProc = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetInstanceProcAddr(instance, "vkCmdEndRenderingKHR"));
|
||||||
vkGetAccelerationStructureBuildSizesKHR = reinterpret_cast<PFN_vkGetAccelerationStructureBuildSizesKHR>(vkGetInstanceProcAddr(instance, "vkGetAccelerationStructureBuildSizesKHR"));
|
vkGetAccelerationStructureBuildSizesKHR = reinterpret_cast<PFN_vkGetAccelerationStructureBuildSizesKHR>(vkGetInstanceProcAddr(instance, "vkGetAccelerationStructureBuildSizesKHR"));
|
||||||
vkCreateAccelerationStructureKHR = reinterpret_cast<PFN_vkCreateAccelerationStructureKHR>(vkGetInstanceProcAddr(instance, "vkCreateAccelerationStructureKHR"));
|
vkCreateAccelerationStructureKHR = reinterpret_cast<PFN_vkCreateAccelerationStructureKHR>(vkGetInstanceProcAddr(instance, "vkCreateAccelerationStructureKHR"));
|
||||||
vkCmdBuildAccelerationStructuresKHR = reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresKHR>(vkGetInstanceProcAddr(instance, "vkCmdBuildAccelerationStructuresKHR"));
|
vkCmdBuildAccelerationStructuresKHR = reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresKHR>(vkGetInstanceProcAddr(instance, "vkCmdBuildAccelerationStructuresKHR"));
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ void WindowVulkan::CreateSwapchain()
|
||||||
swapchainCI.imageFormat = colorFormat;
|
swapchainCI.imageFormat = colorFormat;
|
||||||
swapchainCI.imageColorSpace = colorSpace;
|
swapchainCI.imageColorSpace = colorSpace;
|
||||||
swapchainCI.imageExtent = { swapchainExtent.width, swapchainExtent.height };
|
swapchainCI.imageExtent = { swapchainExtent.width, swapchainExtent.height };
|
||||||
swapchainCI.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
swapchainCI.imageUsage = VK_IMAGE_USAGE_STORAGE_BIT;
|
||||||
swapchainCI.preTransform = (VkSurfaceTransformFlagBitsKHR)preTransform;
|
swapchainCI.preTransform = (VkSurfaceTransformFlagBitsKHR)preTransform;
|
||||||
swapchainCI.imageArrayLayers = 1;
|
swapchainCI.imageArrayLayers = 1;
|
||||||
swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
@ -138,8 +138,6 @@ void WindowVulkan::CreateSwapchain()
|
||||||
// Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the surface area
|
// Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the surface area
|
||||||
swapchainCI.clipped = VK_TRUE;
|
swapchainCI.clipped = VK_TRUE;
|
||||||
swapchainCI.compositeAlpha = compositeAlpha;
|
swapchainCI.compositeAlpha = compositeAlpha;
|
||||||
swapchainCI.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
|
|
||||||
swapchainCI.imageUsage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
|
|
||||||
|
|
||||||
VulkanDevice::CheckVkResult(vkCreateSwapchainKHR(VulkanDevice::device, &swapchainCI, nullptr, &swapChain));
|
VulkanDevice::CheckVkResult(vkCreateSwapchainKHR(VulkanDevice::device, &swapchainCI, nullptr, &swapChain));
|
||||||
|
|
||||||
|
|
@ -177,6 +175,13 @@ void WindowVulkan::CreateSwapchain()
|
||||||
colorAttachmentView.flags = 0;
|
colorAttachmentView.flags = 0;
|
||||||
colorAttachmentView.image = images[i];
|
colorAttachmentView.image = images[i];
|
||||||
VulkanDevice::CheckVkResult(vkCreateImageView(VulkanDevice::device, &colorAttachmentView, nullptr, &imageViews[i]));
|
VulkanDevice::CheckVkResult(vkCreateImageView(VulkanDevice::device, &colorAttachmentView, nullptr, &imageViews[i]));
|
||||||
|
|
||||||
|
VkImageSubresourceRange range{};
|
||||||
|
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
range.baseMipLevel = 0;
|
||||||
|
range.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
|
range.baseArrayLayer = 0;
|
||||||
|
range.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -253,32 +258,6 @@ WindowVulkan::WindowVulkan(std::uint32_t width, std::uint32_t height) : Window(w
|
||||||
|
|
||||||
CreateSwapchain();
|
CreateSwapchain();
|
||||||
|
|
||||||
std::array<VkAttachmentDescription, 1> attachments = {};
|
|
||||||
// Color attachment
|
|
||||||
attachments[0].format = colorFormat;
|
|
||||||
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
||||||
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
||||||
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
||||||
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
||||||
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
|
||||||
|
|
||||||
VkAttachmentReference colorReference = {};
|
|
||||||
colorReference.attachment = 0;
|
|
||||||
colorReference.layout = VK_IMAGE_LAYOUT_GENERAL;
|
|
||||||
|
|
||||||
VkSubpassDescription subpassDescription = {};
|
|
||||||
subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
|
||||||
subpassDescription.colorAttachmentCount = 1;
|
|
||||||
subpassDescription.pColorAttachments = &colorReference;
|
|
||||||
subpassDescription.pDepthStencilAttachment = nullptr;
|
|
||||||
subpassDescription.inputAttachmentCount = 0;
|
|
||||||
subpassDescription.pInputAttachments = nullptr;
|
|
||||||
subpassDescription.preserveAttachmentCount = 0;
|
|
||||||
subpassDescription.pPreserveAttachments = nullptr;
|
|
||||||
subpassDescription.pResolveAttachments = nullptr;
|
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo cmdBufAllocateInfo {};
|
VkCommandBufferAllocateInfo cmdBufAllocateInfo {};
|
||||||
cmdBufAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
cmdBufAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
cmdBufAllocateInfo.commandPool = VulkanDevice::commandPool;
|
cmdBufAllocateInfo.commandPool = VulkanDevice::commandPool;
|
||||||
|
|
@ -337,16 +316,19 @@ void WindowVulkan::Render() {
|
||||||
range.baseArrayLayer = 0;
|
range.baseArrayLayer = 0;
|
||||||
range.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
range.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
|
|
||||||
image_layout_transition(drawCmdBuffers[currentBuffer],
|
VkImageMemoryBarrier image_memory_barrier {
|
||||||
images[currentBuffer],
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.srcAccessMask = 0,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
||||||
0,
|
.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
VK_IMAGE_LAYOUT_GENERAL,
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
range
|
.image = images[currentBuffer],
|
||||||
);
|
.subresourceRange = range
|
||||||
|
};
|
||||||
|
|
||||||
|
vkCmdPipelineBarrier(drawCmdBuffers[currentBuffer], VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
|
||||||
|
|
||||||
onRender.Invoke();
|
onRender.Invoke();
|
||||||
|
|
||||||
|
|
@ -363,12 +345,20 @@ void WindowVulkan::Render() {
|
||||||
vkCmdBindDescriptorSets2(drawCmdBuffers[currentBuffer], &bindDescriptorSetsInfo);
|
vkCmdBindDescriptorSets2(drawCmdBuffers[currentBuffer], &bindDescriptorSetsInfo);
|
||||||
VulkanDevice::vkCmdTraceRaysKHR(drawCmdBuffers[currentBuffer], &raygenRegion, &missRegion, &hitRegion, &callableRegion, width, height, 1);
|
VulkanDevice::vkCmdTraceRaysKHR(drawCmdBuffers[currentBuffer], &raygenRegion, &missRegion, &hitRegion, &callableRegion, width, height, 1);
|
||||||
|
|
||||||
image_layout_transition(drawCmdBuffers[currentBuffer],
|
|
||||||
images[currentBuffer],
|
VkImageMemoryBarrier image_memory_barrier2 {
|
||||||
VK_IMAGE_LAYOUT_GENERAL,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||||
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
||||||
range
|
.dstAccessMask = 0,
|
||||||
);
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||||
|
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = images[currentBuffer],
|
||||||
|
.subresourceRange = range
|
||||||
|
};
|
||||||
|
|
||||||
|
vkCmdPipelineBarrier(drawCmdBuffers[currentBuffer], VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier2);
|
||||||
|
|
||||||
VulkanDevice::CheckVkResult(vkEndCommandBuffer(drawCmdBuffers[currentBuffer]));
|
VulkanDevice::CheckVkResult(vkEndCommandBuffer(drawCmdBuffers[currentBuffer]));
|
||||||
|
|
||||||
|
|
@ -385,7 +375,13 @@ void WindowVulkan::Render() {
|
||||||
presentInfo.pWaitSemaphores = &semaphores.renderComplete;
|
presentInfo.pWaitSemaphores = &semaphores.renderComplete;
|
||||||
presentInfo.waitSemaphoreCount = 1;
|
presentInfo.waitSemaphoreCount = 1;
|
||||||
}
|
}
|
||||||
VulkanDevice::CheckVkResult(vkQueuePresentKHR(VulkanDevice::queue, &presentInfo));
|
|
||||||
|
VkResult result = vkQueuePresentKHR(VulkanDevice::queue, &presentInfo);
|
||||||
|
if(result == VK_SUBOPTIMAL_KHR) {
|
||||||
|
CreateSwapchain();
|
||||||
|
} else {
|
||||||
|
VulkanDevice::CheckVkResult(result);
|
||||||
|
}
|
||||||
VulkanDevice::CheckVkResult(vkQueueWaitIdle(VulkanDevice::queue));
|
VulkanDevice::CheckVkResult(vkQueueWaitIdle(VulkanDevice::queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -393,6 +389,27 @@ VkCommandBuffer WindowVulkan::StartInit() {
|
||||||
VkCommandBufferBeginInfo cmdBufInfo {};
|
VkCommandBufferBeginInfo cmdBufInfo {};
|
||||||
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
VulkanDevice::CheckVkResult(vkBeginCommandBuffer(drawCmdBuffers[currentBuffer], &cmdBufInfo));
|
VulkanDevice::CheckVkResult(vkBeginCommandBuffer(drawCmdBuffers[currentBuffer], &cmdBufInfo));
|
||||||
|
|
||||||
|
VkImageSubresourceRange range{};
|
||||||
|
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
range.baseMipLevel = 0;
|
||||||
|
range.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
|
range.baseArrayLayer = 0;
|
||||||
|
range.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
|
|
||||||
|
for(std::uint32_t i = 0; i < numFrames; i++) {
|
||||||
|
image_layout_transition(drawCmdBuffers[currentBuffer],
|
||||||
|
images[i],
|
||||||
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||||
|
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||||
|
range
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return drawCmdBuffers[currentBuffer];
|
return drawCmdBuffers[currentBuffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
678
implementations/Crafter.Graphics-Window_vulkan_windows.cpp
Normal file
678
implementations/Crafter.Graphics-Window_vulkan_windows.cpp
Normal file
|
|
@ -0,0 +1,678 @@
|
||||||
|
/*
|
||||||
|
Crafter®.Graphics
|
||||||
|
Copyright (C) 2025 Catcrafts®
|
||||||
|
catcrafts.net
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License version 3.0 as published by the Free Software Foundation;
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
module;
|
||||||
|
#include <windows.h>
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
#include <vulkan/vulkan_win32.h>
|
||||||
|
#include <cassert>
|
||||||
|
module Crafter.Graphics:Window_wayland_impl;
|
||||||
|
import :Window;
|
||||||
|
import :RenderingElement;
|
||||||
|
import :MouseElement;
|
||||||
|
import std;
|
||||||
|
import :Types;
|
||||||
|
import :VulkanTransition;
|
||||||
|
import Crafter.Event;
|
||||||
|
|
||||||
|
using namespace Crafter;
|
||||||
|
|
||||||
|
CrafterKeys vk_to_crafter_key(WPARAM vk)
|
||||||
|
{
|
||||||
|
switch (vk)
|
||||||
|
{
|
||||||
|
// Alphabet
|
||||||
|
case 'A': return CrafterKeys::A;
|
||||||
|
case 'B': return CrafterKeys::B;
|
||||||
|
case 'C': return CrafterKeys::C;
|
||||||
|
case 'D': return CrafterKeys::D;
|
||||||
|
case 'E': return CrafterKeys::E;
|
||||||
|
case 'F': return CrafterKeys::F;
|
||||||
|
case 'G': return CrafterKeys::G;
|
||||||
|
case 'H': return CrafterKeys::H;
|
||||||
|
case 'I': return CrafterKeys::I;
|
||||||
|
case 'J': return CrafterKeys::J;
|
||||||
|
case 'K': return CrafterKeys::K;
|
||||||
|
case 'L': return CrafterKeys::L;
|
||||||
|
case 'M': return CrafterKeys::M;
|
||||||
|
case 'N': return CrafterKeys::N;
|
||||||
|
case 'O': return CrafterKeys::O;
|
||||||
|
case 'P': return CrafterKeys::P;
|
||||||
|
case 'Q': return CrafterKeys::Q;
|
||||||
|
case 'R': return CrafterKeys::R;
|
||||||
|
case 'S': return CrafterKeys::S;
|
||||||
|
case 'T': return CrafterKeys::T;
|
||||||
|
case 'U': return CrafterKeys::U;
|
||||||
|
case 'V': return CrafterKeys::V;
|
||||||
|
case 'W': return CrafterKeys::W;
|
||||||
|
case 'X': return CrafterKeys::X;
|
||||||
|
case 'Y': return CrafterKeys::Y;
|
||||||
|
case 'Z': return CrafterKeys::Z;
|
||||||
|
|
||||||
|
// Numbers
|
||||||
|
case '0': return CrafterKeys::_0;
|
||||||
|
case '1': return CrafterKeys::_1;
|
||||||
|
case '2': return CrafterKeys::_2;
|
||||||
|
case '3': return CrafterKeys::_3;
|
||||||
|
case '4': return CrafterKeys::_4;
|
||||||
|
case '5': return CrafterKeys::_5;
|
||||||
|
case '6': return CrafterKeys::_6;
|
||||||
|
case '7': return CrafterKeys::_7;
|
||||||
|
case '8': return CrafterKeys::_8;
|
||||||
|
case '9': return CrafterKeys::_9;
|
||||||
|
|
||||||
|
// Function keys
|
||||||
|
case VK_F1: return CrafterKeys::F1;
|
||||||
|
case VK_F2: return CrafterKeys::F2;
|
||||||
|
case VK_F3: return CrafterKeys::F3;
|
||||||
|
case VK_F4: return CrafterKeys::F4;
|
||||||
|
case VK_F5: return CrafterKeys::F5;
|
||||||
|
case VK_F6: return CrafterKeys::F6;
|
||||||
|
case VK_F7: return CrafterKeys::F7;
|
||||||
|
case VK_F8: return CrafterKeys::F8;
|
||||||
|
case VK_F9: return CrafterKeys::F9;
|
||||||
|
case VK_F10: return CrafterKeys::F10;
|
||||||
|
case VK_F11: return CrafterKeys::F11;
|
||||||
|
case VK_F12: return CrafterKeys::F12;
|
||||||
|
|
||||||
|
// Control keys
|
||||||
|
case VK_ESCAPE: return CrafterKeys::Escape;
|
||||||
|
case VK_TAB: return CrafterKeys::Tab;
|
||||||
|
case VK_RETURN: return CrafterKeys::Enter;
|
||||||
|
case VK_SPACE: return CrafterKeys::Space;
|
||||||
|
case VK_BACK: return CrafterKeys::Backspace;
|
||||||
|
case VK_DELETE: return CrafterKeys::Delete;
|
||||||
|
case VK_INSERT: return CrafterKeys::Insert;
|
||||||
|
case VK_HOME: return CrafterKeys::Home;
|
||||||
|
case VK_END: return CrafterKeys::End;
|
||||||
|
case VK_PRIOR: return CrafterKeys::PageUp;
|
||||||
|
case VK_NEXT: return CrafterKeys::PageDown;
|
||||||
|
case VK_CAPITAL: return CrafterKeys::CapsLock;
|
||||||
|
case VK_NUMLOCK: return CrafterKeys::NumLock;
|
||||||
|
case VK_SCROLL: return CrafterKeys::ScrollLock;
|
||||||
|
|
||||||
|
// Modifiers
|
||||||
|
case VK_LSHIFT: return CrafterKeys::LeftShift;
|
||||||
|
case VK_RSHIFT: return CrafterKeys::RightShift;
|
||||||
|
case VK_LCONTROL: return CrafterKeys::LeftCtrl;
|
||||||
|
case VK_RCONTROL: return CrafterKeys::RightCtrl;
|
||||||
|
case VK_LMENU: return CrafterKeys::LeftAlt;
|
||||||
|
case VK_RMENU: return CrafterKeys::RightAlt;
|
||||||
|
case VK_LWIN: return CrafterKeys::LeftSuper;
|
||||||
|
case VK_RWIN: return CrafterKeys::RightSuper;
|
||||||
|
|
||||||
|
// Arrows
|
||||||
|
case VK_UP: return CrafterKeys::Up;
|
||||||
|
case VK_DOWN: return CrafterKeys::Down;
|
||||||
|
case VK_LEFT: return CrafterKeys::Left;
|
||||||
|
case VK_RIGHT: return CrafterKeys::Right;
|
||||||
|
|
||||||
|
// Keypad
|
||||||
|
case VK_NUMPAD0: return CrafterKeys::keypad_0;
|
||||||
|
case VK_NUMPAD1: return CrafterKeys::keypad_1;
|
||||||
|
case VK_NUMPAD2: return CrafterKeys::keypad_2;
|
||||||
|
case VK_NUMPAD3: return CrafterKeys::keypad_3;
|
||||||
|
case VK_NUMPAD4: return CrafterKeys::keypad_4;
|
||||||
|
case VK_NUMPAD5: return CrafterKeys::keypad_5;
|
||||||
|
case VK_NUMPAD6: return CrafterKeys::keypad_6;
|
||||||
|
case VK_NUMPAD7: return CrafterKeys::keypad_7;
|
||||||
|
case VK_NUMPAD8: return CrafterKeys::keypad_8;
|
||||||
|
case VK_NUMPAD9: return CrafterKeys::keypad_9;
|
||||||
|
case VK_SEPARATOR: return CrafterKeys::keypad_enter;
|
||||||
|
case VK_ADD: return CrafterKeys::keypad_plus;
|
||||||
|
case VK_SUBTRACT: return CrafterKeys::keypad_minus;
|
||||||
|
case VK_MULTIPLY: return CrafterKeys::keypad_multiply;
|
||||||
|
case VK_DIVIDE: return CrafterKeys::keypad_divide;
|
||||||
|
case VK_DECIMAL: return CrafterKeys::keypad_decimal;
|
||||||
|
|
||||||
|
// Punctuation
|
||||||
|
case VK_OEM_3: return CrafterKeys::grave; // `
|
||||||
|
case VK_OEM_MINUS: return CrafterKeys::minus; // -
|
||||||
|
case VK_OEM_PLUS: return CrafterKeys::equal; // =
|
||||||
|
case VK_OEM_4: return CrafterKeys::bracket_left; // [
|
||||||
|
case VK_OEM_6: return CrafterKeys::bracket_right; // ]
|
||||||
|
case VK_OEM_5: return CrafterKeys::backslash; // \
|
||||||
|
case VK_OEM_1: return CrafterKeys::semicolon; // ;
|
||||||
|
case VK_OEM_7: return CrafterKeys::quote; // '
|
||||||
|
case VK_OEM_COMMA:return CrafterKeys::comma; // ,
|
||||||
|
case VK_OEM_PERIOD:return CrafterKeys::period; // .
|
||||||
|
case VK_OEM_2: return CrafterKeys::slash; // /
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CrafterKeys::CrafterKeysMax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowVulkan::CreateSwapchain()
|
||||||
|
{
|
||||||
|
// Store the current swap chain handle so we can use it later on to ease up recreation
|
||||||
|
VkSwapchainKHR oldSwapchain = swapChain;
|
||||||
|
|
||||||
|
// Get physical device surface properties and formats
|
||||||
|
VkSurfaceCapabilitiesKHR surfCaps;
|
||||||
|
VulkanDevice::CheckVkResult(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VulkanDevice::physDevice, vulkanSurface, &surfCaps));
|
||||||
|
|
||||||
|
VkExtent2D swapchainExtent = {};
|
||||||
|
// If width (and height) equals the special value 0xFFFFFFFF, the size of the surface will be set by the swapchain
|
||||||
|
if (surfCaps.currentExtent.width == (uint32_t)-1)
|
||||||
|
{
|
||||||
|
// If the surface size is undefined, the size is set to the size of the images requested
|
||||||
|
swapchainExtent.width = width;
|
||||||
|
swapchainExtent.height = height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the surface size is defined, the swap chain size must match
|
||||||
|
swapchainExtent = surfCaps.currentExtent;
|
||||||
|
width = surfCaps.currentExtent.width;
|
||||||
|
height = surfCaps.currentExtent.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Select a present mode for the swapchain
|
||||||
|
uint32_t presentModeCount;
|
||||||
|
VulkanDevice::CheckVkResult(vkGetPhysicalDeviceSurfacePresentModesKHR(VulkanDevice::physDevice, vulkanSurface, &presentModeCount, NULL));
|
||||||
|
assert(presentModeCount > 0);
|
||||||
|
|
||||||
|
std::vector<VkPresentModeKHR> presentModes(presentModeCount);
|
||||||
|
VulkanDevice::CheckVkResult(vkGetPhysicalDeviceSurfacePresentModesKHR(VulkanDevice::physDevice, vulkanSurface, &presentModeCount, presentModes.data()));
|
||||||
|
|
||||||
|
// The VK_PRESENT_MODE_FIFO_KHR mode must always be present as per spec
|
||||||
|
// This mode waits for the vertical blank ("v-sync")
|
||||||
|
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
|
||||||
|
// Find the transformation of the surface
|
||||||
|
VkSurfaceTransformFlagsKHR preTransform;
|
||||||
|
if (surfCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
|
||||||
|
{
|
||||||
|
// We prefer a non-rotated transform
|
||||||
|
preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
preTransform = surfCaps.currentTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a supported composite alpha format (not all devices support alpha opaque)
|
||||||
|
VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
// Simply select the first composite alpha format available
|
||||||
|
std::vector<VkCompositeAlphaFlagBitsKHR> compositeAlphaFlags = {
|
||||||
|
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
||||||
|
VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
|
||||||
|
VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
|
||||||
|
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
|
||||||
|
};
|
||||||
|
for (auto& compositeAlphaFlag : compositeAlphaFlags) {
|
||||||
|
if (surfCaps.supportedCompositeAlpha & compositeAlphaFlag) {
|
||||||
|
compositeAlpha = compositeAlphaFlag;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSwapchainCreateInfoKHR swapchainCI = {};
|
||||||
|
swapchainCI.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
|
swapchainCI.surface = vulkanSurface;
|
||||||
|
swapchainCI.minImageCount = numFrames;
|
||||||
|
swapchainCI.imageFormat = colorFormat;
|
||||||
|
swapchainCI.imageColorSpace = colorSpace;
|
||||||
|
swapchainCI.imageExtent = { swapchainExtent.width, swapchainExtent.height };
|
||||||
|
swapchainCI.imageUsage = VK_IMAGE_USAGE_STORAGE_BIT;
|
||||||
|
swapchainCI.preTransform = (VkSurfaceTransformFlagBitsKHR)preTransform;
|
||||||
|
swapchainCI.imageArrayLayers = 1;
|
||||||
|
swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
swapchainCI.queueFamilyIndexCount = 0;
|
||||||
|
swapchainCI.presentMode = swapchainPresentMode;
|
||||||
|
// Setting oldSwapChain to the saved handle of the previous swapchain aids in resource reuse and makes sure that we can still present already acquired images
|
||||||
|
swapchainCI.oldSwapchain = oldSwapchain;
|
||||||
|
// Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the surface area
|
||||||
|
swapchainCI.clipped = VK_TRUE;
|
||||||
|
swapchainCI.compositeAlpha = compositeAlpha;
|
||||||
|
|
||||||
|
VulkanDevice::CheckVkResult(vkCreateSwapchainKHR(VulkanDevice::device, &swapchainCI, nullptr, &swapChain));
|
||||||
|
|
||||||
|
// If an existing swap chain is re-created, destroy the old swap chain and the ressources owned by the application (image views, images are owned by the swap chain)
|
||||||
|
if (oldSwapchain != VK_NULL_HANDLE) {
|
||||||
|
for (auto i = 0; i < numFrames; i++) {
|
||||||
|
vkDestroyImageView(VulkanDevice::device, imageViews[i], nullptr);
|
||||||
|
}
|
||||||
|
vkDestroySwapchainKHR(VulkanDevice::device, oldSwapchain, nullptr);
|
||||||
|
}
|
||||||
|
uint32_t imageCount{ 0 };
|
||||||
|
VulkanDevice::CheckVkResult(vkGetSwapchainImagesKHR(VulkanDevice::device, swapChain, &imageCount, nullptr));
|
||||||
|
|
||||||
|
// Get the swap chain images
|
||||||
|
VulkanDevice::CheckVkResult(vkGetSwapchainImagesKHR(VulkanDevice::device, swapChain, &imageCount, images));
|
||||||
|
|
||||||
|
for (auto i = 0; i < numFrames; i++)
|
||||||
|
{
|
||||||
|
VkImageViewCreateInfo colorAttachmentView = {};
|
||||||
|
colorAttachmentView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
colorAttachmentView.pNext = NULL;
|
||||||
|
colorAttachmentView.format = colorFormat;
|
||||||
|
colorAttachmentView.components = {
|
||||||
|
VK_COMPONENT_SWIZZLE_R,
|
||||||
|
VK_COMPONENT_SWIZZLE_G,
|
||||||
|
VK_COMPONENT_SWIZZLE_B,
|
||||||
|
VK_COMPONENT_SWIZZLE_A
|
||||||
|
};
|
||||||
|
colorAttachmentView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
colorAttachmentView.subresourceRange.baseMipLevel = 0;
|
||||||
|
colorAttachmentView.subresourceRange.levelCount = 1;
|
||||||
|
colorAttachmentView.subresourceRange.baseArrayLayer = 0;
|
||||||
|
colorAttachmentView.subresourceRange.layerCount = 1;
|
||||||
|
colorAttachmentView.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
colorAttachmentView.flags = 0;
|
||||||
|
colorAttachmentView.image = images[i];
|
||||||
|
VulkanDevice::CheckVkResult(vkCreateImageView(VulkanDevice::device, &colorAttachmentView, nullptr, &imageViews[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define a window class name
|
||||||
|
const char g_szClassName[] = "myWindowClass";
|
||||||
|
|
||||||
|
// Window procedure function that processes messages
|
||||||
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||||
|
|
||||||
|
WindowVulkan* window = nullptr;
|
||||||
|
|
||||||
|
if (msg == WM_NCCREATE)
|
||||||
|
{
|
||||||
|
CREATESTRUCT* pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
|
||||||
|
window = static_cast<WindowVulkan*>(pCreate->lpCreateParams);
|
||||||
|
|
||||||
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(window));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window = reinterpret_cast<WindowVulkan*>(
|
||||||
|
GetWindowLongPtr(hwnd, GWLP_USERDATA)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (msg) {
|
||||||
|
case WM_DESTROY:{
|
||||||
|
PostQuitMessage(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_KEYDOWN:{
|
||||||
|
if ((lParam & (1 << 30)) == 0) { // only first press
|
||||||
|
CrafterKeys crafterKey = vk_to_crafter_key(wParam);
|
||||||
|
if(window->heldkeys[static_cast<std::uint8_t>(crafterKey)]) {
|
||||||
|
window->onKeyHold[static_cast<std::uint8_t>(crafterKey)].Invoke();
|
||||||
|
window->onAnyKeyHold.Invoke(crafterKey);
|
||||||
|
} else{
|
||||||
|
window->heldkeys[static_cast<std::uint8_t>(crafterKey)] = true;
|
||||||
|
window->onKeyDown[static_cast<std::uint8_t>(crafterKey)].Invoke();
|
||||||
|
window->onAnyKeyDown.Invoke(crafterKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_KEYUP: {
|
||||||
|
CrafterKeys crafterKey = vk_to_crafter_key(wParam);
|
||||||
|
window->heldkeys[static_cast<std::uint8_t>(crafterKey)] = false;
|
||||||
|
window->onKeyUp[static_cast<std::uint8_t>(crafterKey)].Invoke();
|
||||||
|
window->onAnyKeyUp.Invoke(crafterKey);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_MOUSEMOVE: {
|
||||||
|
int x = LOWORD(lParam);
|
||||||
|
int y = HIWORD(lParam);
|
||||||
|
|
||||||
|
MousePoint pos = {FractionalToMappedBoundless<std::uint32_t>(static_cast<float>(x) / window->width), FractionalToMappedBoundless<std::uint32_t>(static_cast<float>(y) / window->height)};
|
||||||
|
window->currentMousePos = pos;
|
||||||
|
window->onMouseMove.Invoke({window->lastMousePos, window->currentMousePos, window->mouseDelta});
|
||||||
|
for(MouseElement* element : window->mouseElements) {
|
||||||
|
if(element) {
|
||||||
|
if(window->currentMousePos.x >= element->mouseScaled.x && window->currentMousePos.x <= element->mouseScaled.x+element->mouseScaled.width && window->currentMousePos.y > element->mouseScaled.y && window->currentMousePos.y < element->mouseScaled.y+element->mouseScaled.height) {
|
||||||
|
element->onMouseMove.Invoke({AbsoluteToMappedBoundless(window->currentMousePos.x - element->mouseScaled.x, element->mouseScaled.width), AbsoluteToMappedBoundless(window->currentMousePos.y - element->mouseScaled.y, element->mouseScaled.height)});
|
||||||
|
if(!(window->lastMousePos.x >= element->mouseScaled.x && window->lastMousePos.x <= element->mouseScaled.x+element->mouseScaled.width && window->lastMousePos.y > element->mouseScaled.y && window->lastMousePos.y < element->mouseScaled.y+element->mouseScaled.height)) {
|
||||||
|
element->onMouseEnter.Invoke({AbsoluteToMappedBoundless(window->currentMousePos.x - element->mouseScaled.x, element->mouseScaled.width), AbsoluteToMappedBoundless(window->currentMousePos.y - element->mouseScaled.y, element->mouseScaled.height)});
|
||||||
|
}
|
||||||
|
} else if(window->lastMousePos.x >= element->mouseScaled.x && window->lastMousePos.x <= element->mouseScaled.x+element->mouseScaled.width && window->lastMousePos.y > element->mouseScaled.y && window->lastMousePos.y < element->mouseScaled.y+element->mouseScaled.height) {
|
||||||
|
element->onMouseLeave.Invoke({AbsoluteToMappedBoundless(window->currentMousePos.x - element->mouseScaled.x, element->mouseScaled.width), AbsoluteToMappedBoundless(window->currentMousePos.y - element->mouseScaled.y, element->mouseScaled.height)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window->mouseElements.erase(std::remove(window->mouseElements.begin(), window->mouseElements.end(), static_cast<MouseElement*>(nullptr)), window->mouseElements.end());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_LBUTTONDOWN: {
|
||||||
|
window->mouseLeftHeld = true;
|
||||||
|
window->onMouseLeftClick.Invoke(window->currentMousePos);
|
||||||
|
for(MouseElement* element : window->mouseElements) {
|
||||||
|
if(element) {
|
||||||
|
if(window->currentMousePos.x >= element->mouseScaled.x && window->currentMousePos.x <= element->mouseScaled.x+element->mouseScaled.width && window->currentMousePos.y > element->mouseScaled.y && window->currentMousePos.y < element->mouseScaled.y+element->mouseScaled.height) {
|
||||||
|
element->onMouseLeftClick.Invoke({AbsoluteToMappedBoundless(window->currentMousePos.x - element->mouseScaled.x, element->mouseScaled.width), AbsoluteToMappedBoundless(window->currentMousePos.y - element->mouseScaled.y, element->mouseScaled.height)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_LBUTTONUP: {
|
||||||
|
window->mouseLeftHeld = false;
|
||||||
|
window->onMouseLeftRelease.Invoke(window->currentMousePos);
|
||||||
|
for(MouseElement* element : window->mouseElements) {
|
||||||
|
if(element) {
|
||||||
|
if(window->currentMousePos.x >= element->mouseScaled.x && window->currentMousePos.x <= element->mouseScaled.x+element->mouseScaled.width && window->currentMousePos.y > element->mouseScaled.y && window->currentMousePos.y < element->mouseScaled.y+element->mouseScaled.height) {
|
||||||
|
element->onMouseLeftRelease.Invoke({AbsoluteToMappedBoundless(window->currentMousePos.x - element->mouseScaled.x, element->mouseScaled.width), AbsoluteToMappedBoundless(window->currentMousePos.y - element->mouseScaled.y, element->mouseScaled.height)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_RBUTTONDOWN: {
|
||||||
|
window->mouseRightHeld = true;
|
||||||
|
window->onMouseRightClick.Invoke(window->currentMousePos);
|
||||||
|
for(MouseElement* element : window->mouseElements) {
|
||||||
|
if(element) {
|
||||||
|
if(window->currentMousePos.x >= element->mouseScaled.x && window->currentMousePos.x <= element->mouseScaled.x+element->mouseScaled.width && window->currentMousePos.y > element->mouseScaled.y && window->currentMousePos.y < element->mouseScaled.y+element->mouseScaled.height) {
|
||||||
|
element->onMouseRightClick.Invoke({AbsoluteToMappedBoundless(window->currentMousePos.x - element->mouseScaled.x, element->mouseScaled.width), AbsoluteToMappedBoundless(window->currentMousePos.y - element->mouseScaled.y, element->mouseScaled.height)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_RBUTTONUP: {
|
||||||
|
window->mouseRightHeld = false;
|
||||||
|
window->onMouseRightRelease.Invoke(window->currentMousePos);
|
||||||
|
for(MouseElement* element : window->mouseElements) {
|
||||||
|
if(element) {
|
||||||
|
if(window->currentMousePos.x >= element->mouseScaled.x && window->currentMousePos.x <= element->mouseScaled.x+element->mouseScaled.width && window->currentMousePos.y > element->mouseScaled.y && window->currentMousePos.y < element->mouseScaled.y+element->mouseScaled.height) {
|
||||||
|
element->onMouseRightRelease.Invoke({AbsoluteToMappedBoundless(window->currentMousePos.x - element->mouseScaled.x, element->mouseScaled.width), AbsoluteToMappedBoundless(window->currentMousePos.y - element->mouseScaled.y, element->mouseScaled.height)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
WindowVulkan::WindowVulkan(std::uint32_t width, std::uint32_t height) : Window(width, height) {
|
||||||
|
|
||||||
|
}
|
||||||
|
WindowVulkan::WindowVulkan(std::uint32_t width, std::uint32_t height, std::string_view title) : Window(width, height) {
|
||||||
|
// Initialize the window class
|
||||||
|
WNDCLASS wc = {0};
|
||||||
|
wc.lpfnWndProc = WndProc; // Set window procedure
|
||||||
|
wc.hInstance = GetModuleHandle(NULL); // Get instance handle
|
||||||
|
wc.lpszClassName = g_szClassName;
|
||||||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
|
||||||
|
if (!RegisterClass(&wc)) {
|
||||||
|
MessageBox(NULL, "Window Class Registration Failed!", "Error", MB_ICONERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT rc = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
|
||||||
|
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
|
||||||
|
|
||||||
|
HWND hwnd = CreateWindowEx(
|
||||||
|
0,
|
||||||
|
g_szClassName,
|
||||||
|
title.data(),
|
||||||
|
WS_OVERLAPPEDWINDOW,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
|
rc.right - rc.left,
|
||||||
|
rc.bottom - rc.top,
|
||||||
|
NULL, NULL, wc.hInstance, this
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (hwnd == NULL) {
|
||||||
|
MessageBox(NULL, "Window Creation Failed!", "Error", MB_ICONERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the window
|
||||||
|
ShowWindow(hwnd, SW_SHOWNORMAL);
|
||||||
|
UpdateWindow(hwnd);
|
||||||
|
|
||||||
|
MSG msg;
|
||||||
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkWin32SurfaceCreateInfoKHR createInfo = {};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||||
|
createInfo.hinstance = wc.hInstance;
|
||||||
|
createInfo.hwnd = hwnd;
|
||||||
|
VulkanDevice::CheckVkResult(vkCreateWin32SurfaceKHR(VulkanDevice::instance, &createInfo, NULL, &vulkanSurface));
|
||||||
|
|
||||||
|
// Get list of supported surface formats
|
||||||
|
std::uint32_t formatCount;
|
||||||
|
VulkanDevice::CheckVkResult(vkGetPhysicalDeviceSurfaceFormatsKHR(VulkanDevice::physDevice, vulkanSurface, &formatCount, NULL));
|
||||||
|
assert(formatCount > 0);
|
||||||
|
|
||||||
|
std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
|
||||||
|
VulkanDevice::CheckVkResult(vkGetPhysicalDeviceSurfaceFormatsKHR(VulkanDevice::physDevice, vulkanSurface, &formatCount, surfaceFormats.data()));
|
||||||
|
|
||||||
|
// We want to get a format that best suits our needs, so we try to get one from a set of preferred formats
|
||||||
|
// Initialize the format to the first one returned by the implementation in case we can't find one of the preffered formats
|
||||||
|
VkSurfaceFormatKHR selectedFormat = surfaceFormats[0];
|
||||||
|
std::vector<VkFormat> preferredImageFormats = {
|
||||||
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
VK_FORMAT_B8G8R8A8_UNORM
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& availableFormat : surfaceFormats) {
|
||||||
|
if (std::find(preferredImageFormats.begin(), preferredImageFormats.end(), availableFormat.format) != preferredImageFormats.end()) {
|
||||||
|
selectedFormat = availableFormat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
colorFormat = selectedFormat.format;
|
||||||
|
colorSpace = selectedFormat.colorSpace;
|
||||||
|
|
||||||
|
CreateSwapchain();
|
||||||
|
|
||||||
|
VkCommandBufferAllocateInfo cmdBufAllocateInfo {};
|
||||||
|
cmdBufAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
|
cmdBufAllocateInfo.commandPool = VulkanDevice::commandPool;
|
||||||
|
cmdBufAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
|
cmdBufAllocateInfo.commandBufferCount = numFrames;
|
||||||
|
VulkanDevice::CheckVkResult(vkAllocateCommandBuffers(VulkanDevice::device, &cmdBufAllocateInfo, drawCmdBuffers));
|
||||||
|
|
||||||
|
VkSemaphoreCreateInfo semaphoreCreateInfo {};
|
||||||
|
semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
VulkanDevice::CheckVkResult(vkCreateSemaphore(VulkanDevice::device, &semaphoreCreateInfo, nullptr, &semaphores.presentComplete));
|
||||||
|
VulkanDevice::CheckVkResult(vkCreateSemaphore(VulkanDevice::device, &semaphoreCreateInfo, nullptr, &semaphores.renderComplete));
|
||||||
|
|
||||||
|
// Set up submit info structure
|
||||||
|
// Semaphores will stay the same during application lifetime
|
||||||
|
// Command buffer submission info is set by each example
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submitInfo.pWaitDstStageMask = &submitPipelineStages;
|
||||||
|
submitInfo.waitSemaphoreCount = 1;
|
||||||
|
submitInfo.pWaitSemaphores = &semaphores.presentComplete;
|
||||||
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
|
submitInfo.pSignalSemaphores = &semaphores.renderComplete;
|
||||||
|
submitInfo.pNext = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowVulkan::~WindowVulkan() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowVulkan::StartSync() {
|
||||||
|
MSG msg;
|
||||||
|
while (GetMessage(&msg, NULL, 0, 0) > 0) {
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowVulkan::SetTitle(const std::string_view title) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WindowVulkan::StartUpdate() {
|
||||||
|
lastFrameBegin = std::chrono::high_resolution_clock::now();
|
||||||
|
updating = true;
|
||||||
|
while(updating) {
|
||||||
|
MSG msg;
|
||||||
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
mouseDelta = {std::int64_t(currentMousePos.x)-lastMousePos.x, std::int64_t(currentMousePos.y)-lastMousePos.y};
|
||||||
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
|
Render();
|
||||||
|
lastMousePos = currentMousePos;
|
||||||
|
currentFrameTime = {start, start-lastFrameBegin};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowVulkan::StopUpdate() {
|
||||||
|
updating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkCommandBuffer WindowVulkan::StartInit() {
|
||||||
|
VkCommandBufferBeginInfo cmdBufInfo {};
|
||||||
|
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
VulkanDevice::CheckVkResult(vkBeginCommandBuffer(drawCmdBuffers[currentBuffer], &cmdBufInfo));
|
||||||
|
|
||||||
|
VkImageSubresourceRange range{};
|
||||||
|
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
range.baseMipLevel = 0;
|
||||||
|
range.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
|
range.baseArrayLayer = 0;
|
||||||
|
range.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
|
|
||||||
|
for(std::uint32_t i = 0; i < numFrames; i++) {
|
||||||
|
image_layout_transition(drawCmdBuffers[currentBuffer],
|
||||||
|
images[i],
|
||||||
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||||
|
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||||
|
range
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return drawCmdBuffers[currentBuffer];
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowVulkan::FinishInit() {
|
||||||
|
VkSubmitInfo submitInfo{};
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
|
||||||
|
VulkanDevice::CheckVkResult(vkEndCommandBuffer(drawCmdBuffers[currentBuffer]));
|
||||||
|
VulkanDevice::CheckVkResult(vkQueueSubmit(VulkanDevice::queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||||
|
VulkanDevice::CheckVkResult(vkQueueWaitIdle(VulkanDevice::queue));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowVulkan::Render() {
|
||||||
|
// Acquire the next image from the swap chain
|
||||||
|
VulkanDevice::CheckVkResult(vkAcquireNextImageKHR(VulkanDevice::device, swapChain, UINT64_MAX, semaphores.presentComplete, (VkFence)nullptr, ¤tBuffer));
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
|
||||||
|
|
||||||
|
VkCommandBufferBeginInfo cmdBufInfo {};
|
||||||
|
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
|
||||||
|
VulkanDevice::CheckVkResult(vkBeginCommandBuffer(drawCmdBuffers[currentBuffer], &cmdBufInfo));
|
||||||
|
|
||||||
|
VkImageSubresourceRange range{};
|
||||||
|
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
range.baseMipLevel = 0;
|
||||||
|
range.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
|
range.baseArrayLayer = 0;
|
||||||
|
range.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
|
|
||||||
|
VkImageMemoryBarrier image_memory_barrier {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||||
|
.srcAccessMask = 0,
|
||||||
|
.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
||||||
|
.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||||
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = images[currentBuffer],
|
||||||
|
.subresourceRange = range
|
||||||
|
};
|
||||||
|
|
||||||
|
vkCmdPipelineBarrier(drawCmdBuffers[currentBuffer], VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
|
||||||
|
|
||||||
|
onRender.Invoke();
|
||||||
|
|
||||||
|
vkCmdBindPipeline(drawCmdBuffers[currentBuffer], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rtPipeline);
|
||||||
|
VkBindDescriptorSetsInfo bindDescriptorSetsInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BIND_DESCRIPTOR_SETS_INFO,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_ALL,
|
||||||
|
.layout = rtPipelineLayout,
|
||||||
|
.firstSet = 0,
|
||||||
|
.descriptorSetCount = static_cast<std::uint32_t>(descriptorsRt.size()),
|
||||||
|
.pDescriptorSets = descriptorsRt.data()
|
||||||
|
};
|
||||||
|
|
||||||
|
vkCmdBindDescriptorSets2(drawCmdBuffers[currentBuffer], &bindDescriptorSetsInfo);
|
||||||
|
VulkanDevice::vkCmdTraceRaysKHR(drawCmdBuffers[currentBuffer], &raygenRegion, &missRegion, &hitRegion, &callableRegion, width, height, 1);
|
||||||
|
|
||||||
|
|
||||||
|
VkImageMemoryBarrier image_memory_barrier2 {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||||
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
||||||
|
.dstAccessMask = 0,
|
||||||
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||||
|
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = images[currentBuffer],
|
||||||
|
.subresourceRange = range
|
||||||
|
};
|
||||||
|
|
||||||
|
vkCmdPipelineBarrier(drawCmdBuffers[currentBuffer], VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier2);
|
||||||
|
|
||||||
|
VulkanDevice::CheckVkResult(vkEndCommandBuffer(drawCmdBuffers[currentBuffer]));
|
||||||
|
|
||||||
|
VulkanDevice::CheckVkResult(vkQueueSubmit(VulkanDevice::queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||||
|
VkPresentInfoKHR presentInfo = {};
|
||||||
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
|
presentInfo.pNext = NULL;
|
||||||
|
presentInfo.swapchainCount = 1;
|
||||||
|
presentInfo.pSwapchains = &swapChain;
|
||||||
|
presentInfo.pImageIndices = ¤tBuffer;
|
||||||
|
// Check if a wait semaphore has been specified to wait for before presenting the image
|
||||||
|
if (semaphores.renderComplete != VK_NULL_HANDLE)
|
||||||
|
{
|
||||||
|
presentInfo.pWaitSemaphores = &semaphores.renderComplete;
|
||||||
|
presentInfo.waitSemaphoreCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult result = vkQueuePresentKHR(VulkanDevice::queue, &presentInfo);
|
||||||
|
if(result == VK_SUBOPTIMAL_KHR) {
|
||||||
|
CreateSwapchain();
|
||||||
|
} else {
|
||||||
|
VulkanDevice::CheckVkResult(result);
|
||||||
|
}
|
||||||
|
VulkanDevice::CheckVkResult(vkQueueWaitIdle(VulkanDevice::queue));
|
||||||
|
}
|
||||||
|
|
@ -117,6 +117,40 @@ export namespace Crafter {
|
||||||
|
|
||||||
return types;
|
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:
|
public:
|
||||||
void BuildPool(std::span<const VkDescriptorPoolSize> poolSizes, std::span<const VkDescriptorSetLayout> setLayouts) {
|
void BuildPool(std::span<const VkDescriptorPoolSize> poolSizes, std::span<const VkDescriptorSetLayout> setLayouts) {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
struct ShaderGroup {
|
||||||
static constexpr std::uint32_t generalShader = GeneralShader;
|
static constexpr std::uint32_t generalShader = GeneralShader;
|
||||||
static constexpr std::uint32_t closestHitShader = ClosestHitShader;
|
static constexpr std::uint32_t closestHitShader = ClosestHitShader;
|
||||||
|
|
@ -135,7 +135,7 @@ export namespace Crafter {
|
||||||
inline static VkStridedDeviceAddressRegionKHR hitRegion;
|
inline static VkStridedDeviceAddressRegionKHR hitRegion;
|
||||||
inline static VkStridedDeviceAddressRegionKHR callableRegion;
|
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 {
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo {
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
.setLayoutCount = static_cast<std::uint32_t>(setLayouts.size()),
|
.setLayoutCount = static_cast<std::uint32_t>(setLayouts.size()),
|
||||||
|
|
@ -176,7 +176,7 @@ export namespace Crafter {
|
||||||
|
|
||||||
hitRegion.stride = sbtStride;
|
hitRegion.stride = sbtStride;
|
||||||
hitRegion.deviceAddress = AlignUp(missRegion.deviceAddress + missRegion.size, VulkanDevice::rayTracingProperties.shaderGroupBaseAlignment);
|
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;
|
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);
|
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;
|
VkRayTracingShaderGroupTypeKHR groupType;
|
||||||
if constexpr(groupTemplate::generalShader != VK_SHADER_UNUSED_KHR) {
|
if constexpr(groupTemplate::generalShader != VK_SHADER_UNUSED_KHR) {
|
||||||
groupType = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_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;
|
groupType = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR;
|
||||||
} else {
|
} else {
|
||||||
static_assert(
|
static_assert(
|
||||||
|
|
@ -237,6 +237,11 @@ export namespace Crafter {
|
||||||
if constexpr(shaderTemplate::_stage == stage) {
|
if constexpr(shaderTemplate::_stage == stage) {
|
||||||
count++;
|
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 {
|
} else {
|
||||||
static_assert(
|
static_assert(
|
||||||
groupTemplate::generalShader != VK_SHADER_UNUSED_KHR ||
|
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);
|
std::memcpy(sbtBuffer.value + offset, shaderHandles.data() + index * VulkanDevice::rayTracingProperties.shaderGroupHandleSize, VulkanDevice::rayTracingProperties.shaderGroupHandleSize);
|
||||||
offset += sbtStride;
|
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 {
|
} else {
|
||||||
static_assert(
|
static_assert(
|
||||||
groupTemplate::generalShader != VK_SHADER_UNUSED_KHR ||
|
groupTemplate::generalShader != VK_SHADER_UNUSED_KHR ||
|
||||||
|
|
@ -283,6 +294,7 @@ export namespace Crafter {
|
||||||
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_MISS_BIT_KHR>(sbtStride, offset), ...);
|
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_MISS_BIT_KHR>(sbtStride, offset), ...);
|
||||||
offset = AlignUp(offset, VulkanDevice::rayTracingProperties.shaderGroupBaseAlignment);
|
offset = AlignUp(offset, VulkanDevice::rayTracingProperties.shaderGroupBaseAlignment);
|
||||||
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR>(sbtStride, offset), ...);
|
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR>(sbtStride, offset), ...);
|
||||||
|
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_ANY_HIT_BIT_KHR>(sbtStride, offset), ...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
module;
|
module;
|
||||||
#ifdef CRAFTER_GRAPHICS_VULKAN
|
#ifdef CRAFTER_GRAPHICS_VULKAN
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include <vulkan/vulkan_wayland.h>
|
|
||||||
#endif
|
#endif
|
||||||
export module Crafter.Graphics:VulkanDevice;
|
export module Crafter.Graphics:VulkanDevice;
|
||||||
#ifdef CRAFTER_GRAPHICS_VULKAN
|
#ifdef CRAFTER_GRAPHICS_VULKAN
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ module;
|
||||||
#include <wayland-client-protocol.h>
|
#include <wayland-client-protocol.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef CRAFTER_GRAPHICS_VULKAN
|
#ifdef CRAFTER_GRAPHICS_VULKAN
|
||||||
|
#ifndef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -61,6 +62,9 @@ module;
|
||||||
#include <wayland-client-protocol.h>
|
#include <wayland-client-protocol.h>
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include <vulkan/vulkan_wayland.h>
|
#include <vulkan/vulkan_wayland.h>
|
||||||
|
#else
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
export module Crafter.Graphics:Window;
|
export module Crafter.Graphics:Window;
|
||||||
|
|
@ -278,7 +282,7 @@ export namespace Crafter {
|
||||||
// Command buffer submission and execution
|
// Command buffer submission and execution
|
||||||
VkSemaphore renderComplete;
|
VkSemaphore renderComplete;
|
||||||
};
|
};
|
||||||
|
#ifndef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32
|
||||||
class WindowVulkan final : public Window, public WindowKeyboard, public WindowMouse, public WindowTitle {
|
class WindowVulkan final : public Window, public WindowKeyboard, public WindowMouse, public WindowTitle {
|
||||||
public:
|
public:
|
||||||
WindowVulkan(std::uint32_t width, std::uint32_t height);
|
WindowVulkan(std::uint32_t width, std::uint32_t height);
|
||||||
|
|
@ -412,5 +416,63 @@ export namespace Crafter {
|
||||||
VkStridedDeviceAddressRegionKHR hitRegion;
|
VkStridedDeviceAddressRegionKHR hitRegion;
|
||||||
VkStridedDeviceAddressRegionKHR callableRegion;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
24
project.json
24
project.json
|
|
@ -3,13 +3,13 @@
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "base",
|
"name": "base",
|
||||||
"implementations": ["implementations/Crafter.Graphics-Font", "implementations/Crafter.Graphics-Shm", "implementations/Crafter.Graphics-Window", "implementations/Crafter.Graphics-MouseElement", "implementations/Crafter.Graphics-Transform", "implementations/Crafter.Graphics-GridElement", "implementations/Crafter.Graphics-Image"],
|
"implementations": ["implementations/Crafter.Graphics-Font", "implementations/Crafter.Graphics-Window", "implementations/Crafter.Graphics-MouseElement", "implementations/Crafter.Graphics-Transform", "implementations/Crafter.Graphics-GridElement", "implementations/Crafter.Graphics-Image"],
|
||||||
"interfaces": ["interfaces/Crafter.Graphics-Window", "interfaces/Crafter.Graphics", "interfaces/Crafter.Graphics-Types", "interfaces/Crafter.Graphics-Font", "interfaces/Crafter.Graphics-Image", "interfaces/Crafter.Graphics-Shm", "interfaces/Crafter.Graphics-Animation", "interfaces/Crafter.Graphics-RenderingElement", "interfaces/Crafter.Graphics-MouseElement", "interfaces/Crafter.Graphics-Transform", "interfaces/Crafter.Graphics-GridElement", "interfaces/Crafter.Graphics-VulkanDevice", "interfaces/Crafter.Graphics-VulkanTransition", "interfaces/Crafter.Graphics-Mesh", "interfaces/Crafter.Graphics-VulkanBuffer", "interfaces/Crafter.Graphics-RenderingElement3DVulkan", "interfaces/Crafter.Graphics-DescriptorPoolVulkan", "interfaces/Crafter.Graphics-ShaderVulkan", "interfaces/Crafter.Graphics-PipelineRTVulkan", "interfaces/Crafter.Graphics-ShaderBindingTableVulkan", "interfaces/Crafter.Graphics-ImageVulkan", "interfaces/Crafter.Graphics-SamplerVulkan", "interfaces/Crafter.Graphics-DescriptorSetLayoutVulkan"],
|
"interfaces": ["interfaces/Crafter.Graphics-Window", "interfaces/Crafter.Graphics", "interfaces/Crafter.Graphics-Types", "interfaces/Crafter.Graphics-Font", "interfaces/Crafter.Graphics-Image", "interfaces/Crafter.Graphics-Shm", "interfaces/Crafter.Graphics-Animation", "interfaces/Crafter.Graphics-RenderingElement", "interfaces/Crafter.Graphics-MouseElement", "interfaces/Crafter.Graphics-Transform", "interfaces/Crafter.Graphics-GridElement", "interfaces/Crafter.Graphics-VulkanDevice", "interfaces/Crafter.Graphics-VulkanTransition", "interfaces/Crafter.Graphics-Mesh", "interfaces/Crafter.Graphics-VulkanBuffer", "interfaces/Crafter.Graphics-RenderingElement3DVulkan", "interfaces/Crafter.Graphics-DescriptorPoolVulkan", "interfaces/Crafter.Graphics-ShaderVulkan", "interfaces/Crafter.Graphics-PipelineRTVulkan", "interfaces/Crafter.Graphics-ShaderBindingTableVulkan", "interfaces/Crafter.Graphics-ImageVulkan", "interfaces/Crafter.Graphics-SamplerVulkan", "interfaces/Crafter.Graphics-DescriptorSetLayoutVulkan"],
|
||||||
"type": "library"
|
"type": "library"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "wayland",
|
"name": "wayland",
|
||||||
"implementations": ["implementations/Crafter.Graphics-Window_wayland"],
|
"implementations": ["implementations/Crafter.Graphics-Window_wayland", "implementations/Crafter.Graphics-Shm"],
|
||||||
"interfaces": [],
|
"interfaces": [],
|
||||||
"libs": ["wayland-client", "xkbcommon"],
|
"libs": ["wayland-client", "xkbcommon"],
|
||||||
"c_files": ["lib/xdg-shell-protocol", "lib/wayland-xdg-decoration-unstable-v1-client-protocol", "lib/fractional-scale-v1", "lib/viewporter"],
|
"c_files": ["lib/xdg-shell-protocol", "lib/wayland-xdg-decoration-unstable-v1-client-protocol", "lib/fractional-scale-v1", "lib/viewporter"],
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "vulkan",
|
"name": "vulkan",
|
||||||
"implementations": ["implementations/Crafter.Graphics-VulkanDevice", "implementations/Crafter.Graphics-Window_vulkan", "implementations/Crafter.Graphics-Mesh_vulkan", "implementations/Crafter.Graphics-RenderingElement3DVulkan"],
|
"implementations": ["implementations/Crafter.Graphics-VulkanDevice", "implementations/Crafter.Graphics-Shm", "implementations/Crafter.Graphics-Window_vulkan", "implementations/Crafter.Graphics-Mesh_vulkan", "implementations/Crafter.Graphics-RenderingElement3DVulkan"],
|
||||||
"interfaces": [],
|
"interfaces": [],
|
||||||
"libs": ["wayland-client", "xkbcommon", "vulkan"],
|
"libs": ["wayland-client", "xkbcommon", "vulkan"],
|
||||||
"c_files": ["lib/xdg-shell-protocol", "lib/wayland-xdg-decoration-unstable-v1-client-protocol", "lib/fractional-scale-v1", "lib/viewporter"],
|
"c_files": ["lib/xdg-shell-protocol", "lib/wayland-xdg-decoration-unstable-v1-client-protocol", "lib/fractional-scale-v1", "lib/viewporter"],
|
||||||
|
|
@ -33,6 +33,18 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "vulkan-windows",
|
||||||
|
"implementations": ["implementations/Crafter.Graphics-VulkanDevice", "implementations/Crafter.Graphics-Window_vulkan_windows", "implementations/Crafter.Graphics-Mesh_vulkan", "implementations/Crafter.Graphics-RenderingElement3DVulkan"],
|
||||||
|
"interfaces": [],
|
||||||
|
"libs": ["vulkan-1"],
|
||||||
|
"extends": ["base"],
|
||||||
|
"defines": [
|
||||||
|
{
|
||||||
|
"name": "CRAFTER_GRAPHICS_VULKAN"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "deps",
|
"name": "deps",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
|
|
@ -94,6 +106,12 @@
|
||||||
"extends": ["vulkan", "deps"],
|
"extends": ["vulkan", "deps"],
|
||||||
"type": "library"
|
"type": "library"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "lib-vulkan-windows",
|
||||||
|
"extends": ["vulkan-windows", "deps"],
|
||||||
|
"type": "library",
|
||||||
|
"target": "x86_64-w64-mingw32"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "lib-vulkan-timing",
|
"name": "lib-vulkan-timing",
|
||||||
"extends": ["vulkan", "deps-timing"],
|
"extends": ["vulkan", "deps-timing"],
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue