descriptor heap rewrite
This commit is contained in:
parent
b4bd0c03c5
commit
f8e142fb06
31 changed files with 429 additions and 1017 deletions
57
interfaces/Crafter.Graphics-DescriptorHeapVulkan.cppm
Normal file
57
interfaces/Crafter.Graphics-DescriptorHeapVulkan.cppm
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
Crafter®.Graphics
|
||||
Copyright (C) 2026 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;
|
||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||
#include "vulkan/vulkan.h"
|
||||
#endif
|
||||
export module Crafter.Graphics:DescriptorHeapVulkan;
|
||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||
import std;
|
||||
import :Device;
|
||||
import :Window;
|
||||
import :Types;
|
||||
import :VulkanBuffer;
|
||||
|
||||
export namespace Crafter {
|
||||
struct DescriptorHeapVulkan {
|
||||
inline static VulkanBuffer<std::uint8_t, true, true> resourceHeap[Window::numFrames];
|
||||
inline static VulkanBuffer<std::uint8_t, true, true> samplerHeap[Window::numFrames];
|
||||
inline static std::uint32_t bufferStartOffset;
|
||||
inline static std::uint16_t bufferStartElement;
|
||||
void Initialize(std::uint16_t images, std::uint16_t buffers, std::uint16_t samplers) {
|
||||
std::uint32_t descriptorRegion = images * Device::descriptorHeapProperties.imageDescriptorSize + buffers * Device::descriptorHeapProperties.bufferDescriptorSize;
|
||||
std::uint32_t alignedDescriptorRegion = (descriptorRegion + Device::descriptorHeapProperties.imageDescriptorAlignment - 1) & ~(Device::descriptorHeapProperties.imageDescriptorAlignment - 1);
|
||||
std::uint32_t resourceSize = alignedDescriptorRegion + Device::descriptorHeapProperties.minResourceHeapReservedRange;
|
||||
std::uint32_t samplerSize = samplers * Device::descriptorHeapProperties.samplerDescriptorSize + Device::descriptorHeapProperties.minSamplerHeapReservedRange;
|
||||
bufferStartElement = images * Device::descriptorHeapProperties.imageDescriptorSize / Device::descriptorHeapProperties.bufferDescriptorSize;
|
||||
|
||||
if(images > 0 && bufferStartElement == 0) {
|
||||
bufferStartElement = 1;
|
||||
}
|
||||
bufferStartOffset = bufferStartElement * Device::descriptorHeapProperties.bufferDescriptorSize;
|
||||
for(std::uint8_t i = 0; i < Window::numFrames; i++) {
|
||||
resourceHeap[i].Create(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_DESCRIPTOR_HEAP_BIT_EXT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, resourceSize);
|
||||
samplerHeap[i].Create(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_DESCRIPTOR_HEAP_BIT_EXT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, samplerSize);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,187 +0,0 @@
|
|||
/*
|
||||
Crafter®.Graphics
|
||||
Copyright (C) 2026 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;
|
||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||
#include "vulkan/vulkan.h"
|
||||
#endif
|
||||
export module Crafter.Graphics:DescriptorPoolVulkan;
|
||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||
import std;
|
||||
import :Device;
|
||||
import :Types;
|
||||
import :DescriptorSetLayoutVulkan;
|
||||
import Crafter.Event;
|
||||
|
||||
export namespace Crafter {
|
||||
struct DescriptorEntry {
|
||||
VkDescriptorType type;
|
||||
bool occured = true;
|
||||
};
|
||||
|
||||
class DescriptorPool {
|
||||
public:
|
||||
std::vector<VkDescriptorSet> sets;
|
||||
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
|
||||
|
||||
template <typename Shader>
|
||||
consteval static void GetOccuringDescriptors(std::array<DescriptorEntry, 20>& types) {
|
||||
for (const VkDescriptorSetLayoutBinding& binding : Shader::descriptors) {
|
||||
for (DescriptorEntry& type : types) {
|
||||
if (type.type == binding.descriptorType) {
|
||||
type.occured = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Shaders>
|
||||
consteval static std::uint32_t GetUniqueDiscriptorCount() {
|
||||
std::array<DescriptorEntry, 20> types = {{{VK_DESCRIPTOR_TYPE_SAMPLER, 0},{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0},{VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0},{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 0},{VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0},{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 0},{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 0},{VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 0},{VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, 0},{VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 0},{VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV, 0},{VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM, 0},{VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, 0},{VK_DESCRIPTOR_TYPE_MUTABLE_EXT, 0},{VK_DESCRIPTOR_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_NV, 0},{VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, 0},{VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, 0}}};
|
||||
|
||||
(GetOccuringDescriptors<Shaders>(types), ... );
|
||||
|
||||
std::uint32_t size = 0;
|
||||
for(DescriptorEntry& type : types) {
|
||||
if(type.occured) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
template <typename... Shaders>
|
||||
consteval static std::array<VkDescriptorPoolSize, GetUniqueDiscriptorCount<Shaders...>()> GetPoolSizes() {
|
||||
std::array<VkDescriptorPoolSize, GetUniqueDiscriptorCount<Shaders...>()> types = {};
|
||||
for(std::uint32_t i = 0; i < GetUniqueDiscriptorCount<Shaders...>(); i++){
|
||||
types[i].descriptorCount = 12345;
|
||||
}
|
||||
|
||||
([&] {
|
||||
for (const VkDescriptorSetLayoutBinding& binding : Shaders::descriptors) {
|
||||
bool found = false;
|
||||
for(VkDescriptorPoolSize& type : types) {
|
||||
if(type.type == binding.descriptorType && type.descriptorCount != 12345) {
|
||||
type.descriptorCount += binding.descriptorCount;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
for(std::uint32_t i = 0; i < GetUniqueDiscriptorCount<Shaders...>(); i++){
|
||||
if(types[i].descriptorCount == 12345) {
|
||||
types[i].type = binding.descriptorType;
|
||||
types[i].descriptorCount = binding.descriptorCount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}(),
|
||||
...);
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
constexpr static std::vector<VkDescriptorPoolSize> GetPoolSizes(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:;
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
~DescriptorPool() {
|
||||
vkDestroyDescriptorPool(Device::device, descriptorPool, nullptr);
|
||||
}
|
||||
void BuildPool(std::span<const VkDescriptorPoolSize> poolSizes, std::span<const VkDescriptorSetLayout> setLayouts) {
|
||||
if(descriptorPool != VK_NULL_HANDLE) {
|
||||
vkDestroyDescriptorPool(Device::device, descriptorPool, nullptr);
|
||||
}
|
||||
|
||||
sets.resize(setLayouts.size());
|
||||
|
||||
VkDescriptorPoolCreateInfo descriptorPoolInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.maxSets = static_cast<std::uint32_t>(sets.size()),
|
||||
.poolSizeCount = static_cast<std::uint32_t>(poolSizes.size()),
|
||||
.pPoolSizes = poolSizes.data()
|
||||
};
|
||||
|
||||
Device::CheckVkResult(vkCreateDescriptorPool(Device::device, &descriptorPoolInfo, nullptr, &descriptorPool));
|
||||
|
||||
VkDescriptorSetAllocateInfo allocInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
.descriptorPool = descriptorPool,
|
||||
.descriptorSetCount = static_cast<std::uint32_t>(sets.size()),
|
||||
.pSetLayouts = setLayouts.data(),
|
||||
};
|
||||
|
||||
Device::CheckVkResult(vkAllocateDescriptorSets(Device::device, &allocInfo, sets.data()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
Crafter®.Graphics
|
||||
Copyright (C) 2026 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;
|
||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||
#include "vulkan/vulkan.h"
|
||||
#endif
|
||||
export module Crafter.Graphics:DescriptorSetLayoutVulkan;
|
||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||
import std;
|
||||
import :Device;
|
||||
import :Types;
|
||||
import Crafter.Event;
|
||||
|
||||
export namespace Crafter {
|
||||
class DescriptorSetLayoutVulkan {
|
||||
public:
|
||||
VkDescriptorSetLayout layout;
|
||||
std::vector<VkDescriptorSetLayoutBinding> descriptors;
|
||||
DescriptorSetLayoutVulkan(std::vector<VkDescriptorSetLayoutBinding>&& layouts) : descriptors(std::move(layouts)) {
|
||||
VkDescriptorSetLayoutCreateInfo descriptorLayoutInfoMesh = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.bindingCount = static_cast<std::uint32_t>(descriptors.size()),
|
||||
.pBindings = descriptors.data()
|
||||
};
|
||||
Device::CheckVkResult(vkCreateDescriptorSetLayout(Device::device, &descriptorLayoutInfoMesh, nullptr, &layout));
|
||||
}
|
||||
};
|
||||
|
||||
template<std::uint32_t DescriptorCount, const std::array<VkDescriptorSetLayoutBinding, DescriptorCount> Descriptors>
|
||||
class DescriptorSetLayoutVulkanConst {
|
||||
public:
|
||||
inline static VkDescriptorSetLayout layout;
|
||||
constexpr static std::span<const VkDescriptorSetLayoutBinding> descriptors = Descriptors;
|
||||
static void Init() {
|
||||
VkDescriptorSetLayoutCreateInfo descriptorLayoutInfoMesh = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.bindingCount = DescriptorCount,
|
||||
.pBindings = Descriptors.data()
|
||||
};
|
||||
Device::CheckVkResult(vkCreateDescriptorSetLayout(Device::device, &descriptorLayoutInfoMesh, nullptr, &layout));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -114,9 +114,19 @@ export namespace Crafter {
|
|||
inline static PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR;
|
||||
inline static PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
|
||||
inline static PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR;
|
||||
inline static PFN_vkCmdBindResourceHeapEXT vkCmdBindResourceHeapEXT;
|
||||
inline static PFN_vkCmdBindSamplerHeapEXT vkCmdBindSamplerHeapEXT;
|
||||
inline static PFN_vkWriteResourceDescriptorsEXT vkWriteResourceDescriptorsEXT;
|
||||
inline static PFN_vkGetPhysicalDeviceDescriptorSizeEXT vkGetPhysicalDeviceDescriptorSizeEXT;
|
||||
|
||||
inline static VkPhysicalDeviceMemoryProperties memoryProperties;
|
||||
|
||||
inline static VkPhysicalDeviceDescriptorHeapPropertiesEXT descriptorHeapProperties = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_PROPERTIES_EXT
|
||||
};
|
||||
inline static VkPhysicalDeviceRayTracingPipelinePropertiesKHR rayTracingProperties = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR,
|
||||
.pNext = &descriptorHeapProperties
|
||||
};
|
||||
|
||||
static void CheckVkResult(VkResult result);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export namespace Crafter {
|
|||
std::uint8_t mipLevels;
|
||||
VkImage image;
|
||||
VkDeviceMemory imageMemory;
|
||||
VulkanBuffer<PixelType, true, false, false> buffer;
|
||||
VulkanBuffer<PixelType, true, false> buffer;
|
||||
VkImageView imageView;
|
||||
VkDescriptorImageInfo descriptor;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ export namespace Crafter {
|
|||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||
class Mesh {
|
||||
public:
|
||||
VulkanBuffer<char, false, true, false> scratchBuffer;
|
||||
VulkanBuffer<char, false, true, false> blasBuffer;
|
||||
VulkanBuffer<Vector<float, 3, 3>, true, true, false> vertexBuffer;
|
||||
VulkanBuffer<std::uint32_t, true, true, false> indexBuffer;
|
||||
VulkanBuffer<char, false, true> scratchBuffer;
|
||||
VulkanBuffer<char, false, true> blasBuffer;
|
||||
VulkanBuffer<Vector<float, 3, 3>, true, true> vertexBuffer;
|
||||
VulkanBuffer<std::uint32_t, true, true> indexBuffer;
|
||||
VkAccelerationStructureGeometryTrianglesDataKHR blasData;
|
||||
VkAccelerationStructureGeometryKHR blas;
|
||||
VkAccelerationStructureKHR accelerationStructure;
|
||||
|
|
|
|||
|
|
@ -30,26 +30,16 @@ import :ShaderBindingTableVulkan;
|
|||
import :Types;
|
||||
|
||||
export namespace Crafter {
|
||||
class PipelineRTVulkan {
|
||||
public:
|
||||
struct PipelineRTVulkan {
|
||||
VkPipeline pipeline;
|
||||
VkPipelineLayout pipelineLayout;
|
||||
std::vector<std::uint8_t> shaderHandles;
|
||||
VulkanBuffer<std::uint8_t, true, true, false> sbtBuffer;
|
||||
VulkanBuffer<std::uint8_t, true, true> sbtBuffer;
|
||||
VkStridedDeviceAddressRegionKHR raygenRegion;
|
||||
VkStridedDeviceAddressRegionKHR missRegion;
|
||||
VkStridedDeviceAddressRegionKHR hitRegion;
|
||||
VkStridedDeviceAddressRegionKHR callableRegion;
|
||||
|
||||
void Init(VkCommandBuffer cmd, std::span<VkDescriptorSetLayout> setLayouts, std::span<VkRayTracingShaderGroupCreateInfoKHR> raygenGroups, std::span<VkRayTracingShaderGroupCreateInfoKHR> missGroups, std::span<VkRayTracingShaderGroupCreateInfoKHR> hitGroups, ShaderBindingTableVulkan& shaderTable) {
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
.setLayoutCount = static_cast<std::uint32_t>(setLayouts.size()),
|
||||
.pSetLayouts = setLayouts.data()
|
||||
};
|
||||
|
||||
Device::CheckVkResult(vkCreatePipelineLayout(Device::device, &pipelineLayoutInfo, nullptr, &pipelineLayout));
|
||||
|
||||
void Init(VkCommandBuffer cmd, std::span<VkRayTracingShaderGroupCreateInfoKHR> raygenGroups, std::span<VkRayTracingShaderGroupCreateInfoKHR> missGroups, std::span<VkRayTracingShaderGroupCreateInfoKHR> hitGroups, ShaderBindingTableVulkan& shaderTable) {
|
||||
std::vector<VkRayTracingShaderGroupCreateInfoKHR> groups;
|
||||
groups.reserve(raygenGroups.size() + missGroups.size() + hitGroups.size());
|
||||
|
||||
|
|
@ -57,14 +47,21 @@ export namespace Crafter {
|
|||
groups.insert(groups.end(), missGroups.begin(), missGroups.end());
|
||||
groups.insert(groups.end(), hitGroups.begin(), hitGroups.end());
|
||||
|
||||
VkRayTracingPipelineCreateInfoKHR rtPipelineInfo{
|
||||
VkPipelineCreateFlags2CreateInfo flags2 = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO,
|
||||
.flags = VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT
|
||||
};
|
||||
|
||||
VkRayTracingPipelineCreateInfoKHR rtPipelineInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR,
|
||||
.pNext = &flags2,
|
||||
.flags = 0,
|
||||
.stageCount = static_cast<std::uint32_t>(shaderTable.shaderStages.size()),
|
||||
.pStages = shaderTable.shaderStages.data(),
|
||||
.groupCount = static_cast<std::uint32_t>(groups.size()),
|
||||
.pGroups = groups.data(),
|
||||
.maxPipelineRayRecursionDepth = 1,
|
||||
.layout = pipelineLayout
|
||||
.layout = VK_NULL_HANDLE
|
||||
};
|
||||
|
||||
Device::CheckVkResult(Device::vkCreateRayTracingPipelinesKHR(Device::device, {}, {}, 1, &rtPipelineInfo, nullptr, &pipeline));
|
||||
|
|
@ -114,189 +111,6 @@ export namespace Crafter {
|
|||
callableRegion.size = 0;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
static constexpr std::uint32_t anyHitShader = AnyHitShader;
|
||||
static constexpr std::uint32_t intersectionShader = IntersectionShader;
|
||||
};
|
||||
|
||||
template <typename Shaders, typename ShaderGroups>
|
||||
class PipelineRTVulkanConst {
|
||||
public:
|
||||
inline static VkPipeline pipeline;
|
||||
inline static VkPipelineLayout pipelineLayout;
|
||||
inline static std::vector<std::uint8_t> shaderHandles;
|
||||
inline static VulkanBuffer<std::uint8_t, true, true, false> sbtBuffer;
|
||||
inline static VkStridedDeviceAddressRegionKHR raygenRegion;
|
||||
inline static VkStridedDeviceAddressRegionKHR missRegion;
|
||||
inline static VkStridedDeviceAddressRegionKHR hitRegion;
|
||||
inline static VkStridedDeviceAddressRegionKHR callableRegion;
|
||||
|
||||
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()),
|
||||
.pSetLayouts = setLayouts.data()
|
||||
};
|
||||
|
||||
Device::CheckVkResult(vkCreatePipelineLayout(Device::device, &pipelineLayoutInfo, nullptr, &pipelineLayout));
|
||||
|
||||
constexpr auto groupIndexSeq = std::make_index_sequence<std::tuple_size_v<ShaderGroups>>{};
|
||||
|
||||
constexpr std::array<VkRayTracingShaderGroupCreateInfoKHR, std::tuple_size_v<ShaderGroups>> groups = GetShaderGroups(groupIndexSeq);
|
||||
|
||||
VkRayTracingPipelineCreateInfoKHR rtPipelineInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR,
|
||||
.stageCount = static_cast<std::uint32_t>(ShaderBindingTableVulkanConst<Shaders>::shaderStages.size()),
|
||||
.pStages = ShaderBindingTableVulkanConst<Shaders>::shaderStages.data(),
|
||||
.groupCount = static_cast<std::uint32_t>(groups.size()),
|
||||
.pGroups = groups.data(),
|
||||
.maxPipelineRayRecursionDepth = 1,
|
||||
.layout = pipelineLayout
|
||||
};
|
||||
|
||||
Device::CheckVkResult(Device::vkCreateRayTracingPipelinesKHR(Device::device, {}, {}, 1, &rtPipelineInfo, nullptr, &pipeline));
|
||||
|
||||
std::size_t dataSize = Device::rayTracingProperties.shaderGroupHandleSize * rtPipelineInfo.groupCount;
|
||||
shaderHandles.resize(dataSize);
|
||||
Device::CheckVkResult(Device::vkGetRayTracingShaderGroupHandlesKHR(Device::device, pipeline, 0, rtPipelineInfo.groupCount, dataSize, shaderHandles.data()));
|
||||
|
||||
std::uint32_t sbtStride = AlignUp(Device::rayTracingProperties.shaderGroupHandleSize, Device::rayTracingProperties.shaderGroupHandleAlignment);
|
||||
|
||||
raygenRegion.stride = sbtStride;
|
||||
raygenRegion.deviceAddress = 0;
|
||||
raygenRegion.size = GetGroupCount<VK_SHADER_STAGE_RAYGEN_BIT_KHR>(groupIndexSeq) * sbtStride;
|
||||
|
||||
missRegion.stride = sbtStride;
|
||||
missRegion.deviceAddress = AlignUp(raygenRegion.size, Device::rayTracingProperties.shaderGroupBaseAlignment);
|
||||
missRegion.size = GetGroupCount<VK_SHADER_STAGE_MISS_BIT_KHR>(groupIndexSeq) * sbtStride;
|
||||
|
||||
hitRegion.stride = sbtStride;
|
||||
hitRegion.deviceAddress = AlignUp(missRegion.deviceAddress + missRegion.size, Device::rayTracingProperties.shaderGroupBaseAlignment);
|
||||
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);
|
||||
|
||||
AddShaderGroupsToBuffer(sbtStride, groupIndexSeq);
|
||||
sbtBuffer.FlushDevice(cmd, VK_ACCESS_MEMORY_READ_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
|
||||
raygenRegion.deviceAddress += sbtBuffer.address;
|
||||
missRegion.deviceAddress += sbtBuffer.address;
|
||||
hitRegion.deviceAddress += sbtBuffer.address;
|
||||
|
||||
callableRegion.deviceAddress = 0;
|
||||
callableRegion.stride = 0;
|
||||
callableRegion.size = 0;
|
||||
}
|
||||
private:
|
||||
template<std::size_t index>
|
||||
consteval static void AddShaderGroup(std::array<VkRayTracingShaderGroupCreateInfoKHR, std::tuple_size_v<ShaderGroups>>& groups) {
|
||||
using groupTemplate = std::tuple_element_t<index, ShaderGroups>;
|
||||
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 || groupTemplate::anyHitShader != VK_SHADER_UNUSED_KHR) {
|
||||
groupType = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR;
|
||||
} else {
|
||||
static_assert(
|
||||
groupTemplate::generalShader != VK_SHADER_UNUSED_KHR ||
|
||||
groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR,
|
||||
"Shader group must define either a general or closest-hit shader"
|
||||
);
|
||||
}
|
||||
groups[index] = {
|
||||
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,
|
||||
.type = groupType,
|
||||
.generalShader = groupTemplate::generalShader,
|
||||
.closestHitShader = groupTemplate::closestHitShader,
|
||||
.anyHitShader = groupTemplate::anyHitShader,
|
||||
.intersectionShader = groupTemplate::intersectionShader
|
||||
};
|
||||
}
|
||||
template<std::size_t... Is>
|
||||
consteval static std::array<VkRayTracingShaderGroupCreateInfoKHR, std::tuple_size_v<ShaderGroups>> GetShaderGroups(std::index_sequence<Is...>) {
|
||||
std::array<VkRayTracingShaderGroupCreateInfoKHR, std::tuple_size_v<ShaderGroups>> groups{};
|
||||
(AddShaderGroup<Is>(groups), ...);
|
||||
return groups;
|
||||
}
|
||||
|
||||
template<std::size_t index, VkShaderStageFlagBits stage>
|
||||
consteval static void GetGroupCountImpl(std::uint32_t& count) {
|
||||
using groupTemplate = std::tuple_element_t<index, ShaderGroups>;
|
||||
if constexpr(groupTemplate::generalShader != VK_SHADER_UNUSED_KHR) {
|
||||
using shaderTemplate = std::tuple_element_t<groupTemplate::generalShader, Shaders>;
|
||||
if constexpr(shaderTemplate::_stage == stage) {
|
||||
count++;
|
||||
}
|
||||
} else if constexpr(groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR) {
|
||||
using shaderTemplate = std::tuple_element_t<groupTemplate::closestHitShader, Shaders>;
|
||||
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 ||
|
||||
groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR,
|
||||
"Shader group must define either a general or closest-hit shader"
|
||||
);
|
||||
}
|
||||
}
|
||||
template<VkShaderStageFlagBits stage, std::size_t... Is>
|
||||
consteval static std::uint32_t GetGroupCount(std::index_sequence<Is...>) {
|
||||
std::uint32_t count = 0;
|
||||
(GetGroupCountImpl<Is, stage>(count), ...);
|
||||
return count;
|
||||
}
|
||||
|
||||
template<std::size_t index, VkShaderStageFlagBits stage>
|
||||
static void AddShaderGroupToBuffer(std::uint32_t sbtStride, std::uint32_t& offset) {
|
||||
using groupTemplate = std::tuple_element_t<index, ShaderGroups>;
|
||||
if constexpr(groupTemplate::generalShader != VK_SHADER_UNUSED_KHR) {
|
||||
using shaderTemplate = std::tuple_element_t<groupTemplate::generalShader, Shaders>;
|
||||
if constexpr(shaderTemplate::_stage == stage) {
|
||||
std::memcpy(sbtBuffer.value + offset, shaderHandles.data() + index * Device::rayTracingProperties.shaderGroupHandleSize, Device::rayTracingProperties.shaderGroupHandleSize);
|
||||
offset += sbtStride;
|
||||
}
|
||||
} else if constexpr(groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR) {
|
||||
using shaderTemplate = std::tuple_element_t<groupTemplate::closestHitShader, Shaders>;
|
||||
if constexpr(shaderTemplate::_stage == stage) {
|
||||
std::memcpy(sbtBuffer.value + offset, shaderHandles.data() + index * Device::rayTracingProperties.shaderGroupHandleSize, Device::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 * Device::rayTracingProperties.shaderGroupHandleSize, Device::rayTracingProperties.shaderGroupHandleSize);
|
||||
offset += sbtStride;
|
||||
}
|
||||
} else {
|
||||
static_assert(
|
||||
groupTemplate::generalShader != VK_SHADER_UNUSED_KHR ||
|
||||
groupTemplate::closestHitShader != VK_SHADER_UNUSED_KHR,
|
||||
"Shader group must define either a general or closest-hit shader"
|
||||
);
|
||||
}
|
||||
}
|
||||
template<std::size_t... Is>
|
||||
static void AddShaderGroupsToBuffer(std::uint32_t sbtStride, std::index_sequence<Is...>) {
|
||||
std::uint32_t offset = 0;
|
||||
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_RAYGEN_BIT_KHR>(sbtStride, offset), ...);
|
||||
offset = AlignUp(offset, Device::rayTracingProperties.shaderGroupBaseAlignment);
|
||||
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_MISS_BIT_KHR>(sbtStride, offset), ...);
|
||||
offset = AlignUp(offset, Device::rayTracingProperties.shaderGroupBaseAlignment);
|
||||
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR>(sbtStride, offset), ...);
|
||||
(AddShaderGroupToBuffer<Is, VK_SHADER_STAGE_ANY_HIT_BIT_KHR>(sbtStride, offset), ...);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -383,29 +383,7 @@ export namespace Crafter {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case OpaqueType::SemiOpaque: {
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
int bufferX = x + i + c_x1 + offsetX;
|
||||
int bufferY = currentY + j + c_y1 + offsetY;
|
||||
|
||||
// Only draw pixels that are within our scaled buffer bounds
|
||||
if constexpr(Scaling) {
|
||||
if (bufferX >= 0 && bufferX < ScalingBase<T, true, Owning, Alignment>::bufferWidth && bufferY >= 0 && bufferY < ScalingBase<T, true, Owning, Alignment>::bufferHeight) {
|
||||
ScalingBase<T, true, Owning, Alignment>::scalingBuffer[bufferY * ScalingBase<T, true, Owning, Alignment>::bufferWidth + bufferX] = {color.r, color.g, color.b, static_cast<T>(bitmap[j * w + i])};
|
||||
}
|
||||
} else {
|
||||
if (bufferX >= 0 && bufferX < (int)this->scaled.size.x && bufferY >= 0 && bufferY < (int)this->scaled.size.y) {
|
||||
std::uint8_t alpha = bitmap[j * w + i];
|
||||
if(alpha != 0) {
|
||||
this->buffer[bufferY * this->scaled.size.x + bufferX] = {color.r, color.g, color.b, static_cast<T>(bitmap[j * w + i])};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpaqueType::SemiOpaque:
|
||||
case OpaqueType::Transparent: {
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
|
|
|
|||
75
interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm
Normal file
75
interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
Crafter®.Graphics
|
||||
Copyright (C) 2026 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 "../lib/stb_truetype.h"
|
||||
export module Crafter.Graphics:RenderingElement2DVulkan;
|
||||
import Crafter.Asset;
|
||||
import std;
|
||||
import :Transform2D;
|
||||
import :Types;
|
||||
import :Window;
|
||||
|
||||
export namespace Crafter {
|
||||
struct __attribute__((packed)) RenderingElement2DVulkanTransformInfo {
|
||||
ScaleData2D scaled; // 0 - 8 bytes
|
||||
std::uint16_t bufferX; // 8 - 2 bytes
|
||||
std::uint16_t bufferY; // 10 - 2 bytes
|
||||
//12 bytes total;
|
||||
}
|
||||
|
||||
|
||||
template<bool Owning, bool Mapped>
|
||||
struct RenderingElement2DVulkan {
|
||||
std::uint16_t index;
|
||||
std:array<VulkanBuffer<_Float16, Mapped, false>*, Window::NumFrames> buffers;
|
||||
RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferWidth, std::uint16_t bufferHeight) requires(Owning) : index(renderingElement2DVulkans.size()-1) {
|
||||
renderingElement2DVulkans.push_back(this);
|
||||
}
|
||||
RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferWidth, std::uint16_t bufferHeight, std:array<VulkanBuffer<_Float16, Mapped, false>*, Window::NumFrames> buffers) requires(!Owning) : buffers(buffers) {
|
||||
renderingElement2DVulkans.push_back(this);
|
||||
}
|
||||
|
||||
~RenderingElement2DVulkan() {
|
||||
if constexpr(Owning) {
|
||||
for(VulkanBuffer<_Float16, Mapped, false>* buffer : buffers) {
|
||||
delete buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderingElement2DVulkan(RenderingElement2DVulkan&) = delete;
|
||||
RenderingElement2DVulkan& operator=(RenderingElement2DVulkan&) = delete;
|
||||
|
||||
void UpdatePosition(RendertargetBase<Frames>& window, Transform2D& parent) override {
|
||||
ScaleData2D oldScale = this->scaled;
|
||||
this->ScaleElement(parent);
|
||||
if(oldScale.size.x != this->scaled.size.x || oldScale.size.y != this->scaled.size.y) {
|
||||
this->buffer.resize(this->scaled.size.x * this->scaled.size.y);
|
||||
}
|
||||
for(Transform2D* child : this->children) {
|
||||
child->UpdatePosition(window, *this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline static std::vector<RenderingElement2DVulkan*> renderingElement2DVulkans;
|
||||
inline static std::vector<VkDescriptorBufferInfo> renderingElement2DVulkanDescriptors[Window::NumFrames];
|
||||
inline static VulkanBuffer<RenderingElement2DVulkanTransformInfo, Mapped, false>* renderingElement2DVulkanTransformBuffer[Window::NumFrames];
|
||||
}
|
||||
|
|
@ -27,20 +27,22 @@ import std;
|
|||
import :Mesh;
|
||||
import :VulkanBuffer;
|
||||
import Crafter.Math;
|
||||
import :Window;
|
||||
|
||||
export namespace Crafter {
|
||||
struct TlasWithBuffer {
|
||||
VulkanBuffer<char, false, true, false> buffer;
|
||||
VkDeviceAddress address;
|
||||
VulkanBuffer<char, false, true> buffer;
|
||||
VkAccelerationStructureKHR accelerationStructure;
|
||||
VulkanBuffer<VkAccelerationStructureInstanceKHR, true, true, false> instanceBuffer;
|
||||
VulkanBuffer<VkAccelerationStructureInstanceKHR, true, true> instanceBuffer;
|
||||
};
|
||||
|
||||
class RenderingElement3D {
|
||||
public:
|
||||
VkAccelerationStructureInstanceKHR instance;
|
||||
static std::vector<RenderingElement3D*> elements;
|
||||
inline static VulkanBuffer<char, false, true, false> scratchBuffer;
|
||||
inline static std::vector<TlasWithBuffer> tlases;
|
||||
inline static VulkanBuffer<char, false, true> scratchBuffer;
|
||||
inline static TlasWithBuffer tlases[Window::numFrames];
|
||||
static void BuildTLAS(VkCommandBuffer cmd, std::uint32_t index);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,33 +36,10 @@ export namespace Crafter {
|
|||
void Init(std::span<VulkanShader> shaders) {
|
||||
shaderStages.reserve(shaders.size());
|
||||
for(const VulkanShader& shader: shaders) {
|
||||
shaderStages.emplace_back(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, shader.stage, shader.shader, shader.entrypoint.c_str(), nullptr);
|
||||
shaderStages.emplace_back(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, shader.stage, shader.shader, shader.entrypoint.c_str(), shader.specilizationInfo);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Shaders>
|
||||
class ShaderBindingTableVulkanConst {
|
||||
public:
|
||||
inline static std::array<VkPipelineShaderStageCreateInfo, std::tuple_size_v<Shaders>> shaderStages;
|
||||
static void Init() {
|
||||
AddAllToSBT(std::make_index_sequence<std::tuple_size_v<Shaders>>{});
|
||||
}
|
||||
private:
|
||||
template<std::size_t index>
|
||||
static void AddToSBT() {
|
||||
shaderStages[index] = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = std::tuple_element_t<index, Shaders>::_stage,
|
||||
.module = std::tuple_element_t<index, Shaders>::shader,
|
||||
.pName = std::tuple_element_t<index, Shaders>::_entrypoint.value
|
||||
};
|
||||
}
|
||||
template<std::size_t... Is>
|
||||
static void AddAllToSBT(std::index_sequence<Is...>) {
|
||||
(AddToSBT<Is>(), ...);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -28,21 +28,14 @@ import :Device;
|
|||
import :Types;
|
||||
|
||||
export namespace Crafter {
|
||||
template<size_t N>
|
||||
struct StringLiteral {
|
||||
constexpr StringLiteral(const char (&str)[N]) {
|
||||
std::copy_n(str, N, value);
|
||||
}
|
||||
|
||||
char value[N];
|
||||
};
|
||||
|
||||
class VulkanShader {
|
||||
public:
|
||||
std::vector<VkSpecializationMapEntry> specilizations;
|
||||
VkSpecializationInfo* specilizationInfo;
|
||||
VkShaderStageFlagBits stage;
|
||||
std::string entrypoint;
|
||||
VkShaderModule shader;
|
||||
VulkanShader(const std::filesystem::path& path, std::string entrypoint, VkShaderStageFlagBits stage) : stage(stage), entrypoint(entrypoint) {
|
||||
VulkanShader(const std::filesystem::path& path, std::string entrypoint, VkShaderStageFlagBits stage, VkSpecializationInfo* specilizationInfo) : stage(stage), entrypoint(entrypoint), specilizationInfo(specilizationInfo) {
|
||||
std::ifstream file(path, std::ios::binary);
|
||||
if (!file) {
|
||||
std::cerr << "Error: Could not open file " << path << std::endl;
|
||||
|
|
@ -69,44 +62,6 @@ export namespace Crafter {
|
|||
Device::CheckVkResult(vkCreateShaderModule(Device::device, &module_info, nullptr, &shader));
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
StringLiteral path,
|
||||
StringLiteral entrypoint,
|
||||
VkShaderStageFlagBits stage
|
||||
>
|
||||
class VulkanShaderConst {
|
||||
public:
|
||||
constexpr static VkShaderStageFlagBits _stage = stage;
|
||||
constexpr static StringLiteral _entrypoint = entrypoint;
|
||||
inline static VkShaderModule shader;
|
||||
static void CreateShader() {
|
||||
std::ifstream file(path.value, std::ios::binary);
|
||||
if (!file) {
|
||||
std::cerr << "Error: Could not open file " << path.value << std::endl;
|
||||
}
|
||||
|
||||
// Move to the end of the file to determine its size
|
||||
file.seekg(0, std::ios::end);
|
||||
std::streamsize size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
std::vector<std::uint32_t> spirv(size / sizeof(std::uint32_t));
|
||||
|
||||
// Read the data into the vector
|
||||
if (!file.read(reinterpret_cast<char*>(spirv.data()), size)) {
|
||||
std::cerr << "Error: Could not read data from file" << std::endl;
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
VkShaderModuleCreateInfo module_info{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
|
||||
module_info.codeSize = spirv.size() * sizeof(uint32_t);
|
||||
module_info.pCode = spirv.data();
|
||||
|
||||
Device::CheckVkResult(vkCreateShaderModule(Device::device, &module_info, nullptr, &shader));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -33,8 +33,8 @@ export namespace Crafter {
|
|||
};
|
||||
|
||||
struct ScaleData2D {
|
||||
Vector<std::uint16_t, 2> position;
|
||||
Vector<std::uint16_t, 2> size;
|
||||
Vector<std::uint16_t, 2, 2> position;
|
||||
Vector<std::uint16_t, 2, 2> size;
|
||||
};
|
||||
|
||||
struct ClipRect {
|
||||
|
|
|
|||
|
|
@ -64,32 +64,15 @@ namespace Crafter {
|
|||
>;
|
||||
|
||||
|
||||
export template <typename T, bool Mapped, bool Adressable, bool Staged> requires ((Mapped && !Staged) || (!Mapped && Staged) || (!Mapped && !Staged))
|
||||
export template <typename T, bool Mapped, bool Adressable>
|
||||
class VulkanBuffer;
|
||||
|
||||
export template <typename T>
|
||||
class VulkanBufferStaged {
|
||||
VulkanBuffer<T, true, false, false>* stagingBuffer;
|
||||
};
|
||||
export class VulkanBufferStagedEmpty {};
|
||||
template<typename T, bool Staged>
|
||||
using VulkanBufferStagedConditional =
|
||||
std::conditional_t<
|
||||
Staged,
|
||||
VulkanBufferStaged<T>,
|
||||
VulkanBufferStagedEmpty
|
||||
>;
|
||||
|
||||
|
||||
export template <typename T, bool Mapped, bool Adressable, bool Staged> requires ((Mapped && !Staged) || (!Mapped && Staged) || (!Mapped && !Staged))
|
||||
class VulkanBuffer : public VulkanBufferBase, public VulkanBufferMappedConditional<T, Mapped>, public VulkanBufferAdressableConditional<Adressable>, public VulkanBufferStagedConditional<T, Staged> {
|
||||
export template <typename T, bool Mapped, bool Adressable>
|
||||
class VulkanBuffer : public VulkanBufferBase, public VulkanBufferMappedConditional<T, Mapped>, public VulkanBufferAdressableConditional<Adressable> {
|
||||
public:
|
||||
VulkanBuffer() = default;
|
||||
void Create(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, std::uint32_t count) {
|
||||
if constexpr(Staged) {
|
||||
new (&VulkanBufferMappedConditional<T, true>::stagingBuffer) VulkanBuffer<T, true, false, false>();
|
||||
VulkanBufferMappedConditional<T, true>::stagingBuffer->Create(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, count);
|
||||
}
|
||||
|
||||
VkBufferCreateInfo bufferCreateInfo {};
|
||||
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
|
|
@ -117,7 +100,7 @@ namespace Crafter {
|
|||
|
||||
descriptor.offset = 0;
|
||||
descriptor.buffer = buffer;
|
||||
descriptor.range = VK_WHOLE_SIZE;
|
||||
descriptor.range = sizeof(T)*count;
|
||||
|
||||
Device::CheckVkResult(vkBindBufferMemory(Device::device, buffer, memory, 0));
|
||||
|
||||
|
|
@ -141,9 +124,6 @@ namespace Crafter {
|
|||
vkDestroyBuffer(Device::device, buffer, nullptr);
|
||||
vkFreeMemory(Device::device, memory, nullptr);
|
||||
buffer = VK_NULL_HANDLE;
|
||||
if constexpr(Staged) {
|
||||
delete VulkanBufferMappedConditional<T, true>::stagingBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
void Resize(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, std::uint32_t count) {
|
||||
|
|
@ -237,22 +217,6 @@ namespace Crafter {
|
|||
};
|
||||
vkInvalidateMappedMemoryRanges(Device::device, 1, &range);
|
||||
}
|
||||
|
||||
void FlushDevice(VkCommandBuffer cmd) requires(Staged) {
|
||||
VulkanBufferStagedConditional<T, true>::stagingBuffer.FlushDevice(VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
VulkanBufferStagedConditional<T, true>::stagingBuffer.Copy(cmd, this);
|
||||
}
|
||||
|
||||
void FlushDevice(VkCommandBuffer cmd, VkAccessFlags dstAccessMask, VkPipelineStageFlags dstStageMask) requires(Staged) {
|
||||
VulkanBufferStagedConditional<T, true>::stagingBuffer.FlushDevice(VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
VulkanBufferStagedConditional<T, true>::stagingBuffer.Copy(cmd, this, VK_ACCESS_TRANSFER_WRITE_BIT, dstAccessMask, VK_PIPELINE_STAGE_TRANSFER_BIT, dstStageMask);
|
||||
}
|
||||
|
||||
void FlushHost(VkCommandBuffer cmd) requires(Staged) {
|
||||
Copy(cmd, VulkanBufferStagedConditional<T, true>::stagingBuffer);
|
||||
VulkanBufferStagedConditional<T, true>::stagingBuffer.FlushHost();
|
||||
}
|
||||
|
||||
|
||||
VulkanBuffer(VulkanBuffer&& other) {
|
||||
descriptor = other.descriptor;
|
||||
|
|
@ -265,9 +229,6 @@ namespace Crafter {
|
|||
if constexpr(Mapped) {
|
||||
VulkanBufferMappedConditional<T, true>::value = other.VulkanBufferMappedConditional<T, true>::value;
|
||||
}
|
||||
if constexpr(Staged) {
|
||||
VulkanBufferStagedConditional<T, true>::stagingBuffer = other.VulkanBufferStagedConditional<T, true>::stagingBuffer;
|
||||
}
|
||||
};
|
||||
|
||||
~VulkanBuffer() {
|
||||
|
|
|
|||
|
|
@ -51,9 +51,6 @@ import :Types;
|
|||
import :Rendertarget;
|
||||
import :Transform2D;
|
||||
import Crafter.Event;
|
||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||
import :PipelineRTVulkan;
|
||||
#endif
|
||||
|
||||
export namespace Crafter {
|
||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||
|
|
@ -63,6 +60,8 @@ export namespace Crafter {
|
|||
// Command buffer submission and execution
|
||||
VkSemaphore renderComplete;
|
||||
};
|
||||
struct PipelineRTVulkan;
|
||||
struct DescriptorHeapVulkan;
|
||||
#endif
|
||||
|
||||
struct MouseElement;
|
||||
|
|
@ -178,17 +177,6 @@ export namespace Crafter {
|
|||
#endif
|
||||
|
||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||
std::vector<VkDescriptorSet> descriptorsRt;
|
||||
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);
|
||||
VkCommandBuffer StartInit();
|
||||
void FinishInit();
|
||||
VkCommandBuffer GetCmd();
|
||||
|
|
@ -200,19 +188,15 @@ export namespace Crafter {
|
|||
VkFormat colorFormat;
|
||||
VkColorSpaceKHR colorSpace;
|
||||
VkImage images[numFrames];
|
||||
VkImageView imageViews[numFrames];
|
||||
VkImageViewCreateInfo imageViews[numFrames];
|
||||
std::thread thread;
|
||||
VkCommandBuffer drawCmdBuffers[numFrames];
|
||||
VkSubmitInfo submitInfo;
|
||||
Semaphores semaphores;
|
||||
std::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;
|
||||
PipelineRTVulkan* pipeline;
|
||||
DescriptorHeapVulkan* descriptorHeap;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
|
@ -38,14 +38,13 @@ export import :ForwardDeclarations;
|
|||
export import :Device;
|
||||
export import :VulkanTransition;
|
||||
export import :VulkanBuffer;
|
||||
export import :DescriptorPoolVulkan;
|
||||
export import :ShaderVulkan;
|
||||
export import :ShaderBindingTableVulkan;
|
||||
export import :PipelineRTVulkan;
|
||||
export import :RenderingElement3D;
|
||||
export import :ImageVulkan;
|
||||
export import :SamplerVulkan;
|
||||
export import :DescriptorSetLayoutVulkan;
|
||||
export import :DescriptorHeapVulkan;
|
||||
#endif
|
||||
|
||||
// export import :WindowWaylandVulkan;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue