Crafter.Graphics/implementations/Crafter.Graphics-Mesh_vulkan.cpp

130 lines
5.8 KiB
C++
Raw Normal View History

2026-01-28 01:07:41 +01:00
/*
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;
2026-03-02 23:53:13 +01:00
#include "vulkan/vulkan.h"
2026-01-28 01:07:41 +01:00
module Crafter.Graphics:Mesh_impl;
2026-02-22 00:46:38 +01:00
import Crafter.Math;
2026-01-28 01:07:41 +01:00
import :Mesh;
import :VulkanDevice;
2026-01-29 01:31:17 +01:00
import :Types;
2026-01-28 01:07:41 +01:00
import std;
using namespace Crafter;
2026-02-22 00:46:38 +01:00
void Mesh::Build(std::span<Vector<float, 3, 3>> verticies, std::span<std::uint32_t> indicies, VkCommandBuffer cmd) {
2026-01-28 18:51:11 +01:00
vertexBuffer.Resize(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, verticies.size());
2026-02-24 02:32:37 +01:00
indexBuffer.Resize(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, indicies.size());
2026-01-28 01:07:41 +01:00
2026-02-22 00:46:38 +01:00
std::memcpy(vertexBuffer.value, verticies.data(), verticies.size() * sizeof(Vector<float, 3, 3>));
2026-01-28 18:51:11 +01:00
std::memcpy(indexBuffer.value, indicies.data(), indicies.size() * sizeof(std::uint32_t));
2026-01-28 01:07:41 +01:00
2026-01-28 18:51:11 +01:00
vertexBuffer.FlushDevice(cmd, VK_ACCESS_MEMORY_READ_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR);
vertexBuffer.FlushDevice(cmd, VK_ACCESS_MEMORY_READ_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR);
2026-01-28 01:07:41 +01:00
VkDeviceOrHostAddressConstKHR vertexAddr;
vertexAddr.deviceAddress = vertexBuffer.address;
VkDeviceOrHostAddressConstKHR indexAddr;
indexAddr.deviceAddress = indexBuffer.address;
auto trianglesData = VkAccelerationStructureGeometryTrianglesDataKHR {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR,
.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT,
.vertexData = vertexAddr,
2026-02-22 00:46:38 +01:00
.vertexStride = sizeof(Vector<float, 3, 3>),
2026-01-28 01:07:41 +01:00
.maxVertex = static_cast<std::uint32_t>(verticies.size())-1,
.indexType = VK_INDEX_TYPE_UINT32,
.indexData = indexAddr,
.transformData = {.deviceAddress = 0}
};
VkAccelerationStructureGeometryDataKHR geometryData(trianglesData);
VkAccelerationStructureGeometryKHR blasGeometry {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR,
.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR,
.geometry = geometryData,
.flags = VK_GEOMETRY_OPAQUE_BIT_KHR
};
VkAccelerationStructureBuildGeometryInfoKHR blasBuildGeometryInfo{
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,
.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,
.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR,
.geometryCount = 1,
.pGeometries = &blasGeometry,
};
// Query the memory sizes that will be needed for this BLAS
auto primitiveCount = static_cast<uint32_t>(indicies.size() / 3);
VkAccelerationStructureBuildSizesInfoKHR blasBuildSizes = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR
};
VulkanDevice::vkGetAccelerationStructureBuildSizesKHR(
VulkanDevice::device,
VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
&blasBuildGeometryInfo,
&primitiveCount,
&blasBuildSizes
);
2026-01-28 18:51:11 +01:00
scratchBuffer.Resize(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, blasBuildSizes.buildScratchSize);
2026-01-28 01:07:41 +01:00
VkPhysicalDeviceAccelerationStructurePropertiesKHR asProps{
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR
};
VkDeviceAddress scratchAddr = scratchBuffer.address;
blasBuildGeometryInfo.scratchData.deviceAddress = scratchAddr;
2026-01-28 18:51:11 +01:00
blasBuffer.Resize(VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, blasBuildSizes.accelerationStructureSize);
2026-01-28 01:07:41 +01:00
// Create and store the BLAS handle
VkAccelerationStructureCreateInfoKHR blasCreateInfo{
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR,
.buffer = blasBuffer.buffer,
.offset = 0,
.size = blasBuildSizes.accelerationStructureSize,
.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,
};
2026-01-28 18:51:11 +01:00
VulkanDevice::CheckVkResult(VulkanDevice::vkCreateAccelerationStructureKHR(VulkanDevice::device, &blasCreateInfo, nullptr, &accelerationStructure));
blasBuildGeometryInfo.dstAccelerationStructure = accelerationStructure;
2026-01-28 01:07:41 +01:00
// Prepare the build range for the BLAS
VkAccelerationStructureBuildRangeInfoKHR blasRangeInfo {
.primitiveCount = primitiveCount,
.primitiveOffset = 0,
.firstVertex = 0,
.transformOffset = 0
};
VkAccelerationStructureBuildRangeInfoKHR* blasRangeInfoPP = &blasRangeInfo;
VulkanDevice::vkCmdBuildAccelerationStructuresKHR(cmd, 1, &blasBuildGeometryInfo, &blasRangeInfoPP);
2026-02-22 00:46:38 +01:00
VkAccelerationStructureDeviceAddressInfoKHR addrInfo {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR,
.accelerationStructure = accelerationStructure
};
blasAddr = VulkanDevice::vkGetAccelerationStructureDeviceAddressKHR(VulkanDevice::device, &addrInfo);
2026-01-28 01:07:41 +01:00
}