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 "evkCommand.h"
#include "evkPipeline.h"
#include "evkMemory.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"
evkBuffer evkCreateBuffer(evkBufferCreateInfo createInfo)
evkBuffer evkCreateBuffer(evkDevice* device, evkBufferCreateInfo createInfo)
{
VkBufferCreateInfo bufferCreateInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
@@ -9,8 +9,9 @@ evkBuffer evkCreateBuffer(evkBufferCreateInfo createInfo)
.flags = createInfo.flags,
.usage = createInfo.usage,
.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,
.size = createInfo.sizeInBytes,
};
evkBuffer buffer = evkGPUCreateBuffer(createInfo.allocationCreateInfo, &bufferCreateInfo);
@@ -18,6 +19,10 @@ evkBuffer evkCreateBuffer(evkBufferCreateInfo createInfo)
if(buffer.vk != VK_NULL_HANDLE)
{
buffer.sizeInBytes = createInfo.sizeInBytes;
buffer.address = vkGetBufferDeviceAddressKHR(device->vk, &(VkBufferDeviceAddressInfo){
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = buffer.vk
});
}
return buffer;

View File

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

View File

@@ -20,10 +20,9 @@ void evkDestroyCommandPool(evkDevice device, evkCommandPool commandPool)
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);
vec_setlen(&buffers, count);
VkCommandBuffer vkBuffers[count];
VkCommandBufferAllocateInfo allocateInfo = (VkCommandBufferAllocateInfo) {
.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,
};
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;
}
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) {
.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);
[[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 evkEndCommandBuffer(VkCommandBuffer cmdBuf);
void evkFreeCommandBuffers(evkDevice device, evkCommandPool pool, vec(evkCommandBuffer) commandBuffers);
void evkBeginPrimaryCommandBuffer(evkCommandBuffer* cmdBuf);
void evkEndCommandBuffer(evkCommandBuffer* cmdBuf);

View File

@@ -10,4 +10,5 @@
#define EV_VEC_SHORTNAMES
#include <ev_vec.h>
#include "evkConstants.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 "evkBuffer.h"
#include "evkCommand.h"
typedef struct {
VkDescriptorSetLayout descriptorSetLayouts[4];
} evkSetLayout;
evkSetLayout evkCreateDescriptorSetLayouts(vec(evkShader) shaders)
EV_FORCEINLINE uint32_t aligned_size(uint32_t value, uint32_t alignment)
{
VkDescriptorSetLayoutCreateInfo createInfos[4];
for(int i = 0; i < 4; i++)
{
createInfos[i] = EV_DEFAULT(
VkDescriptorSetLayoutCreateInfo,
pBindings = vec_init(VkDescriptorSetLayoutBinding)
);
}
return (value + alignment - 1) & ~(alignment - 1);
}
for(int i = 0; i < vec_len(&shaders); i++)
VkBufferUsageFlags evkGetDescriptorSetBufferUsageFlags(evkDescriptorSetLayout* layout)
{
VkBufferUsageFlags flags = 0;
for(int i = 0; i < vec_len(&layout->vkBindings); i++)
{
vec(evkDescriptorBinding) bindings = shaders[i].reflect.bindings;
for(int bi = 0; bi < vec_len(&bindings); bi++)
VkDescriptorType type = layout->vkBindings[i].descriptorType;
if(type == VK_DESCRIPTOR_TYPE_SAMPLER)
{
evkDescriptorBinding b = bindings[bi];
if(b.binding >= vec_len(&createInfos[b.set].pBindings))
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)
{
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 */
}
flags |= VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT;
break;
}
}
}
for(int i = 0; i < 4; i++)
{
createInfos[i].bindingCount = vec_len(&createInfos[i].pBindings);
}
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++)
{
vec_append(&bindings, &shaders[i].reflect.bindings, vec_len(&shaders[i].reflect.bindings));
}
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;
}
void evkSetDescriptor(evkDescriptorSet* set, evstring name, evkBuffer* buf)
{
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"
// 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 "evkAllocator.h"
evstring VkDynamicRenderingExtName = evstr("VK_KHR_dynamic_rendering");
evstring VkSync2ExtName = evstr("VK_KHR_synchronization2");
#define SUPPORTED_EXTENSION_FEATURE_PAIRS \
(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) {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR,
.dynamicRendering = VK_TRUE,
#define EVK_ENABLE_EXTENSION_FEATURES(enabledExtensions,featuresStruct) \
EV_FOREACH_UDATA(EVK_ENABLE_EXTENSION_FEATURE, (enabledExtensions, featuresStruct), SUPPORTED_EXTENSION_FEATURE_PAIRS)
#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) {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES,
.synchronization2 = VK_TRUE,
typedef struct {
evstring name;
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)
{
@@ -48,9 +71,22 @@ evkDevice evkCreateDevice(evkDeviceCreateInfo createInfo)
device._physicalDevice = evkDetectPhysicalDevice(createInfo.instance, createInfo.physicalDeviceType);
device._instance = createInfo.instance;
VkPhysicalDeviceProperties physicalDeviceProperties;
vkGetPhysicalDeviceProperties(device._physicalDevice, &physicalDeviceProperties);
device.limits = physicalDeviceProperties.limits;
VkPhysicalDeviceProperties2 physicalDeviceProperties = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
};
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++) {
device.queueFamilies[i] = (evkDeviceQueueFamily){
@@ -61,22 +97,34 @@ evkDevice evkCreateDevice(evkDeviceCreateInfo createInfo)
VkDeviceCreateInfo vkDeviceCreateInfo = __EV_VEC_EMPTY_ARRAY;
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;
pNext = &dynamicRenderingFeature.pNext;
if(ev_vec_find(&createInfo.deviceExtensions, &evkSupportedExtensions[i].name) != -1)
{
*pNext = evkSupportedExtensions[i].data;
pNext = evkSupportedExtensions[i].ppNext;
}
}
if(ev_vec_find(&createInfo.deviceExtensions, &VkSync2ExtName) != -1)
{
*pNext = &sync2Features;
pNext = &sync2Features.pNext;
}
EVK_ENABLE_EXTENSION_FEATURES(createInfo.deviceExtensions, createInfo.enabledFeatures);
VkPhysicalDeviceFeatures2 enabledFeatures = {
.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.ppEnabledExtensionNames = createInfo.deviceExtensions;
vkDeviceCreateInfo.ppEnabledExtensionNames = (const char* const*) createInfo.deviceExtensions;
// Getting the total number of queues requested from the device
u32 totalQueueCount = 0;

View File

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

View File

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

View File

@@ -2,6 +2,7 @@
#include "evk/evkTypes.h"
#include "evkShader.h"
#include "evk/evkVertexLayout.h"
const u32 DESCRIPTOR_SET_LAYOUT_COUNT = 4;
@@ -9,8 +10,18 @@ evkPipelineLayout evkCreatePipelineLayout(evkDevice device, evkPipelineLayoutCre
{
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) {
.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);
@@ -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 colorAttachmentCount = vec_len(&createInfo.colorAttachments);
u32 dynamicStateCount = vec_len(&createInfo.dynamicStates);
evkPipeline res;
res.type = createInfo.type;
VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
@@ -65,7 +82,10 @@ evkPipeline evkCreatePipeline(evkDevice device, evkPipelineCreateInfo createInfo
.attachmentCount = colorAttachmentCount,
.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;
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++)
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 = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = 0,
.vertexAttributeDescriptionCount = 0,
.vertexBindingDescriptionCount = vec_len(&binding_descriptions),
.pVertexBindingDescriptions = binding_descriptions,
.vertexAttributeDescriptionCount = vec_len(&attribute_descriptions),
.pVertexAttributeDescriptions = attribute_descriptions,
};
/* 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);
for(int i = 0; i < 4; i++)
if(createInfo.setLayouts != NULL)
{
VkDescriptorSetLayoutCreateInfo dsCreateInfo = {};
// Fill descriptorSetLayoutCreateInfos[i] from shader reflection data + Create descriptorSetLayouts[i]
res.layout = evkCreatePipelineLayout(device,
EV_DEFAULT(evkPipelineLayoutCreateInfo,
setLayouts = createInfo.setLayouts,
)
);
}
else
{
assert(!"Set Layout construction through shader reflection not implemented yet.");
}
res.layout = evkCreatePipelineLayout(device,
EV_DEFAULT(evkPipelineLayoutCreateInfo,
descriptorSetLayouts = descriptorSetLayouts
)
);
VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = &pipelineRenderingCreateInfo,
.flags = VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT,
.stageCount = shaderStageCount,
.pStages = shaderStageCreateInfos,
.pVertexInputState = &vertexInputStateCreateInfo,
@@ -153,11 +214,28 @@ evkPipeline evkCreatePipeline(evkDevice device, evkPipelineCreateInfo createInfo
res._device = device;
vec_fini(&attribute_descriptions);
vec_fini(&binding_descriptions);
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)
{
vkDestroyPipeline(pipeline._device.vk, pipeline.vk, NULL);
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);
void evkDestroyPipeline(evkPipeline pipeline);
void evkCmdBindPipeline(evkCommandBuffer* cmdbuf, evkPipeline* pipeline);

View File

@@ -1,6 +1,7 @@
#include "evk/evkShader.h"
#include "shaderc/shaderc.h"
#include "ev_helpers.h"
#include "spirv_reflect.h"
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++)
{
evkDescriptorBinding binding = {
.name = evstring_new(currentSet->bindings[bindingIdx]->name),
.stageFlags = res.stage,
.binding = currentSet->bindings[bindingIdx]->binding,
.descriptorType = (VkDescriptorType) currentSet->bindings[bindingIdx]->descriptor_type,
.descriptorCount = currentSet->bindings[bindingIdx]->count,
.set = currentSet->set,
// .set = currentSet->set,
};
vec_push(&res.bindings, &binding);
@@ -95,6 +97,7 @@ evkShaderCompiler evkCreateShaderCompiler()
compiler.sc = shaderc_compiler_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_generate_debug_info(compiler.scopt);
return compiler;
}

View File

@@ -2,7 +2,6 @@
#include "evkCommon.h"
#include "shaderc/shaderc.h"
#include "spirv_reflect.h"
TYPEDATA_GEN(VkInstance, INVALID(VK_NULL_HANDLE));
TYPEDATA_GEN(VkDevice, INVALID(VK_NULL_HANDLE));
@@ -15,14 +14,14 @@ TYPEDATA_GEN(VkCommandBuffer);
TYPEDATA_GEN(VkDynamicState);
TYPEDATA_GEN(VkSurfaceFormatKHR);
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,
DEFAULT(
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,
.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, // Requires VK_KHR_synchronization2
.loadOp = VK_ATTACHMENT_LOAD_OP_NONE_KHR,
.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,
@@ -44,7 +43,7 @@ TYPEDATA_GEN(VkRenderingInfo,
DEFAULT(
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
.flags = 0,
.renderArea = {0, 0, 0, 0},
.renderArea = {{0, 0}, {0, 0}},
.layerCount = 1,
.viewMask = 0,
.colorAttachmentCount = 0,
@@ -100,6 +99,9 @@ TYPEDATA_GEN(VkDescriptorSetLayoutCreateInfo,
)
);
TYPEDATA_GEN(VkVertexInputBindingDescription);
TYPEDATA_GEN(VkVertexInputAttributeDescription);
// ========================================================================================================= //
// =================================evk Types=============================================================== //
// ========================================================================================================= //
@@ -116,11 +118,19 @@ typedef struct {
u32 count;
} evkDeviceQueueRequirement;
typedef struct {
VkPhysicalDeviceFeatures features10;
VkPhysicalDeviceVulkan11Features features11;
VkPhysicalDeviceVulkan12Features features12;
VkPhysicalDeviceVulkan13Features features13;
} evkPhysicalDeviceFeatures;
typedef struct {
evkInstance instance;
VkPhysicalDeviceType physicalDeviceType;
ev_vec(evkDeviceQueueRequirement) queueRequirements;
ev_vec(evstring) deviceExtensions;
evkPhysicalDeviceFeatures enabledFeatures;
} evkDeviceCreateInfo;
typedef struct {
@@ -129,9 +139,9 @@ typedef struct {
} evkDeviceQueueFamily;
typedef struct {
bool dynamicRendering;
bool multiViewport;
} evkPhysicalDeviceFeatures;
VkPhysicalDeviceLimits limits;
VkPhysicalDeviceDescriptorBufferPropertiesEXT desc_buf;
} evkDeviceProperties;
#define MAX_QUEUE_FAMILIES ((VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT | VK_QUEUE_SPARSE_BINDING_BIT) + 1)
typedef struct {
@@ -139,7 +149,7 @@ typedef struct {
VkPhysicalDevice _physicalDevice;
evkInstance _instance;
evkDeviceQueueFamily queueFamilies[MAX_QUEUE_FAMILIES];
VkPhysicalDeviceLimits limits;
evkDeviceProperties props;
evkPhysicalDeviceFeatures enabledFeatures;
} evkDevice;
@@ -174,11 +184,6 @@ typedef struct {
VkPipelineLayout vk;
} evkPipelineLayout;
typedef struct {
vec(VkDescriptorSetLayout) descriptorSetLayouts;
vec(VkPushConstantRange) pushConstantRanges;
} evkPipelineLayoutCreateInfo;
typedef struct {
VkOffset2D renderOffset;
VkExtent2D renderExtents;
@@ -202,14 +207,30 @@ typedef union {
};
} evkViewport;
typedef union {
VkDescriptorSetLayoutBinding vk;
struct {
VkDescriptorSetLayoutBinding;
u32 set;
};
// typedef union {
// VkDescriptorSetLayoutBinding vk;
// struct {
// VkDescriptorSetLayoutBinding;
// u32 set;
// };
// } evkDescriptorBinding;
// typedef VkDescriptorSetLayoutBinding evkDescriptorBinding;
typedef struct {
evstring name;
VkDescriptorType descriptorType;
VkShaderStageFlags stageFlags;
uint32_t descriptorCount;
const VkSampler* pImmutableSamplers;
uint32_t binding;
} evkDescriptorBinding;
// typedef struct {
// VkDescriptorSetLayout vk;
// vec(evkDescriptorBinding) bindings;
// } evkDescriptorSetLayout;
// typedef VkDescriptorSetLayout evkDescriptorSetLayout;
typedef struct {
VkShaderStageFlags stage;
vec(evkDescriptorBinding) bindings;
@@ -265,6 +286,7 @@ typedef enum evkGPUMemoryUsage
{
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_CPU_TO_GPU = VMA_MEMORY_USAGE_CPU_TO_GPU,
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_HOST = VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
@@ -277,7 +299,6 @@ typedef struct {
typedef struct {
evkGPUAllocationFlags allocationFlags;
evkGPUMemoryUsage memoryUsage;
evkGPUAllocator allocator;
evkGPUMemoryPool pool;
} evkGPUAllocationCreateInfo;
@@ -315,6 +336,8 @@ typedef struct {
VkBuffer vk;
evkGPUAllocationData allocData;
u32 sizeInBytes;
VkBufferUsageFlags usage;
VkDeviceAddress address;
} evkBuffer;
typedef struct {
@@ -355,7 +378,88 @@ typedef struct {
VkPipelineColorBlendAttachmentState blendState;
} 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 {
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(evkShader) shaderStages;
@@ -369,14 +473,25 @@ typedef struct {
u32 viewportCountOverride;
vec(evkViewport) viewports;
vec(evkVertexBufferLayout) vertexBufferLayouts;
vec(evkDescriptorSetLayout) setLayouts;
} evkPipelineCreateInfo;
typedef struct {
VkPipeline vk;
evkPipelineLayout layout;
evkDevice _device;
evkPipelineType type;
evkDescriptorSet boundSets[MAX_DESCRIPTOR_SETS];
} evkPipeline;
typedef struct {
VkCommandBuffer vk;
bool recording;
evkPipeline* boundPipeline;
} evkCommandBuffer;
TYPEDATA_GEN(evkInstance,
INVALID(
.vk = VK_NULL_HANDLE,
@@ -387,7 +502,7 @@ TYPEDATA_GEN(evkShader);
TYPEDATA_GEN(evkPipelineLayoutCreateInfo,
DEFAULT(
.descriptorSetLayouts = EV_VEC_EMPTY,
.setLayouts = EV_VEC_EMPTY,
.pushConstantRanges = EV_VEC_EMPTY,
)
);
@@ -435,6 +550,7 @@ TYPEDATA_GEN(evkColorAttachment);
TYPEDATA_GEN(evkPipelineCreateInfo,
DEFAULT(
.type = EVK_PIPELINE_TYPE_GRAPHICS,
.dynamicStates = 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(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];
}

144
main.c
View File

@@ -7,12 +7,6 @@
evstring PROJECT_NAME = evstr("evk");
float vertexPositions[] = {
0.f,-.5f,
.5f, .5f,
-.5f, .5f
};
int main(void)
{
u32 width = 1024;
@@ -20,10 +14,10 @@ int main(void)
evkInstance instance = evkCreateInstance((evkInstanceCreateInfo){
.applicationInfo = EV_DEFAULT(evkApplicationInfo),
.layers = svec_init(evstring, {
.layers = svec_init(evstring, {
evstr("VK_LAYER_KHRONOS_validation"),
}),
.extensions = svec_init(evstring, {
.extensions = svec_init(evstring, {
evstr("VK_KHR_surface"),
evstr("VK_KHR_win32_surface"),
}),
@@ -51,6 +45,7 @@ int main(void)
evstr("VK_KHR_synchronization2"),
evstr("VK_KHR_buffer_device_address"),
evstr("VK_EXT_descriptor_indexing"),
evstr("VK_EXT_descriptor_buffer"),
}),
});
@@ -85,6 +80,8 @@ int main(void)
puts("Surface creation failed.");
}
evkGPUAllocator allocator = evkGPUCreateAllocator(device);
evkSwapChain swapChain = evkCreateSwapChain((evkSwapChainCreateInfo){
.device = device,
.surface = surface,
@@ -99,7 +96,7 @@ int main(void)
.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();
@@ -109,10 +106,25 @@ int main(void)
evkDestroyShaderCompiler(compiler);
evkColorAttachment colorAttachment0 = {
swapChain.surfaceFormat.format,
swapChain.surfaceFormat.format,
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,
dynamicStates = svec_init(VkDynamicState, {
VK_DYNAMIC_STATE_VIEWPORT,
@@ -126,8 +138,64 @@ int main(void)
colorAttachment0,
}),
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);
VkRect2D scissor = EV_DEFAULT(VkRect2D,extent.width=width, extent.height=height);
@@ -142,7 +210,7 @@ int main(void)
u32 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,
imageView = swapChain.imageViews[imageIdx].vk,
@@ -156,38 +224,43 @@ int main(void)
colorAttachmentCount = 1,
);
evkBeginPrimaryCommandBuffer(cmdbuf);
evkBeginPrimaryCommandBuffer(&cmdbuf);
{
VkDeviceSize offset = 0;
vkCmdBindVertexBuffers(cmdbuf.vk, 0, 1, &vertBuf.vk, &offset);
vkCmdSetScissor(cmdbuf, 0, 1, &scissor);
vkCmdSetViewport(cmdbuf, 0, 1, &viewport);
evkCmdBindDescriptorSets(&cmdbuf, &graphicsPipeline, svec_init(evkDescriptorSet, { set_0 }), svec_init(u32, { 0 }));
vkCmdBeginRenderingKHR(cmdbuf, &renderingInfo);
vkCmdSetScissor(cmdbuf.vk, 0, 1, &scissor);
vkCmdSetViewport(cmdbuf.vk, 0, 1, &viewport);
vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.vk);
vkCmdDraw(cmdbuf, 3, 1, 0, 0);
vkCmdBeginRenderingKHR(cmdbuf.vk, &renderingInfo);
vkCmdEndRenderingKHR(cmdbuf);
evkCmdBindPipeline(&cmdbuf, &graphicsPipeline);
vkCmdDraw(cmdbuf.vk, 3, 1, 0, 0);
VkImageMemoryBarrier imageMemoryBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.image = swapChain.images[imageIdx].vk,
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.layerCount = 1,
.levelCount = 1,
},
};
vkCmdEndRenderingKHR(cmdbuf.vk);
vkCmdPipelineBarrier(cmdbuf, 0, 0, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier);
VkImageMemoryBarrier imageMemoryBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.image = swapChain.images[imageIdx].vk,
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.layerCount = 1,
.levelCount = 1,
},
};
evkEndCommandBuffer(cmdbuf);
vkCmdPipelineBarrier(cmdbuf.vk, 0, 0, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier);
}
evkEndCommandBuffer(&cmdbuf);
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
VkSubmitInfo submitInfo = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pCommandBuffers = &cmdbuf,
.pCommandBuffers = &cmdbuf, // TODO This won't work with more than a single cmdbuf
.commandBufferCount = 1,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &imageAcquiredSemaphore,
@@ -210,7 +283,7 @@ int main(void)
};
vkQueuePresentKHR(graphicsQueue, &presentInfo);
vkResetCommandBuffer(cmdbuf,VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
vkResetCommandBuffer(cmdbuf.vk,VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
// Main Loop
glfwPollEvents();
@@ -224,15 +297,18 @@ int main(void)
evkDestroyPipeline(graphicsPipeline);
evkDestroyDescriptorSet(&device, &set_0);
evkDestroyDescriptorSetLayout(&device, &setLayout_0);
evkDestroyShader(device, vertShader);
evkDestroyShader(device, fragShader);
vkFreeCommandBuffers(device.vk, commandPool.vk, vec_len(&commandBuffers), commandBuffers);
evkFreeCommandBuffers(device, commandPool, commandBuffers);
evkDestroyCommandPool(device, commandPool);
evkDestroySwapChain(device, swapChain);
SwapchainCreationFailed:
// SwapchainCreationFailed:
vkDestroySurfaceKHR(instance.vk, swapChain.surface, NULL);
VKSurfaceCreationFailed:

View File

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

View File

@@ -1,15 +1,15 @@
#version 450
#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;
layout(set=0, binding=0) uniform data {
vec4 positions[3];
} vertexData;
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(inputData.positions[gl_VertexIndex], 0.0, 1.0);
gl_Position = vertexData.positions[gl_VertexIndex];
}

View File

@@ -1,13 +1,11 @@
[wrap-file]
directory = glfw-3.3.10
source_url = https://github.com/glfw/glfw/archive/refs/tags/3.3.10.tar.gz
source_filename = glfw-3.3.10.tar.gz
source_hash = 4ff18a3377da465386374d8127e7b7349b685288cb8e17122f7e1179f73769d5
patch_filename = glfw_3.3.10-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/glfw_3.3.10-1/get_patch
patch_hash = 3567f96c2576a5fc8c9cafd9059f919d7da404f6c22450c6c2ce3f9938909b8b
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
[wrap-git]
directory = glfw
url = https://github.com/glfw/glfw
revision = 3.3.10
depth=1
patch_directory = glfw
[provide]
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')
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,
)
python = find_program('python3')
run_command(python, './utils/git-sync-deps', check: true)
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)

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_DYNAMIC_VULKAN_FUNCTIONS 0
#define VMA_IMPLEMENTATION
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Weverything"
#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]
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_filename = libshaderc-upstream-msvc.zip
source_hash = a6879869e580d5991ebd9909f3665d1f6fe39cdb9830adf4f48b35dfd3782a78
lead_directory_missing = libshaderc
patch_directory = libshaderc
patch_directory = libshaderc_old
[provide]
dependency_names = shaderc
dependency_names = shaderc_old