fixed descriptors

This commit is contained in:
Jorijn van der Graaf 2026-01-29 23:31:56 +01:00
commit 5e3a7738ed
14 changed files with 334 additions and 167 deletions

View file

@ -0,0 +1,12 @@
#version 460
#extension GL_EXT_ray_tracing : enable
#extension GL_EXT_nonuniform_qualifier : enable
layout(location = 0) rayPayloadInEXT vec3 hitValue;
hitAttributeEXT vec2 attribs;
void main()
{
const vec3 barycentricCoords = vec3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y);
hitValue = barycentricCoords;
}

View file

@ -0,0 +1,128 @@
#include <vulkan/vulkan.h>
import Crafter.Graphics;
using namespace Crafter;
import std;
import Crafter.Event;
import Crafter.Math;
typedef VulkanShader<"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR, 2, {{{VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 0}, {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1}}}> Raygenspv;
typedef VulkanShader<"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, 0, {{}}> Closesthitspv;
typedef VulkanShader<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR, 0, {{}}> Misspv;
int main() {
/*
This sets up all necessary things and creates the vulkan device.
This must be called before any vulkan related things.
Things like VkDevice are static members of the VulkanDevice class.
*/
VulkanDevice::CreateDevice();
Raygenspv::CreateShader();
Closesthitspv::CreateShader();
Misspv::CreateShader();
DescriptorLayoutVulkan<Raygenspv, Closesthitspv, Misspv>::Init();
PipelineRTVulkan<Raygenspv, Closesthitspv, Misspv, Raygenspv, Closesthitspv, Misspv>::Init();
DescriptorPool<1, Raygenspv, Closesthitspv, Misspv> pool;
pool.setsCount = 2;
pool.BuildPool(0);
WindowVulkan window(1280, 720, "HelloVulkan");
/*
StartInit gives you a VkCommandBuffer to use before the event loop starts
Use this for inititializing things like textures.
*/
VkCommandBuffer cmd = window.StartInit();
Mesh triangleMesh;
std::array<Vertex, 3> verts {{{-150, -150, 100}, {0, 150, 100}, {150, -150, 100}}};
std::array<std::uint32_t, 3> index {{2,1,0}};
triangleMesh.Build(verts, index, cmd);
RenderingElement3DVulkan& el = RenderingElement3DVulkan::elements.emplace_back(triangleMesh);
MatrixRowMajor<float, 4, 3, 1> transform = MatrixRowMajor<float, 4, 3, 1>::Identity();
std::memcpy(el.instance.transform.matrix, transform.m, sizeof(transform.m));
RenderingElement3DVulkan::tlases.resize(2);
window.SetPipelineRT<Raygenspv, Closesthitspv, Misspv, Raygenspv, Closesthitspv, Misspv>();
window.descriptorsRt = pool.sets;
RenderingElement3DVulkan::BuildTLAS(cmd, 0);
VkDescriptorImageInfo imageInfo = {
.imageView = window.imageViews[0],
.imageLayout = VK_IMAGE_LAYOUT_GENERAL
};
VkWriteDescriptorSetAccelerationStructureKHR writeDescriptorSetAccelerationStructure {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,
.accelerationStructureCount = 1,
.pAccelerationStructures = &RenderingElement3DVulkan::tlases[0].accelerationStructure
};
VkWriteDescriptorSet write[2] = {
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = &writeDescriptorSetAccelerationStructure,
.dstSet = pool.sets[0],
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
},
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = pool.sets[0],
.dstBinding = 1,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
.pImageInfo = &imageInfo
}
};
vkUpdateDescriptorSets(VulkanDevice::device, 2, write, 0, nullptr);
/*
FinishInit executes all commands recorded to StartInit.
This must be called before the the event loops starts if you called StartInit before.
*/
window.FinishInit();
EventListener<VkCommandBuffer> updateListener(&window.onRender, [&](VkCommandBuffer cmd){
RenderingElement3DVulkan::BuildTLAS(cmd, window.currentBuffer);
VkDescriptorImageInfo imageInfo = {
.imageView = window.imageViews[window.currentBuffer],
.imageLayout = VK_IMAGE_LAYOUT_GENERAL
};
VkWriteDescriptorSetAccelerationStructureKHR writeDescriptorSetAccelerationStructure {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,
.accelerationStructureCount = 1,
.pAccelerationStructures = &RenderingElement3DVulkan::tlases[window.currentBuffer].accelerationStructure
};
VkWriteDescriptorSet write[2] = {
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = &writeDescriptorSetAccelerationStructure,
.dstSet = pool.sets[window.currentBuffer],
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
},
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = pool.sets[window.currentBuffer],
.dstBinding = 1,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
.pImageInfo = &imageInfo
}
};
vkUpdateDescriptorSets(VulkanDevice::device, 2, write, 0, nullptr);
});
window.Render();
window.StartUpdate();
window.StartSync();
}

View file

@ -0,0 +1,9 @@
#version 460
#extension GL_EXT_ray_tracing : enable
layout(location = 0) rayPayloadInEXT vec3 hitValue;
void main()
{
hitValue = vec3(1, 1, 1);
}

View file

@ -0,0 +1,32 @@
{
"name": "crafter-graphics",
"configurations": [
{
"name": "executable",
"implementations": ["main"],
"dependencies": [
{
"path":"../../project.json",
"configuration":"lib-vulkan-debug"
}
],
"shaders": [
{
"path":"raygen.glsl",
"type": 6,
"entrypoint":"main"
},
{
"path":"closesthit.glsl",
"type": 9,
"entrypoint":"main"
},
{
"path":"miss.glsl",
"type": 10,
"entrypoint":"main"
}
]
}
]
}

View file

@ -0,0 +1,47 @@
#version 460
#extension GL_EXT_ray_tracing : enable
#extension GL_EXT_shader_image_load_formatted : enable
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
layout(binding = 1, set = 0, rgba8) uniform writeonly image2D image;
layout(location = 0) rayPayloadEXT vec3 hitValue;
void main()
{
// Pixel coordinates
uvec2 pixel = gl_LaunchIDEXT.xy;
uvec2 resolution = gl_LaunchSizeEXT.xy;
// Normalized coordinates in range [-1, 1]
vec2 uv = (vec2(pixel) + 0.5) / vec2(resolution);
vec2 ndc = uv * 2.0 - 1.0;
// Camera parameters
vec3 origin = vec3(0.0, 0.0, -300.0);
float aspect = float(resolution.x) / float(resolution.y);
float fov = radians(60.0);
float tanHalfFov = tan(fov * 0.5);
// Simple pinhole camera facing +Z
vec3 direction = normalize(vec3(
ndc.x * aspect * tanHalfFov,
-ndc.y * tanHalfFov,
1.0
));
traceRayEXT(
topLevelAS,
gl_RayFlagsNoneEXT,
0xff,
0, 0, 0,
origin,
0.001,
direction,
10000.0,
0
);
imageStore(image, ivec2(pixel), vec4(hitValue, 1.0));
}

View file

@ -11,8 +11,6 @@ typedef VulkanShader<"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_K
typedef VulkanShader<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR, 0, {{}}> Misspv; typedef VulkanShader<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR, 0, {{}}> Misspv;
int main() { int main() {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
/* /*
This sets up all necessary things and creates the vulkan device. This sets up all necessary things and creates the vulkan device.
This must be called before any vulkan related things. This must be called before any vulkan related things.
@ -22,11 +20,11 @@ int main() {
Raygenspv::CreateShader(); Raygenspv::CreateShader();
Closesthitspv::CreateShader(); Closesthitspv::CreateShader();
Misspv::CreateShader(); Misspv::CreateShader();
DescriptorLayoutVulkan<Raygenspv, Closesthitspv, Misspv>::Init(); std::array<VkDescriptorSetLayout, 3> layouts {{Raygenspv::layout, Closesthitspv::layout, Misspv::layout}};
PipelineRTVulkan<Raygenspv, Closesthitspv, Misspv, Raygenspv, Closesthitspv, Misspv>::Init(); PipelineRTVulkan<Raygenspv, Closesthitspv, Misspv, Raygenspv, Closesthitspv, Misspv>::Init(layouts);
DescriptorPool<1, Raygenspv, Closesthitspv, Misspv> pool; DescriptorPool pool;
pool.setsCount = 1; pool.sets.resize(1);
pool.BuildPool(0); pool.BuildPool(DescriptorPool::GetPoolSizes<Raygenspv, Closesthitspv, Misspv>(), layouts);
WindowVulkan window(1280, 720, "HelloVulkan"); WindowVulkan window(1280, 720, "HelloVulkan");

View file

@ -368,6 +368,7 @@ void WindowVulkan::Render() {
range range
); );
onRender.Invoke(drawCmdBuffers[currentBuffer]);
vkCmdBindPipeline(drawCmdBuffers[currentBuffer], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rtPipeline); vkCmdBindPipeline(drawCmdBuffers[currentBuffer], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rtPipeline);
VkBindDescriptorSetsInfo bindDescriptorSetsInfo{ VkBindDescriptorSetsInfo bindDescriptorSetsInfo{

View file

@ -1,128 +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_VULKAN
#include <vulkan/vulkan.h>
#endif
export module Crafter.Graphics:DescriptorLayoutVulkan;
#ifdef CRAFTER_GRAPHICS_VULKAN
import std;
import :VulkanDevice;
import :Types;
export namespace Crafter {
struct DescriptorEntry {
VkDescriptorType type;
bool occured = true;
};
template <typename... Shaders>
class DescriptorLayoutVulkan {
public:
inline static VkDescriptorSetLayout descriptorSetLayout[sizeof...(Shaders)];
template <typename Shader>
consteval static void GetOccuringDescriptors(std::array<DescriptorEntry, 20>& types) {
for (const DescriptorBinding& binding : Shader::descriptors) {
for (DescriptorEntry& type : types) {
if (type.type == binding.type) {
type.occured = true;
}
}
}
}
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;
}
constexpr static std::uint32_t uniqueDescriptorCount = GetUniqueDiscriptorCount();
consteval static std::array<VkDescriptorPoolSize, uniqueDescriptorCount> GetPoolSizes() {
std::array<VkDescriptorPoolSize, uniqueDescriptorCount> types = {};
for(std::uint32_t i = 0; i < uniqueDescriptorCount; i++){
types[i].descriptorCount = 12345;
}
([&] {
for (const DescriptorBinding& binding : Shaders::descriptors) {
bool found = false;
for(VkDescriptorPoolSize& type : types) {
if(type.type == binding.type && type.descriptorCount != 12345) {
type.descriptorCount += 1;
found = true;
}
}
if(!found) {
for(std::uint32_t i = 0; i < uniqueDescriptorCount; i++){
if(types[i].descriptorCount == 12345) {
types[i].type = binding.type;
types[i].descriptorCount = 1;
break;
}
}
}
}
}(),
...);
return types;
}
template <typename Shader>
consteval static std::array<VkDescriptorSetLayoutBinding, Shader::descriptorCount> GetDescriptorSet() {
std::array<VkDescriptorSetLayoutBinding, Shader::descriptorCount> set;
for(std::uint32_t i = 0; i < Shader::descriptors.size(); i++) {
set[i] = {Shader::descriptors[i].slot, Shader::descriptors[i].type, 1, Shader::_stage, nullptr};
}
return set;
}
public:
static void Init() {
std::uint32_t shaderIndex = 0;
([&] {
constexpr std::array<VkDescriptorSetLayoutBinding, Shaders::descriptorCount> setLayoutBindingsMesh = GetDescriptorSet<Shaders>();
VkDescriptorSetLayoutCreateInfo descriptorLayoutInfoMesh = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = Shaders::descriptorCount,
.pBindings = setLayoutBindingsMesh.data()
};
VulkanDevice::CheckVkResult(vkCreateDescriptorSetLayout(VulkanDevice::device, &descriptorLayoutInfoMesh, nullptr, &descriptorSetLayout[shaderIndex++]));
}(),
...);
}
};
}
#endif

View file

@ -26,51 +26,104 @@ export module Crafter.Graphics:DescriptorPoolVulkan;
import std; import std;
import :VulkanDevice; import :VulkanDevice;
import :Types; import :Types;
import :DescriptorLayoutVulkan;
import Crafter.Event; import Crafter.Event;
export namespace Crafter { export namespace Crafter {
class DescriptorPoolBase { struct DescriptorEntry {
public: VkDescriptorType type;
std::vector<VkDescriptorSet> sets; bool occured = true;
}; };
template <std::uint32_t PoolCount, typename... Shaders>
class DescriptorPool : public DescriptorPoolBase { class DescriptorPool {
public: public:
Event<void> onDescriptorRefresh; Event<void> onDescriptorRefresh;
std::uint32_t setIndex = 0; std::uint32_t setIndex = 0;
std::uint32_t setsCount = 0; std::vector<VkDescriptorSet> sets;
VkDescriptorPool descriptorPool[PoolCount] = { VK_NULL_HANDLE }; VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
template <typename Shader>
consteval static void GetOccuringDescriptors(std::array<DescriptorEntry, 20>& types) {
for (const DescriptorBinding& binding : Shader::descriptors) {
for (DescriptorEntry& type : types) {
if (type.type == binding.type) {
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 DescriptorBinding& binding : Shaders::descriptors) {
bool found = false;
for(VkDescriptorPoolSize& type : types) {
if(type.type == binding.type && type.descriptorCount != 12345) {
type.descriptorCount += 1;
found = true;
}
}
if(!found) {
for(std::uint32_t i = 0; i < GetUniqueDiscriptorCount<Shaders...>(); i++){
if(types[i].descriptorCount == 12345) {
types[i].type = binding.type;
types[i].descriptorCount = 1;
break;
}
}
}
}
}(),
...);
return types;
}
public: public:
void BuildPool(std::uint32_t poolIndex) { void BuildPool(std::span<const VkDescriptorPoolSize> poolSizes, std::span<const VkDescriptorSetLayout> setLayouts) {
if(descriptorPool[poolIndex] != VK_NULL_HANDLE) { if(descriptorPool != VK_NULL_HANDLE) {
vkDestroyDescriptorPool(VulkanDevice::device, descriptorPool[poolIndex], nullptr); vkDestroyDescriptorPool(VulkanDevice::device, descriptorPool, nullptr);
} }
std::array<VkDescriptorPoolSize, DescriptorLayoutVulkan<Shaders...>::uniqueDescriptorCount> poolSizes = DescriptorLayoutVulkan<Shaders...>::GetPoolSizes();
for(VkDescriptorPoolSize& size : poolSizes) {
size.descriptorCount *= setsCount;
}
VkDescriptorPoolCreateInfo descriptorPoolInfo { VkDescriptorPoolCreateInfo descriptorPoolInfo {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.maxSets = static_cast<std::uint32_t>(setsCount), .maxSets = static_cast<std::uint32_t>(sets.size()),
.poolSizeCount = DescriptorLayoutVulkan<Shaders...>::uniqueDescriptorCount, .poolSizeCount = static_cast<std::uint32_t>(poolSizes.size()),
.pPoolSizes = poolSizes.data() .pPoolSizes = poolSizes.data()
}; };
VulkanDevice::CheckVkResult(vkCreateDescriptorPool(VulkanDevice::device, &descriptorPoolInfo, nullptr, &descriptorPool[poolIndex])); VulkanDevice::CheckVkResult(vkCreateDescriptorPool(VulkanDevice::device, &descriptorPoolInfo, nullptr, &descriptorPool));
VkDescriptorSetAllocateInfo allocInfo { VkDescriptorSetAllocateInfo allocInfo {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = descriptorPool[poolIndex], .descriptorPool = descriptorPool,
.descriptorSetCount = setsCount, .descriptorSetCount = static_cast<std::uint32_t>(sets.size()),
.pSetLayouts = DescriptorLayoutVulkan<Shaders...>::descriptorSetLayout, .pSetLayouts = setLayouts.data(),
}; };
sets.resize(setsCount);
VulkanDevice::CheckVkResult(vkAllocateDescriptorSets(VulkanDevice::device, &allocInfo, sets.data())); VulkanDevice::CheckVkResult(vkAllocateDescriptorSets(VulkanDevice::device, &allocInfo, sets.data()));
setIndex = 0; setIndex = 0;

View file

@ -25,7 +25,6 @@ export module Crafter.Graphics:PipelineRTVulkan;
#ifdef CRAFTER_GRAPHICS_VULKAN #ifdef CRAFTER_GRAPHICS_VULKAN
import std; import std;
import :VulkanDevice; import :VulkanDevice;
import :DescriptorLayoutVulkan;
import :VulkanBuffer; import :VulkanBuffer;
import :Types; import :Types;
@ -42,11 +41,11 @@ export namespace Crafter {
inline static VkStridedDeviceAddressRegionKHR hitRegion; inline static VkStridedDeviceAddressRegionKHR hitRegion;
inline static VkStridedDeviceAddressRegionKHR callableRegion; inline static VkStridedDeviceAddressRegionKHR callableRegion;
static void Init() { static void Init(std::span<VkDescriptorSetLayout> setLayouts) {
VkPipelineLayoutCreateInfo pipelineLayoutInfo { VkPipelineLayoutCreateInfo pipelineLayoutInfo {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = sizeof...(Shaders), .setLayoutCount = static_cast<std::uint32_t>(setLayouts.size()),
.pSetLayouts = DescriptorLayoutVulkan<Shaders...>::descriptorSetLayout .pSetLayouts = setLayouts.data()
}; };
VulkanDevice::CheckVkResult(vkCreatePipelineLayout(VulkanDevice::device, &pipelineLayoutInfo, nullptr, &pipelineLayout)); VulkanDevice::CheckVkResult(vkCreatePipelineLayout(VulkanDevice::device, &pipelineLayoutInfo, nullptr, &pipelineLayout));

View file

@ -47,10 +47,20 @@ export namespace Crafter {
class VulkanShader { class VulkanShader {
public: public:
constexpr static VkShaderStageFlagBits _stage = stage; constexpr static VkShaderStageFlagBits _stage = stage;
constexpr static std::array<DescriptorBinding, DescriptorCount> descriptors = Descriptors;
constexpr static std::uint32_t descriptorCount = DescriptorCount;
constexpr static StringLiteral _entrypoint = entrypoint; constexpr static StringLiteral _entrypoint = entrypoint;
constexpr static std::span<const DescriptorBinding> descriptors = Descriptors;
inline static VkShaderModule shader; inline static VkShaderModule shader;
inline static VkDescriptorSetLayout layout;
consteval static std::array<VkDescriptorSetLayoutBinding, DescriptorCount> GetDescriptorSet() {
std::array<VkDescriptorSetLayoutBinding, DescriptorCount> set;
for(std::uint32_t i = 0; i < Descriptors.size(); i++) {
set[i] = {Descriptors[i].slot, Descriptors[i].type, 1, stage, nullptr};
}
return set;
}
static void CreateShader() { static void CreateShader() {
std::ifstream file(path.value, std::ios::binary); std::ifstream file(path.value, std::ios::binary);
@ -78,6 +88,14 @@ export namespace Crafter {
VkShaderModule shader_module; VkShaderModule shader_module;
VulkanDevice::CheckVkResult(vkCreateShaderModule(VulkanDevice::device, &module_info, nullptr, &shader)); VulkanDevice::CheckVkResult(vkCreateShaderModule(VulkanDevice::device, &module_info, nullptr, &shader));
constexpr std::array<VkDescriptorSetLayoutBinding, DescriptorCount> setLayoutBindingsMesh = GetDescriptorSet();
VkDescriptorSetLayoutCreateInfo descriptorLayoutInfoMesh = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = DescriptorCount,
.pBindings = setLayoutBindingsMesh.data()
};
VulkanDevice::CheckVkResult(vkCreateDescriptorSetLayout(VulkanDevice::device, &descriptorLayoutInfoMesh, nullptr, &layout));
} }
}; };
} }

View file

@ -300,6 +300,7 @@ export namespace Crafter {
xkb_keymap* xkb_keymap; xkb_keymap* xkb_keymap;
xkb_context* xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); xkb_context* xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
xkb_state* xkb_state; xkb_state* xkb_state;
Event<VkCommandBuffer> onRender;
std::vector<VkDescriptorSet> descriptorsRt; std::vector<VkDescriptorSet> descriptorsRt;
void Render(); void Render();
void QueueRender(); void QueueRender();
@ -389,12 +390,10 @@ export namespace Crafter {
std::vector<VkImageView> imageViews; std::vector<VkImageView> imageViews;
std::thread thread; std::thread thread;
std::vector<VkCommandBuffer> drawCmdBuffers; std::vector<VkCommandBuffer> drawCmdBuffers;
//std::vector<VkFramebuffer> frameBuffers;
VkSubmitInfo submitInfo; VkSubmitInfo submitInfo;
Semaphores semaphores; Semaphores semaphores;
uint32_t currentBuffer = 0; uint32_t currentBuffer = 0;
VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
//VkRenderPass renderPass = VK_NULL_HANDLE;
VkPipeline rtPipeline; VkPipeline rtPipeline;
VkPipelineLayout rtPipelineLayout; VkPipelineLayout rtPipelineLayout;
VkStridedDeviceAddressRegionKHR raygenRegion; VkStridedDeviceAddressRegionKHR raygenRegion;

View file

@ -37,7 +37,6 @@ export import :VulkanDevice;
export import :VulkanTransition; export import :VulkanTransition;
export import :VulkanBuffer; export import :VulkanBuffer;
export import :DescriptorPoolVulkan; export import :DescriptorPoolVulkan;
export import :DescriptorLayoutVulkan;
export import :ShaderVulkan; export import :ShaderVulkan;
export import :PipelineRTVulkan; export import :PipelineRTVulkan;
export import :RenderingElement3DVulkan; export import :RenderingElement3DVulkan;

View file

@ -4,7 +4,7 @@
{ {
"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-Shm", "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-DescriptorLayoutVulkan"], "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"],
"type": "library" "type": "library"
}, },
{ {