working mesh shader
This commit is contained in:
parent
c45afab0dd
commit
97ca634108
18 changed files with 2591 additions and 340 deletions
|
|
@ -9,6 +9,8 @@ module;
|
|||
#include <cstring>
|
||||
#include <print>
|
||||
#include <cstdio>
|
||||
#include "VulkanInitializers.hpp"
|
||||
#include "VulkanBuffer.h"
|
||||
|
||||
#define GET_EXTENSION_FUNCTION(_id) ((PFN_##_id)(vkGetInstanceProcAddr(instance, #_id)))
|
||||
|
||||
|
|
@ -23,7 +25,8 @@ const char* const deviceExtensionNames[] = {
|
|||
"VK_KHR_swapchain",
|
||||
"VK_KHR_spirv_1_4",
|
||||
"VK_EXT_mesh_shader",
|
||||
"VK_KHR_shader_float_controls"
|
||||
"VK_KHR_shader_float_controls",
|
||||
"VK_KHR_dynamic_rendering"
|
||||
};
|
||||
const char* const layerNames[] = {
|
||||
"VK_LAYER_KHRONOS_validation"
|
||||
|
|
@ -182,6 +185,7 @@ void VulkanDevice::CreateDevice() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float priority = 1;
|
||||
|
||||
|
|
@ -191,8 +195,13 @@ void VulkanDevice::CreateDevice() {
|
|||
queueCreateInfo.queueCount = 1;
|
||||
queueCreateInfo.pQueuePriorities = &priority;
|
||||
|
||||
VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeature = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR};
|
||||
dynamicRenderingFeature.dynamicRendering = VK_TRUE;
|
||||
|
||||
VkPhysicalDeviceMeshShaderFeaturesEXT ext_feature = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT};
|
||||
ext_feature.meshShader = VK_TRUE;
|
||||
ext_feature.pNext = &dynamicRenderingFeature;
|
||||
|
||||
VkPhysicalDeviceFeatures2 physical_features2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
|
||||
physical_features2.pNext = &ext_feature;
|
||||
|
||||
|
|
@ -237,4 +246,134 @@ void VulkanDevice::CreateDevice() {
|
|||
commandPoolcreateInfo.queueFamilyIndex = queueFamilyIndex;
|
||||
commandPoolcreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
CHECK_VK_RESULT(vkCreateCommandPool(device, &commandPoolcreateInfo, NULL, &commandPool));
|
||||
|
||||
vkGetPhysicalDeviceMemoryProperties(physDevice, &memoryProperties);
|
||||
|
||||
std::vector<VkFormat> formatList = {
|
||||
VK_FORMAT_D32_SFLOAT,
|
||||
};
|
||||
|
||||
for (auto& format : formatList) {
|
||||
VkFormatProperties formatProps;
|
||||
vkGetPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
|
||||
if (formatProps.optimalTilingFeatures)
|
||||
{
|
||||
depthFormat = format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vkCmdDrawMeshTasksEXTProc = reinterpret_cast<PFN_vkCmdDrawMeshTasksEXT>(vkGetDeviceProcAddr(device, "vkCmdDrawMeshTasksEXT"));
|
||||
vkCmdBeginRenderingKHRProc = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetInstanceProcAddr(instance, "vkCmdBeginRenderingKHR"));
|
||||
vkCmdEndRenderingKHRProc = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetInstanceProcAddr(instance, "vkCmdEndRenderingKHR"));
|
||||
}
|
||||
|
||||
std::uint32_t VulkanDevice::GetMemoryType(uint32_t typeBits, VkMemoryPropertyFlags properties) {
|
||||
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++)
|
||||
{
|
||||
if ((typeBits & 1) == 1)
|
||||
{
|
||||
if ((memoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
typeBits >>= 1;
|
||||
}
|
||||
|
||||
throw std::runtime_error("Could not find a matching memory type");
|
||||
}
|
||||
|
||||
void VulkanDevice::CreateBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, VkDeviceSize size, VkBuffer *buffer, VkDeviceMemory *memory, void *data)
|
||||
{
|
||||
// Create the buffer handle
|
||||
VkBufferCreateInfo bufferCreateInfo = vks::initializers::bufferCreateInfo(usageFlags, size);
|
||||
bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
CHECK_VK_RESULT(vkCreateBuffer(device, &bufferCreateInfo, nullptr, buffer));
|
||||
|
||||
// Create the memory backing up the buffer handle
|
||||
VkMemoryRequirements memReqs;
|
||||
VkMemoryAllocateInfo memAlloc = vks::initializers::memoryAllocateInfo();
|
||||
vkGetBufferMemoryRequirements(device, *buffer, &memReqs);
|
||||
memAlloc.allocationSize = memReqs.size;
|
||||
// Find a memory type index that fits the properties of the buffer
|
||||
memAlloc.memoryTypeIndex = GetMemoryType(memReqs.memoryTypeBits, memoryPropertyFlags);
|
||||
// If the buffer has VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT set we also need to enable the appropriate flag during allocation
|
||||
VkMemoryAllocateFlagsInfoKHR allocFlagsInfo{};
|
||||
if (usageFlags & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) {
|
||||
allocFlagsInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR;
|
||||
allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
|
||||
memAlloc.pNext = &allocFlagsInfo;
|
||||
}
|
||||
CHECK_VK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, memory));
|
||||
|
||||
// If a pointer to the buffer data has been passed, map the buffer and copy over the data
|
||||
if (data != nullptr)
|
||||
{
|
||||
void *mapped;
|
||||
CHECK_VK_RESULT(vkMapMemory(device, *memory, 0, size, 0, &mapped));
|
||||
memcpy(mapped, data, size);
|
||||
// If host coherency hasn't been requested, do a manual flush to make writes visible
|
||||
if ((memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
|
||||
{
|
||||
VkMappedMemoryRange mappedRange = vks::initializers::mappedMemoryRange();
|
||||
mappedRange.memory = *memory;
|
||||
mappedRange.offset = 0;
|
||||
mappedRange.size = size;
|
||||
vkFlushMappedMemoryRanges(device, 1, &mappedRange);
|
||||
}
|
||||
vkUnmapMemory(device, *memory);
|
||||
}
|
||||
|
||||
// Attach the memory to the buffer object
|
||||
CHECK_VK_RESULT(vkBindBufferMemory(device, *buffer, *memory, 0));
|
||||
}
|
||||
|
||||
|
||||
void VulkanDevice::CreateBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, vks::Buffer *buffer, VkDeviceSize size, void *data)
|
||||
{
|
||||
buffer->device = device;
|
||||
|
||||
// Create the buffer handle
|
||||
VkBufferCreateInfo bufferCreateInfo = vks::initializers::bufferCreateInfo(usageFlags, size);
|
||||
CHECK_VK_RESULT(vkCreateBuffer(device, &bufferCreateInfo, nullptr, &buffer->buffer));
|
||||
|
||||
// Create the memory backing up the buffer handle
|
||||
VkMemoryRequirements memReqs;
|
||||
VkMemoryAllocateInfo memAlloc = vks::initializers::memoryAllocateInfo();
|
||||
vkGetBufferMemoryRequirements(device, buffer->buffer, &memReqs);
|
||||
memAlloc.allocationSize = memReqs.size;
|
||||
// Find a memory type index that fits the properties of the buffer
|
||||
memAlloc.memoryTypeIndex = GetMemoryType(memReqs.memoryTypeBits, memoryPropertyFlags);
|
||||
// If the buffer has VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT set we also need to enable the appropriate flag during allocation
|
||||
VkMemoryAllocateFlagsInfoKHR allocFlagsInfo{};
|
||||
if (usageFlags & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) {
|
||||
allocFlagsInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR;
|
||||
allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
|
||||
memAlloc.pNext = &allocFlagsInfo;
|
||||
}
|
||||
CHECK_VK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &buffer->memory));
|
||||
|
||||
buffer->alignment = memReqs.alignment;
|
||||
buffer->size = size;
|
||||
buffer->usageFlags = usageFlags;
|
||||
buffer->memoryPropertyFlags = memoryPropertyFlags;
|
||||
|
||||
// If a pointer to the buffer data has been passed, map the buffer and copy over the data
|
||||
if (data != nullptr)
|
||||
{
|
||||
CHECK_VK_RESULT(buffer->map());
|
||||
memcpy(buffer->mapped, data, size);
|
||||
if ((memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0) {
|
||||
buffer->flush();
|
||||
}
|
||||
|
||||
buffer->unmap();
|
||||
}
|
||||
|
||||
// Initialize a default descriptor that covers the whole buffer size
|
||||
buffer->setupDescriptor();
|
||||
|
||||
// Attach the memory to the buffer object
|
||||
CHECK_VK_RESULT(buffer->bind());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue