descriptor heap rewrite
This commit is contained in:
parent
b4bd0c03c5
commit
f8e142fb06
31 changed files with 429 additions and 1017 deletions
BIN
examples/VulkanTriangle/executable-linux.zip
Normal file
BIN
examples/VulkanTriangle/executable-linux.zip
Normal file
Binary file not shown.
BIN
examples/VulkanTriangle/executable-windows.zip
Normal file
BIN
examples/VulkanTriangle/executable-windows.zip
Normal file
Binary file not shown.
|
|
@ -1,4 +1,5 @@
|
||||||
#include "vulkan/vulkan.h"
|
#include "vulkan/vulkan.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
import Crafter.Graphics;
|
import Crafter.Graphics;
|
||||||
using namespace Crafter;
|
using namespace Crafter;
|
||||||
|
|
@ -6,55 +7,69 @@ import std;
|
||||||
import Crafter.Event;
|
import Crafter.Event;
|
||||||
import Crafter.Math;
|
import Crafter.Math;
|
||||||
|
|
||||||
typedef VulkanShaderConst<"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR> Raygenspv;
|
|
||||||
typedef VulkanShaderConst<"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR> Closesthitspv;
|
|
||||||
typedef VulkanShaderConst<"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR> Misspv;
|
|
||||||
typedef std::tuple<Raygenspv, Misspv, Closesthitspv> AllShaders;
|
|
||||||
typedef std::tuple<
|
|
||||||
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<VK_SHADER_UNUSED_KHR, 2, VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR>
|
|
||||||
> ShaderGroups;
|
|
||||||
typedef PipelineRTVulkanConst<AllShaders, ShaderGroups> Pipeline;
|
|
||||||
typedef DescriptorSetLayoutVulkanConst<3, {{
|
|
||||||
{
|
|
||||||
.binding = 0,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.binding = 1,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.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;
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Device::Initialize();
|
Device::Initialize();
|
||||||
Window window(1280, 720, "HelloVulkan");
|
Window window(1280, 720, "HelloVulkan");
|
||||||
VkCommandBuffer cmd = window.StartInit();
|
VkCommandBuffer cmd = window.StartInit();
|
||||||
|
DescriptorHeapVulkan descriptorHeap;
|
||||||
|
descriptorHeap.Initialize(1,1,0);
|
||||||
|
|
||||||
Raygenspv::CreateShader();
|
VkSpecializationMapEntry entry = {
|
||||||
Closesthitspv::CreateShader();
|
.constantID = 0,
|
||||||
Misspv::CreateShader();
|
.offset = 0,
|
||||||
ShaderBindingTableVulkanConst<AllShaders>::Init();
|
.size = sizeof(uint16_t)
|
||||||
|
};
|
||||||
|
|
||||||
descriptorSetLayout::Init();
|
VkSpecializationInfo specilizationInfo = {
|
||||||
std::array<VkDescriptorSetLayout, 1> layouts {{descriptorSetLayout::layout}};
|
.mapEntryCount = 1,
|
||||||
|
.pMapEntries = &entry,
|
||||||
|
.dataSize = sizeof(uint16_t),
|
||||||
|
.pData = &descriptorHeap.bufferStartElement
|
||||||
|
};
|
||||||
|
|
||||||
DescriptorPool pool;
|
std::array<VulkanShader, 3> shaders{{
|
||||||
pool.sets.resize(1);
|
{"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR, &specilizationInfo},
|
||||||
pool.BuildPool(DescriptorPool::GetPoolSizes<descriptorSetLayout>(), layouts);
|
{"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR, nullptr},
|
||||||
|
{"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, nullptr}
|
||||||
|
}};
|
||||||
|
|
||||||
Pipeline::Init(cmd, layouts);
|
ShaderBindingTableVulkan shaderTable;
|
||||||
|
shaderTable.Init(shaders);
|
||||||
|
|
||||||
|
std::array<VkRayTracingShaderGroupCreateInfoKHR, 1> raygenGroups {{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,
|
||||||
|
.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR,
|
||||||
|
.generalShader = 0,
|
||||||
|
.closestHitShader = VK_SHADER_UNUSED_KHR,
|
||||||
|
.anyHitShader = VK_SHADER_UNUSED_KHR,
|
||||||
|
.intersectionShader = VK_SHADER_UNUSED_KHR,
|
||||||
|
},
|
||||||
|
}};
|
||||||
|
std::array<VkRayTracingShaderGroupCreateInfoKHR, 1> missGroups {{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,
|
||||||
|
.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR,
|
||||||
|
.generalShader = 1,
|
||||||
|
.closestHitShader = VK_SHADER_UNUSED_KHR,
|
||||||
|
.anyHitShader = VK_SHADER_UNUSED_KHR,
|
||||||
|
.intersectionShader = VK_SHADER_UNUSED_KHR,
|
||||||
|
},
|
||||||
|
}};
|
||||||
|
std::array<VkRayTracingShaderGroupCreateInfoKHR, 1> hitGroups {{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,
|
||||||
|
.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR,
|
||||||
|
.generalShader = VK_SHADER_UNUSED_KHR,
|
||||||
|
.closestHitShader = 2,
|
||||||
|
.anyHitShader = VK_SHADER_UNUSED_KHR,
|
||||||
|
.intersectionShader = VK_SHADER_UNUSED_KHR,
|
||||||
|
},
|
||||||
|
}};
|
||||||
|
|
||||||
|
PipelineRTVulkan pipeline;
|
||||||
|
pipeline.Init(cmd, raygenGroups, missGroups, hitGroups, shaderTable);
|
||||||
|
|
||||||
Mesh triangleMesh;
|
Mesh triangleMesh;
|
||||||
std::array<Vector<float, 3, 3>, 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}}};
|
||||||
|
|
@ -75,59 +90,111 @@ int main() {
|
||||||
|
|
||||||
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(renderer.instance.transform.matrix, transform.m, sizeof(transform.m));
|
std::memcpy(renderer.instance.transform.matrix, transform.m, sizeof(transform.m));
|
||||||
RenderingElement3D::tlases.resize(1);
|
|
||||||
RenderingElement3D::BuildTLAS(cmd, 0);
|
RenderingElement3D::BuildTLAS(cmd, 0);
|
||||||
|
RenderingElement3D::BuildTLAS(cmd, 1);
|
||||||
VkDescriptorImageInfo imageInfo = {
|
RenderingElement3D::BuildTLAS(cmd, 2);
|
||||||
.imageView = window.imageViews[0],
|
|
||||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL
|
|
||||||
};
|
|
||||||
|
|
||||||
VkWriteDescriptorSetAccelerationStructureKHR writeDescriptorSetAccelerationStructure {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,
|
|
||||||
.accelerationStructureCount = 1,
|
|
||||||
.pAccelerationStructures = &RenderingElement3D::tlases[0].accelerationStructure
|
|
||||||
};
|
|
||||||
|
|
||||||
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,
|
|
||||||
.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
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.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(Device::device, 3, write, 0, nullptr);
|
|
||||||
|
|
||||||
|
|
||||||
window.SetPipelineRT<Pipeline>();
|
|
||||||
window.descriptorsRt = pool.sets;
|
|
||||||
|
|
||||||
window.FinishInit();
|
window.FinishInit();
|
||||||
|
|
||||||
|
VkDeviceAddressRangeKHR tlasRange0 = {
|
||||||
|
.address = RenderingElement3D::tlases[0].address,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDeviceAddressRangeKHR tlasRange1 = {
|
||||||
|
.address = RenderingElement3D::tlases[1].address,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDeviceAddressRangeKHR tlasRange2 = {
|
||||||
|
.address = RenderingElement3D::tlases[2].address,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkImageDescriptorInfoEXT imageInfo0 = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT,
|
||||||
|
.pView = &window.imageViews[0],
|
||||||
|
.layout = VK_IMAGE_LAYOUT_GENERAL
|
||||||
|
};
|
||||||
|
|
||||||
|
VkImageDescriptorInfoEXT imageInfo1 = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT,
|
||||||
|
.pView = &window.imageViews[1],
|
||||||
|
.layout = VK_IMAGE_LAYOUT_GENERAL
|
||||||
|
};
|
||||||
|
|
||||||
|
VkImageDescriptorInfoEXT imageInfo2 = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT,
|
||||||
|
.pView = &window.imageViews[2],
|
||||||
|
.layout = VK_IMAGE_LAYOUT_GENERAL
|
||||||
|
};
|
||||||
|
|
||||||
|
VkResourceDescriptorInfoEXT resources[6] = {
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT,
|
||||||
|
.type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
|
||||||
|
.data = { .pAddressRange = &tlasRange0}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT,
|
||||||
|
.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||||
|
.data = { .pImage = &imageInfo0 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT,
|
||||||
|
.type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
|
||||||
|
.data = { .pAddressRange = &tlasRange1}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT,
|
||||||
|
.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||||
|
.data = { .pImage = &imageInfo1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT,
|
||||||
|
.type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
|
||||||
|
.data = { .pAddressRange = &tlasRange2}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT,
|
||||||
|
.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||||
|
.data = { .pImage = &imageInfo2 }
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
VkHostAddressRangeEXT destinations[6] = {
|
||||||
|
{
|
||||||
|
.address = descriptorHeap.resourceHeap[0].value + descriptorHeap.bufferStartOffset,
|
||||||
|
.size = Device::descriptorHeapProperties.bufferDescriptorSize
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.address = descriptorHeap.resourceHeap[0].value,
|
||||||
|
.size = Device::descriptorHeapProperties.imageDescriptorSize
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.address = descriptorHeap.resourceHeap[1].value + descriptorHeap.bufferStartOffset,
|
||||||
|
.size = Device::descriptorHeapProperties.bufferDescriptorSize
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.address = descriptorHeap.resourceHeap[1].value,
|
||||||
|
.size = Device::descriptorHeapProperties.imageDescriptorSize
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.address = descriptorHeap.resourceHeap[2].value + descriptorHeap.bufferStartOffset,
|
||||||
|
.size = Device::descriptorHeapProperties.bufferDescriptorSize
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.address = descriptorHeap.resourceHeap[2].value,
|
||||||
|
.size = Device::descriptorHeapProperties.imageDescriptorSize
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Device::vkWriteResourceDescriptorsEXT(Device::device, 6, resources, destinations);
|
||||||
|
|
||||||
|
descriptorHeap.resourceHeap[0].FlushDevice();
|
||||||
|
descriptorHeap.resourceHeap[1].FlushDevice();
|
||||||
|
descriptorHeap.resourceHeap[2].FlushDevice();
|
||||||
|
|
||||||
|
window.pipeline = &pipeline;
|
||||||
|
window.descriptorHeap = &descriptorHeap;
|
||||||
|
|
||||||
window.Render();
|
window.Render();
|
||||||
window.StartSync();
|
window.StartSync();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@
|
||||||
"configuration":"lib-win32-vulkan-debug"
|
"configuration":"lib-win32-vulkan-debug"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"march": "x86-64-v3",
|
||||||
|
"mtune": "generic",
|
||||||
"target": "x86_64-w64-mingw32",
|
"target": "x86_64-w64-mingw32",
|
||||||
"debug": true,
|
"debug": false,
|
||||||
"shaders": [
|
"shaders": [
|
||||||
{
|
{
|
||||||
"path":"raygen.glsl",
|
"path":"raygen.glsl",
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
#version 460
|
#version 460
|
||||||
#extension GL_EXT_ray_tracing : enable
|
#extension GL_EXT_ray_tracing : enable
|
||||||
#extension GL_EXT_shader_image_load_formatted : enable
|
#extension GL_EXT_shader_image_load_formatted : enable
|
||||||
|
#extension GL_EXT_shader_explicit_arithmetic_types_int16 : enable
|
||||||
|
#extension GL_EXT_descriptor_heap : enable
|
||||||
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
|
|
||||||
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
|
layout(constant_id = 0) const uint16_t bufferStart = 0us;
|
||||||
layout(binding = 1, set = 0, rgba8) uniform writeonly image2D image;
|
layout(descriptor_heap) uniform accelerationStructureEXT topLevelAS[];
|
||||||
|
layout(descriptor_heap) uniform writeonly image2D image[];
|
||||||
|
|
||||||
layout(location = 0) rayPayloadEXT vec3 hitValue;
|
layout(location = 0) rayPayloadEXT vec3 hitValue;
|
||||||
|
|
||||||
void main()
|
void main() {
|
||||||
{
|
|
||||||
// Pixel coordinates
|
// Pixel coordinates
|
||||||
uvec2 pixel = gl_LaunchIDEXT.xy;
|
uvec2 pixel = gl_LaunchIDEXT.xy;
|
||||||
uvec2 resolution = gl_LaunchSizeEXT.xy;
|
uvec2 resolution = gl_LaunchSizeEXT.xy;
|
||||||
|
|
@ -32,7 +35,7 @@ void main()
|
||||||
));
|
));
|
||||||
|
|
||||||
traceRayEXT(
|
traceRayEXT(
|
||||||
topLevelAS,
|
topLevelAS[bufferStart],
|
||||||
gl_RayFlagsNoneEXT,
|
gl_RayFlagsNoneEXT,
|
||||||
0xff,
|
0xff,
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
|
|
@ -43,5 +46,5 @@ void main()
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
imageStore(image, ivec2(pixel), vec4(hitValue, 1.0));
|
imageStore(image[0], ivec2(pixel), vec4(hitValue, 1));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
# HelloWindow Example
|
|
||||||
|
|
||||||
## Description
|
|
||||||
|
|
||||||
This example demonstrates how to load shaders and render a triangle.
|
|
||||||
|
|
||||||
## Expected Result
|
|
||||||
|
|
||||||
A blue tinted vulkan window with a white triangle in the center.
|
|
||||||
|
|
||||||
## Highlighted Code Snippet
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
EventListener<VkCommandBuffer> listener(&window.onDraw, [&descriptors, &meshShader](VkCommandBuffer cmd){
|
|
||||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipelineLayout, 0, 2, &descriptors.set[0], 0, NULL);
|
|
||||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipeline);
|
|
||||||
Device::vkCmdDrawMeshTasksEXTProc(cmd, meshShader.threadCount, 1, 1);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to Run
|
|
||||||
|
|
||||||
```bash
|
|
||||||
crafter-build build executable -r
|
|
||||||
```
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,138 +0,0 @@
|
||||||
#include "vulkan/vulkan.h"
|
|
||||||
|
|
||||||
import Crafter.Graphics;
|
|
||||||
using namespace Crafter;
|
|
||||||
import std;
|
|
||||||
import Crafter.Event;
|
|
||||||
import Crafter.Math;
|
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
Device::CreateDevice();
|
|
||||||
WindowVulkan window(1280, 720, "HelloVulkan");
|
|
||||||
VkCommandBuffer cmd = window.StartInit();
|
|
||||||
|
|
||||||
std::vector<VkDescriptorSetLayoutBinding> bindings {
|
|
||||||
{
|
|
||||||
.binding = 0,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.binding = 1,
|
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
DescriptorSetLayoutVulkan layout(std::move(bindings));
|
|
||||||
|
|
||||||
std::array<VkDescriptorSetLayout, 1> layouts {{layout.layout}};
|
|
||||||
|
|
||||||
DescriptorPool pool;
|
|
||||||
pool.sets.resize(1);
|
|
||||||
pool.BuildPool(DescriptorPool::GetPoolSizes({layout}), layouts);
|
|
||||||
|
|
||||||
std::array<VulkanShader, 3> shaders{{
|
|
||||||
{"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR},
|
|
||||||
{"miss.spv", "main", VK_SHADER_STAGE_MISS_BIT_KHR},
|
|
||||||
{"closesthit.spv", "main", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR}
|
|
||||||
}};
|
|
||||||
|
|
||||||
ShaderBindingTableVulkan shaderTable;
|
|
||||||
shaderTable.Init(shaders);
|
|
||||||
|
|
||||||
std::array<VkRayTracingShaderGroupCreateInfoKHR, 1> raygenGroups {{
|
|
||||||
{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,
|
|
||||||
.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR,
|
|
||||||
.generalShader = 0,
|
|
||||||
.closestHitShader = VK_SHADER_UNUSED_KHR,
|
|
||||||
.anyHitShader = VK_SHADER_UNUSED_KHR,
|
|
||||||
.intersectionShader = VK_SHADER_UNUSED_KHR,
|
|
||||||
},
|
|
||||||
}};
|
|
||||||
std::array<VkRayTracingShaderGroupCreateInfoKHR, 1> missGroups {{
|
|
||||||
{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,
|
|
||||||
.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR,
|
|
||||||
.generalShader = 1,
|
|
||||||
.closestHitShader = VK_SHADER_UNUSED_KHR,
|
|
||||||
.anyHitShader = VK_SHADER_UNUSED_KHR,
|
|
||||||
.intersectionShader = VK_SHADER_UNUSED_KHR,
|
|
||||||
},
|
|
||||||
}};
|
|
||||||
std::array<VkRayTracingShaderGroupCreateInfoKHR, 1> hitGroups {{
|
|
||||||
{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR,
|
|
||||||
.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR,
|
|
||||||
.generalShader = VK_SHADER_UNUSED_KHR,
|
|
||||||
.closestHitShader = 2,
|
|
||||||
.anyHitShader = VK_SHADER_UNUSED_KHR,
|
|
||||||
.intersectionShader = VK_SHADER_UNUSED_KHR,
|
|
||||||
},
|
|
||||||
}};
|
|
||||||
|
|
||||||
PipelineRTVulkan pipeline;
|
|
||||||
pipeline.Init(cmd, layouts, raygenGroups, missGroups, hitGroups, shaderTable);
|
|
||||||
|
|
||||||
Mesh triangleMesh;
|
|
||||||
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}};
|
|
||||||
triangleMesh.Build(verts, index, cmd);
|
|
||||||
RenderingElement3D renderer = {
|
|
||||||
.instance = {
|
|
||||||
.instanceCustomIndex = 0,
|
|
||||||
.mask = 0xFF,
|
|
||||||
.instanceShaderBindingTableRecordOffset = 0,
|
|
||||||
.flags = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR,
|
|
||||||
.accelerationStructureReference = triangleMesh.blasAddr
|
|
||||||
}
|
|
||||||
};
|
|
||||||
MatrixRowMajor<float, 4, 3, 1> transform = MatrixRowMajor<float, 4, 3, 1>::Identity();
|
|
||||||
std::memcpy(renderer.instance.transform.matrix, transform.m, sizeof(transform.m));
|
|
||||||
RenderingElement3D::tlases.resize(1);
|
|
||||||
RenderingElement3D::elements.push_back(&renderer);
|
|
||||||
RenderingElement3D::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 = &RenderingElement3D::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(Device::device, 2, write, 0, nullptr);
|
|
||||||
|
|
||||||
window.SetPipelineRT(pipeline);
|
|
||||||
window.descriptorsRt = pool.sets;
|
|
||||||
|
|
||||||
window.FinishInit();
|
|
||||||
window.Render();
|
|
||||||
window.StartSync();
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
#version 460
|
|
||||||
#extension GL_EXT_ray_tracing : enable
|
|
||||||
|
|
||||||
layout(location = 0) rayPayloadInEXT vec3 hitValue;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
hitValue = vec3(1, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
#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));
|
|
||||||
}
|
|
||||||
|
|
@ -65,10 +65,12 @@ const char* const deviceExtensionNames[] = {
|
||||||
"VK_KHR_swapchain",
|
"VK_KHR_swapchain",
|
||||||
"VK_KHR_spirv_1_4",
|
"VK_KHR_spirv_1_4",
|
||||||
"VK_KHR_shader_float_controls",
|
"VK_KHR_shader_float_controls",
|
||||||
"VK_KHR_dynamic_rendering",
|
|
||||||
"VK_KHR_acceleration_structure",
|
"VK_KHR_acceleration_structure",
|
||||||
"VK_KHR_deferred_host_operations",
|
|
||||||
"VK_KHR_ray_tracing_pipeline",
|
"VK_KHR_ray_tracing_pipeline",
|
||||||
|
"VK_EXT_descriptor_heap",
|
||||||
|
"VK_KHR_deferred_host_operations",
|
||||||
|
"VK_KHR_maintenance5",
|
||||||
|
"VK_KHR_shader_untyped_pointers"
|
||||||
};
|
};
|
||||||
const char* const layerNames[] = {
|
const char* const layerNames[] = {
|
||||||
"VK_LAYER_KHRONOS_validation"
|
"VK_LAYER_KHRONOS_validation"
|
||||||
|
|
@ -474,10 +476,21 @@ void Device::Initialize() {
|
||||||
VkApplicationInfo app{VK_STRUCTURE_TYPE_APPLICATION_INFO};
|
VkApplicationInfo app{VK_STRUCTURE_TYPE_APPLICATION_INFO};
|
||||||
app.pApplicationName = "";
|
app.pApplicationName = "";
|
||||||
app.pEngineName = "Crafter.Graphics";
|
app.pEngineName = "Crafter.Graphics";
|
||||||
app.apiVersion = VK_MAKE_VERSION(1, 3, 0);
|
app.apiVersion = VK_MAKE_VERSION(1, 4, 0);
|
||||||
|
|
||||||
|
VkValidationFeatureEnableEXT enables[] = {
|
||||||
|
VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT
|
||||||
|
};
|
||||||
|
|
||||||
|
VkValidationFeaturesEXT validationFeatures = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
|
||||||
|
.enabledValidationFeatureCount = 1,
|
||||||
|
.pEnabledValidationFeatures = enables
|
||||||
|
};
|
||||||
|
|
||||||
VkInstanceCreateInfo instanceCreateInfo = {};
|
VkInstanceCreateInfo instanceCreateInfo = {};
|
||||||
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
instanceCreateInfo.pNext = &validationFeatures;
|
||||||
instanceCreateInfo.pApplicationInfo = &app;
|
instanceCreateInfo.pApplicationInfo = &app;
|
||||||
instanceCreateInfo.enabledExtensionCount = sizeof(instanceExtensionNames) / sizeof(const char*);
|
instanceCreateInfo.enabledExtensionCount = sizeof(instanceExtensionNames) / sizeof(const char*);
|
||||||
instanceCreateInfo.ppEnabledExtensionNames = instanceExtensionNames;
|
instanceCreateInfo.ppEnabledExtensionNames = instanceExtensionNames;
|
||||||
|
|
@ -590,8 +603,20 @@ void Device::Initialize() {
|
||||||
queueCreateInfo.queueCount = 1;
|
queueCreateInfo.queueCount = 1;
|
||||||
queueCreateInfo.pQueuePriorities = &priority;
|
queueCreateInfo.pQueuePriorities = &priority;
|
||||||
|
|
||||||
|
VkPhysicalDeviceShaderUntypedPointersFeaturesKHR untypedPointersFeatures {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNTYPED_POINTERS_FEATURES_KHR,
|
||||||
|
.shaderUntypedPointers = VK_TRUE,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPhysicalDeviceDescriptorHeapFeaturesEXT desciptorHeapFeatures {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_FEATURES_EXT,
|
||||||
|
.pNext = &untypedPointersFeatures,
|
||||||
|
.descriptorHeap = VK_TRUE,
|
||||||
|
};
|
||||||
|
|
||||||
VkPhysicalDevice16BitStorageFeatures bit16 {
|
VkPhysicalDevice16BitStorageFeatures bit16 {
|
||||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
|
||||||
|
.pNext = &desciptorHeapFeatures,
|
||||||
.storageBuffer16BitAccess = VK_TRUE,
|
.storageBuffer16BitAccess = VK_TRUE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -614,21 +639,14 @@ void Device::Initialize() {
|
||||||
.accelerationStructure = VK_TRUE
|
.accelerationStructure = VK_TRUE
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeature = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR};
|
|
||||||
dynamicRenderingFeature.dynamicRendering = VK_FALSE;
|
|
||||||
dynamicRenderingFeature.pNext = &deviceAccelerationStructureFeature;
|
|
||||||
|
|
||||||
VkPhysicalDeviceMeshShaderFeaturesEXT ext_feature = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT};
|
|
||||||
ext_feature.meshShader = VK_FALSE;
|
|
||||||
ext_feature.pNext = &dynamicRenderingFeature;
|
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures2 physical_features2 = {
|
VkPhysicalDeviceFeatures2 physical_features2 = {
|
||||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
|
||||||
|
.pNext = &deviceAccelerationStructureFeature,
|
||||||
.features = {
|
.features = {
|
||||||
.samplerAnisotropy = VK_TRUE
|
.samplerAnisotropy = VK_TRUE,
|
||||||
|
.shaderInt16 = VK_TRUE
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
physical_features2.pNext = &ext_feature;
|
|
||||||
|
|
||||||
VkDeviceCreateInfo deviceCreateInfo = {};
|
VkDeviceCreateInfo deviceCreateInfo = {};
|
||||||
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
|
@ -681,6 +699,10 @@ void Device::Initialize() {
|
||||||
vkCreateRayTracingPipelinesKHR = reinterpret_cast<PFN_vkCreateRayTracingPipelinesKHR>(vkGetInstanceProcAddr(instance, "vkCreateRayTracingPipelinesKHR"));
|
vkCreateRayTracingPipelinesKHR = reinterpret_cast<PFN_vkCreateRayTracingPipelinesKHR>(vkGetInstanceProcAddr(instance, "vkCreateRayTracingPipelinesKHR"));
|
||||||
vkGetRayTracingShaderGroupHandlesKHR = reinterpret_cast<PFN_vkGetRayTracingShaderGroupHandlesKHR>(vkGetInstanceProcAddr(instance, "vkGetRayTracingShaderGroupHandlesKHR"));
|
vkGetRayTracingShaderGroupHandlesKHR = reinterpret_cast<PFN_vkGetRayTracingShaderGroupHandlesKHR>(vkGetInstanceProcAddr(instance, "vkGetRayTracingShaderGroupHandlesKHR"));
|
||||||
vkCmdTraceRaysKHR = reinterpret_cast<PFN_vkCmdTraceRaysKHR>(vkGetInstanceProcAddr(instance, "vkCmdTraceRaysKHR"));
|
vkCmdTraceRaysKHR = reinterpret_cast<PFN_vkCmdTraceRaysKHR>(vkGetInstanceProcAddr(instance, "vkCmdTraceRaysKHR"));
|
||||||
|
vkCmdBindResourceHeapEXT = reinterpret_cast<PFN_vkCmdBindResourceHeapEXT>(vkGetInstanceProcAddr(instance, "vkCmdBindResourceHeapEXT"));
|
||||||
|
vkCmdBindSamplerHeapEXT = reinterpret_cast<PFN_vkCmdBindSamplerHeapEXT>(vkGetInstanceProcAddr(instance, "vkCmdBindSamplerHeapEXT"));
|
||||||
|
vkWriteResourceDescriptorsEXT = reinterpret_cast<PFN_vkWriteResourceDescriptorsEXT>(vkGetInstanceProcAddr(instance, "vkWriteResourceDescriptorsEXT"));
|
||||||
|
vkGetPhysicalDeviceDescriptorSizeEXT = reinterpret_cast<PFN_vkGetPhysicalDeviceDescriptorSizeEXT>(vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDescriptorSizeEXT"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,12 @@ void RenderingElement3D::BuildTLAS(VkCommandBuffer cmd, std::uint32_t index) {
|
||||||
0, nullptr,
|
0, nullptr,
|
||||||
0, nullptr
|
0, nullptr
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VkAccelerationStructureDeviceAddressInfoKHR addrInfo {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR,
|
||||||
|
.accelerationStructure = tlases[index].accelerationStructure
|
||||||
|
};
|
||||||
|
tlases[index].address = Device::vkGetAccelerationStructureDeviceAddressKHR(Device::device, &addrInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -62,6 +62,8 @@ import :MouseElement;
|
||||||
import :Device;
|
import :Device;
|
||||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||||
import :VulkanTransition;
|
import :VulkanTransition;
|
||||||
|
import :DescriptorHeapVulkan;
|
||||||
|
import :PipelineRTVulkan;
|
||||||
#endif
|
#endif
|
||||||
import std;
|
import std;
|
||||||
|
|
||||||
|
|
@ -813,10 +815,31 @@ void Window::Render() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vkCmdBindPipeline(drawCmdBuffers[currentBuffer], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rtPipeline);
|
vkCmdBindPipeline(drawCmdBuffers[currentBuffer], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline->pipeline);
|
||||||
vkCmdBindDescriptorSets(drawCmdBuffers[currentBuffer], VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rtPipelineLayout, 0, static_cast<std::uint32_t>(descriptorsRt.size()), descriptorsRt.data(), 0, nullptr);
|
|
||||||
Device::vkCmdTraceRaysKHR(drawCmdBuffers[currentBuffer], &raygenRegion, &missRegion, &hitRegion, &callableRegion, width, height, 1);
|
|
||||||
|
|
||||||
|
VkBindHeapInfoEXT resourceHeapInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BIND_HEAP_INFO_EXT,
|
||||||
|
.heapRange = {
|
||||||
|
.address = descriptorHeap->resourceHeap[currentBuffer].address,
|
||||||
|
.size = static_cast<std::uint32_t>(descriptorHeap->resourceHeap[currentBuffer].descriptor.range)
|
||||||
|
},
|
||||||
|
.reservedRangeOffset = (descriptorHeap->resourceHeap[currentBuffer].descriptor.range - Device::descriptorHeapProperties.minResourceHeapReservedRange) & ~(Device::descriptorHeapProperties.imageDescriptorAlignment - 1),
|
||||||
|
.reservedRangeSize = Device::descriptorHeapProperties.minResourceHeapReservedRange
|
||||||
|
};
|
||||||
|
Device::vkCmdBindResourceHeapEXT(drawCmdBuffers[currentBuffer], &resourceHeapInfo);
|
||||||
|
|
||||||
|
VkBindHeapInfoEXT samplerHeapInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BIND_HEAP_INFO_EXT,
|
||||||
|
.heapRange = {
|
||||||
|
.address = descriptorHeap->samplerHeap[currentBuffer].address,
|
||||||
|
.size = static_cast<std::uint32_t>(descriptorHeap->samplerHeap[currentBuffer].descriptor.range)
|
||||||
|
},
|
||||||
|
.reservedRangeOffset = descriptorHeap->samplerHeap[currentBuffer].descriptor.range - Device::descriptorHeapProperties.minSamplerHeapReservedRange,
|
||||||
|
.reservedRangeSize = Device::descriptorHeapProperties.minSamplerHeapReservedRange
|
||||||
|
};
|
||||||
|
Device::vkCmdBindSamplerHeapEXT(drawCmdBuffers[currentBuffer], &samplerHeapInfo);
|
||||||
|
|
||||||
|
Device::vkCmdTraceRaysKHR(drawCmdBuffers[currentBuffer], &pipeline->raygenRegion, &pipeline->missRegion, &pipeline->hitRegion, &pipeline->callableRegion, width, height, 1);
|
||||||
|
|
||||||
VkImageMemoryBarrier image_memory_barrier2 {
|
VkImageMemoryBarrier image_memory_barrier2 {
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||||
|
|
@ -986,9 +1009,6 @@ void Window::CreateSwapchain()
|
||||||
|
|
||||||
// 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 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) {
|
if (oldSwapchain != VK_NULL_HANDLE) {
|
||||||
for (auto i = 0; i < numFrames; i++) {
|
|
||||||
vkDestroyImageView(Device::device, imageViews[i], nullptr);
|
|
||||||
}
|
|
||||||
vkDestroySwapchainKHR(Device::device, oldSwapchain, nullptr);
|
vkDestroySwapchainKHR(Device::device, oldSwapchain, nullptr);
|
||||||
}
|
}
|
||||||
uint32_t imageCount{ 0 };
|
uint32_t imageCount{ 0 };
|
||||||
|
|
@ -997,34 +1017,27 @@ void Window::CreateSwapchain()
|
||||||
// Get the swap chain images
|
// Get the swap chain images
|
||||||
Device::CheckVkResult(vkGetSwapchainImagesKHR(Device::device, swapChain, &imageCount, images));
|
Device::CheckVkResult(vkGetSwapchainImagesKHR(Device::device, swapChain, &imageCount, images));
|
||||||
|
|
||||||
for (auto i = 0; i < numFrames; i++)
|
for (std::uint8_t i = 0; i < numFrames; i++) {
|
||||||
{
|
imageViews[i] = {
|
||||||
VkImageViewCreateInfo colorAttachmentView = {};
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||||
colorAttachmentView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
.flags = 0,
|
||||||
colorAttachmentView.pNext = NULL;
|
.image = images[i],
|
||||||
colorAttachmentView.format = colorFormat;
|
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
||||||
colorAttachmentView.components = {
|
.format = colorFormat,
|
||||||
|
.components = {
|
||||||
VK_COMPONENT_SWIZZLE_R,
|
VK_COMPONENT_SWIZZLE_R,
|
||||||
VK_COMPONENT_SWIZZLE_G,
|
VK_COMPONENT_SWIZZLE_G,
|
||||||
VK_COMPONENT_SWIZZLE_B,
|
VK_COMPONENT_SWIZZLE_B,
|
||||||
VK_COMPONENT_SWIZZLE_A
|
VK_COMPONENT_SWIZZLE_A
|
||||||
|
},
|
||||||
|
.subresourceRange = {
|
||||||
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = 1,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
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];
|
|
||||||
Device::CheckVkResult(vkCreateImageView(Device::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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
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_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR;
|
||||||
inline static PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
|
inline static PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
|
||||||
inline static PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR;
|
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 VkPhysicalDeviceMemoryProperties memoryProperties;
|
||||||
|
|
||||||
|
inline static VkPhysicalDeviceDescriptorHeapPropertiesEXT descriptorHeapProperties = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_PROPERTIES_EXT
|
||||||
|
};
|
||||||
inline static VkPhysicalDeviceRayTracingPipelinePropertiesKHR rayTracingProperties = {
|
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);
|
static void CheckVkResult(VkResult result);
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export namespace Crafter {
|
||||||
std::uint8_t mipLevels;
|
std::uint8_t mipLevels;
|
||||||
VkImage image;
|
VkImage image;
|
||||||
VkDeviceMemory imageMemory;
|
VkDeviceMemory imageMemory;
|
||||||
VulkanBuffer<PixelType, true, false, false> buffer;
|
VulkanBuffer<PixelType, true, false> buffer;
|
||||||
VkImageView imageView;
|
VkImageView imageView;
|
||||||
VkDescriptorImageInfo descriptor;
|
VkDescriptorImageInfo descriptor;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,10 @@ export namespace Crafter {
|
||||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||||
class Mesh {
|
class Mesh {
|
||||||
public:
|
public:
|
||||||
VulkanBuffer<char, false, true, false> scratchBuffer;
|
VulkanBuffer<char, false, true> scratchBuffer;
|
||||||
VulkanBuffer<char, false, true, false> blasBuffer;
|
VulkanBuffer<char, false, true> blasBuffer;
|
||||||
VulkanBuffer<Vector<float, 3, 3>, true, true, false> vertexBuffer;
|
VulkanBuffer<Vector<float, 3, 3>, true, true> vertexBuffer;
|
||||||
VulkanBuffer<std::uint32_t, true, true, false> indexBuffer;
|
VulkanBuffer<std::uint32_t, true, true> indexBuffer;
|
||||||
VkAccelerationStructureGeometryTrianglesDataKHR blasData;
|
VkAccelerationStructureGeometryTrianglesDataKHR blasData;
|
||||||
VkAccelerationStructureGeometryKHR blas;
|
VkAccelerationStructureGeometryKHR blas;
|
||||||
VkAccelerationStructureKHR accelerationStructure;
|
VkAccelerationStructureKHR accelerationStructure;
|
||||||
|
|
|
||||||
|
|
@ -30,26 +30,16 @@ import :ShaderBindingTableVulkan;
|
||||||
import :Types;
|
import :Types;
|
||||||
|
|
||||||
export namespace Crafter {
|
export namespace Crafter {
|
||||||
class PipelineRTVulkan {
|
struct PipelineRTVulkan {
|
||||||
public:
|
|
||||||
VkPipeline pipeline;
|
VkPipeline pipeline;
|
||||||
VkPipelineLayout pipelineLayout;
|
|
||||||
std::vector<std::uint8_t> shaderHandles;
|
std::vector<std::uint8_t> shaderHandles;
|
||||||
VulkanBuffer<std::uint8_t, true, true, false> sbtBuffer;
|
VulkanBuffer<std::uint8_t, true, true> sbtBuffer;
|
||||||
VkStridedDeviceAddressRegionKHR raygenRegion;
|
VkStridedDeviceAddressRegionKHR raygenRegion;
|
||||||
VkStridedDeviceAddressRegionKHR missRegion;
|
VkStridedDeviceAddressRegionKHR missRegion;
|
||||||
VkStridedDeviceAddressRegionKHR hitRegion;
|
VkStridedDeviceAddressRegionKHR hitRegion;
|
||||||
VkStridedDeviceAddressRegionKHR callableRegion;
|
VkStridedDeviceAddressRegionKHR callableRegion;
|
||||||
|
|
||||||
void Init(VkCommandBuffer cmd, std::span<VkDescriptorSetLayout> setLayouts, std::span<VkRayTracingShaderGroupCreateInfoKHR> raygenGroups, std::span<VkRayTracingShaderGroupCreateInfoKHR> missGroups, std::span<VkRayTracingShaderGroupCreateInfoKHR> hitGroups, ShaderBindingTableVulkan& shaderTable) {
|
void Init(VkCommandBuffer cmd, 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));
|
|
||||||
|
|
||||||
std::vector<VkRayTracingShaderGroupCreateInfoKHR> groups;
|
std::vector<VkRayTracingShaderGroupCreateInfoKHR> groups;
|
||||||
groups.reserve(raygenGroups.size() + missGroups.size() + hitGroups.size());
|
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(), missGroups.begin(), missGroups.end());
|
||||||
groups.insert(groups.end(), hitGroups.begin(), hitGroups.end());
|
groups.insert(groups.end(), hitGroups.begin(), hitGroups.end());
|
||||||
|
|
||||||
|
VkPipelineCreateFlags2CreateInfo flags2 = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO,
|
||||||
|
.flags = VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT
|
||||||
|
};
|
||||||
|
|
||||||
VkRayTracingPipelineCreateInfoKHR rtPipelineInfo {
|
VkRayTracingPipelineCreateInfoKHR rtPipelineInfo {
|
||||||
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR,
|
.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR,
|
||||||
|
.pNext = &flags2,
|
||||||
|
.flags = 0,
|
||||||
.stageCount = static_cast<std::uint32_t>(shaderTable.shaderStages.size()),
|
.stageCount = static_cast<std::uint32_t>(shaderTable.shaderStages.size()),
|
||||||
.pStages = shaderTable.shaderStages.data(),
|
.pStages = shaderTable.shaderStages.data(),
|
||||||
.groupCount = static_cast<std::uint32_t>(groups.size()),
|
.groupCount = static_cast<std::uint32_t>(groups.size()),
|
||||||
.pGroups = groups.data(),
|
.pGroups = groups.data(),
|
||||||
.maxPipelineRayRecursionDepth = 1,
|
.maxPipelineRayRecursionDepth = 1,
|
||||||
.layout = pipelineLayout
|
.layout = VK_NULL_HANDLE
|
||||||
};
|
};
|
||||||
|
|
||||||
Device::CheckVkResult(Device::vkCreateRayTracingPipelinesKHR(Device::device, {}, {}, 1, &rtPipelineInfo, nullptr, &pipeline));
|
Device::CheckVkResult(Device::vkCreateRayTracingPipelinesKHR(Device::device, {}, {}, 1, &rtPipelineInfo, nullptr, &pipeline));
|
||||||
|
|
@ -114,189 +111,6 @@ export namespace Crafter {
|
||||||
callableRegion.size = 0;
|
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
|
#endif
|
||||||
|
|
@ -383,29 +383,7 @@ export namespace Crafter {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpaqueType::SemiOpaque: {
|
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::Transparent: {
|
case OpaqueType::Transparent: {
|
||||||
for (int j = 0; j < h; j++) {
|
for (int j = 0; j < h; j++) {
|
||||||
for (int i = 0; i < w; i++) {
|
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 :Mesh;
|
||||||
import :VulkanBuffer;
|
import :VulkanBuffer;
|
||||||
import Crafter.Math;
|
import Crafter.Math;
|
||||||
|
import :Window;
|
||||||
|
|
||||||
export namespace Crafter {
|
export namespace Crafter {
|
||||||
struct TlasWithBuffer {
|
struct TlasWithBuffer {
|
||||||
VulkanBuffer<char, false, true, false> buffer;
|
VkDeviceAddress address;
|
||||||
|
VulkanBuffer<char, false, true> buffer;
|
||||||
VkAccelerationStructureKHR accelerationStructure;
|
VkAccelerationStructureKHR accelerationStructure;
|
||||||
VulkanBuffer<VkAccelerationStructureInstanceKHR, true, true, false> instanceBuffer;
|
VulkanBuffer<VkAccelerationStructureInstanceKHR, true, true> instanceBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RenderingElement3D {
|
class RenderingElement3D {
|
||||||
public:
|
public:
|
||||||
VkAccelerationStructureInstanceKHR instance;
|
VkAccelerationStructureInstanceKHR instance;
|
||||||
static std::vector<RenderingElement3D*> elements;
|
static std::vector<RenderingElement3D*> elements;
|
||||||
inline static VulkanBuffer<char, false, true, false> scratchBuffer;
|
inline static VulkanBuffer<char, false, true> scratchBuffer;
|
||||||
inline static std::vector<TlasWithBuffer> tlases;
|
inline static TlasWithBuffer tlases[Window::numFrames];
|
||||||
static void BuildTLAS(VkCommandBuffer cmd, std::uint32_t index);
|
static void BuildTLAS(VkCommandBuffer cmd, std::uint32_t index);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,33 +36,10 @@ export namespace Crafter {
|
||||||
void Init(std::span<VulkanShader> shaders) {
|
void Init(std::span<VulkanShader> shaders) {
|
||||||
shaderStages.reserve(shaders.size());
|
shaderStages.reserve(shaders.size());
|
||||||
for(const VulkanShader& shader: shaders) {
|
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
|
#endif
|
||||||
|
|
@ -28,21 +28,14 @@ import :Device;
|
||||||
import :Types;
|
import :Types;
|
||||||
|
|
||||||
export namespace Crafter {
|
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 {
|
class VulkanShader {
|
||||||
public:
|
public:
|
||||||
|
std::vector<VkSpecializationMapEntry> specilizations;
|
||||||
|
VkSpecializationInfo* specilizationInfo;
|
||||||
VkShaderStageFlagBits stage;
|
VkShaderStageFlagBits stage;
|
||||||
std::string entrypoint;
|
std::string entrypoint;
|
||||||
VkShaderModule shader;
|
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);
|
std::ifstream file(path, std::ios::binary);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
std::cerr << "Error: Could not open file " << path << std::endl;
|
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));
|
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
|
#endif
|
||||||
|
|
@ -33,8 +33,8 @@ export namespace Crafter {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ScaleData2D {
|
struct ScaleData2D {
|
||||||
Vector<std::uint16_t, 2> position;
|
Vector<std::uint16_t, 2, 2> position;
|
||||||
Vector<std::uint16_t, 2> size;
|
Vector<std::uint16_t, 2, 2> size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClipRect {
|
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;
|
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>
|
||||||
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> {
|
||||||
class VulkanBuffer : public VulkanBufferBase, public VulkanBufferMappedConditional<T, Mapped>, public VulkanBufferAdressableConditional<Adressable>, public VulkanBufferStagedConditional<T, Staged> {
|
|
||||||
public:
|
public:
|
||||||
VulkanBuffer() = default;
|
VulkanBuffer() = default;
|
||||||
void Create(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, std::uint32_t count) {
|
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 {};
|
VkBufferCreateInfo bufferCreateInfo {};
|
||||||
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
|
@ -117,7 +100,7 @@ namespace Crafter {
|
||||||
|
|
||||||
descriptor.offset = 0;
|
descriptor.offset = 0;
|
||||||
descriptor.buffer = buffer;
|
descriptor.buffer = buffer;
|
||||||
descriptor.range = VK_WHOLE_SIZE;
|
descriptor.range = sizeof(T)*count;
|
||||||
|
|
||||||
Device::CheckVkResult(vkBindBufferMemory(Device::device, buffer, memory, 0));
|
Device::CheckVkResult(vkBindBufferMemory(Device::device, buffer, memory, 0));
|
||||||
|
|
||||||
|
|
@ -141,9 +124,6 @@ namespace Crafter {
|
||||||
vkDestroyBuffer(Device::device, buffer, nullptr);
|
vkDestroyBuffer(Device::device, buffer, nullptr);
|
||||||
vkFreeMemory(Device::device, memory, nullptr);
|
vkFreeMemory(Device::device, memory, nullptr);
|
||||||
buffer = VK_NULL_HANDLE;
|
buffer = VK_NULL_HANDLE;
|
||||||
if constexpr(Staged) {
|
|
||||||
delete VulkanBufferMappedConditional<T, true>::stagingBuffer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resize(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, std::uint32_t count) {
|
void Resize(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, std::uint32_t count) {
|
||||||
|
|
@ -238,22 +218,6 @@ namespace Crafter {
|
||||||
vkInvalidateMappedMemoryRanges(Device::device, 1, &range);
|
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) {
|
VulkanBuffer(VulkanBuffer&& other) {
|
||||||
descriptor = other.descriptor;
|
descriptor = other.descriptor;
|
||||||
buffer = other.buffer;
|
buffer = other.buffer;
|
||||||
|
|
@ -265,9 +229,6 @@ namespace Crafter {
|
||||||
if constexpr(Mapped) {
|
if constexpr(Mapped) {
|
||||||
VulkanBufferMappedConditional<T, true>::value = other.VulkanBufferMappedConditional<T, true>::value;
|
VulkanBufferMappedConditional<T, true>::value = other.VulkanBufferMappedConditional<T, true>::value;
|
||||||
}
|
}
|
||||||
if constexpr(Staged) {
|
|
||||||
VulkanBufferStagedConditional<T, true>::stagingBuffer = other.VulkanBufferStagedConditional<T, true>::stagingBuffer;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
~VulkanBuffer() {
|
~VulkanBuffer() {
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,6 @@ import :Types;
|
||||||
import :Rendertarget;
|
import :Rendertarget;
|
||||||
import :Transform2D;
|
import :Transform2D;
|
||||||
import Crafter.Event;
|
import Crafter.Event;
|
||||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
|
||||||
import :PipelineRTVulkan;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
export namespace Crafter {
|
export namespace Crafter {
|
||||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||||
|
|
@ -63,6 +60,8 @@ export namespace Crafter {
|
||||||
// Command buffer submission and execution
|
// Command buffer submission and execution
|
||||||
VkSemaphore renderComplete;
|
VkSemaphore renderComplete;
|
||||||
};
|
};
|
||||||
|
struct PipelineRTVulkan;
|
||||||
|
struct DescriptorHeapVulkan;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct MouseElement;
|
struct MouseElement;
|
||||||
|
|
@ -178,17 +177,6 @@ export namespace Crafter {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
#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();
|
VkCommandBuffer StartInit();
|
||||||
void FinishInit();
|
void FinishInit();
|
||||||
VkCommandBuffer GetCmd();
|
VkCommandBuffer GetCmd();
|
||||||
|
|
@ -200,19 +188,15 @@ export namespace Crafter {
|
||||||
VkFormat colorFormat;
|
VkFormat colorFormat;
|
||||||
VkColorSpaceKHR colorSpace;
|
VkColorSpaceKHR colorSpace;
|
||||||
VkImage images[numFrames];
|
VkImage images[numFrames];
|
||||||
VkImageView imageViews[numFrames];
|
VkImageViewCreateInfo imageViews[numFrames];
|
||||||
std::thread thread;
|
std::thread thread;
|
||||||
VkCommandBuffer drawCmdBuffers[numFrames];
|
VkCommandBuffer drawCmdBuffers[numFrames];
|
||||||
VkSubmitInfo submitInfo;
|
VkSubmitInfo submitInfo;
|
||||||
Semaphores semaphores;
|
Semaphores semaphores;
|
||||||
std::uint32_t currentBuffer = 0;
|
std::uint32_t currentBuffer = 0;
|
||||||
VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
VkPipeline rtPipeline;
|
PipelineRTVulkan* pipeline;
|
||||||
VkPipelineLayout rtPipelineLayout;
|
DescriptorHeapVulkan* descriptorHeap;
|
||||||
VkStridedDeviceAddressRegionKHR raygenRegion;
|
|
||||||
VkStridedDeviceAddressRegionKHR missRegion;
|
|
||||||
VkStridedDeviceAddressRegionKHR hitRegion;
|
|
||||||
VkStridedDeviceAddressRegionKHR callableRegion;
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -38,14 +38,13 @@ export import :ForwardDeclarations;
|
||||||
export import :Device;
|
export import :Device;
|
||||||
export import :VulkanTransition;
|
export import :VulkanTransition;
|
||||||
export import :VulkanBuffer;
|
export import :VulkanBuffer;
|
||||||
export import :DescriptorPoolVulkan;
|
|
||||||
export import :ShaderVulkan;
|
export import :ShaderVulkan;
|
||||||
export import :ShaderBindingTableVulkan;
|
export import :ShaderBindingTableVulkan;
|
||||||
export import :PipelineRTVulkan;
|
export import :PipelineRTVulkan;
|
||||||
export import :RenderingElement3D;
|
export import :RenderingElement3D;
|
||||||
export import :ImageVulkan;
|
export import :ImageVulkan;
|
||||||
export import :SamplerVulkan;
|
export import :SamplerVulkan;
|
||||||
export import :DescriptorSetLayoutVulkan;
|
export import :DescriptorHeapVulkan;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// export import :WindowWaylandVulkan;
|
// export import :WindowWaylandVulkan;
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,12 @@
|
||||||
"interfaces/Crafter.Graphics-Mesh",
|
"interfaces/Crafter.Graphics-Mesh",
|
||||||
"interfaces/Crafter.Graphics-VulkanBuffer",
|
"interfaces/Crafter.Graphics-VulkanBuffer",
|
||||||
"interfaces/Crafter.Graphics-RenderingElement3D",
|
"interfaces/Crafter.Graphics-RenderingElement3D",
|
||||||
"interfaces/Crafter.Graphics-DescriptorPoolVulkan",
|
|
||||||
"interfaces/Crafter.Graphics-ShaderVulkan",
|
"interfaces/Crafter.Graphics-ShaderVulkan",
|
||||||
"interfaces/Crafter.Graphics-PipelineRTVulkan",
|
"interfaces/Crafter.Graphics-PipelineRTVulkan",
|
||||||
"interfaces/Crafter.Graphics-ShaderBindingTableVulkan",
|
"interfaces/Crafter.Graphics-ShaderBindingTableVulkan",
|
||||||
"interfaces/Crafter.Graphics-ImageVulkan",
|
"interfaces/Crafter.Graphics-ImageVulkan",
|
||||||
"interfaces/Crafter.Graphics-SamplerVulkan",
|
"interfaces/Crafter.Graphics-SamplerVulkan",
|
||||||
"interfaces/Crafter.Graphics-DescriptorSetLayoutVulkan",
|
"interfaces/Crafter.Graphics-DescriptorHeapVulkan",
|
||||||
"interfaces/Crafter.Graphics-Rendertarget",
|
"interfaces/Crafter.Graphics-Rendertarget",
|
||||||
"interfaces/Crafter.Graphics-ForwardDeclarations"
|
"interfaces/Crafter.Graphics-ForwardDeclarations"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue