Major changes

Signed-off-by: Robear Selwans <robear.selwans@outlook.com>
This commit is contained in:
2025-07-02 12:26:20 +03:00
parent 4ec57bbd79
commit dd0d232c97
32 changed files with 997 additions and 182 deletions

17
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,17 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "c",
"stdio": [
"input.txt",
null
],
"preLaunchTask": "Compile",
"expressions": "native",
"program": "${workspaceFolder}/build/evk.exe"
}
]
}

20
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,20 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Compile",
"type": "shell",
"command": "meson compile -C build"
},
{
"label": "Run",
"type": "shell",
"command": "build/evk.exe"
},
{
"label": "Test",
"type": "shell",
"command": "echo \"Hi Bye\""
}
]
}

View File

@@ -13,4 +13,8 @@
#include "evkSwapChain.h" #include "evkSwapChain.h"
#include "evkCommand.h" #include "evkCommand.h"
#include "evkPipeline.h" #include "evkPipeline.h"
#include "evkMemory.h"
#include "evkImage.h" #include "evkImage.h"
#include "evkBuffer.h"
#include "evkDescriptor.h"
#include "evkVertexLayout.h"

View File

@@ -1,7 +1,7 @@
#include "evkImage.h" #include "evkBuffer.h"
#include "evk/evkMemory.h" #include "evk/evkMemory.h"
evkBuffer evkCreateBuffer(evkBufferCreateInfo createInfo) evkBuffer evkCreateBuffer(evkDevice* device, evkBufferCreateInfo createInfo)
{ {
VkBufferCreateInfo bufferCreateInfo = { VkBufferCreateInfo bufferCreateInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
@@ -9,8 +9,9 @@ evkBuffer evkCreateBuffer(evkBufferCreateInfo createInfo)
.flags = createInfo.flags, .flags = createInfo.flags,
.usage = createInfo.usage, .usage = createInfo.usage,
.sharingMode = createInfo.exclusive?VK_SHARING_MODE_EXCLUSIVE:VK_SHARING_MODE_CONCURRENT, .sharingMode = createInfo.exclusive?VK_SHARING_MODE_EXCLUSIVE:VK_SHARING_MODE_CONCURRENT,
.queueFamilyIndexCount = vec_len(&createInfo.queueFamilyIndices), .queueFamilyIndexCount = createInfo.exclusive?0:vec_len(&createInfo.queueFamilyIndices),
.pQueueFamilyIndices = createInfo.queueFamilyIndices, .pQueueFamilyIndices = createInfo.queueFamilyIndices,
.size = createInfo.sizeInBytes,
}; };
evkBuffer buffer = evkGPUCreateBuffer(createInfo.allocationCreateInfo, &bufferCreateInfo); evkBuffer buffer = evkGPUCreateBuffer(createInfo.allocationCreateInfo, &bufferCreateInfo);
@@ -18,6 +19,10 @@ evkBuffer evkCreateBuffer(evkBufferCreateInfo createInfo)
if(buffer.vk != VK_NULL_HANDLE) if(buffer.vk != VK_NULL_HANDLE)
{ {
buffer.sizeInBytes = createInfo.sizeInBytes; buffer.sizeInBytes = createInfo.sizeInBytes;
buffer.address = vkGetBufferDeviceAddressKHR(device->vk, &(VkBufferDeviceAddressInfo){
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = buffer.vk
});
} }
return buffer; return buffer;

View File

@@ -2,5 +2,5 @@
#include "evkCommon.h" #include "evkCommon.h"
evkBuffer evkCreateBuffer(evkBufferCreateInfo createInfo); evkBuffer evkCreateBuffer(evkDevice* device, evkBufferCreateInfo createInfo);
void evkDestroyBuffer(evkBuffer buf); void evkDestroyBuffer(evkBuffer buf);

View File

@@ -20,10 +20,9 @@ void evkDestroyCommandPool(evkDevice device, evkCommandPool commandPool)
vkDestroyCommandPool(device.vk, commandPool.vk, NULL); vkDestroyCommandPool(device.vk, commandPool.vk, NULL);
} }
vec(VkCommandBuffer) evkAllocateCommandBuffers(evkDevice device, evkCommandPool commandPool, u32 count, bool primary) vec(evkCommandBuffer) evkAllocateCommandBuffers(evkDevice device, evkCommandPool commandPool, u32 count, bool primary)
{ {
vec(VkCommandBuffer) buffers = vec_init(VkCommandBuffer); VkCommandBuffer vkBuffers[count];
vec_setlen(&buffers, count);
VkCommandBufferAllocateInfo allocateInfo = (VkCommandBufferAllocateInfo) { VkCommandBufferAllocateInfo allocateInfo = (VkCommandBufferAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
@@ -32,20 +31,46 @@ vec(VkCommandBuffer) evkAllocateCommandBuffers(evkDevice device, evkCommandPool
.level = primary?VK_COMMAND_BUFFER_LEVEL_PRIMARY:VK_COMMAND_BUFFER_LEVEL_SECONDARY, .level = primary?VK_COMMAND_BUFFER_LEVEL_PRIMARY:VK_COMMAND_BUFFER_LEVEL_SECONDARY,
}; };
vkAllocateCommandBuffers(device.vk, &allocateInfo, buffers); vkAllocateCommandBuffers(device.vk, &allocateInfo, vkBuffers);
vec(evkCommandBuffer) buffers = vec_init(evkCommandBuffer);
vec_setlen(&buffers, count);
for(int i = 0; i < count; i++)
{
buffers[i] = (evkCommandBuffer) {
.vk = vkBuffers[i],
.recording = false,
.boundPipeline = NULL,
};
}
return buffers; return buffers;
} }
void evkBeginPrimaryCommandBuffer(VkCommandBuffer cmdBuf) void evkFreeCommandBuffers(evkDevice device, evkCommandPool pool, vec(evkCommandBuffer) commandBuffers)
{
vec(VkCommandBuffer) cmdbufs = vec_init(VkCommandBuffer);
for(u32 i = 0; i < vec_len(&commandBuffers); i++)
{
vec_push(&cmdbufs, &commandBuffers[i].vk);
}
vkFreeCommandBuffers(device.vk, pool.vk, vec_len(&cmdbufs), cmdbufs);
}
void evkBeginPrimaryCommandBuffer(evkCommandBuffer* cmdBuf)
{ {
VkCommandBufferBeginInfo beginInfo = (VkCommandBufferBeginInfo) { VkCommandBufferBeginInfo beginInfo = (VkCommandBufferBeginInfo) {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
}; };
vkBeginCommandBuffer(cmdBuf, &beginInfo); vkBeginCommandBuffer(cmdBuf->vk, &beginInfo);
cmdBuf->recording = true;
} }
void evkEndCommandBuffer(VkCommandBuffer cmdBuf) void evkEndCommandBuffer(evkCommandBuffer* cmdBuf)
{ {
vkEndCommandBuffer(cmdBuf); vkEndCommandBuffer(cmdBuf->vk);
cmdBuf->recording = false;
cmdBuf->boundPipeline = NULL;
} }

View File

@@ -9,7 +9,9 @@ evkCommandPool evkCreateCommandPool(evkCommandPoolCreateInfo createInfo);
void evkDestroyCommandPool(evkDevice device, evkCommandPool commandPool); void evkDestroyCommandPool(evkDevice device, evkCommandPool commandPool);
[[nodiscard("Leaking allocated CommandBuffers")]] [[nodiscard("Leaking allocated CommandBuffers")]]
vec(VkCommandBuffer) evkAllocateCommandBuffers(evkDevice device, evkCommandPool commandPool, u32 count, bool primary); vec(evkCommandBuffer) evkAllocateCommandBuffers(evkDevice device, evkCommandPool commandPool, u32 count, bool primary);
void evkBeginPrimaryCommandBuffer(VkCommandBuffer cmdBuf); void evkFreeCommandBuffers(evkDevice device, evkCommandPool pool, vec(evkCommandBuffer) commandBuffers);
void evkEndCommandBuffer(VkCommandBuffer cmdBuf);
void evkBeginPrimaryCommandBuffer(evkCommandBuffer* cmdBuf);
void evkEndCommandBuffer(evkCommandBuffer* cmdBuf);

View File

@@ -10,4 +10,5 @@
#define EV_VEC_SHORTNAMES #define EV_VEC_SHORTNAMES
#include <ev_vec.h> #include <ev_vec.h>
#include "evkConstants.h"
#include "evkTypes.h" #include "evkTypes.h"

3
evk/evkConstants.h Normal file
View File

@@ -0,0 +1,3 @@
#pragma once
#define MAX_DESCRIPTOR_SETS 4

View File

@@ -1,43 +1,186 @@
#pragma once
#include "evkDescriptor.h" #include "evkDescriptor.h"
#include "evkBuffer.h"
#include "evkCommand.h"
typedef struct { EV_FORCEINLINE uint32_t aligned_size(uint32_t value, uint32_t alignment)
VkDescriptorSetLayout descriptorSetLayouts[4];
} evkSetLayout;
evkSetLayout evkCreateDescriptorSetLayouts(vec(evkShader) shaders)
{ {
VkDescriptorSetLayoutCreateInfo createInfos[4]; return (value + alignment - 1) & ~(alignment - 1);
for(int i = 0; i < 4; i++)
{
createInfos[i] = EV_DEFAULT(
VkDescriptorSetLayoutCreateInfo,
pBindings = vec_init(VkDescriptorSetLayoutBinding)
);
} }
VkBufferUsageFlags evkGetDescriptorSetBufferUsageFlags(evkDescriptorSetLayout* layout)
{
VkBufferUsageFlags flags = 0;
for(int i = 0; i < vec_len(&layout->vkBindings); i++)
{
VkDescriptorType type = layout->vkBindings[i].descriptorType;
if(type == VK_DESCRIPTOR_TYPE_SAMPLER)
{
flags |= VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT;
}
else
{
flags |= VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT;
if(type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
{
flags |= VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT;
break;
}
}
}
return flags;
}
evkDescriptorSet evkCreateDescriptorSet(evkDescriptorSetCreateInfo* createInfo)
{
evkDescriptorSet res;
res.device = createInfo->device;
res.layout = (evkDescriptorSetLayout){
.names = ev_vec_dup(&createInfo->layout->names),
.vkBindings = ev_vec_dup(&createInfo->layout->vkBindings),
.vk = createInfo->layout->vk,
.size = createInfo->layout->size,
.offset = createInfo->layout->offset,
};
res.buffer = evkCreateBuffer(createInfo->device, (evkBufferCreateInfo) {
.allocationCreateInfo = (evkGPUAllocationCreateInfo) {
.allocator = *createInfo->allocator,
.allocationFlags = EVK_GPU_ALLOCATION_CREATE_MAPPED_BIT | EVK_GPU_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
},
.sizeInBytes = res.layout.size,
.usage = evkGetDescriptorSetBufferUsageFlags(&res.layout) | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.exclusive = true,
});
return res;
}
void evkDestroyDescriptorSet(evkDevice* device, evkDescriptorSet* set)
{
evkDestroyBuffer(set->buffer);
set->layout.vk = VK_NULL_HANDLE; // Not owned, so don't destroy
evkDestroyDescriptorSetLayout(device, &set->layout);
}
evkDescriptorSetLayout evkCreateDescriptorSetLayoutFromBindings(evkDevice* device, vec(evkDescriptorBinding) bindings)
{
evkDescriptorSetLayout layout;
layout.names = ev_vec_init(evstring);
layout.vkBindings = ev_vec_init(VkDescriptorSetLayoutBinding);
for(int i = 0; i < ev_vec_len(&bindings); i++)
{
VkDescriptorSetLayoutBinding b = {
.binding = bindings[i].binding,
.descriptorCount = bindings[i].descriptorCount,
.descriptorType = bindings[i].descriptorType,
.pImmutableSamplers = bindings[i].pImmutableSamplers,
.stageFlags = bindings[i].stageFlags,
};
ev_vec_push(&layout.names, &bindings[i].name);
ev_vec_push(&layout.vkBindings, &b);
}
vkCreateDescriptorSetLayout(device->vk, &(VkDescriptorSetLayoutCreateInfo){
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = vec_len(&layout.vkBindings),
.pBindings = layout.vkBindings,
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT,
}, NULL, &layout.vk);
vkGetDescriptorSetLayoutSizeEXT(device->vk, layout.vk, &layout.size);
layout.size = aligned_size(layout.size, device->props.desc_buf.descriptorBufferOffsetAlignment);
vkGetDescriptorSetLayoutBindingOffsetEXT(device->vk, layout.vk, 0u, &layout.offset);
return layout;
}
void evkDescriptorBindingDedup(vec(evkDescriptorBinding) bindings)
{
}
evkDescriptorSetLayout evkCreateDescriptorSetLayoutFromShaders(evkDevice* device, vec(evkShader) shaders)
{
vec(evkDescriptorBinding) bindings = vec_init(evkDescriptorBinding);
for(int i = 0; i < vec_len(&shaders); i++) for(int i = 0; i < vec_len(&shaders); i++)
{ {
vec(evkDescriptorBinding) bindings = shaders[i].reflect.bindings; vec_append(&bindings, &shaders[i].reflect.bindings, vec_len(&shaders[i].reflect.bindings));
for(int bi = 0; bi < vec_len(&bindings); bi++)
{
evkDescriptorBinding b = bindings[bi];
if(b.binding >= vec_len(&createInfos[b.set].pBindings))
{
u32 old_len = vec_len(&createInfos[b.set].pBindings);
vec_setlen(&createInfos[b.set].pBindings, b.binding+1);
for(int cs = old_len; cs < b.binding+1; cs++)
{
/* createInfos[b.set].pBindings[cs].binding */
} }
evkDescriptorBindingDedup(bindings);
return evkCreateDescriptorSetLayoutFromBindings(device, bindings);
} }
} void evkDestroyDescriptorSetLayout(evkDevice* device, evkDescriptorSetLayout* layout)
{
if(layout->vk != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(device->vk, layout->vk, NULL);
ev_vec_fini(&layout->names);
ev_vec_fini(&layout->vkBindings);
layout->offset = 0;
layout->size = 0;
} }
for(int i = 0; i < 4; i++) void evkSetDescriptor(evkDescriptorSet* set, evstring name, evkBuffer* buf)
{ {
createInfos[i].bindingCount = vec_len(&createInfos[i].pBindings); i32 layoutBindingIdx = ev_vec_find(&set->layout.names, &name);
if(layoutBindingIdx == -1) return;
i32 bindingIdx = set->layout.vkBindings[layoutBindingIdx].binding;
u64 bindingOffset = 0;
vkGetDescriptorSetLayoutBindingOffsetEXT(set->device->vk, set->layout.vk, bindingIdx, &bindingOffset);
VkDescriptorAddressInfoEXT addressInfo = {
VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT,
.address = buf->address,
.range = buf->sizeInBytes,
.format = VK_FORMAT_UNDEFINED,
};
VkDescriptorGetInfoEXT getInfo = {
VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT,
.type = set->layout.vkBindings[layoutBindingIdx].descriptorType,
.data = {
.pUniformBuffer = &addressInfo
} }
};
vkGetDescriptorEXT(set->device->vk, &getInfo, set->device->props.desc_buf.uniformBufferDescriptorSize, set->buffer.allocData.allocationInfo.vma.pMappedData);
}
void evkCmdBindDescriptorSets(evkCommandBuffer* cmdbuf, evkPipeline* pipeline, vec(evkDescriptorSet) sets, vec(u32) setIndices)
{
VkDescriptorBufferBindingInfoEXT bindingInfos[MAX_DESCRIPTOR_SETS];
VkDeviceSize setOffsets[MAX_DESCRIPTOR_SETS];
u32 actualSetIndices[MAX_DESCRIPTOR_SETS];
for(int i = 0; i < MAX_DESCRIPTOR_SETS; i++)
actualSetIndices[i] = i;
int bindingCount = min(MAX_DESCRIPTOR_SETS, vec_len(&sets));
int offset = 0;
for(int i = 0; i < bindingCount; i++)
{
bindingInfos[i] = (VkDescriptorBufferBindingInfoEXT) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT,
.address = sets[setIndices[i]].buffer.address,
.usage = sets[setIndices[i]].buffer.usage,
};
setOffsets[i] = offset;
offset += sets[setIndices[i]].layout.size;
}
vkCmdBindDescriptorBuffersEXT(cmdbuf->vk, bindingCount, bindingInfos);
vkCmdSetDescriptorBufferOffsetsEXT(cmdbuf->vk,
(VkPipelineBindPoint)pipeline->type,
pipeline->layout.vk,
0, bindingCount,
actualSetIndices,
setOffsets);
} }

View File

@@ -3,3 +3,17 @@
#include "evkCommon.h" #include "evkCommon.h"
// void evkFillSetLayoutCreateInfos(vec(evkShader) shaders, VkDescriptorSetLayoutCreateInfo layoutCreateInfos[4]); // void evkFillSetLayoutCreateInfos(vec(evkShader) shaders, VkDescriptorSetLayoutCreateInfo layoutCreateInfos[4]);
evkDescriptorSetLayout evkCreateDescriptorSetLayoutFromBindings(evkDevice* device, vec(evkDescriptorBinding) bindings);
evkDescriptorSetLayout evkCreateDescriptorSetLayoutFromShaders(evkDevice* device, vec(evkShader) shaders);
void evkDestroyDescriptorSetLayout(evkDevice* device, evkDescriptorSetLayout* layout);
evkDescriptorSet evkCreateDescriptorSet(evkDescriptorSetCreateInfo* createInfo);
void evkDestroyDescriptorSet(evkDevice* device, evkDescriptorSet* set);
void evkSetDescriptor(evkDescriptorSet* set, evstring name, evkBuffer* buf);
void evkCmdBindDescriptorSets(evkCommandBuffer* cmdbuf, evkPipeline* pipeline, vec(evkDescriptorSet) sets, vec(u32) setIndices);
// evkDescriptorSet evkCreateDescriptorSet(evkDevice* device, evkGPUAllocator* allocator, vec(evkDescriptorBinding) bindings);
// void evkCmdBindDescriptorBuffers(VkCommandBuffer cmdbuf, vec(evkDescriptorSet) sets);

View File

@@ -2,18 +2,41 @@
#include "evkTypes.h" #include "evkTypes.h"
#include "evkAllocator.h" #include "evkAllocator.h"
evstring VkDynamicRenderingExtName = evstr("VK_KHR_dynamic_rendering"); #define SUPPORTED_EXTENSION_FEATURE_PAIRS \
evstring VkSync2ExtName = evstr("VK_KHR_synchronization2"); (VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME , features12.descriptorIndexing ), \
(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, features12.bufferDeviceAddress), \
(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME , features13.dynamicRendering ), \
(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME , features13.synchronization2 )
VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeature = (VkPhysicalDeviceDynamicRenderingFeaturesKHR) { #define EVK_ENABLE_EXTENSION_FEATURES(enabledExtensions,featuresStruct) \
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR, EV_FOREACH_UDATA(EVK_ENABLE_EXTENSION_FEATURE, (enabledExtensions, featuresStruct), SUPPORTED_EXTENSION_FEATURE_PAIRS)
.dynamicRendering = VK_TRUE,
#define EVK_ENABLE_EXTENSION_FEATURE(ef_pair, name_flag_pair) \
{ \
evstring name = evstr(EV_HEAD name_flag_pair); \
if(ev_vec_find(&EV_HEAD ef_pair, &name) != -1) \
EV_TAIL ef_pair.EV_TAIL name_flag_pair = true; \
}
VkPhysicalDeviceDescriptorBufferFeaturesEXT descriptorBufFeature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT,
.descriptorBuffer = VK_TRUE,
EV_DEBUG(
.descriptorBufferCaptureReplay = VK_TRUE,
)
}; };
VkPhysicalDeviceSynchronization2Features sync2Features = (VkPhysicalDeviceSynchronization2Features) { typedef struct {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, evstring name;
.synchronization2 = VK_TRUE, void* data;
void* ppNext;
} evkDeviceExtension;
const evkDeviceExtension evkSupportedExtensions[] = {
{ evstr(VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME) , &descriptorBufFeature , &descriptorBufFeature.pNext },
}; };
const u32 evkSupportedExtensionsCount = EV_ARRSIZE(evkSupportedExtensions);
VkPhysicalDevice evkDetectPhysicalDevice(evkInstance instance, VkPhysicalDeviceType deviceType) VkPhysicalDevice evkDetectPhysicalDevice(evkInstance instance, VkPhysicalDeviceType deviceType)
{ {
@@ -48,9 +71,22 @@ evkDevice evkCreateDevice(evkDeviceCreateInfo createInfo)
device._physicalDevice = evkDetectPhysicalDevice(createInfo.instance, createInfo.physicalDeviceType); device._physicalDevice = evkDetectPhysicalDevice(createInfo.instance, createInfo.physicalDeviceType);
device._instance = createInfo.instance; device._instance = createInfo.instance;
VkPhysicalDeviceProperties physicalDeviceProperties; VkPhysicalDeviceProperties2 physicalDeviceProperties = {
vkGetPhysicalDeviceProperties(device._physicalDevice, &physicalDeviceProperties); VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
device.limits = physicalDeviceProperties.limits; };
void** pNextProps = (void**)&physicalDeviceProperties.pNext;
evstring VkDescriptorBufferExtName = evstr(VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME);
if(ev_vec_find(&createInfo.deviceExtensions, &VkDescriptorBufferExtName) != -1)
{
device.props.desc_buf = (VkPhysicalDeviceDescriptorBufferPropertiesEXT){ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_PROPERTIES_EXT };
*pNextProps = &device.props.desc_buf;
pNextProps = &device.props.desc_buf.pNext;
}
vkGetPhysicalDeviceProperties2(device._physicalDevice, &physicalDeviceProperties);
device.props.limits = physicalDeviceProperties.properties.limits;
for (u32 i = 0; i < MAX_QUEUE_FAMILIES; i++) { for (u32 i = 0; i < MAX_QUEUE_FAMILIES; i++) {
device.queueFamilies[i] = (evkDeviceQueueFamily){ device.queueFamilies[i] = (evkDeviceQueueFamily){
@@ -61,22 +97,34 @@ evkDevice evkCreateDevice(evkDeviceCreateInfo createInfo)
VkDeviceCreateInfo vkDeviceCreateInfo = __EV_VEC_EMPTY_ARRAY; VkDeviceCreateInfo vkDeviceCreateInfo = __EV_VEC_EMPTY_ARRAY;
vkDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; vkDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
void** pNext = &vkDeviceCreateInfo.pNext; void** pNext = (void**)&vkDeviceCreateInfo.pNext;
if(ev_vec_find(&createInfo.deviceExtensions, &VkDynamicRenderingExtName) != -1) for(int i = 0; i < evkSupportedExtensionsCount; i++)
{ {
*pNext = &dynamicRenderingFeature; if(ev_vec_find(&createInfo.deviceExtensions, &evkSupportedExtensions[i].name) != -1)
pNext = &dynamicRenderingFeature.pNext; {
*pNext = evkSupportedExtensions[i].data;
pNext = evkSupportedExtensions[i].ppNext;
}
} }
if(ev_vec_find(&createInfo.deviceExtensions, &VkSync2ExtName) != -1) EVK_ENABLE_EXTENSION_FEATURES(createInfo.deviceExtensions, createInfo.enabledFeatures);
{
*pNext = &sync2Features; VkPhysicalDeviceFeatures2 enabledFeatures = {
pNext = &sync2Features.pNext; .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
} .features = createInfo.enabledFeatures.features10,
.pNext = &createInfo.enabledFeatures.features11,
};
createInfo.enabledFeatures.features11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
createInfo.enabledFeatures.features12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
createInfo.enabledFeatures.features13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
createInfo.enabledFeatures.features11.pNext = &createInfo.enabledFeatures.features12;
createInfo.enabledFeatures.features12.pNext = &createInfo.enabledFeatures.features13;
*pNext = &enabledFeatures;
pNext = NULL;
vkDeviceCreateInfo.enabledExtensionCount = vec_len(&createInfo.deviceExtensions); vkDeviceCreateInfo.enabledExtensionCount = vec_len(&createInfo.deviceExtensions);
vkDeviceCreateInfo.ppEnabledExtensionNames = createInfo.deviceExtensions; vkDeviceCreateInfo.ppEnabledExtensionNames = (const char* const*) createInfo.deviceExtensions;
// Getting the total number of queues requested from the device // Getting the total number of queues requested from the device
u32 totalQueueCount = 0; u32 totalQueueCount = 0;

View File

@@ -3,5 +3,5 @@
#include "evk.h" #include "evk.h"
[[nodiscard("Leaking VkInstance")]] [[nodiscard("Leaking VkInstance")]]
evkInstance evkCreateInstance(evkInstanceCreateInfo); evkInstance evkCreateInstance(evkInstanceCreateInfo instanceCreateInfo);
void evkDestroyInstance(evkInstance); void evkDestroyInstance(evkInstance instance);

View File

@@ -1,5 +1,3 @@
#pragma once
#include "evkMemory.h" #include "evkMemory.h"
evkGPUAllocator evkGPUCreateAllocator(evkDevice device) evkGPUAllocator evkGPUCreateAllocator(evkDevice device)
@@ -7,6 +5,7 @@ evkGPUAllocator evkGPUCreateAllocator(evkDevice device)
VmaVulkanFunctions vmaFunctions = { VmaVulkanFunctions vmaFunctions = {
.vkGetPhysicalDeviceProperties = vkGetPhysicalDeviceProperties, .vkGetPhysicalDeviceProperties = vkGetPhysicalDeviceProperties,
.vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties, .vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties,
.vkGetPhysicalDeviceMemoryProperties2KHR = vkGetPhysicalDeviceMemoryProperties2,
.vkAllocateMemory = vkAllocateMemory, .vkAllocateMemory = vkAllocateMemory,
.vkFreeMemory = vkFreeMemory, .vkFreeMemory = vkFreeMemory,
.vkMapMemory = vkMapMemory, .vkMapMemory = vkMapMemory,
@@ -14,9 +13,13 @@ evkGPUAllocator evkGPUCreateAllocator(evkDevice device)
.vkFlushMappedMemoryRanges = vkFlushMappedMemoryRanges, .vkFlushMappedMemoryRanges = vkFlushMappedMemoryRanges,
.vkInvalidateMappedMemoryRanges = vkInvalidateMappedMemoryRanges, .vkInvalidateMappedMemoryRanges = vkInvalidateMappedMemoryRanges,
.vkBindBufferMemory = vkBindBufferMemory, .vkBindBufferMemory = vkBindBufferMemory,
.vkBindBufferMemory2KHR = vkBindBufferMemory2KHR,
.vkBindImageMemory = vkBindImageMemory, .vkBindImageMemory = vkBindImageMemory,
.vkBindImageMemory2KHR = vkBindImageMemory2KHR,
.vkGetBufferMemoryRequirements = vkGetBufferMemoryRequirements, .vkGetBufferMemoryRequirements = vkGetBufferMemoryRequirements,
.vkGetBufferMemoryRequirements2KHR = vkGetBufferMemoryRequirements2,
.vkGetImageMemoryRequirements = vkGetImageMemoryRequirements, .vkGetImageMemoryRequirements = vkGetImageMemoryRequirements,
.vkGetImageMemoryRequirements2KHR = vkGetImageMemoryRequirements2KHR,
.vkCreateBuffer = vkCreateBuffer, .vkCreateBuffer = vkCreateBuffer,
.vkDestroyBuffer = vkDestroyBuffer, .vkDestroyBuffer = vkDestroyBuffer,
.vkCreateImage = vkCreateImage, .vkCreateImage = vkCreateImage,
@@ -30,10 +33,11 @@ evkGPUAllocator evkGPUCreateAllocator(evkDevice device)
.instance = device._instance.vk, .instance = device._instance.vk,
.vulkanApiVersion = device._instance.apiVersion, .vulkanApiVersion = device._instance.apiVersion,
.pVulkanFunctions = &vmaFunctions, .pVulkanFunctions = &vmaFunctions,
.flags = VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT | VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT,
}; };
evkGPUAllocator alloc; evkGPUAllocator alloc;
vmaCreateAllocator(&createInfo, &alloc.vma); assert(vmaCreateAllocator(&createInfo, &alloc.vma) == VK_SUCCESS);
return alloc; return alloc;
} }
@@ -48,7 +52,7 @@ evkImage evkGPUCreateImage(evkGPUAllocationCreateInfo allocationCreateInfo, VkIm
evkImage img; evkImage img;
VmaAllocationCreateInfo vmaAllocCreateInfo = { VmaAllocationCreateInfo vmaAllocCreateInfo = {
.usage = allocationCreateInfo.memoryUsage, .usage = VMA_MEMORY_USAGE_AUTO,
.flags = allocationCreateInfo.allocationFlags, .flags = allocationCreateInfo.allocationFlags,
.pool = allocationCreateInfo.pool.vma, .pool = allocationCreateInfo.pool.vma,
}; };
@@ -63,17 +67,18 @@ void evkGPUDestroyImage(evkImage img)
vmaDestroyImage(img.allocData.allocator.vma, img.vk, img.allocData.allocation.vma); vmaDestroyImage(img.allocData.allocator.vma, img.vk, img.allocData.allocation.vma);
} }
evkBuffer evkGPUCreateBuffer(evkGPUAllocationCreateInfo allocationCreateInfo, VkBufferCreateInfo* imageCreateInfo) evkBuffer evkGPUCreateBuffer(evkGPUAllocationCreateInfo allocationCreateInfo, VkBufferCreateInfo* bufferCreateInfo)
{ {
evkBuffer buf; evkBuffer buf;
VmaAllocationCreateInfo vmaAllocCreateInfo = { VmaAllocationCreateInfo vmaAllocCreateInfo = {
.usage = allocationCreateInfo.memoryUsage, .usage = VMA_MEMORY_USAGE_AUTO,
.flags = allocationCreateInfo.allocationFlags, .flags = allocationCreateInfo.allocationFlags,
.pool = allocationCreateInfo.pool.vma, .pool = allocationCreateInfo.pool.vma,
}; };
vmaCreateBuffer(allocationCreateInfo.allocator.vma, imageCreateInfo, &vmaAllocCreateInfo, &buf.vk, &buf.allocData.allocation.vma, &buf.allocData.allocationInfo.vma); vmaCreateBuffer(allocationCreateInfo.allocator.vma, bufferCreateInfo, &vmaAllocCreateInfo, &buf.vk, &buf.allocData.allocation.vma, &buf.allocData.allocationInfo.vma);
buf.usage = bufferCreateInfo->usage;
return buf; return buf;
} }

View File

@@ -2,6 +2,7 @@
#include "evk/evkTypes.h" #include "evk/evkTypes.h"
#include "evkShader.h" #include "evkShader.h"
#include "evk/evkVertexLayout.h"
const u32 DESCRIPTOR_SET_LAYOUT_COUNT = 4; const u32 DESCRIPTOR_SET_LAYOUT_COUNT = 4;
@@ -9,8 +10,18 @@ evkPipelineLayout evkCreatePipelineLayout(evkDevice device, evkPipelineLayoutCre
{ {
evkPipelineLayout layout; evkPipelineLayout layout;
vec(VkDescriptorSetLayout) setLayouts = vec_init(VkDescriptorSetLayout);
for(int i = 0; i < vec_len(&createInfo.setLayouts); i++)
vec_push(&setLayouts, &createInfo.setLayouts[i].vk);
VkPipelineLayoutCreateInfo vkCreateInfo = (VkPipelineLayoutCreateInfo) { VkPipelineLayoutCreateInfo vkCreateInfo = (VkPipelineLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.setLayoutCount = vec_len(&setLayouts),
.pSetLayouts = setLayouts,
.pushConstantRangeCount = vec_len(&createInfo.pushConstantRanges),
.pPushConstantRanges = createInfo.pushConstantRanges,
}; };
vkCreatePipelineLayout(device.vk, &vkCreateInfo, NULL, &layout.vk); vkCreatePipelineLayout(device.vk, &vkCreateInfo, NULL, &layout.vk);
@@ -24,13 +35,19 @@ void evkDestroyPipelineLayout(evkDevice device, evkPipelineLayout layout)
} }
evkPipeline evkCreatePipeline(evkDevice device, evkPipelineCreateInfo createInfo) evkPipeline evkCreateComputePipeline(evkDevice device, evkPipelineCreateInfo createInfo)
{
}
evkPipeline evkCreateGraphicsPipeline(evkDevice device, evkPipelineCreateInfo createInfo)
{ {
u32 shaderStageCount = vec_len(&createInfo.shaderStages); u32 shaderStageCount = vec_len(&createInfo.shaderStages);
u32 colorAttachmentCount = vec_len(&createInfo.colorAttachments); u32 colorAttachmentCount = vec_len(&createInfo.colorAttachments);
u32 dynamicStateCount = vec_len(&createInfo.dynamicStates); u32 dynamicStateCount = vec_len(&createInfo.dynamicStates);
evkPipeline res; evkPipeline res;
res.type = createInfo.type;
VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = { VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
@@ -65,7 +82,10 @@ evkPipeline evkCreatePipeline(evkDevice device, evkPipelineCreateInfo createInfo
.attachmentCount = colorAttachmentCount, .attachmentCount = colorAttachmentCount,
.pAttachments = colorAttachmentBlendStates, .pAttachments = colorAttachmentBlendStates,
}; };
memcpy(colorBlending.blendConstants, createInfo.blendConstants, sizeof(f32) * 4); colorBlending.blendConstants[0] = createInfo.blendConstants[0];
colorBlending.blendConstants[1] = createInfo.blendConstants[1];
colorBlending.blendConstants[2] = createInfo.blendConstants[2];
colorBlending.blendConstants[3] = createInfo.blendConstants[3];
u32 viewportCount = createInfo.viewportCountOverride; u32 viewportCount = createInfo.viewportCountOverride;
if(viewportCount == 0 && createInfo.viewports) if(viewportCount == 0 && createInfo.viewports)
@@ -100,10 +120,43 @@ evkPipeline evkCreatePipeline(evkDevice device, evkPipelineCreateInfo createInfo
for(int i = 0; i < vec_len(&createInfo.shaderStages); i++) for(int i = 0; i < vec_len(&createInfo.shaderStages); i++)
shaderStageCreateInfos[i] = evkGetShaderStageCreateInfo(createInfo.shaderStages[i]); shaderStageCreateInfos[i] = evkGetShaderStageCreateInfo(createInfo.shaderStages[i]);
vec(VkVertexInputBindingDescription) binding_descriptions = vec_init(VkVertexInputBindingDescription);
vec(VkVertexInputAttributeDescription) attribute_descriptions = vec_init(VkVertexInputAttributeDescription);
for(int i = 0; i < vec_len(&createInfo.vertexBufferLayouts); i++)
{
evkVertexBufferLayout buf = createInfo.vertexBufferLayouts[i];
int vertexStride = 0;
for(int j = 0; j < EVK_VERTEX_ATTRIBUTE_TYPE_COUNT; j++)
{
evkVertexAttribute attr = buf.attributes[j];
if(attr.fmt == EVK_VERTEX_ATTRIBUTE_INVALID) break;
VkVertexInputAttributeDescription attr_desc = {
.binding = i,
.location = j,
.format = evkVertexAttributeGetVkFormat(attr),
.offset = vertexStride,
};
vec_push(&attribute_descriptions, &attr_desc);
vertexStride += evkVertexAttributeGetSize(attr);
}
VkVertexInputBindingDescription vert_desc = // {0, 8, VK_VERTEX_INPUT_RATE_VERTEX};
{
.inputRate = createInfo.vertexBufferLayouts[i].inputRate,
.binding = i,
.stride = vertexStride,
};
vec_push(&binding_descriptions, &vert_desc);
}
VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = { VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = 0, .vertexBindingDescriptionCount = vec_len(&binding_descriptions),
.vertexAttributeDescriptionCount = 0, .pVertexBindingDescriptions = binding_descriptions,
.vertexAttributeDescriptionCount = vec_len(&attribute_descriptions),
.pVertexAttributeDescriptions = attribute_descriptions,
}; };
/* VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfos[DESCRIPTOR_SET_LAYOUT_COUNT] = {}; */ /* VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfos[DESCRIPTOR_SET_LAYOUT_COUNT] = {}; */
@@ -117,26 +170,34 @@ evkPipeline evkCreatePipeline(evkDevice device, evkPipelineCreateInfo createInfo
/* } */ /* } */
/* } */ /* } */
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfos[4]; // VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfos[4];
//
// svec(VkDescriptorSetLayout) descriptorSetLayouts = svec_init_w_len(VkDescriptorSetLayout, 4);
//
// for(int i = 0; i < 4; i++)
// {
// VkDescriptorSetLayoutCreateInfo dsCreateInfo = {};
//
// // Fill descriptorSetLayoutCreateInfos[i] from shader reflection data + Create descriptorSetLayouts[i]
// }
svec(VkDescriptorSetLayout) descriptorSetLayouts = svec_init_w_len(VkDescriptorSetLayout, 4); if(createInfo.setLayouts != NULL)
for(int i = 0; i < 4; i++)
{ {
VkDescriptorSetLayoutCreateInfo dsCreateInfo = {};
// Fill descriptorSetLayoutCreateInfos[i] from shader reflection data + Create descriptorSetLayouts[i]
}
res.layout = evkCreatePipelineLayout(device, res.layout = evkCreatePipelineLayout(device,
EV_DEFAULT(evkPipelineLayoutCreateInfo, EV_DEFAULT(evkPipelineLayoutCreateInfo,
descriptorSetLayouts = descriptorSetLayouts setLayouts = createInfo.setLayouts,
) )
); );
}
else
{
assert(!"Set Layout construction through shader reflection not implemented yet.");
}
VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = { VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = &pipelineRenderingCreateInfo, .pNext = &pipelineRenderingCreateInfo,
.flags = VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT,
.stageCount = shaderStageCount, .stageCount = shaderStageCount,
.pStages = shaderStageCreateInfos, .pStages = shaderStageCreateInfos,
.pVertexInputState = &vertexInputStateCreateInfo, .pVertexInputState = &vertexInputStateCreateInfo,
@@ -153,11 +214,28 @@ evkPipeline evkCreatePipeline(evkDevice device, evkPipelineCreateInfo createInfo
res._device = device; res._device = device;
vec_fini(&attribute_descriptions);
vec_fini(&binding_descriptions);
return res; return res;
} }
evkPipeline evkCreatePipeline(evkDevice device, evkPipelineCreateInfo createInfo)
{
if(createInfo.type == EVK_PIPELINE_TYPE_GRAPHICS)
return evkCreateGraphicsPipeline(device, createInfo);
else
return evkCreateComputePipeline(device, createInfo);
}
void evkDestroyPipeline(evkPipeline pipeline) void evkDestroyPipeline(evkPipeline pipeline)
{ {
vkDestroyPipeline(pipeline._device.vk, pipeline.vk, NULL); vkDestroyPipeline(pipeline._device.vk, pipeline.vk, NULL);
evkDestroyPipelineLayout(pipeline._device, pipeline.layout); evkDestroyPipelineLayout(pipeline._device, pipeline.layout);
} }
void evkCmdBindPipeline(evkCommandBuffer* cmdbuf, evkPipeline* pipeline)
{
cmdbuf->boundPipeline = pipeline;
vkCmdBindPipeline(cmdbuf->vk, (VkPipelineBindPoint)pipeline->type, pipeline->vk);
}

View File

@@ -8,3 +8,5 @@ void evkDestroyPipelineLayout(evkDevice device, evkPipelineLayout layout);
evkPipeline evkCreatePipeline(evkDevice device, evkPipelineCreateInfo createInfo); evkPipeline evkCreatePipeline(evkDevice device, evkPipelineCreateInfo createInfo);
void evkDestroyPipeline(evkPipeline pipeline); void evkDestroyPipeline(evkPipeline pipeline);
void evkCmdBindPipeline(evkCommandBuffer* cmdbuf, evkPipeline* pipeline);

View File

@@ -1,6 +1,7 @@
#include "evk/evkShader.h" #include "evk/evkShader.h"
#include "shaderc/shaderc.h" #include "shaderc/shaderc.h"
#include "ev_helpers.h" #include "ev_helpers.h"
#include "spirv_reflect.h"
evkShader evkInitShaderFromBytes(evkDevice device, const u8* shaderBytes, u32 shaderLen) evkShader evkInitShaderFromBytes(evkDevice device, const u8* shaderBytes, u32 shaderLen)
{ {
@@ -43,11 +44,12 @@ evkShaderReflectionData evkGenerateShaderReflectionData(const u8* shaderBytes, u
for(int bindingIdx = 0; bindingIdx < currentSet->binding_count; bindingIdx++) for(int bindingIdx = 0; bindingIdx < currentSet->binding_count; bindingIdx++)
{ {
evkDescriptorBinding binding = { evkDescriptorBinding binding = {
.name = evstring_new(currentSet->bindings[bindingIdx]->name),
.stageFlags = res.stage, .stageFlags = res.stage,
.binding = currentSet->bindings[bindingIdx]->binding, .binding = currentSet->bindings[bindingIdx]->binding,
.descriptorType = (VkDescriptorType) currentSet->bindings[bindingIdx]->descriptor_type, .descriptorType = (VkDescriptorType) currentSet->bindings[bindingIdx]->descriptor_type,
.descriptorCount = currentSet->bindings[bindingIdx]->count, .descriptorCount = currentSet->bindings[bindingIdx]->count,
.set = currentSet->set, // .set = currentSet->set,
}; };
vec_push(&res.bindings, &binding); vec_push(&res.bindings, &binding);
@@ -95,6 +97,7 @@ evkShaderCompiler evkCreateShaderCompiler()
compiler.sc = shaderc_compiler_initialize(); compiler.sc = shaderc_compiler_initialize();
compiler.scopt = shaderc_compile_options_initialize(); compiler.scopt = shaderc_compile_options_initialize();
shaderc_compile_options_set_include_callbacks(compiler.scopt, _shader_include_resolve, _shader_include_release, NULL); shaderc_compile_options_set_include_callbacks(compiler.scopt, _shader_include_resolve, _shader_include_release, NULL);
shaderc_compile_options_set_generate_debug_info(compiler.scopt);
return compiler; return compiler;
} }

View File

@@ -2,7 +2,6 @@
#include "evkCommon.h" #include "evkCommon.h"
#include "shaderc/shaderc.h" #include "shaderc/shaderc.h"
#include "spirv_reflect.h"
TYPEDATA_GEN(VkInstance, INVALID(VK_NULL_HANDLE)); TYPEDATA_GEN(VkInstance, INVALID(VK_NULL_HANDLE));
TYPEDATA_GEN(VkDevice, INVALID(VK_NULL_HANDLE)); TYPEDATA_GEN(VkDevice, INVALID(VK_NULL_HANDLE));
@@ -15,14 +14,14 @@ TYPEDATA_GEN(VkCommandBuffer);
TYPEDATA_GEN(VkDynamicState); TYPEDATA_GEN(VkDynamicState);
TYPEDATA_GEN(VkSurfaceFormatKHR); TYPEDATA_GEN(VkSurfaceFormatKHR);
TYPEDATA_GEN(VkFormat); TYPEDATA_GEN(VkFormat);
TYPEDATA_GEN(VkClearValue, DEFAULT(0.f,0.f,0.f,1.f)); TYPEDATA_GEN(VkClearValue, DEFAULT({{0.f,0.f,0.f,1.f}}));
TYPEDATA_GEN(VkRenderingAttachmentInfoKHR, TYPEDATA_GEN(VkRenderingAttachmentInfoKHR,
DEFAULT( DEFAULT(
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,
.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, // Requires VK_KHR_synchronization2 .imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, // Requires VK_KHR_synchronization2
.loadOp = VK_ATTACHMENT_LOAD_OP_NONE_KHR, .loadOp = VK_ATTACHMENT_LOAD_OP_NONE_KHR,
.storeOp = VK_ATTACHMENT_STORE_OP_NONE, .storeOp = VK_ATTACHMENT_STORE_OP_NONE,
.clearValue = (VkClearValue){0.f, 0.f, 0.f, 1.f}, .clearValue = (VkClearValue){{{0.f, 0.f, 0.f, 1.f}}},
) )
); );
TYPEDATA_GEN(VkViewport, TYPEDATA_GEN(VkViewport,
@@ -44,7 +43,7 @@ TYPEDATA_GEN(VkRenderingInfo,
DEFAULT( DEFAULT(
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO, .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
.flags = 0, .flags = 0,
.renderArea = {0, 0, 0, 0}, .renderArea = {{0, 0}, {0, 0}},
.layerCount = 1, .layerCount = 1,
.viewMask = 0, .viewMask = 0,
.colorAttachmentCount = 0, .colorAttachmentCount = 0,
@@ -100,6 +99,9 @@ TYPEDATA_GEN(VkDescriptorSetLayoutCreateInfo,
) )
); );
TYPEDATA_GEN(VkVertexInputBindingDescription);
TYPEDATA_GEN(VkVertexInputAttributeDescription);
// ========================================================================================================= // // ========================================================================================================= //
// =================================evk Types=============================================================== // // =================================evk Types=============================================================== //
// ========================================================================================================= // // ========================================================================================================= //
@@ -116,11 +118,19 @@ typedef struct {
u32 count; u32 count;
} evkDeviceQueueRequirement; } evkDeviceQueueRequirement;
typedef struct {
VkPhysicalDeviceFeatures features10;
VkPhysicalDeviceVulkan11Features features11;
VkPhysicalDeviceVulkan12Features features12;
VkPhysicalDeviceVulkan13Features features13;
} evkPhysicalDeviceFeatures;
typedef struct { typedef struct {
evkInstance instance; evkInstance instance;
VkPhysicalDeviceType physicalDeviceType; VkPhysicalDeviceType physicalDeviceType;
ev_vec(evkDeviceQueueRequirement) queueRequirements; ev_vec(evkDeviceQueueRequirement) queueRequirements;
ev_vec(evstring) deviceExtensions; ev_vec(evstring) deviceExtensions;
evkPhysicalDeviceFeatures enabledFeatures;
} evkDeviceCreateInfo; } evkDeviceCreateInfo;
typedef struct { typedef struct {
@@ -129,9 +139,9 @@ typedef struct {
} evkDeviceQueueFamily; } evkDeviceQueueFamily;
typedef struct { typedef struct {
bool dynamicRendering; VkPhysicalDeviceLimits limits;
bool multiViewport; VkPhysicalDeviceDescriptorBufferPropertiesEXT desc_buf;
} evkPhysicalDeviceFeatures; } evkDeviceProperties;
#define MAX_QUEUE_FAMILIES ((VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT | VK_QUEUE_SPARSE_BINDING_BIT) + 1) #define MAX_QUEUE_FAMILIES ((VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT | VK_QUEUE_SPARSE_BINDING_BIT) + 1)
typedef struct { typedef struct {
@@ -139,7 +149,7 @@ typedef struct {
VkPhysicalDevice _physicalDevice; VkPhysicalDevice _physicalDevice;
evkInstance _instance; evkInstance _instance;
evkDeviceQueueFamily queueFamilies[MAX_QUEUE_FAMILIES]; evkDeviceQueueFamily queueFamilies[MAX_QUEUE_FAMILIES];
VkPhysicalDeviceLimits limits; evkDeviceProperties props;
evkPhysicalDeviceFeatures enabledFeatures; evkPhysicalDeviceFeatures enabledFeatures;
} evkDevice; } evkDevice;
@@ -174,11 +184,6 @@ typedef struct {
VkPipelineLayout vk; VkPipelineLayout vk;
} evkPipelineLayout; } evkPipelineLayout;
typedef struct {
vec(VkDescriptorSetLayout) descriptorSetLayouts;
vec(VkPushConstantRange) pushConstantRanges;
} evkPipelineLayoutCreateInfo;
typedef struct { typedef struct {
VkOffset2D renderOffset; VkOffset2D renderOffset;
VkExtent2D renderExtents; VkExtent2D renderExtents;
@@ -202,14 +207,30 @@ typedef union {
}; };
} evkViewport; } evkViewport;
typedef union { // typedef union {
VkDescriptorSetLayoutBinding vk; // VkDescriptorSetLayoutBinding vk;
struct { // struct {
VkDescriptorSetLayoutBinding; // VkDescriptorSetLayoutBinding;
u32 set; // u32 set;
}; // };
// } evkDescriptorBinding;
// typedef VkDescriptorSetLayoutBinding evkDescriptorBinding;
typedef struct {
evstring name;
VkDescriptorType descriptorType;
VkShaderStageFlags stageFlags;
uint32_t descriptorCount;
const VkSampler* pImmutableSamplers;
uint32_t binding;
} evkDescriptorBinding; } evkDescriptorBinding;
// typedef struct {
// VkDescriptorSetLayout vk;
// vec(evkDescriptorBinding) bindings;
// } evkDescriptorSetLayout;
// typedef VkDescriptorSetLayout evkDescriptorSetLayout;
typedef struct { typedef struct {
VkShaderStageFlags stage; VkShaderStageFlags stage;
vec(evkDescriptorBinding) bindings; vec(evkDescriptorBinding) bindings;
@@ -265,6 +286,7 @@ typedef enum evkGPUMemoryUsage
{ {
EVK_GPU_MEMORY_USAGE_UNKNOWN = VMA_MEMORY_USAGE_UNKNOWN, EVK_GPU_MEMORY_USAGE_UNKNOWN = VMA_MEMORY_USAGE_UNKNOWN,
EVK_GPU_MEMORY_USAGE_GPU_LAZILY_ALLOCATED = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED, EVK_GPU_MEMORY_USAGE_GPU_LAZILY_ALLOCATED = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED,
EVK_GPU_MEMORY_USAGE_CPU_TO_GPU = VMA_MEMORY_USAGE_CPU_TO_GPU,
EVK_GPU_MEMORY_USAGE_AUTO = VMA_MEMORY_USAGE_AUTO, EVK_GPU_MEMORY_USAGE_AUTO = VMA_MEMORY_USAGE_AUTO,
EVK_GPU_MEMORY_USAGE_AUTO_PREFER_DEVICE = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, EVK_GPU_MEMORY_USAGE_AUTO_PREFER_DEVICE = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
EVK_GPU_MEMORY_USAGE_AUTO_PREFER_HOST = VMA_MEMORY_USAGE_AUTO_PREFER_HOST, EVK_GPU_MEMORY_USAGE_AUTO_PREFER_HOST = VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
@@ -277,7 +299,6 @@ typedef struct {
typedef struct { typedef struct {
evkGPUAllocationFlags allocationFlags; evkGPUAllocationFlags allocationFlags;
evkGPUMemoryUsage memoryUsage;
evkGPUAllocator allocator; evkGPUAllocator allocator;
evkGPUMemoryPool pool; evkGPUMemoryPool pool;
} evkGPUAllocationCreateInfo; } evkGPUAllocationCreateInfo;
@@ -315,6 +336,8 @@ typedef struct {
VkBuffer vk; VkBuffer vk;
evkGPUAllocationData allocData; evkGPUAllocationData allocData;
u32 sizeInBytes; u32 sizeInBytes;
VkBufferUsageFlags usage;
VkDeviceAddress address;
} evkBuffer; } evkBuffer;
typedef struct { typedef struct {
@@ -355,7 +378,88 @@ typedef struct {
VkPipelineColorBlendAttachmentState blendState; VkPipelineColorBlendAttachmentState blendState;
} evkColorAttachment; } evkColorAttachment;
typedef enum {
EVK_VERTEX_ATTRIBUTE_INVALID = 0,
EVK_VERTEX_ATTRIBUTE_POSITION,
EVK_VERTEX_ATTRIBUTE_NORMAL,
EVK_VERTEX_ATTRIBUTE_TANGENT,
EVK_VERTEX_ATTRIBUTE_COLOR,
EVK_VERTEX_ATTRIBUTE_UV0,
EVK_VERTEX_ATTRIBUTE_UV1,
EVK_VERTEX_ATTRIBUTE_UV2,
EVK_VERTEX_ATTRIBUTE_UV3,
EVK_VERTEX_ATTRIBUTE_UV4,
EVK_VERTEX_ATTRIBUTE_UV5,
EVK_VERTEX_ATTRIBUTE_UV6,
EVK_VERTEX_ATTRIBUTE_UV7,
EVK_VERTEX_ATTRIBUTE_BLENDWEIGHT,
EVK_VERTEX_ATTRIBUTE_BLENDINDICES,
EVK_VERTEX_ATTRIBUTE_TYPE_COUNT
} evkVertexAttributeType;
typedef enum {
EVK_FMT_INVALID = 0,
EVK_FMT_FLOAT32,
EVK_FMT_UINT32,
EVK_FMT_SINT32,
EVK_FMT_FLOAT16,
EVK_FMT_UNORM16,
EVK_FMT_SNORM16,
EVK_FMT_UINT16,
EVK_FMT_SINT16,
EVK_FMT_UNORM8,
EVK_FMT_SNORM8,
EVK_FMT_UINT8,
EVK_FMT_SINT8,
EVK_VERTEX_ATTRIBUTE_FORMAT_COUNT
} evkVertexAttributeFormat;
typedef struct { typedef struct {
evkVertexAttributeType type;
evkVertexAttributeFormat fmt;
u32 dim;
} evkVertexAttribute;
typedef struct {
evkVertexAttribute attributes[EVK_VERTEX_ATTRIBUTE_TYPE_COUNT];
VkVertexInputRate inputRate;
} evkVertexBufferLayout;
// typedef evkVertexAttribute evkVertexBufferLayout[EVK_VERTEX_ATTRIBUTE_TYPE_COUNT];
typedef struct {
VkDescriptorSetLayout vk;
vec(evstring) names;
vec(VkDescriptorSetLayoutBinding) vkBindings;
u64 size;
u64 offset;
} evkDescriptorSetLayout;
typedef struct {
evkDevice* device;
evkGPUAllocator* allocator;
evkDescriptorSetLayout* layout;
} evkDescriptorSetCreateInfo;
typedef struct {
evkDevice* device;
evkDescriptorSetLayout layout;
evkBuffer buffer;
} evkDescriptorSet;
typedef enum {
EVK_PIPELINE_TYPE_GRAPHICS = VK_PIPELINE_BIND_POINT_GRAPHICS,
EVK_PIPELINE_TYPE_COMPUTE = VK_PIPELINE_BIND_POINT_COMPUTE,
} evkPipelineType;
typedef struct {
vec(evkDescriptorSetLayout) setLayouts;
vec(VkPushConstantRange) pushConstantRanges;
} evkPipelineLayoutCreateInfo;
typedef struct {
evkPipelineType type;
vec(VkDynamicState) dynamicStates; vec(VkDynamicState) dynamicStates;
vec(evkShader) shaderStages; vec(evkShader) shaderStages;
@@ -369,14 +473,25 @@ typedef struct {
u32 viewportCountOverride; u32 viewportCountOverride;
vec(evkViewport) viewports; vec(evkViewport) viewports;
vec(evkVertexBufferLayout) vertexBufferLayouts;
vec(evkDescriptorSetLayout) setLayouts;
} evkPipelineCreateInfo; } evkPipelineCreateInfo;
typedef struct { typedef struct {
VkPipeline vk; VkPipeline vk;
evkPipelineLayout layout; evkPipelineLayout layout;
evkDevice _device; evkDevice _device;
evkPipelineType type;
evkDescriptorSet boundSets[MAX_DESCRIPTOR_SETS];
} evkPipeline; } evkPipeline;
typedef struct {
VkCommandBuffer vk;
bool recording;
evkPipeline* boundPipeline;
} evkCommandBuffer;
TYPEDATA_GEN(evkInstance, TYPEDATA_GEN(evkInstance,
INVALID( INVALID(
.vk = VK_NULL_HANDLE, .vk = VK_NULL_HANDLE,
@@ -387,7 +502,7 @@ TYPEDATA_GEN(evkShader);
TYPEDATA_GEN(evkPipelineLayoutCreateInfo, TYPEDATA_GEN(evkPipelineLayoutCreateInfo,
DEFAULT( DEFAULT(
.descriptorSetLayouts = EV_VEC_EMPTY, .setLayouts = EV_VEC_EMPTY,
.pushConstantRanges = EV_VEC_EMPTY, .pushConstantRanges = EV_VEC_EMPTY,
) )
); );
@@ -435,6 +550,7 @@ TYPEDATA_GEN(evkColorAttachment);
TYPEDATA_GEN(evkPipelineCreateInfo, TYPEDATA_GEN(evkPipelineCreateInfo,
DEFAULT( DEFAULT(
.type = EVK_PIPELINE_TYPE_GRAPHICS,
.dynamicStates = EV_VEC_EMPTY, .dynamicStates = EV_VEC_EMPTY,
.shaderStages = EV_VEC_EMPTY, .shaderStages = EV_VEC_EMPTY,
@@ -445,4 +561,11 @@ TYPEDATA_GEN(evkPipelineCreateInfo,
) )
); );
TYPEDATA_GEN(evkVertexBufferLayout);
TYPEDATA_GEN(evkVertexAttribute);
TYPEDATA_GEN(evkDescriptorBinding); TYPEDATA_GEN(evkDescriptorBinding);
TYPEDATA_GEN(evkDescriptorSetLayout);
TYPEDATA_GEN(evkDescriptorSet);
TYPEDATA_GEN(evkCommandBuffer);

1
evk/evkVertexLayout.c Normal file
View File

@@ -0,0 +1 @@
#include "evkVertexLayout.h"

47
evk/evkVertexLayout.h Normal file
View File

@@ -0,0 +1,47 @@
#pragma once
#include "evk.h"
const static VkFormat evkToVkFmtLUT[][5] = {
[EVK_FMT_INVALID] = { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED , VK_FORMAT_UNDEFINED , VK_FORMAT_UNDEFINED , VK_FORMAT_UNDEFINED },
[EVK_FMT_FLOAT32] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT, VK_FORMAT_R32G32B32A32_SFLOAT },
[EVK_FMT_UINT32] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_UINT , VK_FORMAT_R32G32_UINT , VK_FORMAT_R32G32B32_UINT , VK_FORMAT_R32G32B32A32_UINT },
[EVK_FMT_SINT32] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_SINT , VK_FORMAT_R32G32_SINT , VK_FORMAT_R32G32B32_SINT , VK_FORMAT_R32G32B32A32_SINT },
[EVK_FMT_FLOAT16] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16G16_SFLOAT, VK_FORMAT_R16G16B16_SFLOAT, VK_FORMAT_R16G16B16A16_SFLOAT },
[EVK_FMT_UNORM16] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R16_UNORM , VK_FORMAT_R16G16_UNORM , VK_FORMAT_R16G16B16_UNORM , VK_FORMAT_R16G16B16A16_UNORM },
[EVK_FMT_SNORM16] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R16_SNORM , VK_FORMAT_R16G16_SNORM , VK_FORMAT_R16G16B16_SNORM , VK_FORMAT_R16G16B16A16_SNORM },
[EVK_FMT_UINT16] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R16_UINT , VK_FORMAT_R16G16_UINT , VK_FORMAT_R16G16B16_UINT , VK_FORMAT_R16G16B16A16_UINT },
[EVK_FMT_SINT16] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R16_SINT , VK_FORMAT_R16G16_SINT , VK_FORMAT_R16G16B16_SINT , VK_FORMAT_R16G16B16A16_SINT },
[EVK_FMT_UNORM8] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R8_UNORM , VK_FORMAT_R8G8_UNORM , VK_FORMAT_R8G8B8_UNORM , VK_FORMAT_R8G8B8A8_UNORM },
[EVK_FMT_SNORM8] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R8_SNORM , VK_FORMAT_R8G8_SNORM , VK_FORMAT_R8G8B8_SNORM , VK_FORMAT_R8G8B8A8_SNORM },
[EVK_FMT_UINT8] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R8_UINT , VK_FORMAT_R8G8_UINT , VK_FORMAT_R8G8B8_UINT , VK_FORMAT_R8G8B8A8_UINT },
[EVK_FMT_SINT8] = { VK_FORMAT_UNDEFINED, VK_FORMAT_R8_SINT , VK_FORMAT_R8G8_SINT , VK_FORMAT_R8G8B8_SINT , VK_FORMAT_R8G8B8A8_SINT },
};
const static u32 evkFmtToSizeLUT[][5] = {
[EVK_FMT_INVALID] = { 0, 0, 0, 0, 0 },
[EVK_FMT_FLOAT32] = { 0, 4, 8, 12, 16 },
[EVK_FMT_UINT32] = { 0, 4, 8, 12, 16 },
[EVK_FMT_SINT32] = { 0, 4, 8, 12, 16 },
[EVK_FMT_FLOAT16] = { 0, 2, 4, 6, 8 },
[EVK_FMT_UNORM16] = { 0, 2, 4, 6, 8 },
[EVK_FMT_SNORM16] = { 0, 2, 4, 6, 8 },
[EVK_FMT_UINT16] = { 0, 2, 4, 6, 8 },
[EVK_FMT_SINT16] = { 0, 2, 4, 6, 8 },
[EVK_FMT_UNORM8] = { 0, 1, 2, 3, 4 },
[EVK_FMT_SNORM8] = { 0, 1, 2, 3, 4 },
[EVK_FMT_UINT8] = { 0, 1, 2, 3, 4 },
[EVK_FMT_SINT8] = { 0, 1, 2, 3, 4 },
};
static EV_FORCEINLINE VkFormat evkVertexAttributeGetVkFormat(evkVertexAttribute attr)
{
if(attr.dim > 4) assert(!"Unsupported Vertex Attribute Dimension");
return evkToVkFmtLUT[attr.fmt][attr.dim];
}
static EV_FORCEINLINE u32 evkVertexAttributeGetSize(evkVertexAttribute attr)
{
if(attr.dim > 4) assert(!"Unsupported Vertex Attribute Dimension");
return evkFmtToSizeLUT[attr.fmt][attr.dim];
}

120
main.c
View File

@@ -7,12 +7,6 @@
evstring PROJECT_NAME = evstr("evk"); evstring PROJECT_NAME = evstr("evk");
float vertexPositions[] = {
0.f,-.5f,
.5f, .5f,
-.5f, .5f
};
int main(void) int main(void)
{ {
u32 width = 1024; u32 width = 1024;
@@ -51,6 +45,7 @@ int main(void)
evstr("VK_KHR_synchronization2"), evstr("VK_KHR_synchronization2"),
evstr("VK_KHR_buffer_device_address"), evstr("VK_KHR_buffer_device_address"),
evstr("VK_EXT_descriptor_indexing"), evstr("VK_EXT_descriptor_indexing"),
evstr("VK_EXT_descriptor_buffer"),
}), }),
}); });
@@ -85,6 +80,8 @@ int main(void)
puts("Surface creation failed."); puts("Surface creation failed.");
} }
evkGPUAllocator allocator = evkGPUCreateAllocator(device);
evkSwapChain swapChain = evkCreateSwapChain((evkSwapChainCreateInfo){ evkSwapChain swapChain = evkCreateSwapChain((evkSwapChainCreateInfo){
.device = device, .device = device,
.surface = surface, .surface = surface,
@@ -99,7 +96,7 @@ int main(void)
.poolFlags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT .poolFlags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
}); });
vec(VkCommandBuffer) commandBuffers = evkAllocateCommandBuffers(device, commandPool, vec_len(&swapChain.images), true); vec(evkCommandBuffer) commandBuffers = evkAllocateCommandBuffers(device, commandPool, vec_len(&swapChain.images), true);
evkShaderCompiler compiler = evkCreateShaderCompiler(); evkShaderCompiler compiler = evkCreateShaderCompiler();
@@ -113,6 +110,21 @@ int main(void)
EV_DEFAULT(VkPipelineColorBlendAttachmentState) EV_DEFAULT(VkPipelineColorBlendAttachmentState)
}; };
// TODO Get this from shader reflection data
// evkDescriptorSetLayout setLayout_0 = evkCreateDescriptorSetLayout(
// &device, svec_init(evkDescriptorBinding, {
// {
// .name = evstr("positions"),
// .binding = 0,
// .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
// .descriptorCount = 1,
// .stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS,
// },
// })
// );
// evkDescriptorSetLayout setLayout_0 = evkCreateDescriptorSetLayoutFromBindings(&device, vertShader.reflect.bindings);
evkDescriptorSetLayout setLayout_0 = evkCreateDescriptorSetLayoutFromShaders(&device, svec_init(evkShader, {vertShader, fragShader}));
evkPipelineCreateInfo pipelineCreateInfo = EV_DEFAULT(evkPipelineCreateInfo, evkPipelineCreateInfo pipelineCreateInfo = EV_DEFAULT(evkPipelineCreateInfo,
dynamicStates = svec_init(VkDynamicState, { dynamicStates = svec_init(VkDynamicState, {
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_VIEWPORT,
@@ -126,8 +138,64 @@ int main(void)
colorAttachment0, colorAttachment0,
}), }),
viewportCountOverride = 1, viewportCountOverride = 1,
vertexBufferLayouts = svec_init(evkVertexBufferLayout, {
{{ // VB #0
{ EVK_VERTEX_ATTRIBUTE_POSITION, EVK_FMT_FLOAT32, 2 },
}},
}),
setLayouts = svec_init(evkDescriptorSetLayout, {setLayout_0}),
); );
evkDescriptorSet set_0 = evkCreateDescriptorSet(&(evkDescriptorSetCreateInfo){
.device = &device,
.allocator = &allocator,
.layout = &setLayout_0
});
// // if stageflags is 0, it's all graphics
// // if descriptor count is 0, it's 1
// // if
// evkDescriptorSetLayout set_0 = evkCreateDescriptorSetLayout(&device, svec_init(evkDescriptorBinding, {
// { "positions", VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER },
// })
// );
evkBuffer vertBuf = evkCreateBuffer(&device, (evkBufferCreateInfo) {
.queueFamilyIndices = svec_init(u32, {device.queueFamilies[VK_QUEUE_GRAPHICS_BIT].familyIndex}),
.sizeInBytes = 6 * 4,
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.allocationCreateInfo = {
.allocationFlags = EVK_GPU_ALLOCATION_CREATE_MAPPED_BIT | EVK_GPU_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.allocator = allocator,
},
.exclusive = true,
});
evkBuffer uniBuf = evkCreateBuffer(&device, (evkBufferCreateInfo) {
.sizeInBytes = 12 * 4,
.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.allocationCreateInfo = {
.allocationFlags = EVK_GPU_ALLOCATION_CREATE_MAPPED_BIT | EVK_GPU_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.allocator = allocator,
},
.exclusive = true,
});
float* vert_arr = (float*)vertBuf.allocData.allocationInfo.vma.pMappedData;
vert_arr[0] = 0.0f; vert_arr[1] = -0.5f;
vert_arr[2] = 0.5f; vert_arr[3] = 0.5f;
vert_arr[4] = -0.5f; vert_arr[5] = 0.5f;
float* uni_arr = (float*)uniBuf.allocData.allocationInfo.vma.pMappedData;
uni_arr[0] = 0.0f; uni_arr[1] = -0.5f; uni_arr[2] = 0.0f; uni_arr[3] = 1.0f;
uni_arr[4] = 0.5f; uni_arr[5] = 0.5f; uni_arr[6] = 0.0f; uni_arr[7] = 1.0f;
uni_arr[8] = -0.5f; uni_arr[9] = 0.5f; uni_arr[10] = 0.0f; uni_arr[11] = 1.0f;
evkSetDescriptor(&set_0, evstr("vertexData"), &uniBuf);
VkViewport viewport = EV_DEFAULT(VkViewport, width=width, height=height); VkViewport viewport = EV_DEFAULT(VkViewport, width=width, height=height);
VkRect2D scissor = EV_DEFAULT(VkRect2D,extent.width=width, extent.height=height); VkRect2D scissor = EV_DEFAULT(VkRect2D,extent.width=width, extent.height=height);
@@ -142,7 +210,7 @@ int main(void)
u32 imageIdx; u32 imageIdx;
vkAcquireNextImageKHR(device.vk, swapChain.vk, UInt64.MAX, imageAcquiredSemaphore, VK_NULL_HANDLE, &imageIdx); vkAcquireNextImageKHR(device.vk, swapChain.vk, UInt64.MAX, imageAcquiredSemaphore, VK_NULL_HANDLE, &imageIdx);
VkCommandBuffer cmdbuf = commandBuffers[imageIdx]; evkCommandBuffer cmdbuf = commandBuffers[imageIdx];
VkRenderingAttachmentInfoKHR colorAttachment = EV_DEFAULT(VkRenderingAttachmentInfoKHR, VkRenderingAttachmentInfoKHR colorAttachment = EV_DEFAULT(VkRenderingAttachmentInfoKHR,
imageView = swapChain.imageViews[imageIdx].vk, imageView = swapChain.imageViews[imageIdx].vk,
@@ -156,17 +224,22 @@ int main(void)
colorAttachmentCount = 1, colorAttachmentCount = 1,
); );
evkBeginPrimaryCommandBuffer(cmdbuf); evkBeginPrimaryCommandBuffer(&cmdbuf);
{
VkDeviceSize offset = 0;
vkCmdBindVertexBuffers(cmdbuf.vk, 0, 1, &vertBuf.vk, &offset);
vkCmdSetScissor(cmdbuf, 0, 1, &scissor); evkCmdBindDescriptorSets(&cmdbuf, &graphicsPipeline, svec_init(evkDescriptorSet, { set_0 }), svec_init(u32, { 0 }));
vkCmdSetViewport(cmdbuf, 0, 1, &viewport);
vkCmdBeginRenderingKHR(cmdbuf, &renderingInfo); vkCmdSetScissor(cmdbuf.vk, 0, 1, &scissor);
vkCmdSetViewport(cmdbuf.vk, 0, 1, &viewport);
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.vk); vkCmdBeginRenderingKHR(cmdbuf.vk, &renderingInfo);
vkCmdDraw(cmdbuf, 3, 1, 0, 0);
vkCmdEndRenderingKHR(cmdbuf); evkCmdBindPipeline(&cmdbuf, &graphicsPipeline);
vkCmdDraw(cmdbuf.vk, 3, 1, 0, 0);
vkCmdEndRenderingKHR(cmdbuf.vk);
VkImageMemoryBarrier imageMemoryBarrier = { VkImageMemoryBarrier imageMemoryBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
@@ -179,15 +252,15 @@ int main(void)
}, },
}; };
vkCmdPipelineBarrier(cmdbuf, 0, 0, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier); vkCmdPipelineBarrier(cmdbuf.vk, 0, 0, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier);
}
evkEndCommandBuffer(cmdbuf); evkEndCommandBuffer(&cmdbuf);
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
VkSubmitInfo submitInfo = { VkSubmitInfo submitInfo = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pCommandBuffers = &cmdbuf, .pCommandBuffers = &cmdbuf, // TODO This won't work with more than a single cmdbuf
.commandBufferCount = 1, .commandBufferCount = 1,
.waitSemaphoreCount = 1, .waitSemaphoreCount = 1,
.pWaitSemaphores = &imageAcquiredSemaphore, .pWaitSemaphores = &imageAcquiredSemaphore,
@@ -210,7 +283,7 @@ int main(void)
}; };
vkQueuePresentKHR(graphicsQueue, &presentInfo); vkQueuePresentKHR(graphicsQueue, &presentInfo);
vkResetCommandBuffer(cmdbuf,VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); vkResetCommandBuffer(cmdbuf.vk,VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
// Main Loop // Main Loop
glfwPollEvents(); glfwPollEvents();
@@ -224,15 +297,18 @@ int main(void)
evkDestroyPipeline(graphicsPipeline); evkDestroyPipeline(graphicsPipeline);
evkDestroyDescriptorSet(&device, &set_0);
evkDestroyDescriptorSetLayout(&device, &setLayout_0);
evkDestroyShader(device, vertShader); evkDestroyShader(device, vertShader);
evkDestroyShader(device, fragShader); evkDestroyShader(device, fragShader);
vkFreeCommandBuffers(device.vk, commandPool.vk, vec_len(&commandBuffers), commandBuffers); evkFreeCommandBuffers(device, commandPool, commandBuffers);
evkDestroyCommandPool(device, commandPool); evkDestroyCommandPool(device, commandPool);
evkDestroySwapChain(device, swapChain); evkDestroySwapChain(device, swapChain);
SwapchainCreationFailed: // SwapchainCreationFailed:
vkDestroySurfaceKHR(instance.vk, swapChain.surface, NULL); vkDestroySurfaceKHR(instance.vk, swapChain.surface, NULL);
VKSurfaceCreationFailed: VKSurfaceCreationFailed:

View File

@@ -5,4 +5,7 @@ cpp = 'clang++.exe'
cpp_ld = 'lld' cpp_ld = 'lld'
[properties] [properties]
c_args = ['-DEV_CC_CLANG=1'] c_args = ['-DEV_CC_CLANG=1','-fcolor-diagnostics', '-fansi-escape-codes']
[cmake]
CMAKE_C_COMPILER = 'clang.exe'

View File

@@ -1,6 +1,6 @@
project('evk', ['c','cpp'], project('evk', ['c','cpp'],
version : '0.1', version : '0.1',
default_options : ['c_std=gnu23']) default_options : ['c_std=gnu23', 'default_library=static'])
build_config = configuration_data() build_config = configuration_data()
@@ -15,6 +15,12 @@ endif
configure_file(output: 'evk_buildconfig.h', configuration: build_config) configure_file(output: 'evk_buildconfig.h', configuration: build_config)
disabled_warnings = {
'clang': [
'microsoft-anon-tag',
],
}
subproject('evol-headers') subproject('evol-headers')
evh_c_args = [] evh_c_args = []
@@ -26,6 +32,10 @@ elif cc.get_id() == 'clang'
evh_c_args += '-DEV_CC_CLANG=1' evh_c_args += '-DEV_CC_CLANG=1'
endif endif
foreach w : disabled_warnings[cc.get_id()]
evh_c_args += '-Wno-'+w
endforeach
evk_incdir = [ evk_incdir = [
'.', '.',
] ]
@@ -45,6 +55,7 @@ evk_src = [
'evk/evkDescriptor.c', 'evk/evkDescriptor.c',
'evk/evkRender.c', 'evk/evkRender.c',
'evk/evkImage.c', 'evk/evkImage.c',
'evk/evkBuffer.c',
'evk/evkMemory.c', 'evk/evkMemory.c',
] ]

View File

@@ -1,15 +1,15 @@
#version 450 #version 450
#pragma shader_stage(vertex) #pragma shader_stage(vertex)
vec2 positions[3] = vec2[](
vec2(0.0, -0.5),
vec2(0.5, 0.5),
vec2(-0.5, 0.5)
);
// in layout(location=0) vec2 position; // in layout(location=0) vec2 position;
layout(set=0, binding=0) uniform data {
vec4 positions[3];
} vertexData;
void main() { void main() {
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); // gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
// gl_Position = vec4(position, 0.0, 1.0); // gl_Position = vec4(position, 0.0, 1.0);
// gl_Position = vec4(inputData.positions[gl_VertexIndex], 0.0, 1.0);
gl_Position = vertexData.positions[gl_VertexIndex];
} }

View File

@@ -1,13 +1,11 @@
[wrap-file] [wrap-git]
directory = glfw-3.3.10 directory = glfw
source_url = https://github.com/glfw/glfw/archive/refs/tags/3.3.10.tar.gz
source_filename = glfw-3.3.10.tar.gz url = https://github.com/glfw/glfw
source_hash = 4ff18a3377da465386374d8127e7b7349b685288cb8e17122f7e1179f73769d5 revision = 3.3.10
patch_filename = glfw_3.3.10-1_patch.zip depth=1
patch_url = https://wrapdb.mesonbuild.com/v2/glfw_3.3.10-1/get_patch
patch_hash = 3567f96c2576a5fc8c9cafd9059f919d7da404f6c22450c6c2ce3f9938909b8b patch_directory = glfw
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/glfw_3.3.10-1/glfw-3.3.10.tar.gz
wrapdb_version = 3.3.10-1
[provide] [provide]
glfw3 = glfw_dep glfw3 = glfw_dep

View File

@@ -0,0 +1,145 @@
# Modified Meson WrapDB file
project(
'glfw',
'c',
version: '3.3.10',
license: 'Zlib',
default_options: ['b_ndebug=if-release', 'c_std=c99', 'warning_level=0'],
meson_version: '>=0.58.0',
)
#@ Project variables
sys_os = host_machine.system()
sys_cc = meson.get_compiler('c')
opt_libdir = get_option('libdir')
is_posix = sys_os != 'windows'
if get_option('default_library') != 'static'
add_project_arguments('-D_GLFW_BUILD_DLL', language: 'c')
endif
if sys_os == 'windows'
opt_display = 'win32'
elif sys_os == 'darwin'
opt_display = 'cocoa'
else
opt_display = 'x11'
endif
### Dependencies ###
deps = []
#@ Backend API
# X11
if opt_display == 'x11'
foreach x : ['x11', 'xrandr', 'xinerama', 'xcursor', 'xi', 'xkbcommon']
deps += dependency(x, required: true)
endforeach
# Win32
elif opt_display == 'win32'
if sys_os != 'windows'
error('Non Windows is unsupportred')
endif
# Cocoa
elif opt_display == 'cocoa'
if sys_os != 'darwin'
error('Non macOS is unsupported')
endif
deps += dependency('appleframeworks', modules: ['Cocoa', 'CoreFoundation', 'IOKit'])
endif
#@ System Dependencies
foreach l : ['m', 'rt']
deps += sys_cc.find_library(l, required: false)
endforeach
if meson.version().version_compare('>= 0.62')
deps += dependency('dl', required: false)
else
deps += sys_cc.find_library('dl', required: false)
endif
deps += dependency('threads')
### Configuration ###
cfg_data = configuration_data()
foreach d : ['osmesa', 'x11', 'wayland', 'win32', 'cocoa']
cfg_data.set('_GLFW_' + d.to_upper(), opt_display == d)
endforeach
cfg_file = configure_file(configuration: cfg_data, output: 'glfw_config.h')
### Targets ###
#@ Primary target:
## GLFW library
# Common files
s_common = files('src/context.c', 'src/init.c', 'src/input.c', 'src/monitor.c', 'src/vulkan.c', 'src/window.c')
s_common += cfg_file
# Backend files
if opt_display == 'x11'
s_display = files(
'src/egl_context.c',
'src/glx_context.c',
'src/osmesa_context.c',
'src/posix_thread.c',
'src/posix_time.c',
'src/x11_init.c',
'src/x11_monitor.c',
'src/x11_window.c',
'src/xkb_unicode.c',
'src/@0@_joystick.c'.format(sys_os == 'linux' ? 'linux' : 'null'),
)
elif opt_display == 'win32'
s_display = files(
'src/egl_context.c',
'src/osmesa_context.c',
'src/wgl_context.c',
'src/win32_init.c',
'src/win32_joystick.c',
'src/win32_monitor.c',
'src/win32_thread.c',
'src/win32_time.c',
'src/win32_window.c',
)
elif opt_display == 'cocoa'
add_languages('objc', native: false)
s_display = files(
'src/cocoa_init.m',
'src/cocoa_joystick.m',
'src/cocoa_monitor.m',
'src/cocoa_time.c',
'src/cocoa_window.m',
'src/egl_context.c',
'src/nsgl_context.m',
'src/osmesa_context.c',
'src/posix_thread.c',
)
add_project_arguments('-D_GLFW_USE_CONFIG_H', language: 'objc')
if host_machine.system() == 'darwin'
add_project_arguments('-D_DARWIN_C_SOURCE', language: 'objc')
endif
endif
srcfiles = [s_common, s_display]
incdirs = include_directories('include', 'src')
#@ Flags
add_project_arguments('-D_GLFW_USE_CONFIG_H', language: 'c')
if host_machine.system() == 'darwin'
add_project_arguments('-D_DARWIN_C_SOURCE', language: 'c')
endif
c_args = ['-Wno-everything']
# Build
glfw_lib = library(
'glfw3',
srcfiles,
include_directories: incdirs,
dependencies: deps,
version: meson.project_version(),
build_by_default: true,
pic: true,
c_args: c_args,
)
glfw_dep = declare_dependency(
include_directories: incdirs,
link_with: glfw_lib,
)
meson.override_dependency('glfw3', glfw_dep)

View File

@@ -1,13 +1,27 @@
project('libshaderc', 'cpp', default_options: ['buildtype=release']) project('libshaderc', 'cpp')
fs = import('fs') python = find_program('python3')
cxxc = meson.get_compiler('cpp') run_command(python, './utils/git-sync-deps', check: true)
shaderc_inc = include_directories('install/include')
shaderc_dep = declare_dependency(
dependencies: cxxc.find_library('shaderc_combined', dirs: meson.current_source_dir()/'install/lib'),
include_directories: shaderc_inc,
)
cmake = import('cmake')
opts = cmake.subproject_options()
opts.add_cmake_defines({
'CMAKE_MSVC_RUNTIME_LIBRARY': 'MultiThreaded',
'CMAKE_POLICY_DEFAULT_CMP0091': 'NEW',
'SHADERC_SKIP_INSTALL': 'ON',
'SHADERC_SKIP_TESTS': 'ON',
'SHADERC_SKIP_EXAMPLES': 'ON',
'SHADERC_SKIP_COPYRIGHT_CHECK': 'ON'
})
shaderc_proj = cmake.subproject('shaderc', options: opts)
shaderc_dep = declare_dependency(dependencies: [
shaderc_proj.dependency('shaderc'),
shaderc_proj.dependency('shaderc_util'),
shaderc_proj.dependency('SPIRV'),
shaderc_proj.dependency('SPIRV-Tools-static'),
shaderc_proj.dependency('SPIRV-Tools-opt'),
shaderc_proj.dependency('glslang'),
shaderc_proj.dependency('GenericCodeGen'),
shaderc_proj.dependency('MachineIndependent'),
])
meson.override_dependency('shaderc', shaderc_dep) meson.override_dependency('shaderc', shaderc_dep)

View File

@@ -0,0 +1,13 @@
project('libshaderc', 'cpp', default_options: ['buildtype=release', 'default_library=static'])
fs = import('fs')
cxxc = meson.get_compiler('cpp')
shaderc_inc = include_directories('install/include')
shaderc_dep = declare_dependency(
dependencies: cxxc.find_library('shaderc_combined', dirs: meson.current_source_dir()/'install/lib'),
include_directories: shaderc_inc,
)
meson.override_dependency('shaderc', shaderc_dep)

View File

@@ -0,0 +1 @@
project('shaderc_cmake', 'cpp')

View File

@@ -1,4 +1,7 @@
#define VMA_STATIC_VULKAN_FUNCTIONS 0 #define VMA_STATIC_VULKAN_FUNCTIONS 0
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 0
#define VMA_IMPLEMENTATION #define VMA_IMPLEMENTATION
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Weverything"
#include <vk_mem_alloc.h> #include <vk_mem_alloc.h>
#pragma clang diagnostic pop

View File

@@ -0,0 +1,10 @@
[wrap-git]
directory = shaderc_cmake
url = https://github.com/google/shaderc
revision = v2024.4
depth=1
patch_directory = shaderc_cmake
[provide]
dependency_names = shaderc_cmake

View File

@@ -1,12 +1,12 @@
[wrap-file] [wrap-file]
directory = libshaderc directory = libshaderc_old
source_url = https://storage.googleapis.com/shaderc/artifacts/prod/graphics_shader_compiler/shaderc/windows/continuous_release_2019/64/20241106-090939/install.zip source_url = https://storage.googleapis.com/shaderc/artifacts/prod/graphics_shader_compiler/shaderc/windows/continuous_release_2019/64/20241106-090939/install.zip
source_filename = libshaderc-upstream-msvc.zip source_filename = libshaderc-upstream-msvc.zip
source_hash = a6879869e580d5991ebd9909f3665d1f6fe39cdb9830adf4f48b35dfd3782a78 source_hash = a6879869e580d5991ebd9909f3665d1f6fe39cdb9830adf4f48b35dfd3782a78
lead_directory_missing = libshaderc lead_directory_missing = libshaderc
patch_directory = libshaderc patch_directory = libshaderc_old
[provide] [provide]
dependency_names = shaderc dependency_names = shaderc_old