From 2fa373a71672245238de03b3fbe4b839cf8a23f5 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Sun, 26 Sep 2021 20:28:43 +0530 Subject: [PATCH 01/12] Bug fix to HeaderConfigurationSystem, added Garbage Collector, string Refactored renderer.h and added vk_get_instance_extension_properties(), vk_get_instance_layer_properties(), and some to_string & dump functions. Added few more properties in engine_t (renderer) and converted the pointers to void* so that no one can use it directly at compile time [like private member], added engine_get_renderer(). Added Garbage Collector [tgc] and its wrapper garbage_collector/garbage_collector.h. Fixed a bug in header configuration system, header_config_reset.h was malfunctioned. Added garbage collected string data structure [string(), string_array()]. Added some type definitions in template_system.h because template() doesn't take asterisk or space. Moved the vulkan code from engine.c to renderer.c and created new struct renderer_t in renderer.h --- dependencies/tgc | 1 + include/engine/engine.h | 7 +- include/engine/renderer/renderer.h | 37 +- include/garbage_collector/garbage_collector.h | 18 + .../header_config_reset.h | 24 +- include/string/string.h | 7 + include/template_system.h | 11 + include/tgc/tgc.h | 51 ++ include/tuple/template_instantiations.h | 2 - makefile | 2 +- source/engine.c | 46 +- source/garbage_collector.c | 6 + source/main.c | 10 +- source/renderer.c | 226 ++++++++- source/string.c | 32 ++ source/tgc.c | 458 ++++++++++++++++++ 16 files changed, 878 insertions(+), 60 deletions(-) create mode 160000 dependencies/tgc create mode 100644 include/garbage_collector/garbage_collector.h create mode 100644 include/string/string.h create mode 100644 include/tgc/tgc.h create mode 100644 source/garbage_collector.c create mode 100644 source/string.c create mode 100644 source/tgc.c diff --git a/dependencies/tgc b/dependencies/tgc new file mode 160000 index 00000000..35207051 --- /dev/null +++ b/dependencies/tgc @@ -0,0 +1 @@ +Subproject commit 35207051557c79ea25942c021fb18856c72af8e3 diff --git a/include/engine/engine.h b/include/engine/engine.h index ef4bc109..9190f601 100644 --- a/include/engine/engine.h +++ b/include/engine/engine.h @@ -18,13 +18,15 @@ #include #include #include - #include +#include + typedef struct engine_t { void* window; - scene_manager_t* scene_manager; + void* scene_manager; + void* renderer; } engine_t; @@ -39,6 +41,7 @@ void engine_update(engine_t* engine); scene_manager_t* engine_get_scene_manager(engine_t* engine); +renderer_t* engine_get_renderer(engine_t* engine); #endif/*__ENGINE_H__*/ \ No newline at end of file diff --git a/include/engine/renderer/renderer.h b/include/engine/renderer/renderer.h index 58dccc34..8f18d517 100644 --- a/include/engine/renderer/renderer.h +++ b/include/engine/renderer/renderer.h @@ -8,15 +8,46 @@ #include #include +#include #include typedef VkPhysicalDevice* pVkPhysicalDevice_t; instantiate_tuple_t(uint32_t, pVkPhysicalDevice_t); -VkInstance vk_create_instance(VkInstanceCreateInfo* create_info, VkAllocationCallbacks* host_memory_allocator); +typedef VkExtensionProperties* pVkExtensionProperties_t; +instantiate_tuple_t(uint32_t, pVkExtensionProperties_t); + +typedef VkLayerProperties* pVkLayerProperties_t; +instantiate_tuple_t(uint32_t, pVkLayerProperties_t); + +typedef const char* const* ppVkChar_t; +instantiate_tuple_t(uint32_t, ppVkChar_t); + + +typedef struct renderer_t +{ + VkInstance vk_instance; +} renderer_t; + + +renderer_t* renderer_init(); +void renderer_terminate(renderer_t* renderer); + +VkInstance vk_create_instance(); tuple_t(uint32_t, pVkPhysicalDevice_t) vk_get_physical_devices(VkInstance instance); +tuple_t(uint32_t, pVkExtensionProperties_t) vk_get_instance_extension_properties(); +tuple_t(uint32_t, pVkLayerProperties_t) vk_get_instance_layer_properties(); VkPhysicalDeviceProperties vk_get_physical_device_properties(VkPhysicalDevice physical_device); VkPhysicalDeviceFeatures vk_get_physical_device_features(VkPhysicalDevice physical_device); -NOT_IMPLEMENTED VkPhysicalDeviceMemoryProperties vk_get_physical_device_memory_properties(VkPhysicalDevice physical_device); -//NOT_IMPLEMENTED VkPhysicalDeviceQueueFamilyProperites vk_get_physical_device_queue_family_properties(VkPhysicalDevice physical_device); \ No newline at end of file +VkPhysicalDeviceMemoryProperties vk_get_physical_device_memory_properties(VkPhysicalDevice physical_device); +bool vk_check_layer_support(tuple_t(uint32_t, ppVkChar_t) layers); +bool vk_check_extension_support(tuple_t(uint32_t, ppVkChar_t) extensions); +//NOT_IMPLEMENTED VkPhysicalDeviceQueueFamilyProperites vk_get_physical_device_queue_family_properties(VkPhysicalDevice physical_device); + + +void vk_dump_instance_extensions(); +void vk_dump_instance_layers(); +const char* vk_physical_device_memory_properties_to_string(VkPhysicalDeviceMemoryProperties *memory_properties); +const char* vk_physical_device_properties_to_string(VkPhysicalDeviceProperties* properties); +const char* vk_physical_device_type_to_string(VkPhysicalDeviceType* deviceType); diff --git a/include/garbage_collector/garbage_collector.h b/include/garbage_collector/garbage_collector.h new file mode 100644 index 00000000..80fdda08 --- /dev/null +++ b/include/garbage_collector/garbage_collector.h @@ -0,0 +1,18 @@ + +#pragma once + + +#include + +extern tgc_t gc; + +#define GC_START(stack_address) tgc_start(&gc, (void*)(stack_address)) +#define GC_STOP() tgc_stop(&gc) +#define GC_RUN() tgc_run(&gc) +#define GC_PAUSE() tgc_pause(&gc) +#define GC_RESUME() tgc_resume(&gc) +#define GC_ALLOC(size) tgc_alloc(&gc, size) +#define GC_FREE(ptr) tgc_free(&gc, ptr) + +#define GC_NEW(type) (type*)GC_ALLOC(sizeof(type)) +#define GC_NEWV(type, count) (type*)GC_ALLOC(sizeof(type) * (count)) \ No newline at end of file diff --git a/include/header_configuration_system/header_config_reset.h b/include/header_configuration_system/header_config_reset.h index 25849940..7b1191b3 100644 --- a/include/header_configuration_system/header_config_reset.h +++ b/include/header_configuration_system/header_config_reset.h @@ -1,47 +1,47 @@ -#ifdef HEADER_CONFIGURATION_SYSTEM_HEADER +#if defined(HEADER_CONFIGURATION_SYSTEM_HEADER) && !defined(GLOBAL_HEADER) # undef HEADER_CONFIGURATION_SYSTEM_HEADER #endif -#ifdef HEADER +#if defined(HEADER) && !defined(GLOBAL_HEADER) # undef HEADER #endif -#ifdef HPML_HEADER +#if defined(HPML_HEADER) && !defined(GLOBAL_HEADER) # undef HPML_HEADER #endif -#ifdef HEADER_CONFIGURATION_SYSTEM_IMPLEMENTATION +#if defined(HEADER_CONFIGURATION_SYSTEM_IMPLEMENTATION) && !defined(GLOBAL_IMPLEMENATION) # undef HEADER_CONFIGURATION_SYSTEM_IMPLEMENTATION #endif -#ifdef IMPLEMENTATION +#if defined(IMPLEMENTATION) && !defined(GLOBAL_IMPLEMENATION) # undef IMPLEMENTATION #endif -#ifdef HPML_IMPLEMENTATION +#if defined(HPML_IMPLEMENTATION) && !defined(GLOBAL_IMPLEMENATION) # undef HPML_IMPLEMENTATION #endif -#ifdef HEADER_CONFIGURATION_SYSTEM_DEBUG_MODE +#if defined(HEADER_CONFIGURATION_SYSTEM_DEBUG_MODE) && !defined(GLOBAL_DEBUG) # undef HEADER_CONFIGURATION_SYSTEM_DEBUG_MODE #endif -#ifdef DEBUG_MODE +#if defined(DEBUG_MODE) && !defined(GLOBAL_DEBUG) # undef DEBUG_MODE #endif -#ifdef DEBUG +#if defined(DEBUG) && !defined(GLOBAL_DEBUG) # undef DEBUG #endif -#ifdef HEADER_CONFIGURATION_SYSTEM_RELEASE_MODE +#if defined(HEADER_CONFIGURATION_SYSTEM_RELEASE_MODE) && !defined(GLOBAL_RELEASE) # undef HEADER_CONFIGURATION_SYSTEM_RELEASE_MODE #endif -#ifdef RELEASE_MODE +#if defined(RELEASE_MODE) && !defined(GLOBAL_RELEASE) # undef RELEASE_MODE #endif -#ifdef RELEASE +#if defined(RELEASE) && !defined(GLOBAL_RELEASE) # undef RELEASE #endif \ No newline at end of file diff --git a/include/string/string.h b/include/string/string.h new file mode 100644 index 00000000..94d75270 --- /dev/null +++ b/include/string/string.h @@ -0,0 +1,7 @@ + +#pragma once + +#include + +const char* string(uint32_t length, const char* format, ...); +const char* const* string_array(uint32_t count, ...); \ No newline at end of file diff --git a/include/template_system.h b/include/template_system.h index 95affacc..78c72895 100644 --- a/include/template_system.h +++ b/include/template_system.h @@ -9,4 +9,15 @@ #define template1(typename, T) template(typename, T) #define template2(typename, T1, T2) typename##_##T1##T2 + +typedef char* pchar_t; +typedef int* pint_t; +typedef float* pfloat_t; +typedef double* pdouble_t; + +typedef const char* pcchar_t; +typedef const int* pcint_t; +typedef const float* pcfloat_t; +typedef const double* pcdouble_t; + #endif/*__HPML_TEMPLATE_SYSTEM_H__*/ \ No newline at end of file diff --git a/include/tgc/tgc.h b/include/tgc/tgc.h new file mode 100644 index 00000000..888576d7 --- /dev/null +++ b/include/tgc/tgc.h @@ -0,0 +1,51 @@ +#ifndef TGC_H +#define TGC_H + +#include +#include +#include +#include + +enum { + TGC_MARK = 0x01, + TGC_ROOT = 0x02, + TGC_LEAF = 0x04 +}; + +typedef struct { + void *ptr; + int flags; + size_t size, hash; + void (*dtor)(void*); +} tgc_ptr_t; + +typedef struct { + void *bottom; + int paused; + uintptr_t minptr, maxptr; + tgc_ptr_t *items, *frees; + double loadfactor, sweepfactor; + size_t nitems, nslots, mitems, nfrees; +} tgc_t; + +void tgc_start(tgc_t *gc, void *stk); +void tgc_stop(tgc_t *gc); +void tgc_pause(tgc_t *gc); +void tgc_resume(tgc_t *gc); +void tgc_run(tgc_t *gc); + +void *tgc_alloc(tgc_t *gc, size_t size); +void *tgc_calloc(tgc_t *gc, size_t num, size_t size); +void *tgc_realloc(tgc_t *gc, void *ptr, size_t size); +void tgc_free(tgc_t *gc, void *ptr); + +void *tgc_alloc_opt(tgc_t *gc, size_t size, int flags, void(*dtor)(void*)); +void *tgc_calloc_opt(tgc_t *gc, size_t num, size_t size, int flags, void(*dtor)(void*)); + +void tgc_set_dtor(tgc_t *gc, void *ptr, void(*dtor)(void*)); +void tgc_set_flags(tgc_t *gc, void *ptr, int flags); +int tgc_get_flags(tgc_t *gc, void *ptr); +void(*tgc_get_dtor(tgc_t *gc, void *ptr))(void*); +size_t tgc_get_size(tgc_t *gc, void *ptr); + +#endif diff --git a/include/tuple/template_instantiations.h b/include/tuple/template_instantiations.h index d711313c..198a73f4 100644 --- a/include/tuple/template_instantiations.h +++ b/include/tuple/template_instantiations.h @@ -4,8 +4,6 @@ #include -typedef char* pchar_t; - instantiate_tuple_t(int, pchar_t); instantiate_declaration_tuple_get1(int, pchar_t); diff --git a/makefile b/makefile index ac514951..9fe4bd73 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ -DEFINES= -DHPML_DEBUG_MODE -DLOG_DEBUG +DEFINES= -DHPML_DEBUG_MODE -DLOG_DEBUG -DGLOBAL_DEBUG COMPILATION_CONFIG= -m64 INCLUDES= -I.\include -I.\include\engine -I.\scripts diff --git a/source/engine.c b/source/engine.c index de1d58b5..43ee0adf 100644 --- a/source/engine.c +++ b/source/engine.c @@ -1,52 +1,25 @@ -#include #include #include #include +#include engine_t* engine_init(uint32_t screen_width, uint32_t screen_height, const char* window_name) { glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - GLFWwindow* window = glfwCreateWindow(screen_width, screen_height, window_name, NULL, NULL); - - // VkApplicationInfo application_info = {}; - // application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - // application_info.pNext = NULL; - // applicaiton_info.pApplicationName = "Vulkan Renderer"; - - - - VkInstanceCreateInfo instance_create_info = { }; - instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - instance_create_info.pNext = NULL; - instance_create_info.flags = 0; - instance_create_info.pApplicationInfo = NULL; - instance_create_info.enabledLayerCount = 0; - instance_create_info.ppEnabledLayerNames = NULL; - instance_create_info.enabledExtensionCount = 0; - instance_create_info.ppEnabledExtensionNames = NULL; - - VkInstance instance = vk_create_instance(&instance_create_info, NULL); - tuple_t(uint32_t, pVkPhysicalDevice_t) physical_devices = vk_get_physical_devices(instance); - //iterate through each physical device connected to this host device - for(uint32_t i = 0; i < physical_devices.value1; i++) - { - VkPhysicalDevice device = physical_devices.value2[i]; - VkPhysicalDeviceProperties properties = vk_get_physical_device_properties(device); - log_msg(properties.deviceName); - } - - engine_t* engine = (engine_t*)malloc(sizeof(engine_t)); - scene_manager_t* scene_manager = scene_manager_init(); - engine->window = (void*)window; - engine->scene_manager = scene_manager; + engine_t* engine = GC_NEW(engine_t); + engine->window = glfwCreateWindow(screen_width, screen_height, window_name, NULL, NULL); + engine->scene_manager = scene_manager_init(); + engine->renderer = renderer_init(); return engine; } void engine_terminate(engine_t* engine) { scene_manager_for_each_objects_in_all_scenes(engine->scene_manager, object_destroy); + renderer_terminate(engine_get_renderer(engine)); + glfwDestroyWindow((GLFWwindow*)(engine->window)); glfwTerminate(); } @@ -56,6 +29,11 @@ scene_manager_t* engine_get_scene_manager(engine_t* engine) return engine->scene_manager; } +renderer_t* engine_get_renderer(engine_t* engine) +{ + return engine->renderer; +} + void engine_start(engine_t* engine) { scene_manager_for_each_objects_in_all_scenes(engine->scene_manager, object_call_awake); diff --git a/source/garbage_collector.c b/source/garbage_collector.c new file mode 100644 index 00000000..19fb1f99 --- /dev/null +++ b/source/garbage_collector.c @@ -0,0 +1,6 @@ + + +#include + + +tgc_t gc; \ No newline at end of file diff --git a/source/main.c b/source/main.c index a144165b..f6299fde 100644 --- a/source/main.c +++ b/source/main.c @@ -1,17 +1,20 @@ +#include + #include #include "TestBehaviour.h" #include "Ammo.h" - static void prepare_scene(engine_t* engine); int main(int argc, char** argv) { + GC_START(&argc); + engine_t* engine = engine_init(600, 500, "Vulkan 3D Engine"); - prepare_scene(engine); + //prepare_scene(engine); engine_start(engine); while(engine_is_running(engine)) @@ -21,6 +24,9 @@ int main(int argc, char** argv) } engine_terminate(engine); + + GC_RUN(); + GC_STOP(); return 0; } diff --git a/source/renderer.c b/source/renderer.c index f60f9690..7bc2b0e0 100644 --- a/source/renderer.c +++ b/source/renderer.c @@ -2,8 +2,13 @@ #include #include - #include +#include +#include +#include +#include //custom string library +#include //standard string library +#include declare_exception(VULKAN_ABORTED); define_exception(VULKAN_ABORTED); @@ -18,10 +23,104 @@ define_exception(VULKAN_ABORTED); )\ } -VkInstance vk_create_instance(VkInstanceCreateInfo* create_info, VkAllocationCallbacks* host_memory_allocator) +#ifdef DEBUG +static const bool enable_validation_layers = true; +#else +static const bool enable_validation_layers = false; +#endif + +renderer_t* renderer_init() +{ + renderer_t* renderer = GC_NEW(renderer_t); + VkInstance instance = renderer->vk_instance = vk_create_instance(); + +#ifdef DEBUG + vk_dump_instance_extensions(); + vk_dump_instance_layers(); +#endif + + if(vk_check_layer_support((tuple_t(uint32_t, ppVkChar_t)){ 1, string_array(1, "VK_LAYER_KHRONOS_validation") })) + puts("VK_LAYER_KHRONOS_validation is supported"); + else puts("VK_LAYER_KHRONOS_validation is not supported"); + + if(vk_check_extension_support((tuple_t(uint32_t, ppVkChar_t)) { 1, string_array(1, "My Extension") } )) + puts("My Extension is supported"); + else puts("My Extension is not supported"); + + tuple_t(uint32_t, pVkPhysicalDevice_t) physical_devices = vk_get_physical_devices(instance); + for(uint32_t i = 0; i < physical_devices.value1; i++) + { + VkPhysicalDevice device = physical_devices.value2[i]; + VkPhysicalDeviceProperties properties = vk_get_physical_device_properties(device); + VkPhysicalDeviceMemoryProperties memory_properties = vk_get_physical_device_memory_properties(device); + puts("Physical Device Properties----------------------"); + puts(vk_physical_device_properties_to_string(&properties)); + puts("Physical Device Memory Properties---------------"); + puts(vk_physical_device_memory_properties_to_string(&memory_properties)); + } + return renderer; +} + +void renderer_terminate(renderer_t* renderer) +{ + vkDestroyInstance(renderer->vk_instance, NULL); +} + + +bool vk_check_layer_support(tuple_t(uint32_t, ppVkChar_t) layers) { + tuple_t(uint32_t, pVkLayerProperties_t) layer_properties = vk_get_instance_layer_properties(); + for(uint32_t i = 0; i < layers.value1; i++) + { + bool contains = false; + for(uint32_t j = 0; j < layer_properties.value1; j++) + { + if(strcmp(layers.value2[i], layer_properties.value2[j].layerName) == 0) + { + contains = true; + break; + } + } + if(!contains) + return false; + } + return true; +} + + +bool vk_check_extension_support(tuple_t(uint32_t, ppVkChar_t) extensions) +{ + tuple_t(uint32_t, pVkExtensionProperties_t) extension_properties = vk_get_instance_extension_properties(); + for(uint32_t i = 0; i < extensions.value1; i++) + { + bool contains = false; + for(uint32_t j = 0; j < extension_properties.value1; j++) + { + if(strcmp(extensions.value2[i], extension_properties.value2[j].extensionName) == 0) + { + contains = true; + break; + } + } + if(!contains) + return false; + } + return true; +} + +VkInstance vk_create_instance() +{ + VkInstanceCreateInfo instance_create_info = { }; + instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instance_create_info.pNext = NULL; + instance_create_info.flags = 0; + instance_create_info.pApplicationInfo = NULL; + instance_create_info.enabledLayerCount = 0; + instance_create_info.ppEnabledLayerNames = NULL; + instance_create_info.enabledExtensionCount = 0; + instance_create_info.ppEnabledExtensionNames = NULL; VkInstance instance; - vkCall(vkCreateInstance(create_info, host_memory_allocator, &instance)); + vkCall(vkCreateInstance(&instance_create_info, NULL, &instance)); return instance; } @@ -29,11 +128,29 @@ tuple_t(uint32_t, pVkPhysicalDevice_t) vk_get_physical_devices(VkInstance instan { tuple_t(uint32_t, pVkPhysicalDevice_t) pair; vkCall(vkEnumeratePhysicalDevices(instance, &(pair.value1), NULL)); - pair.value2 = (pVkPhysicalDevice_t)malloc(sizeof(VkPhysicalDevice) * pair.value1); + pair.value2 = (pVkPhysicalDevice_t)GC_ALLOC(sizeof(VkPhysicalDevice) * pair.value1); vkCall(vkEnumeratePhysicalDevices(instance, &(pair.value1), pair.value2)); return pair; } +tuple_t(uint32_t, pVkExtensionProperties_t) vk_get_instance_extension_properties() +{ + tuple_t(uint32_t, pVkExtensionProperties_t) pair; + vkCall(vkEnumerateInstanceExtensionProperties(NULL, &(pair.value1), NULL)); + pair.value2 = GC_NEWV(VkExtensionProperties, pair.value1); + vkCall(vkEnumerateInstanceExtensionProperties(NULL, &(pair.value1), pair.value2)); + return pair; +} + +tuple_t(uint32_t, pVkLayerProperties_t) vk_get_instance_layer_properties() +{ + tuple_t(uint32_t, pVkLayerProperties_t) pair; + vkCall(vkEnumerateInstanceLayerProperties(&(pair.value1), NULL)); + pair.value2 = GC_NEWV(VkLayerProperties, pair.value1); + vkCall(vkEnumerateInstanceLayerProperties(&(pair.value1), pair.value2)); + return pair; +} + VkPhysicalDeviceProperties vk_get_physical_device_properties(VkPhysicalDevice physical_device) { VkPhysicalDeviceProperties properties; @@ -46,4 +163,105 @@ VkPhysicalDeviceFeatures vk_get_physical_device_features(VkPhysicalDevice physic VkPhysicalDeviceFeatures features; vkGetPhysicalDeviceFeatures(physical_device, &features); return features; +} + +VkPhysicalDeviceMemoryProperties vk_get_physical_device_memory_properties(VkPhysicalDevice physical_device) +{ + VkPhysicalDeviceMemoryProperties memory_properties; + vkGetPhysicalDeviceMemoryProperties(physical_device, &memory_properties); + return memory_properties; +} + + +void vk_dump_instance_layers() +{ + tuple_t(uint32_t, pVkLayerProperties_t) layer_properties = vk_get_instance_layer_properties(); + puts("Instance Layer Properties----------------------"); + for(uint32_t i = 0; i < layer_properties.value1; i++) + puts(layer_properties.value2[i].layerName); +} + +void vk_dump_instance_extensions() +{ + tuple_t(uint32_t, pVkExtensionProperties_t) extension_properties = vk_get_instance_extension_properties(); + puts("Instance Extension Properties----------------------"); + for(uint32_t i = 0; i < extension_properties.value1; i++) + puts(extension_properties.value2[i].extensionName); +} + +const char* vk_physical_device_memory_properties_to_string(VkPhysicalDeviceMemoryProperties* memory_properties) +{ + return string(128, + "Memory Type Count: %u\n", + memory_properties->memoryTypeCount + ); +} + +const char* vk_physical_device_limits_to_string(VkPhysicalDeviceLimits* device_limits) +{ + return string(512, + "Max Image Dimension 1D [width]: %u\n" + "Max Image Dimension 2D max(width, height): %u\n" + "Max Image Dimension 3D max(width, height, depth): %u\n" + "Max Image Dimension Cube max(width, height): %u\n" + "Max Image Layers: %u\n" + "Max Texel Buffer Elements: %u\n" + , + device_limits->maxImageDimension1D, + device_limits->maxImageDimension2D, + device_limits->maxImageDimension3D, + device_limits->maxImageDimensionCube, + device_limits->maxImageArrayLayers, + device_limits->maxTexelBufferElements + // device_limits->maxUniformBufferRange, + // device_limits->maxStorageBufferRange, + // device_limits->maxPushConstantsSize, + // device_limits->maxMemoryAllocationCount, + // device_limits->maxSamplerAllocationCount, + // device_limits->bufferImageGranularity, + // device_limits->sparseAddressSpaceSize, + // device_limits->maxBoundDescriptorSets, + // device_limits->maxPerStageDescriptorSampler, + ); +} + +const char* vk_physical_device_type_to_string(VkPhysicalDeviceType *device_type) +{ + switch(*device_type) + { + case VK_PHYSICAL_DEVICE_TYPE_OTHER: + return "VK_PHYSICAL_DEVICE_TYPE_OTHER"; + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: + return "VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU"; + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: + return "VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU"; + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: + return "VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU"; + case VK_PHYSICAL_DEVICE_TYPE_CPU: + return "VK_PHYSICAL_DEVICE_TYPE_CPU"; + default: + return "(Unknown)"; + } +} + +const char* vk_physical_device_properties_to_string(VkPhysicalDeviceProperties* properties) +{ + return string(1024, + "API Version: %d\n" + "Driver Version: %d\n" + "Vendor ID: %d\n" + "Device ID: %d\n" + "Device Name: %s\n" + "Device Type: %s\n" + "Pipeline Cache UUID: %d\n" + "Device Limits: \n" + "%s", + properties->apiVersion, + properties->driverVersion, + properties->vendorID, + properties->deviceID, + properties->deviceName, + vk_physical_device_type_to_string(&(properties->deviceType)), + properties->pipelineCacheUUID, + vk_physical_device_limits_to_string(&(properties->limits))); } \ No newline at end of file diff --git a/source/string.c b/source/string.c new file mode 100644 index 00000000..a7789396 --- /dev/null +++ b/source/string.c @@ -0,0 +1,32 @@ + +#include +#include + +#include +#include + +const char* string(uint32_t length, const char* format, ...) +{ + char* buffer = GC_ALLOC(length); + va_list args; + va_start(args, format); + vsprintf(buffer, format, args); + va_end(args); + return buffer; +} + +const char* const* string_array(uint32_t count, ...) +{ + const char* *buffer = GC_NEWV(const char*, count); + va_list args; + va_start(args, count); + uint32_t i = 0; + while(i < count) + { + const char* str = va_arg(args, const char*); + buffer[i] = string(strlen(str), str); + i++; + } + va_end(args); + return buffer; +} \ No newline at end of file diff --git a/source/tgc.c b/source/tgc.c new file mode 100644 index 00000000..e60470a5 --- /dev/null +++ b/source/tgc.c @@ -0,0 +1,458 @@ +#include + +static size_t tgc_hash(void *ptr) { + return ((uintptr_t)ptr) >> 3; +} + +static size_t tgc_probe(tgc_t* gc, size_t i, size_t h) { + long v = i - (h-1); + if (v < 0) { v = gc->nslots + v; } + return v; +} + +static tgc_ptr_t *tgc_get_ptr(tgc_t *gc, void *ptr) { + size_t i, j, h; + i = tgc_hash(ptr) % gc->nslots; j = 0; + while (1) { + h = gc->items[i].hash; + if (h == 0 || j > tgc_probe(gc, i, h)) { return NULL; } + if (gc->items[i].ptr == ptr) { return &gc->items[i]; } + i = (i+1) % gc->nslots; j++; + } + return NULL; +} + +static void tgc_add_ptr( + tgc_t *gc, void *ptr, size_t size, + int flags, void(*dtor)(void*)) { + + tgc_ptr_t item, tmp; + size_t h, p, i, j; + + i = tgc_hash(ptr) % gc->nslots; j = 0; + + item.ptr = ptr; + item.flags = flags; + item.size = size; + item.hash = i+1; + item.dtor = dtor; + + while (1) { + h = gc->items[i].hash; + if (h == 0) { gc->items[i] = item; return; } + if (gc->items[i].ptr == item.ptr) { return; } + p = tgc_probe(gc, i, h); + if (j >= p) { + tmp = gc->items[i]; + gc->items[i] = item; + item = tmp; + j = p; + } + i = (i+1) % gc->nslots; j++; + } + +} + +static void tgc_rem_ptr(tgc_t *gc, void *ptr) { + + size_t i, j, h, nj, nh; + + if (gc->nitems == 0) { return; } + + for (i = 0; i < gc->nfrees; i++) { + if (gc->frees[i].ptr == ptr) { gc->frees[i].ptr = NULL; } + } + + i = tgc_hash(ptr) % gc->nslots; j = 0; + + while (1) { + h = gc->items[i].hash; + if (h == 0 || j > tgc_probe(gc, i, h)) { return; } + if (gc->items[i].ptr == ptr) { + memset(&gc->items[i], 0, sizeof(tgc_ptr_t)); + j = i; + while (1) { + nj = (j+1) % gc->nslots; + nh = gc->items[nj].hash; + if (nh != 0 && tgc_probe(gc, nj, nh) > 0) { + memcpy(&gc->items[ j], &gc->items[nj], sizeof(tgc_ptr_t)); + memset(&gc->items[nj], 0, sizeof(tgc_ptr_t)); + j = nj; + } else { + break; + } + } + gc->nitems--; + return; + } + i = (i+1) % gc->nslots; j++; + } + +} + + +enum { + TGC_PRIMES_COUNT = 24 +}; + +static const size_t tgc_primes[TGC_PRIMES_COUNT] = { + 0, 1, 5, 11, + 23, 53, 101, 197, + 389, 683, 1259, 2417, + 4733, 9371, 18617, 37097, + 74093, 148073, 296099, 592019, + 1100009, 2200013, 4400021, 8800019 +}; + +static size_t tgc_ideal_size(tgc_t* gc, size_t size) { + size_t i, last; + size = (size_t)((double)(size+1) / gc->loadfactor); + for (i = 0; i < TGC_PRIMES_COUNT; i++) { + if (tgc_primes[i] >= size) { return tgc_primes[i]; } + } + last = tgc_primes[TGC_PRIMES_COUNT-1]; + for (i = 0;; i++) { + if (last * i >= size) { return last * i; } + } + return 0; +} + +static int tgc_rehash(tgc_t* gc, size_t new_size) { + + size_t i; + tgc_ptr_t *old_items = gc->items; + size_t old_size = gc->nslots; + + gc->nslots = new_size; + gc->items = calloc(gc->nslots, sizeof(tgc_ptr_t)); + + if (gc->items == NULL) { + gc->nslots = old_size; + gc->items = old_items; + return 0; + } + + for (i = 0; i < old_size; i++) { + if (old_items[i].hash != 0) { + tgc_add_ptr(gc, + old_items[i].ptr, old_items[i].size, + old_items[i].flags, old_items[i].dtor); + } + } + + free(old_items); + + return 1; +} + +static int tgc_resize_more(tgc_t *gc) { + size_t new_size = tgc_ideal_size(gc, gc->nitems); + size_t old_size = gc->nslots; + return (new_size > old_size) ? tgc_rehash(gc, new_size) : 1; +} + +static int tgc_resize_less(tgc_t *gc) { + size_t new_size = tgc_ideal_size(gc, gc->nitems); + size_t old_size = gc->nslots; + return (new_size < old_size) ? tgc_rehash(gc, new_size) : 1; +} + +static void tgc_mark_ptr(tgc_t *gc, void *ptr) { + + size_t i, j, h, k; + + if ((uintptr_t)ptr < gc->minptr + || (uintptr_t)ptr > gc->maxptr) { return; } + + i = tgc_hash(ptr) % gc->nslots; j = 0; + + while (1) { + h = gc->items[i].hash; + if (h == 0 || j > tgc_probe(gc, i, h)) { return; } + if (ptr == gc->items[i].ptr) { + if (gc->items[i].flags & TGC_MARK) { return; } + gc->items[i].flags |= TGC_MARK; + if (gc->items[i].flags & TGC_LEAF) { return; } + for (k = 0; k < gc->items[i].size/sizeof(void*); k++) { + tgc_mark_ptr(gc, ((void**)gc->items[i].ptr)[k]); + } + return; + } + i = (i+1) % gc->nslots; j++; + } + +} + +static void tgc_mark_stack(tgc_t *gc) { + + void *stk, *bot, *top, *p; + bot = gc->bottom; top = &stk; + + if (bot == top) { return; } + + if (bot < top) { + for (p = top; p >= bot; p = ((char*)p) - sizeof(void*)) { + tgc_mark_ptr(gc, *((void**)p)); + } + } + + if (bot > top) { + for (p = top; p <= bot; p = ((char*)p) + sizeof(void*)) { + tgc_mark_ptr(gc, *((void**)p)); + } + } + +} + +static void tgc_mark(tgc_t *gc) { + + size_t i, k; + jmp_buf env; + void (*volatile mark_stack)(tgc_t*) = tgc_mark_stack; + + if (gc->nitems == 0) { return; } + + for (i = 0; i < gc->nslots; i++) { + if (gc->items[i].hash == 0) { continue; } + if (gc->items[i].flags & TGC_MARK) { continue; } + if (gc->items[i].flags & TGC_ROOT) { + gc->items[i].flags |= TGC_MARK; + if (gc->items[i].flags & TGC_LEAF) { continue; } + for (k = 0; k < gc->items[i].size/sizeof(void*); k++) { + tgc_mark_ptr(gc, ((void**)gc->items[i].ptr)[k]); + } + continue; + } + } + + memset(&env, 0, sizeof(jmp_buf)); + setjmp(env); + mark_stack(gc); + +} + +void tgc_sweep(tgc_t *gc) { + + size_t i, j, k, nj, nh; + + if (gc->nitems == 0) { return; } + + gc->nfrees = 0; + for (i = 0; i < gc->nslots; i++) { + if (gc->items[i].hash == 0) { continue; } + if (gc->items[i].flags & TGC_MARK) { continue; } + if (gc->items[i].flags & TGC_ROOT) { continue; } + gc->nfrees++; + } + + gc->frees = realloc(gc->frees, sizeof(tgc_ptr_t) * gc->nfrees); + if (gc->frees == NULL) { return; } + + i = 0; k = 0; + while (i < gc->nslots) { + if (gc->items[i].hash == 0) { i++; continue; } + if (gc->items[i].flags & TGC_MARK) { i++; continue; } + if (gc->items[i].flags & TGC_ROOT) { i++; continue; } + + gc->frees[k] = gc->items[i]; k++; + memset(&gc->items[i], 0, sizeof(tgc_ptr_t)); + + j = i; + while (1) { + nj = (j+1) % gc->nslots; + nh = gc->items[nj].hash; + if (nh != 0 && tgc_probe(gc, nj, nh) > 0) { + memcpy(&gc->items[ j], &gc->items[nj], sizeof(tgc_ptr_t)); + memset(&gc->items[nj], 0, sizeof(tgc_ptr_t)); + j = nj; + } else { + break; + } + } + gc->nitems--; + } + + for (i = 0; i < gc->nslots; i++) { + if (gc->items[i].hash == 0) { continue; } + if (gc->items[i].flags & TGC_MARK) { + gc->items[i].flags &= ~TGC_MARK; + } + } + + tgc_resize_less(gc); + + gc->mitems = gc->nitems + (size_t)(gc->nitems * gc->sweepfactor) + 1; + + for (i = 0; i < gc->nfrees; i++) { + if (gc->frees[i].ptr) { + if (gc->frees[i].dtor) { gc->frees[i].dtor(gc->frees[i].ptr); } + free(gc->frees[i].ptr); + } + } + + free(gc->frees); + gc->frees = NULL; + gc->nfrees = 0; + +} + +void tgc_start(tgc_t *gc, void *stk) { + gc->bottom = stk; + gc->paused = 0; + gc->nitems = 0; + gc->nslots = 0; + gc->mitems = 0; + gc->nfrees = 0; + gc->maxptr = 0; + gc->items = NULL; + gc->frees = NULL; + gc->minptr = UINTPTR_MAX; + gc->loadfactor = 0.9; + gc->sweepfactor = 0.5; +} + +void tgc_stop(tgc_t *gc) { + tgc_sweep(gc); + free(gc->items); + free(gc->frees); +} + +void tgc_pause(tgc_t *gc) { + gc->paused = 1; +} + +void tgc_resume(tgc_t *gc) { + gc->paused = 0; +} + +void tgc_run(tgc_t *gc) { + tgc_mark(gc); + tgc_sweep(gc); +} + +static void *tgc_add( + tgc_t *gc, void *ptr, size_t size, + int flags, void(*dtor)(void*)) { + + gc->nitems++; + gc->maxptr = ((uintptr_t)ptr) + size > gc->maxptr ? + ((uintptr_t)ptr) + size : gc->maxptr; + gc->minptr = ((uintptr_t)ptr) < gc->minptr ? + ((uintptr_t)ptr) : gc->minptr; + + if (tgc_resize_more(gc)) { + tgc_add_ptr(gc, ptr, size, flags, dtor); + if (!gc->paused && gc->nitems > gc->mitems) { + tgc_run(gc); + } + return ptr; + } else { + gc->nitems--; + free(ptr); + return NULL; + } +} + +static void tgc_rem(tgc_t *gc, void *ptr) { + tgc_rem_ptr(gc, ptr); + tgc_resize_less(gc); + gc->mitems = gc->nitems + gc->nitems / 2 + 1; +} + +void *tgc_alloc(tgc_t *gc, size_t size) { + return tgc_alloc_opt(gc, size, 0, NULL); +} + +void *tgc_calloc(tgc_t *gc, size_t num, size_t size) { + return tgc_calloc_opt(gc, num, size, 0, NULL); +} + +void *tgc_realloc(tgc_t *gc, void *ptr, size_t size) { + + tgc_ptr_t *p; + void *qtr = realloc(ptr, size); + + if (qtr == NULL) { + tgc_rem(gc, ptr); + return qtr; + } + + if (ptr == NULL) { + tgc_add(gc, qtr, size, 0, NULL); + return qtr; + } + + p = tgc_get_ptr(gc, ptr); + + if (p && qtr == ptr) { + p->size = size; + return qtr; + } + + if (p && qtr != ptr) { + int flags = p->flags; + void(*dtor)(void*) = p->dtor; + tgc_rem(gc, ptr); + tgc_add(gc, qtr, size, flags, dtor); + return qtr; + } + + return NULL; +} + +void tgc_free(tgc_t *gc, void *ptr) { + tgc_ptr_t *p = tgc_get_ptr(gc, ptr); + if (p) { + if (p->dtor) { + p->dtor(ptr); + } + free(ptr); + tgc_rem(gc, ptr); + } +} + +void *tgc_alloc_opt(tgc_t *gc, size_t size, int flags, void(*dtor)(void*)) { + void *ptr = malloc(size); + if (ptr != NULL) { + ptr = tgc_add(gc, ptr, size, flags, dtor); + } + return ptr; +} + +void *tgc_calloc_opt( + tgc_t *gc, size_t num, size_t size, + int flags, void(*dtor)(void*)) { + void *ptr = calloc(num, size); + if (ptr != NULL) { + ptr = tgc_add(gc, ptr, num * size, flags, dtor); + } + return ptr; +} + +void tgc_set_dtor(tgc_t *gc, void *ptr, void(*dtor)(void*)) { + tgc_ptr_t *p = tgc_get_ptr(gc, ptr); + if (p) { p->dtor = dtor; } +} + +void tgc_set_flags(tgc_t *gc, void *ptr, int flags) { + tgc_ptr_t *p = tgc_get_ptr(gc, ptr); + if (p) { p->flags = flags; } +} + +int tgc_get_flags(tgc_t *gc, void *ptr) { + tgc_ptr_t *p = tgc_get_ptr(gc, ptr); + if (p) { return p->flags; } + return 0; +} + +void(*tgc_get_dtor(tgc_t *gc, void *ptr))(void*) { + tgc_ptr_t *p = tgc_get_ptr(gc, ptr); + if (p) { return p->dtor; } + return NULL; +} + +size_t tgc_get_size(tgc_t *gc, void *ptr) { + tgc_ptr_t *p = tgc_get_ptr(gc, ptr); + if (p) { return p->size; } + return 0; +} From a801ff47176decb15863c4be35f4e98ff2c95695 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Mon, 27 Sep 2021 00:00:20 +0530 Subject: [PATCH 02/12] Setted up Vulkan Logical Device & Graphics Queue Added string_bool(bool value), and some abstract function signatures in string.h [to be implemented]. --- include/engine/renderer/renderer.h | 10 ++ include/string/string.h | 12 +- source/renderer.c | 269 ++++++++++++++++++++++++++--- source/string.c | 4 +- 4 files changed, 269 insertions(+), 26 deletions(-) diff --git a/include/engine/renderer/renderer.h b/include/engine/renderer/renderer.h index 8f18d517..88b71797 100644 --- a/include/engine/renderer/renderer.h +++ b/include/engine/renderer/renderer.h @@ -23,10 +23,14 @@ instantiate_tuple_t(uint32_t, pVkLayerProperties_t); typedef const char* const* ppVkChar_t; instantiate_tuple_t(uint32_t, ppVkChar_t); +typedef VkQueueFamilyProperties* pVkQueueFamilyProperties_t; +instantiate_tuple_t(uint32_t, pVkQueueFamilyProperties_t); + typedef struct renderer_t { VkInstance vk_instance; + VkDevice vk_device; } renderer_t; @@ -37,17 +41,23 @@ VkInstance vk_create_instance(); tuple_t(uint32_t, pVkPhysicalDevice_t) vk_get_physical_devices(VkInstance instance); tuple_t(uint32_t, pVkExtensionProperties_t) vk_get_instance_extension_properties(); tuple_t(uint32_t, pVkLayerProperties_t) vk_get_instance_layer_properties(); +tuple_t(uint32_t, pVkQueueFamilyProperties_t) vk_get_queue_family_properties(VkPhysicalDevice physical_device); VkPhysicalDeviceProperties vk_get_physical_device_properties(VkPhysicalDevice physical_device); VkPhysicalDeviceFeatures vk_get_physical_device_features(VkPhysicalDevice physical_device); VkPhysicalDeviceMemoryProperties vk_get_physical_device_memory_properties(VkPhysicalDevice physical_device); bool vk_check_layer_support(tuple_t(uint32_t, ppVkChar_t) layers); bool vk_check_extension_support(tuple_t(uint32_t, ppVkChar_t) extensions); +VkPhysicalDevice vk_select_suitable_device(tuple_t(uint32_t, pVkPhysicalDevice_t) physical_devices); //NOT_IMPLEMENTED VkPhysicalDeviceQueueFamilyProperites vk_get_physical_device_queue_family_properties(VkPhysicalDevice physical_device); void vk_dump_instance_extensions(); void vk_dump_instance_layers(); +void vk_dump_physical_devices(tuple_t(uint32_t, pVkPhysicalDevice_t)* physical_devices); +void vk_dump_queue_families(tuple_t(uint32_t, pVkQueueFamilyProperties_t)* queue_families); const char* vk_physical_device_memory_properties_to_string(VkPhysicalDeviceMemoryProperties *memory_properties); const char* vk_physical_device_properties_to_string(VkPhysicalDeviceProperties* properties); const char* vk_physical_device_type_to_string(VkPhysicalDeviceType* deviceType); +const char* vk_physical_device_features_to_string(VkPhysicalDeviceFeatures* device_features); +const char* vk_physical_device_queue_family_to_string(VkQueueFamilyProperties properties); diff --git a/include/string/string.h b/include/string/string.h index 94d75270..6928dd00 100644 --- a/include/string/string.h +++ b/include/string/string.h @@ -2,6 +2,16 @@ #pragma once #include +#include const char* string(uint32_t length, const char* format, ...); -const char* const* string_array(uint32_t count, ...); \ No newline at end of file +const char* const* string_array(uint32_t count, ...); + + +const char* string_bool(bool value); +const char* string_uint32(uint32_t value); +const char* string_int32(int32_t value); +const char* string_uint64(uint64_t value); +const char* string_int64(int64_t value); +const char* string_float(float value); +const char* string_char(char value); \ No newline at end of file diff --git a/source/renderer.c b/source/renderer.c index 7bc2b0e0..bf019d6b 100644 --- a/source/renderer.c +++ b/source/renderer.c @@ -12,6 +12,12 @@ declare_exception(VULKAN_ABORTED); define_exception(VULKAN_ABORTED); +declare_exception(VULKAN_LAYER_NOT_SUPPORTED); +define_exception(VULKAN_LAYER_NOT_SUPPORTED); +declare_exception(VULKAN_EXTENSION_NOT_SUPPORTED); +define_exception(VULKAN_EXTENSION_NOT_SUPPORTED); +define_exception(VULKAN_DEVICE_NOT_FOUND); +declare_exception(VULKAN_DEVICE_NOT_FOUND); #define vkCall(call)\ {\ @@ -23,50 +29,85 @@ define_exception(VULKAN_ABORTED); )\ } -#ifdef DEBUG -static const bool enable_validation_layers = true; -#else -static const bool enable_validation_layers = false; -#endif +static void vk_setup_validation_layers(); renderer_t* renderer_init() { renderer_t* renderer = GC_NEW(renderer_t); VkInstance instance = renderer->vk_instance = vk_create_instance(); -#ifdef DEBUG - vk_dump_instance_extensions(); - vk_dump_instance_layers(); +#ifdef ENABLE_VALIDATION_LAYERS + vk_setup_validation_layers(); #endif - if(vk_check_layer_support((tuple_t(uint32_t, ppVkChar_t)){ 1, string_array(1, "VK_LAYER_KHRONOS_validation") })) - puts("VK_LAYER_KHRONOS_validation is supported"); - else puts("VK_LAYER_KHRONOS_validation is not supported"); - - if(vk_check_extension_support((tuple_t(uint32_t, ppVkChar_t)) { 1, string_array(1, "My Extension") } )) - puts("My Extension is supported"); - else puts("My Extension is not supported"); - + //TODO: this should be something like this: + // VkPhysicalDevice vulkan_device = vk_get_suitable_vulkan_device(); tuple_t(uint32_t, pVkPhysicalDevice_t) physical_devices = vk_get_physical_devices(instance); - for(uint32_t i = 0; i < physical_devices.value1; i++) + VkPhysicalDevice vulkan_device = vk_select_suitable_device(physical_devices); + + int32_t graphics_queue_index = -1; + tuple_t(uint32_t, pVkQueueFamilyProperties_t) queue_families = vk_get_queue_family_properties(vulkan_device); + for(uint32_t i = 0; i < queue_families.value1; i++) { - VkPhysicalDevice device = physical_devices.value2[i]; - VkPhysicalDeviceProperties properties = vk_get_physical_device_properties(device); - VkPhysicalDeviceMemoryProperties memory_properties = vk_get_physical_device_memory_properties(device); - puts("Physical Device Properties----------------------"); - puts(vk_physical_device_properties_to_string(&properties)); - puts("Physical Device Memory Properties---------------"); - puts(vk_physical_device_memory_properties_to_string(&memory_properties)); + VkQueueFamilyProperties properties = queue_families.value2[i]; + if(properties.queueFlags & VK_QUEUE_GRAPHICS_BIT) + { + graphics_queue_index = i; + break; + } } + + VkDeviceQueueCreateInfo queueCreateInfo = { }; + queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueCreateInfo.queueFamilyIndex = graphics_queue_index; + queueCreateInfo.queueCount = 1; + float queuePriorities = 1.0f; + queueCreateInfo.pQueuePriorities = &queuePriorities; + + VkPhysicalDeviceFeatures features = { }; + VkDeviceCreateInfo logicalDeviceCreateInfo = { }; + logicalDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + logicalDeviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; + logicalDeviceCreateInfo.queueCreateInfoCount = 1; + logicalDeviceCreateInfo.pEnabledFeatures = &features; + logicalDeviceCreateInfo.enabledExtensionCount = 0; + logicalDeviceCreateInfo.enabledLayerCount = 0; + + VkDevice logicalDevice; + vkCall(vkCreateDevice(vulkan_device, &logicalDeviceCreateInfo, NULL, &logicalDevice)); + + renderer->vk_device = logicalDevice; + + VkQueue graphicsQueue; + vkGetDeviceQueue(logicalDevice, graphics_queue_index, 0, &graphicsQueue); + + + +#ifdef DEBUG + vk_dump_instance_extensions(); + vk_dump_instance_layers(); + vk_dump_physical_devices(&physical_devices); + vk_dump_queue_families(&queue_families); +#endif return renderer; } void renderer_terminate(renderer_t* renderer) { + vkDestroyDevice(renderer->vk_device, NULL); vkDestroyInstance(renderer->vk_instance, NULL); } +VkPhysicalDevice vk_select_suitable_device(tuple_t(uint32_t, pVkPhysicalDevice_t) physical_devices) +{ + EXCEPTION_BLOCK( + if(physical_devices.value1 <= 0) + throw_exception(VULKAN_DEVICE_NOT_FOUND); + ); + return physical_devices.value2[0]; +} + bool vk_check_layer_support(tuple_t(uint32_t, ppVkChar_t) layers) { tuple_t(uint32_t, pVkLayerProperties_t) layer_properties = vk_get_instance_layer_properties(); @@ -172,6 +213,52 @@ VkPhysicalDeviceMemoryProperties vk_get_physical_device_memory_properties(VkPhys return memory_properties; } +tuple_t(uint32_t, pVkQueueFamilyProperties_t) vk_get_queue_family_properties(VkPhysicalDevice physical_device) +{ + tuple_t(uint32_t, pVkQueueFamilyProperties_t) pair; + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &(pair.value1), NULL); + pair.value2 = GC_NEWV(VkQueueFamilyProperties, pair.value1); + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &(pair.value1), pair.value2); + return pair; +} + +static void vk_setup_validation_layers() +{ + EXCEPTION_BLOCK + ( + if(!vk_check_layer_support((tuple_t(uint32_t, ppVkChar_t)){ 1, string_array(1, "VK_LAYER_KHRONOS_validation") })) + throw_exception(VULKAN_LAYER_NOT_SUPPORTED); + + if(!vk_check_extension_support((tuple_t(uint32_t, ppVkChar_t)) { 1, string_array(1, "My Extension") } )) + throw_exception(VULKAN_EXTENSION_NOT_SUPPORTED); + ); +} + + +void vk_dump_physical_devices(tuple_t(uint32_t, pVkPhysicalDevice_t)* physical_devices) +{ + for(uint32_t i = 0; i < physical_devices->value1; i++) + { + VkPhysicalDevice device = physical_devices->value2[i]; + VkPhysicalDeviceProperties properties = vk_get_physical_device_properties(device); + VkPhysicalDeviceMemoryProperties memory_properties = vk_get_physical_device_memory_properties(device); + VkPhysicalDeviceFeatures features = vk_get_physical_device_features(device); + + puts("Physical Device Properties----------------------"); + puts(vk_physical_device_properties_to_string(&properties)); + puts("Physical Device Memory Properties---------------"); + puts(vk_physical_device_memory_properties_to_string(&memory_properties)); + puts("Physical Device Features------------------------"); + puts(vk_physical_device_features_to_string(&features)); + } +} + +void vk_dump_queue_families(tuple_t(uint32_t, pVkQueueFamilyProperties_t)* queue_families) +{ + puts("Physical Device Queue Family::QueueFlags---------"); + for(uint32_t i = 0; i < queue_families->value1; i++) + puts(vk_physical_device_queue_family_to_string(queue_families->value2[i])); +} void vk_dump_instance_layers() { @@ -189,6 +276,24 @@ void vk_dump_instance_extensions() puts(extension_properties.value2[i].extensionName); } + +const char* vk_physical_device_queue_family_to_string(VkQueueFamilyProperties properties) +{ + char* buffer = GC_NEWV(char, 1024); //1KB + sprintf(buffer, "Queue Count: %u, ", properties.queueCount); + strcat(buffer, "Queue Flags: "); + if(properties.queueFlags & VK_QUEUE_GRAPHICS_BIT) + strcat(buffer, "[VK_QUEUE_GRAPHICS_BIT]"); + if(properties.queueFlags & VK_QUEUE_COMPUTE_BIT) + strcat(buffer, "[VK_QUEUE_COMPUTE_BIT]"); + if(properties.queueFlags & VK_QUEUE_TRANSFER_BIT) + strcat(buffer, "[VK_QUEUE_TRANSFER_BIT]"); + strcat(buffer, ", "); + VkExtent3D extents = properties.minImageTransferGranularity; + sprintf(buffer + strlen(buffer), "minImageTransferGranularity: (%u, %u, %u)", extents.width, extents.height, extents.depth); + return buffer; +} + const char* vk_physical_device_memory_properties_to_string(VkPhysicalDeviceMemoryProperties* memory_properties) { return string(128, @@ -225,6 +330,122 @@ const char* vk_physical_device_limits_to_string(VkPhysicalDeviceLimits* device_l ); } +const char* vk_physical_device_features_to_string(VkPhysicalDeviceFeatures* device_features) +{ + //2KB of memory + return string(2048, + "robustBufferAccess = %s\n" + "fullDrawIndexUint32 = %s\n" + "imageCubeArray = %s\n" + "independentBlend = %s\n" + "geometryShader = %s\n" + "tessellationShader = %s\n" + "sampleRateShading = %s\n" + "dualSrcBlend = %s\n" + "logicOp = %s\n" + "multiDrawIndirect = %s\n" + "drawIndirectFirstInstance = %s\n" + "depthClamp = %s\n" + "depthBiasClamp = %s\n" + "fillModeNonSolid = %s\n" + "depthBounds = %s\n" + "wideLines = %s\n" + "largePoints = %s\n" + "alphaToOne = %s\n" + "multiViewport = %s\n" + "samplerAnisotropy = %s\n" + "textureCompressionETC2 = %s\n" + "textureCompressionASTC_LDR = %s\n" + "textureCompressionBC = %s\n" + "occlusionQueryPrecise = %s\n" + "pipelineStatisticsQuery = %s\n" + "vertexPipelineStoresAndAtomics = %s\n" + "fragmentStoresAndAtomics = %s\n" + "shaderTessellationAndGeometryPointSize = %s\n" + "shaderImageGatherExtended = %s\n" + "shaderStorageImageExtendedFormats = %s\n" + "shaderStorageImageMultisample = %s\n" + "shaderStorageImageReadWithoutFormat = %s\n" + "shaderStorageImageWriteWithoutFormat = %s\n" + "shaderUniformBufferArrayDynamicIndexing = %s\n" + "shaderSampledImageArrayDynamicIndexing = %s\n" + "shaderStorageBufferArrayDynamicIndexing = %s\n" + "shaderStorageImageArrayDynamicIndexing = %s\n" + "shaderClipDistance = %s\n" + "shaderCullDistance = %s\n" + "shaderFloat64 = %s\n" + "shaderInt64 = %s\n" + "shaderInt16 = %s\n" + "shaderResourceResidency = %s\n" + "shaderResourceMinLod = %s\n" + "sparseBinding = %s\n" + "sparseResidencyBuffer = %s\n" + "sparseResidencyImage2D = %s\n" + "sparseResidencyImage3D = %s\n" + "sparseResidency2Samples = %s\n" + "sparseResidency4Samples = %s\n" + "sparseResidency8Samples = %s\n" + "sparseResidency16Samples = %s\n" + "sparseResidencyAliased = %s\n" + "variableMultisampleRate = %s\n" + "inheritedQueries = %s\n" + ,string_bool(device_features->robustBufferAccess) + ,string_bool(device_features->fullDrawIndexUint32) + ,string_bool(device_features->imageCubeArray) + ,string_bool(device_features->independentBlend) + ,string_bool(device_features->geometryShader) + ,string_bool(device_features->tessellationShader) + ,string_bool(device_features->sampleRateShading) + ,string_bool(device_features->dualSrcBlend) + ,string_bool(device_features->logicOp) + ,string_bool(device_features->multiDrawIndirect) + ,string_bool(device_features->drawIndirectFirstInstance) + ,string_bool(device_features->depthClamp) + ,string_bool(device_features->depthBiasClamp) + ,string_bool(device_features->fillModeNonSolid) + ,string_bool(device_features->depthBounds) + ,string_bool(device_features->wideLines) + ,string_bool(device_features->largePoints) + ,string_bool(device_features->alphaToOne) + ,string_bool(device_features->multiViewport) + ,string_bool(device_features->samplerAnisotropy) + ,string_bool(device_features->textureCompressionETC2) + ,string_bool(device_features->textureCompressionASTC_LDR) + ,string_bool(device_features->textureCompressionBC) + ,string_bool(device_features->occlusionQueryPrecise) + ,string_bool(device_features->pipelineStatisticsQuery) + ,string_bool(device_features->vertexPipelineStoresAndAtomics) + ,string_bool(device_features->fragmentStoresAndAtomics) + ,string_bool(device_features->shaderTessellationAndGeometryPointSize) + ,string_bool(device_features->shaderImageGatherExtended) + ,string_bool(device_features->shaderStorageImageExtendedFormats) + ,string_bool(device_features->shaderStorageImageMultisample) + ,string_bool(device_features->shaderStorageImageReadWithoutFormat) + ,string_bool(device_features->shaderStorageImageWriteWithoutFormat) + ,string_bool(device_features->shaderUniformBufferArrayDynamicIndexing) + ,string_bool(device_features->shaderSampledImageArrayDynamicIndexing) + ,string_bool(device_features->shaderStorageBufferArrayDynamicIndexing) + ,string_bool(device_features->shaderStorageImageArrayDynamicIndexing) + ,string_bool(device_features->shaderClipDistance) + ,string_bool(device_features->shaderCullDistance) + ,string_bool(device_features->shaderFloat64) + ,string_bool(device_features->shaderInt64) + ,string_bool(device_features->shaderInt16) + ,string_bool(device_features->shaderResourceResidency) + ,string_bool(device_features->shaderResourceMinLod) + ,string_bool(device_features->sparseBinding) + ,string_bool(device_features->sparseResidencyBuffer) + ,string_bool(device_features->sparseResidencyImage2D) + ,string_bool(device_features->sparseResidencyImage3D) + ,string_bool(device_features->sparseResidency2Samples) + ,string_bool(device_features->sparseResidency4Samples) + ,string_bool(device_features->sparseResidency8Samples) + ,string_bool(device_features->sparseResidency16Samples) + ,string_bool(device_features->sparseResidencyAliased) + ,string_bool(device_features->variableMultisampleRate) + ,string_bool(device_features->inheritedQueries)); +} + const char* vk_physical_device_type_to_string(VkPhysicalDeviceType *device_type) { switch(*device_type) diff --git a/source/string.c b/source/string.c index a7789396..3255bcdd 100644 --- a/source/string.c +++ b/source/string.c @@ -29,4 +29,6 @@ const char* const* string_array(uint32_t count, ...) } va_end(args); return buffer; -} \ No newline at end of file +} + +const char* string_bool(bool value) { return value == true ? "true" : "false"; } \ No newline at end of file From 41b4bec46056c357746280c79f602b1d37eeeba3 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Tue, 28 Sep 2021 22:07:19 +0530 Subject: [PATCH 03/12] Added release mode defined in makefile --- makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/makefile b/makefile index 9fe4bd73..50f4e757 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,7 @@ -DEFINES= -DHPML_DEBUG_MODE -DLOG_DEBUG -DGLOBAL_DEBUG +DEFINES= -DHPML_DEBUG_MODE -DLOG_DEBUG -DGLOBAL_DEBUG -DDEBUG +# DEFINES= -DHPML_RELEASE_MODE -DLOG_RELEASE -DGLOBAL_RELEASE -DRELEASE + COMPILATION_CONFIG= -m64 INCLUDES= -I.\include -I.\include\engine -I.\scripts From 5c41f41221e40b741a348cca388a18902319f952 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Tue, 28 Sep 2021 22:08:18 +0530 Subject: [PATCH 04/12] added vulkan_wrapper header and source vulkan_wrapper will contains some basic wrapper functions for the vulkan api in a very good manner --- include/vulkan/vulkan_wrapper.h | 79 ++++++ source/vulkan_wrapper.c | 458 ++++++++++++++++++++++++++++++++ 2 files changed, 537 insertions(+) create mode 100644 include/vulkan/vulkan_wrapper.h create mode 100644 source/vulkan_wrapper.c diff --git a/include/vulkan/vulkan_wrapper.h b/include/vulkan/vulkan_wrapper.h new file mode 100644 index 00000000..007863b3 --- /dev/null +++ b/include/vulkan/vulkan_wrapper.h @@ -0,0 +1,79 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + + +#define vkCall(call)\ +{\ + VkResult result = call;\ + EXCEPTION_BLOCK\ + (\ + if(result != VK_SUCCESS)\ + throw_exception(VULKAN_ABORTED);\ + )\ +} + + +declare_exception(VULKAN_EXTENSION_NOT_SUPPORTED); +declare_exception(VULKAN_LAYER_NOT_SUPPORTED); +declare_exception(VULKAN_ABORTED); +declare_exception(VULKAN_DEVICE_NOT_FOUND); + + +typedef VkPhysicalDevice* pVkPhysicalDevice_t; +instantiate_tuple_t(uint32_t, pVkPhysicalDevice_t); + +typedef VkExtensionProperties* pVkExtensionProperties_t; +instantiate_tuple_t(uint32_t, pVkExtensionProperties_t); + +typedef VkLayerProperties* pVkLayerProperties_t; +instantiate_tuple_t(uint32_t, pVkLayerProperties_t); + +typedef const char* const* ppVkChar_t; +instantiate_tuple_t(uint32_t, ppVkChar_t); + +typedef VkQueueFamilyProperties* pVkQueueFamilyProperties_t; +instantiate_tuple_t(uint32_t, pVkQueueFamilyProperties_t); + +typedef VkSurfaceFormatKHR* pVkSurfaceFormatKHR_t; +instantiate_tuple_t(uint32_t, pVkSurfaceFormatKHR_t); + +typedef VkPresentModeKHR* pVkPresentModeKHR_t; +instantiate_tuple_t(uint32_t, pVkPresentModeKHR_t); + +void vk_setup_validation_layers(); +VkInstance vk_create_instance(); +tuple_t(uint32_t, pVkPhysicalDevice_t) vk_get_physical_devices(VkInstance instance); +tuple_t(uint32_t, pVkExtensionProperties_t) vk_get_instance_extension_properties(); +tuple_t(uint32_t, pVkExtensionProperties_t) vk_get_physical_device_extension_properties(VkPhysicalDevice physical_device); +tuple_t(uint32_t, pVkLayerProperties_t) vk_get_instance_layer_properties(); +tuple_t(uint32_t, pVkQueueFamilyProperties_t) vk_get_queue_family_properties(VkPhysicalDevice physical_device); +tuple_t(uint32_t, pVkSurfaceFormatKHR_t) vk_get_physical_device_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface); +tuple_t(uint32_t, pVkPresentModeKHR_t) vk_get_physical_device_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface); + +VkSurfaceCapabilitiesKHR vk_get_physical_device_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface); +VkPhysicalDeviceProperties vk_get_physical_device_properties(VkPhysicalDevice physical_device); +VkPhysicalDeviceFeatures vk_get_physical_device_features(VkPhysicalDevice physical_device); +VkPhysicalDeviceMemoryProperties vk_get_physical_device_memory_properties(VkPhysicalDevice physical_device); +bool vk_check_layer_support(tuple_t(uint32_t, ppVkChar_t) layers); +bool vk_check_instance_extension_support(tuple_t(uint32_t, ppVkChar_t) extensions); +bool vk_check_physical_device_extension_support(VkPhysicalDevice device, tuple_t(uint32_t, ppVkChar_t) extensions); +VkPhysicalDevice vk_select_suitable_device(tuple_t(uint32_t, pVkPhysicalDevice_t) physical_devices); +//NOT_IMPLEMENTED VkPhysicalDeviceQueueFamilyProperites vk_get_physical_device_queue_family_properties(VkPhysicalDevice physical_device); + +void vk_dump_instance_extensions(); +void vk_dump_instance_layers(); +void vk_dump_physical_devices(tuple_t(uint32_t, pVkPhysicalDevice_t)* physical_devices); +void vk_dump_queue_families(tuple_t(uint32_t, pVkQueueFamilyProperties_t)* queue_families); + + +const char* vk_physical_device_memory_properties_to_string(VkPhysicalDeviceMemoryProperties *memory_properties); +const char* vk_physical_device_properties_to_string(VkPhysicalDeviceProperties* properties); +const char* vk_physical_device_type_to_string(VkPhysicalDeviceType* deviceType); +const char* vk_physical_device_features_to_string(VkPhysicalDeviceFeatures* device_features); +const char* vk_physical_device_queue_family_to_string(VkQueueFamilyProperties properties); \ No newline at end of file diff --git a/source/vulkan_wrapper.c b/source/vulkan_wrapper.c new file mode 100644 index 00000000..3a3be696 --- /dev/null +++ b/source/vulkan_wrapper.c @@ -0,0 +1,458 @@ + + +#include +#include +#include +#include +#include +#include +#include //custom string library +#include //standard string library +#include + +define_exception(VULKAN_ABORTED); +define_exception(VULKAN_LAYER_NOT_SUPPORTED); +define_exception(VULKAN_DEVICE_NOT_FOUND); +define_exception(VULKAN_EXTENSION_NOT_SUPPORTED); + +VkPhysicalDevice vk_select_suitable_device(tuple_t(uint32_t, pVkPhysicalDevice_t) physical_devices) +{ + EXCEPTION_BLOCK( + if(physical_devices.value1 <= 0) + throw_exception(VULKAN_DEVICE_NOT_FOUND); + ); + return physical_devices.value2[0]; +} + +bool vk_check_layer_support(tuple_t(uint32_t, ppVkChar_t) layers) +{ + tuple_t(uint32_t, pVkLayerProperties_t) layer_properties = vk_get_instance_layer_properties(); + for(uint32_t i = 0; i < layers.value1; i++) + { + bool contains = false; + for(uint32_t j = 0; j < layer_properties.value1; j++) + { + if(strcmp(layers.value2[i], layer_properties.value2[j].layerName) == 0) + { + contains = true; + break; + } + } + if(!contains) + return false; + } + return true; +} + + +bool vk_check_physical_device_extension_support(VkPhysicalDevice device, tuple_t(uint32_t, ppVkChar_t) extensions) +{ + tuple_t(uint32_t, pVkExtensionProperties_t) extension_properties = vk_get_physical_device_extension_properties(device); + for (uint32_t i = 0; i < extensions.value1; ++i) + { + bool contains = false; + for(uint32_t j = 0; j < extension_properties.value1; j++) + { + if(strcmp(extensions.value2[i], extension_properties.value2[j].extensionName) == 0) + { + contains = true; + break; + } + } + if(!contains) + return false; + } + return true; +} + +bool vk_check_instance_extension_support(tuple_t(uint32_t, ppVkChar_t) extensions) +{ + tuple_t(uint32_t, pVkExtensionProperties_t) extension_properties = vk_get_instance_extension_properties(); + for(uint32_t i = 0; i < extensions.value1; i++) + { + bool contains = false; + for(uint32_t j = 0; j < extension_properties.value1; j++) + { + if(strcmp(extensions.value2[i], extension_properties.value2[j].extensionName) == 0) + { + contains = true; + break; + } + } + if(!contains) + return false; + } + return true; +} + +VkInstance vk_create_instance() +{ + VkInstanceCreateInfo instance_create_info = { }; + instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instance_create_info.pNext = NULL; + instance_create_info.flags = 0; + instance_create_info.pApplicationInfo = NULL; + instance_create_info.enabledLayerCount = 0; + instance_create_info.ppEnabledLayerNames = NULL; + instance_create_info.enabledExtensionCount = 2; + instance_create_info.ppEnabledExtensionNames = string_array(2, "VK_KHR_surface", "VK_KHR_win32_surface"); + VkInstance instance; + vkCall(vkCreateInstance(&instance_create_info, NULL, &instance)); + return instance; +} + +tuple_t(uint32_t, pVkPhysicalDevice_t) vk_get_physical_devices(VkInstance instance) +{ + tuple_t(uint32_t, pVkPhysicalDevice_t) pair; + vkCall(vkEnumeratePhysicalDevices(instance, &(pair.value1), NULL)); + pair.value2 = (pVkPhysicalDevice_t)GC_ALLOC(sizeof(VkPhysicalDevice) * pair.value1); + vkCall(vkEnumeratePhysicalDevices(instance, &(pair.value1), pair.value2)); + return pair; +} + +tuple_t(uint32_t, pVkExtensionProperties_t) vk_get_instance_extension_properties() +{ + tuple_t(uint32_t, pVkExtensionProperties_t) pair; + vkCall(vkEnumerateInstanceExtensionProperties(NULL, &(pair.value1), NULL)); + pair.value2 = GC_NEWV(VkExtensionProperties, pair.value1); + vkCall(vkEnumerateInstanceExtensionProperties(NULL, &(pair.value1), pair.value2)); + return pair; +} + +tuple_t(uint32_t, pVkExtensionProperties_t) vk_get_physical_device_extension_properties(VkPhysicalDevice physical_device) +{ + tuple_t(uint32_t, pVkExtensionProperties_t) pair; + vkCall(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &(pair.value1), NULL)); + pair.value2 = GC_NEWV(VkExtensionProperties, pair.value1); + vkCall(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &(pair.value1), pair.value2)); + return pair; +} + +tuple_t(uint32_t, pVkLayerProperties_t) vk_get_instance_layer_properties() +{ + tuple_t(uint32_t, pVkLayerProperties_t) pair; + vkCall(vkEnumerateInstanceLayerProperties(&(pair.value1), NULL)); + pair.value2 = GC_NEWV(VkLayerProperties, pair.value1); + vkCall(vkEnumerateInstanceLayerProperties(&(pair.value1), pair.value2)); + return pair; +} + +VkPhysicalDeviceProperties vk_get_physical_device_properties(VkPhysicalDevice physical_device) +{ + VkPhysicalDeviceProperties properties; + vkGetPhysicalDeviceProperties(physical_device, &properties); + return properties; +} + +VkSurfaceCapabilitiesKHR vk_get_physical_device_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface) +{ + VkSurfaceCapabilitiesKHR capabilities; + vkCall(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &capabilities)); + return capabilities; +} + +VkPhysicalDeviceFeatures vk_get_physical_device_features(VkPhysicalDevice physical_device) +{ + VkPhysicalDeviceFeatures features; + vkGetPhysicalDeviceFeatures(physical_device, &features); + return features; +} + +VkPhysicalDeviceMemoryProperties vk_get_physical_device_memory_properties(VkPhysicalDevice physical_device) +{ + VkPhysicalDeviceMemoryProperties memory_properties; + vkGetPhysicalDeviceMemoryProperties(physical_device, &memory_properties); + return memory_properties; +} + +tuple_t(uint32_t, pVkQueueFamilyProperties_t) vk_get_queue_family_properties(VkPhysicalDevice physical_device) +{ + tuple_t(uint32_t, pVkQueueFamilyProperties_t) pair; + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &(pair.value1), NULL); + pair.value2 = GC_NEWV(VkQueueFamilyProperties, pair.value1); + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &(pair.value1), pair.value2); + return pair; +} + +tuple_t(uint32_t, pVkSurfaceFormatKHR_t) vk_get_physical_device_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface) +{ + tuple_t(uint32_t, pVkSurfaceFormatKHR_t) pair; + vkCall(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &(pair.value1), NULL)); + pair.value2 = GC_NEWV(VkSurfaceFormatKHR, pair.value1); + vkCall(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &(pair.value1), pair.value2)); + return pair; +} + +tuple_t(uint32_t, pVkPresentModeKHR_t) vk_get_physical_device_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface) +{ + tuple_t(uint32_t, pVkPresentModeKHR_t) pair; + vkCall(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &(pair.value1), NULL)); + pair.value2 = GC_NEWV(VkPresentModeKHR, pair.value1); + vkCall(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &(pair.value1), pair.value2)); + return pair; +} + +void vk_setup_validation_layers() +{ + EXCEPTION_BLOCK + ( + if(!vk_check_layer_support((tuple_t(uint32_t, ppVkChar_t)){ 1, string_array(1, "VK_LAYER_KHRONOS_validation") })) + throw_exception(VULKAN_LAYER_NOT_SUPPORTED); + + if(!vk_check_instance_extension_support((tuple_t(uint32_t, ppVkChar_t)) { 1, string_array(1, "My Extension") } )) + throw_exception(VULKAN_EXTENSION_NOT_SUPPORTED); + ); +} + + +void vk_dump_physical_devices(tuple_t(uint32_t, pVkPhysicalDevice_t)* physical_devices) +{ + for(uint32_t i = 0; i < physical_devices->value1; i++) + { + VkPhysicalDevice device = physical_devices->value2[i]; + VkPhysicalDeviceProperties properties = vk_get_physical_device_properties(device); + VkPhysicalDeviceMemoryProperties memory_properties = vk_get_physical_device_memory_properties(device); + VkPhysicalDeviceFeatures features = vk_get_physical_device_features(device); + + puts("Physical Device Properties----------------------"); + puts(vk_physical_device_properties_to_string(&properties)); + puts("Physical Device Memory Properties---------------"); + puts(vk_physical_device_memory_properties_to_string(&memory_properties)); + puts("Physical Device Features------------------------"); + puts(vk_physical_device_features_to_string(&features)); + } +} + +void vk_dump_queue_families(tuple_t(uint32_t, pVkQueueFamilyProperties_t)* queue_families) +{ + puts("Physical Device Queue Family::QueueFlags---------"); + for(uint32_t i = 0; i < queue_families->value1; i++) + puts(vk_physical_device_queue_family_to_string(queue_families->value2[i])); +} + +void vk_dump_instance_layers() +{ + tuple_t(uint32_t, pVkLayerProperties_t) layer_properties = vk_get_instance_layer_properties(); + puts("Instance Layer Properties----------------------"); + for(uint32_t i = 0; i < layer_properties.value1; i++) + puts(layer_properties.value2[i].layerName); +} + +void vk_dump_instance_extensions() +{ + tuple_t(uint32_t, pVkExtensionProperties_t) extension_properties = vk_get_instance_extension_properties(); + puts("Instance Extension Properties----------------------"); + for(uint32_t i = 0; i < extension_properties.value1; i++) + puts(extension_properties.value2[i].extensionName); +} + + +const char* vk_physical_device_queue_family_to_string(VkQueueFamilyProperties properties) +{ + char* buffer = GC_NEWV(char, 1024); //1KB + sprintf(buffer, "Queue Count: %u, ", properties.queueCount); + strcat(buffer, "Queue Flags: "); + if(properties.queueFlags & VK_QUEUE_GRAPHICS_BIT) + strcat(buffer, "[VK_QUEUE_GRAPHICS_BIT]"); + if(properties.queueFlags & VK_QUEUE_COMPUTE_BIT) + strcat(buffer, "[VK_QUEUE_COMPUTE_BIT]"); + if(properties.queueFlags & VK_QUEUE_TRANSFER_BIT) + strcat(buffer, "[VK_QUEUE_TRANSFER_BIT]"); + strcat(buffer, ", "); + VkExtent3D extents = properties.minImageTransferGranularity; + sprintf(buffer + strlen(buffer), "minImageTransferGranularity: (%u, %u, %u)", extents.width, extents.height, extents.depth); + return buffer; +} + +const char* vk_physical_device_memory_properties_to_string(VkPhysicalDeviceMemoryProperties* memory_properties) +{ + return string(128, + "Memory Type Count: %u\n", + memory_properties->memoryTypeCount + ); +} + +const char* vk_physical_device_limits_to_string(VkPhysicalDeviceLimits* device_limits) +{ + return string(512, + "Max Image Dimension 1D [width]: %u\n" + "Max Image Dimension 2D max(width, height): %u\n" + "Max Image Dimension 3D max(width, height, depth): %u\n" + "Max Image Dimension Cube max(width, height): %u\n" + "Max Image Layers: %u\n" + "Max Texel Buffer Elements: %u\n" + , + device_limits->maxImageDimension1D, + device_limits->maxImageDimension2D, + device_limits->maxImageDimension3D, + device_limits->maxImageDimensionCube, + device_limits->maxImageArrayLayers, + device_limits->maxTexelBufferElements + // device_limits->maxUniformBufferRange, + // device_limits->maxStorageBufferRange, + // device_limits->maxPushConstantsSize, + // device_limits->maxMemoryAllocationCount, + // device_limits->maxSamplerAllocationCount, + // device_limits->bufferImageGranularity, + // device_limits->sparseAddressSpaceSize, + // device_limits->maxBoundDescriptorSets, + // device_limits->maxPerStageDescriptorSampler, + ); +} + +const char* vk_physical_device_features_to_string(VkPhysicalDeviceFeatures* device_features) +{ + //2KB of memory + return string(2048, + "robustBufferAccess = %s\n" + "fullDrawIndexUint32 = %s\n" + "imageCubeArray = %s\n" + "independentBlend = %s\n" + "geometryShader = %s\n" + "tessellationShader = %s\n" + "sampleRateShading = %s\n" + "dualSrcBlend = %s\n" + "logicOp = %s\n" + "multiDrawIndirect = %s\n" + "drawIndirectFirstInstance = %s\n" + "depthClamp = %s\n" + "depthBiasClamp = %s\n" + "fillModeNonSolid = %s\n" + "depthBounds = %s\n" + "wideLines = %s\n" + "largePoints = %s\n" + "alphaToOne = %s\n" + "multiViewport = %s\n" + "samplerAnisotropy = %s\n" + "textureCompressionETC2 = %s\n" + "textureCompressionASTC_LDR = %s\n" + "textureCompressionBC = %s\n" + "occlusionQueryPrecise = %s\n" + "pipelineStatisticsQuery = %s\n" + "vertexPipelineStoresAndAtomics = %s\n" + "fragmentStoresAndAtomics = %s\n" + "shaderTessellationAndGeometryPointSize = %s\n" + "shaderImageGatherExtended = %s\n" + "shaderStorageImageExtendedFormats = %s\n" + "shaderStorageImageMultisample = %s\n" + "shaderStorageImageReadWithoutFormat = %s\n" + "shaderStorageImageWriteWithoutFormat = %s\n" + "shaderUniformBufferArrayDynamicIndexing = %s\n" + "shaderSampledImageArrayDynamicIndexing = %s\n" + "shaderStorageBufferArrayDynamicIndexing = %s\n" + "shaderStorageImageArrayDynamicIndexing = %s\n" + "shaderClipDistance = %s\n" + "shaderCullDistance = %s\n" + "shaderFloat64 = %s\n" + "shaderInt64 = %s\n" + "shaderInt16 = %s\n" + "shaderResourceResidency = %s\n" + "shaderResourceMinLod = %s\n" + "sparseBinding = %s\n" + "sparseResidencyBuffer = %s\n" + "sparseResidencyImage2D = %s\n" + "sparseResidencyImage3D = %s\n" + "sparseResidency2Samples = %s\n" + "sparseResidency4Samples = %s\n" + "sparseResidency8Samples = %s\n" + "sparseResidency16Samples = %s\n" + "sparseResidencyAliased = %s\n" + "variableMultisampleRate = %s\n" + "inheritedQueries = %s\n" + ,string_bool(device_features->robustBufferAccess) + ,string_bool(device_features->fullDrawIndexUint32) + ,string_bool(device_features->imageCubeArray) + ,string_bool(device_features->independentBlend) + ,string_bool(device_features->geometryShader) + ,string_bool(device_features->tessellationShader) + ,string_bool(device_features->sampleRateShading) + ,string_bool(device_features->dualSrcBlend) + ,string_bool(device_features->logicOp) + ,string_bool(device_features->multiDrawIndirect) + ,string_bool(device_features->drawIndirectFirstInstance) + ,string_bool(device_features->depthClamp) + ,string_bool(device_features->depthBiasClamp) + ,string_bool(device_features->fillModeNonSolid) + ,string_bool(device_features->depthBounds) + ,string_bool(device_features->wideLines) + ,string_bool(device_features->largePoints) + ,string_bool(device_features->alphaToOne) + ,string_bool(device_features->multiViewport) + ,string_bool(device_features->samplerAnisotropy) + ,string_bool(device_features->textureCompressionETC2) + ,string_bool(device_features->textureCompressionASTC_LDR) + ,string_bool(device_features->textureCompressionBC) + ,string_bool(device_features->occlusionQueryPrecise) + ,string_bool(device_features->pipelineStatisticsQuery) + ,string_bool(device_features->vertexPipelineStoresAndAtomics) + ,string_bool(device_features->fragmentStoresAndAtomics) + ,string_bool(device_features->shaderTessellationAndGeometryPointSize) + ,string_bool(device_features->shaderImageGatherExtended) + ,string_bool(device_features->shaderStorageImageExtendedFormats) + ,string_bool(device_features->shaderStorageImageMultisample) + ,string_bool(device_features->shaderStorageImageReadWithoutFormat) + ,string_bool(device_features->shaderStorageImageWriteWithoutFormat) + ,string_bool(device_features->shaderUniformBufferArrayDynamicIndexing) + ,string_bool(device_features->shaderSampledImageArrayDynamicIndexing) + ,string_bool(device_features->shaderStorageBufferArrayDynamicIndexing) + ,string_bool(device_features->shaderStorageImageArrayDynamicIndexing) + ,string_bool(device_features->shaderClipDistance) + ,string_bool(device_features->shaderCullDistance) + ,string_bool(device_features->shaderFloat64) + ,string_bool(device_features->shaderInt64) + ,string_bool(device_features->shaderInt16) + ,string_bool(device_features->shaderResourceResidency) + ,string_bool(device_features->shaderResourceMinLod) + ,string_bool(device_features->sparseBinding) + ,string_bool(device_features->sparseResidencyBuffer) + ,string_bool(device_features->sparseResidencyImage2D) + ,string_bool(device_features->sparseResidencyImage3D) + ,string_bool(device_features->sparseResidency2Samples) + ,string_bool(device_features->sparseResidency4Samples) + ,string_bool(device_features->sparseResidency8Samples) + ,string_bool(device_features->sparseResidency16Samples) + ,string_bool(device_features->sparseResidencyAliased) + ,string_bool(device_features->variableMultisampleRate) + ,string_bool(device_features->inheritedQueries)); +} + +const char* vk_physical_device_type_to_string(VkPhysicalDeviceType *device_type) +{ + switch(*device_type) + { + case VK_PHYSICAL_DEVICE_TYPE_OTHER: + return "VK_PHYSICAL_DEVICE_TYPE_OTHER"; + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: + return "VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU"; + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: + return "VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU"; + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: + return "VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU"; + case VK_PHYSICAL_DEVICE_TYPE_CPU: + return "VK_PHYSICAL_DEVICE_TYPE_CPU"; + default: + return "(Unknown)"; + } +} + +const char* vk_physical_device_properties_to_string(VkPhysicalDeviceProperties* properties) +{ + return string(1024, + "API Version: %d\n" + "Driver Version: %d\n" + "Vendor ID: %d\n" + "Device ID: %d\n" + "Device Name: %s\n" + "Device Type: %s\n" + "Pipeline Cache UUID: %d\n" + "Device Limits: \n" + "%s", + properties->apiVersion, + properties->driverVersion, + properties->vendorID, + properties->deviceID, + properties->deviceName, + vk_physical_device_type_to_string(&(properties->deviceType)), + properties->pipelineCacheUUID, + vk_physical_device_limits_to_string(&(properties->limits))); +} \ No newline at end of file From 55831369eae4e9891544222517d7bbb6b06205c6 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Tue, 28 Sep 2021 22:10:32 +0530 Subject: [PATCH 05/12] Added malloc allocator in debug mode in garbage_collector When we will build our project in RELEASE mode then garbage_collector will use tgc_alloc allocator, otherwise in DEBUG mode, it will use the malloc allocator.. --- include/garbage_collector/garbage_collector.h | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/include/garbage_collector/garbage_collector.h b/include/garbage_collector/garbage_collector.h index 80fdda08..06e8e688 100644 --- a/include/garbage_collector/garbage_collector.h +++ b/include/garbage_collector/garbage_collector.h @@ -6,13 +6,26 @@ extern tgc_t gc; -#define GC_START(stack_address) tgc_start(&gc, (void*)(stack_address)) -#define GC_STOP() tgc_stop(&gc) -#define GC_RUN() tgc_run(&gc) -#define GC_PAUSE() tgc_pause(&gc) -#define GC_RESUME() tgc_resume(&gc) -#define GC_ALLOC(size) tgc_alloc(&gc, size) -#define GC_FREE(ptr) tgc_free(&gc, ptr) +#ifndef DEBUG +# define GC_START(stack_address) tgc_start(&gc, (void*)(stack_address)) +# define GC_STOP() tgc_stop(&gc) +# define GC_RUN() tgc_run(&gc) +# define GC_PAUSE() tgc_pause(&gc) +# define GC_RESUME() tgc_resume(&gc) +# define GC_ALLOC(size) tgc_alloc(&gc, size) +# define GC_FREE(ptr) tgc_free(&gc, ptr) +# warning "Using GC_ALLOC" +#else +# include +# define GC_START(stack_address) +# define GC_STOP() +# define GC_RUN() +# define GC_PAUSE() +# define GC_RESUME() +# define GC_ALLOC(size) malloc(size) +# define GC_FREE(ptr) free(ptr) +# warning "Using MALLOC" +#endif #define GC_NEW(type) (type*)GC_ALLOC(sizeof(type)) #define GC_NEWV(type, count) (type*)GC_ALLOC(sizeof(type) * (count)) \ No newline at end of file From 86c16b3348e38ba91d309a08a695acbcb99789de Mon Sep 17 00:00:00 2001 From: ravi688 Date: Tue, 28 Sep 2021 22:11:27 +0530 Subject: [PATCH 06/12] Added swapchain creation, & refactored Added swapchain creation and moved some code [refactored] to vulkan_wrapper.h & vulkan_wrapper.c --- include/engine/engine.h | 9 +- include/engine/renderer/renderer.h | 60 +-- source/engine.c | 63 +++- source/renderer.c | 582 +++++++++-------------------- 4 files changed, 243 insertions(+), 471 deletions(-) diff --git a/include/engine/engine.h b/include/engine/engine.h index 9190f601..b5468d66 100644 --- a/include/engine/engine.h +++ b/include/engine/engine.h @@ -22,13 +22,7 @@ #include -typedef struct engine_t -{ - void* window; - void* scene_manager; - void* renderer; -} engine_t; - +typedef struct engine_t engine_t; engine_t* engine_init(uint32_t screen_width, uint32_t screen_height, const char* window_name); void engine_terminate(engine_t* engine); @@ -40,6 +34,7 @@ void engine_update(engine_t* engine); +void* engine_get_window(engine_t* engine); scene_manager_t* engine_get_scene_manager(engine_t* engine); renderer_t* engine_get_renderer(engine_t* engine); diff --git a/include/engine/renderer/renderer.h b/include/engine/renderer/renderer.h index 88b71797..e682cfc0 100644 --- a/include/engine/renderer/renderer.h +++ b/include/engine/renderer/renderer.h @@ -1,63 +1,17 @@ #pragma once - -#include -#include - -#include #include - #include -#include -#include - -typedef VkPhysicalDevice* pVkPhysicalDevice_t; -instantiate_tuple_t(uint32_t, pVkPhysicalDevice_t); - -typedef VkExtensionProperties* pVkExtensionProperties_t; -instantiate_tuple_t(uint32_t, pVkExtensionProperties_t); - -typedef VkLayerProperties* pVkLayerProperties_t; -instantiate_tuple_t(uint32_t, pVkLayerProperties_t); - -typedef const char* const* ppVkChar_t; -instantiate_tuple_t(uint32_t, ppVkChar_t); - -typedef VkQueueFamilyProperties* pVkQueueFamilyProperties_t; -instantiate_tuple_t(uint32_t, pVkQueueFamilyProperties_t); - - -typedef struct renderer_t -{ - VkInstance vk_instance; - VkDevice vk_device; -} renderer_t; +typedef struct renderer_t renderer_t; renderer_t* renderer_init(); void renderer_terminate(renderer_t* renderer); -VkInstance vk_create_instance(); -tuple_t(uint32_t, pVkPhysicalDevice_t) vk_get_physical_devices(VkInstance instance); -tuple_t(uint32_t, pVkExtensionProperties_t) vk_get_instance_extension_properties(); -tuple_t(uint32_t, pVkLayerProperties_t) vk_get_instance_layer_properties(); -tuple_t(uint32_t, pVkQueueFamilyProperties_t) vk_get_queue_family_properties(VkPhysicalDevice physical_device); - -VkPhysicalDeviceProperties vk_get_physical_device_properties(VkPhysicalDevice physical_device); -VkPhysicalDeviceFeatures vk_get_physical_device_features(VkPhysicalDevice physical_device); -VkPhysicalDeviceMemoryProperties vk_get_physical_device_memory_properties(VkPhysicalDevice physical_device); -bool vk_check_layer_support(tuple_t(uint32_t, ppVkChar_t) layers); -bool vk_check_extension_support(tuple_t(uint32_t, ppVkChar_t) extensions); -VkPhysicalDevice vk_select_suitable_device(tuple_t(uint32_t, pVkPhysicalDevice_t) physical_devices); -//NOT_IMPLEMENTED VkPhysicalDeviceQueueFamilyProperites vk_get_physical_device_queue_family_properties(VkPhysicalDevice physical_device); - -void vk_dump_instance_extensions(); -void vk_dump_instance_layers(); -void vk_dump_physical_devices(tuple_t(uint32_t, pVkPhysicalDevice_t)* physical_devices); -void vk_dump_queue_families(tuple_t(uint32_t, pVkQueueFamilyProperties_t)* queue_families); -const char* vk_physical_device_memory_properties_to_string(VkPhysicalDeviceMemoryProperties *memory_properties); -const char* vk_physical_device_properties_to_string(VkPhysicalDeviceProperties* properties); -const char* vk_physical_device_type_to_string(VkPhysicalDeviceType* deviceType); -const char* vk_physical_device_features_to_string(VkPhysicalDeviceFeatures* device_features); -const char* vk_physical_device_queue_family_to_string(VkQueueFamilyProperties properties); +//Graphics API specifics +void renderer_init_surface(renderer_t* renderer, void* surface); +void* renderer_get_vulkan_instance(renderer_t* renderer); +void* renderer_get_vulkan_device(renderer_t* renderer); +void* renderer_get_vulkan_surface(renderer_t* renderer); +void* renderer_get_vulkan_swapchain(renderer_t* renderer); \ No newline at end of file diff --git a/source/engine.c b/source/engine.c index 43ee0adf..809ba30e 100644 --- a/source/engine.c +++ b/source/engine.c @@ -3,35 +3,80 @@ #include #include +#define GLFW_INCLUDE_VULKAN +#include + +#include + +typedef struct engine_t +{ + void* window; + scene_manager_t* scene_manager; + renderer_t* renderer; +} engine_t; + +void* engine_get_window(engine_t* engine) { return engine->window; } +scene_manager_t* engine_get_scene_manager(engine_t* engine) { return engine->scene_manager; } +renderer_t* engine_get_renderer(engine_t* engine) { return engine->renderer; } + +static VkSurfaceKHR glfw_get_vulkan_surface(GLFWwindow* window, renderer_t* renderer); +static tuple_t(uint32_t, ppVkChar_t) glfw_get_required_instance_extensions(); +static void glfw_dump_required_extensions(); + engine_t* engine_init(uint32_t screen_width, uint32_t screen_height, const char* window_name) { glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); engine_t* engine = GC_NEW(engine_t); engine->window = glfwCreateWindow(screen_width, screen_height, window_name, NULL, NULL); engine->scene_manager = scene_manager_init(); engine->renderer = renderer_init(); +#if DEBUG + glfw_dump_required_extensions(); +#endif + VkSurfaceKHR surface = glfw_get_vulkan_surface((GLFWwindow*)(engine->window), engine->renderer); + renderer_init_surface(engine->renderer, (void*)(&surface)); return engine; } -void engine_terminate(engine_t* engine) + +static VkSurfaceKHR glfw_get_vulkan_surface(GLFWwindow* window, renderer_t* renderer) { - scene_manager_for_each_objects_in_all_scenes(engine->scene_manager, object_destroy); - renderer_terminate(engine_get_renderer(engine)); + VkInstance instance = *((VkInstance*)renderer_get_vulkan_instance(renderer)); + VkSurfaceKHR surface; + vkCall(glfwCreateWindowSurface(instance, window, NULL, &surface)); + return surface; +} - glfwDestroyWindow((GLFWwindow*)(engine->window)); - glfwTerminate(); +static tuple_t(uint32_t, ppVkChar_t) glfw_get_required_instance_extensions() +{ + tuple_t(uint32_t, ppVkChar_t) pair; + pair.value2 = (ppVkChar_t)glfwGetRequiredInstanceExtensions(&(pair.value1)); + return pair; } -scene_manager_t* engine_get_scene_manager(engine_t* engine) +static void glfw_dump_required_extensions() { - return engine->scene_manager; + tuple_t(uint32_t, ppVkChar_t) required_extensions = glfw_get_required_instance_extensions(); +EXCEPTION_BLOCK +( + if(!vk_check_instance_extension_support(required_extensions)) + throw_exception(VULKAN_EXTENSION_NOT_SUPPORTED); +) + puts("GLFW required_extensions ----------------"); + for(uint32_t i = 0; i < required_extensions.value1; i++) + puts(required_extensions.value2[i]); } -renderer_t* engine_get_renderer(engine_t* engine) +void engine_terminate(engine_t* engine) { - return engine->renderer; + scene_manager_for_each_objects_in_all_scenes(engine->scene_manager, object_destroy); + renderer_terminate(engine_get_renderer(engine)); + + glfwDestroyWindow((GLFWwindow*)(engine->window)); + glfwTerminate(); } void engine_start(engine_t* engine) diff --git a/source/renderer.c b/source/renderer.c index bf019d6b..4da04b08 100644 --- a/source/renderer.c +++ b/source/renderer.c @@ -8,33 +8,62 @@ #include #include //custom string library #include //standard string library + +#include +#include + #include +#include -declare_exception(VULKAN_ABORTED); -define_exception(VULKAN_ABORTED); -declare_exception(VULKAN_LAYER_NOT_SUPPORTED); -define_exception(VULKAN_LAYER_NOT_SUPPORTED); -declare_exception(VULKAN_EXTENSION_NOT_SUPPORTED); -define_exception(VULKAN_EXTENSION_NOT_SUPPORTED); -define_exception(VULKAN_DEVICE_NOT_FOUND); -declare_exception(VULKAN_DEVICE_NOT_FOUND); - -#define vkCall(call)\ -{\ - VkResult result = call;\ - EXCEPTION_BLOCK\ - (\ - if(result != VK_SUCCESS)\ - throw_exception(VULKAN_ABORTED);\ - )\ -} +#include +#include + + +typedef VkImage* pVkImage_t; +instantiate_tuple_t(uint32_t, pVkImage_t); + +typedef VkImageView* pVkImageView_t; +instantiate_tuple_t(uint32_t, pVkImageView_t); + +define_exception(VULKAN_GRAPHICS_QUEUE_NOT_FOUND); +declare_exception(VULKAN_GRAPHICS_QUEUE_NOT_FOUND); + +define_exception(VULKAN_SURFACE_NOT_SUPPORTED); +declare_exception(VULKAN_SURFACE_NOT_SUPPORTED); + +define_exception(VULKAN_PHYSICAL_DEVICE_EXTENSION_NOT_SUPPORTED); +declare_exception(VULKAN_PHYSICAL_DEVICE_EXTENSION_NOT_SUPPORTED); + +static void vk_dump_physical_device_extensions(renderer_t* renderer); +static tuple_t(uint32_t, pVkImage_t) vk_get_images(renderer_t* renderer); +static tuple_t(uint32_t, pVkImageView_t) vk_get_image_views(renderer_t* renderer); + +typedef struct renderer_t +{ + VkInstance vk_instance; + VkPhysicalDevice vk_physical_device; + VkDevice vk_device; + VkQueue vk_graphics_queue; + VkSurfaceKHR vk_surface; + VkSwapchainKHR vk_swapchain; + uint32_t vk_graphics_queue_index; + tuple_t(uint32_t, pVkImage_t) vk_images; + tuple_t(uint32_t, pVkImageView_t) vk_image_views; + VkFormat vk_format; + VkExtent2D vk_extent; +} renderer_t; + +void* renderer_get_vulkan_instance(renderer_t* renderer) { return (void*)(&(renderer->vk_instance)); } +void* renderer_get_vulkan_device(renderer_t* renderer) { return (void*)(&(renderer->vk_device)); } +void* renderer_get_vulkan_surface(renderer_t* renderer) { return (void*)(&(renderer->vk_surface)); } +void* renderer_get_vulkan_swapchain(renderer_t* renderer) { return (void*)(&(renderer->vk_swapchain)); } +static VkSwapchainKHR vk_get_swapchain(renderer_t* renderer); -static void vk_setup_validation_layers(); renderer_t* renderer_init() { renderer_t* renderer = GC_NEW(renderer_t); - VkInstance instance = renderer->vk_instance = vk_create_instance(); + renderer->vk_instance = vk_create_instance(); #ifdef ENABLE_VALIDATION_LAYERS vk_setup_validation_layers(); @@ -42,20 +71,26 @@ renderer_t* renderer_init() //TODO: this should be something like this: // VkPhysicalDevice vulkan_device = vk_get_suitable_vulkan_device(); - tuple_t(uint32_t, pVkPhysicalDevice_t) physical_devices = vk_get_physical_devices(instance); - VkPhysicalDevice vulkan_device = vk_select_suitable_device(physical_devices); + tuple_t(uint32_t, pVkPhysicalDevice_t) physical_devices = vk_get_physical_devices(renderer->vk_instance); + renderer->vk_physical_device = vk_select_suitable_device(physical_devices); int32_t graphics_queue_index = -1; - tuple_t(uint32_t, pVkQueueFamilyProperties_t) queue_families = vk_get_queue_family_properties(vulkan_device); + tuple_t(uint32_t, pVkQueueFamilyProperties_t) queue_families = vk_get_queue_family_properties(renderer->vk_physical_device); for(uint32_t i = 0; i < queue_families.value1; i++) { VkQueueFamilyProperties properties = queue_families.value2[i]; if(properties.queueFlags & VK_QUEUE_GRAPHICS_BIT) { graphics_queue_index = i; + renderer->vk_graphics_queue_index = (uint32_t)i; break; } } +EXCEPTION_BLOCK +( + if(graphics_queue_index == -1) + throw_exception(VULKAN_GRAPHICS_QUEUE_NOT_FOUND); +) VkDeviceQueueCreateInfo queueCreateInfo = { }; queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; @@ -64,27 +99,35 @@ renderer_t* renderer_init() float queuePriorities = 1.0f; queueCreateInfo.pQueuePriorities = &queuePriorities; + tuple_t(uint32_t, ppVkChar_t) requiredPhysicalDevicExtensions = (tuple_t(uint32_t, ppVkChar_t)) { 1, string_array(1, "VK_KHR_swapchain") }; +EXCEPTION_BLOCK +( + if(!vk_check_physical_device_extension_support(renderer->vk_physical_device, requiredPhysicalDevicExtensions)) + throw_exception(VULKAN_PHYSICAL_DEVICE_EXTENSION_NOT_SUPPORTED); +) + VkPhysicalDeviceFeatures features = { }; VkDeviceCreateInfo logicalDeviceCreateInfo = { }; logicalDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; logicalDeviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; logicalDeviceCreateInfo.queueCreateInfoCount = 1; logicalDeviceCreateInfo.pEnabledFeatures = &features; - logicalDeviceCreateInfo.enabledExtensionCount = 0; + logicalDeviceCreateInfo.enabledExtensionCount = 1; + logicalDeviceCreateInfo.ppEnabledExtensionNames = requiredPhysicalDevicExtensions.value2; logicalDeviceCreateInfo.enabledLayerCount = 0; VkDevice logicalDevice; - vkCall(vkCreateDevice(vulkan_device, &logicalDeviceCreateInfo, NULL, &logicalDevice)); + vkCall(vkCreateDevice(renderer->vk_physical_device, &logicalDeviceCreateInfo, NULL, &logicalDevice)); renderer->vk_device = logicalDevice; VkQueue graphicsQueue; - vkGetDeviceQueue(logicalDevice, graphics_queue_index, 0, &graphicsQueue); - - + vkGetDeviceQueue(renderer->vk_device, graphics_queue_index, 0, &graphicsQueue); + renderer->vk_graphics_queue = graphicsQueue; #ifdef DEBUG vk_dump_instance_extensions(); + vk_dump_physical_device_extensions(renderer); vk_dump_instance_layers(); vk_dump_physical_devices(&physical_devices); vk_dump_queue_families(&queue_families); @@ -92,397 +135,132 @@ renderer_t* renderer_init() return renderer; } -void renderer_terminate(renderer_t* renderer) -{ - vkDestroyDevice(renderer->vk_device, NULL); - vkDestroyInstance(renderer->vk_instance, NULL); -} - - -VkPhysicalDevice vk_select_suitable_device(tuple_t(uint32_t, pVkPhysicalDevice_t) physical_devices) -{ - EXCEPTION_BLOCK( - if(physical_devices.value1 <= 0) - throw_exception(VULKAN_DEVICE_NOT_FOUND); - ); - return physical_devices.value2[0]; -} - -bool vk_check_layer_support(tuple_t(uint32_t, ppVkChar_t) layers) +void renderer_init_surface(renderer_t* renderer, void* surface) { - tuple_t(uint32_t, pVkLayerProperties_t) layer_properties = vk_get_instance_layer_properties(); - for(uint32_t i = 0; i < layers.value1; i++) - { - bool contains = false; - for(uint32_t j = 0; j < layer_properties.value1; j++) - { - if(strcmp(layers.value2[i], layer_properties.value2[j].layerName) == 0) - { - contains = true; - break; - } - } - if(!contains) - return false; - } - return true; + renderer->vk_surface = *((VkSurfaceKHR*)surface); + +EXCEPTION_BLOCK +( + VkBool32 isSupported; + vkCall(vkGetPhysicalDeviceSurfaceSupportKHR(renderer->vk_physical_device, renderer->vk_graphics_queue_index, renderer->vk_surface, &isSupported)); + if(!isSupported) + throw_exception(VULKAN_SURFACE_NOT_SUPPORTED); +) + renderer->vk_swapchain = vk_get_swapchain(renderer); + renderer->vk_images = vk_get_images(renderer); + renderer->vk_image_views = vk_get_image_views(renderer); } - -bool vk_check_extension_support(tuple_t(uint32_t, ppVkChar_t) extensions) +static tuple_t(uint32_t, pVkImageView_t) vk_get_image_views(renderer_t* renderer) { - tuple_t(uint32_t, pVkExtensionProperties_t) extension_properties = vk_get_instance_extension_properties(); - for(uint32_t i = 0; i < extensions.value1; i++) + tuple_t(uint32_t, pVkImageView_t) imageViews = { renderer->vk_images.value1, GC_NEWV(VkImageView, renderer->vk_images.value1) }; + for(uint32_t i = 0; i < imageViews.value1; i++) { - bool contains = false; - for(uint32_t j = 0; j < extension_properties.value1; j++) - { - if(strcmp(extensions.value2[i], extension_properties.value2[j].extensionName) == 0) - { - contains = true; - break; - } - } - if(!contains) - return false; + VkImageViewCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + createInfo.image = renderer->vk_images.value2[i]; + createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + createInfo.format = renderer->vk_format; + createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + createInfo.subresourceRange.baseMipLevel = 0; + createInfo.subresourceRange.levelCount = 1; + createInfo.subresourceRange.baseArrayLayer = 0; + createInfo.subresourceRange.layerCount = 1; + vkCall(vkCreateImageView(renderer->vk_device, &createInfo, NULL, &(imageViews.value2[i]))); } - return true; -} - -VkInstance vk_create_instance() -{ - VkInstanceCreateInfo instance_create_info = { }; - instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - instance_create_info.pNext = NULL; - instance_create_info.flags = 0; - instance_create_info.pApplicationInfo = NULL; - instance_create_info.enabledLayerCount = 0; - instance_create_info.ppEnabledLayerNames = NULL; - instance_create_info.enabledExtensionCount = 0; - instance_create_info.ppEnabledExtensionNames = NULL; - VkInstance instance; - vkCall(vkCreateInstance(&instance_create_info, NULL, &instance)); - return instance; -} - -tuple_t(uint32_t, pVkPhysicalDevice_t) vk_get_physical_devices(VkInstance instance) -{ - tuple_t(uint32_t, pVkPhysicalDevice_t) pair; - vkCall(vkEnumeratePhysicalDevices(instance, &(pair.value1), NULL)); - pair.value2 = (pVkPhysicalDevice_t)GC_ALLOC(sizeof(VkPhysicalDevice) * pair.value1); - vkCall(vkEnumeratePhysicalDevices(instance, &(pair.value1), pair.value2)); - return pair; -} - -tuple_t(uint32_t, pVkExtensionProperties_t) vk_get_instance_extension_properties() -{ - tuple_t(uint32_t, pVkExtensionProperties_t) pair; - vkCall(vkEnumerateInstanceExtensionProperties(NULL, &(pair.value1), NULL)); - pair.value2 = GC_NEWV(VkExtensionProperties, pair.value1); - vkCall(vkEnumerateInstanceExtensionProperties(NULL, &(pair.value1), pair.value2)); - return pair; -} - -tuple_t(uint32_t, pVkLayerProperties_t) vk_get_instance_layer_properties() -{ - tuple_t(uint32_t, pVkLayerProperties_t) pair; - vkCall(vkEnumerateInstanceLayerProperties(&(pair.value1), NULL)); - pair.value2 = GC_NEWV(VkLayerProperties, pair.value1); - vkCall(vkEnumerateInstanceLayerProperties(&(pair.value1), pair.value2)); - return pair; -} - -VkPhysicalDeviceProperties vk_get_physical_device_properties(VkPhysicalDevice physical_device) -{ - VkPhysicalDeviceProperties properties; - vkGetPhysicalDeviceProperties(physical_device, &properties); - return properties; -} - -VkPhysicalDeviceFeatures vk_get_physical_device_features(VkPhysicalDevice physical_device) -{ - VkPhysicalDeviceFeatures features; - vkGetPhysicalDeviceFeatures(physical_device, &features); - return features; -} - -VkPhysicalDeviceMemoryProperties vk_get_physical_device_memory_properties(VkPhysicalDevice physical_device) -{ - VkPhysicalDeviceMemoryProperties memory_properties; - vkGetPhysicalDeviceMemoryProperties(physical_device, &memory_properties); - return memory_properties; + return imageViews; } -tuple_t(uint32_t, pVkQueueFamilyProperties_t) vk_get_queue_family_properties(VkPhysicalDevice physical_device) +static tuple_t(uint32_t, pVkImage_t) vk_get_images(renderer_t* renderer) { - tuple_t(uint32_t, pVkQueueFamilyProperties_t) pair; - vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &(pair.value1), NULL); - pair.value2 = GC_NEWV(VkQueueFamilyProperties, pair.value1); - vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &(pair.value1), pair.value2); + tuple_t(uint32_t, pVkImage_t) pair; + vkCall(vkGetSwapchainImagesKHR(renderer->vk_device, renderer->vk_swapchain, &(pair.value1), NULL)); + pair.value2 = GC_NEWV(VkImage, pair.value1); + vkCall(vkGetSwapchainImagesKHR(renderer->vk_device, renderer->vk_swapchain, &(pair.value1), pair.value2)); return pair; } -static void vk_setup_validation_layers() -{ - EXCEPTION_BLOCK - ( - if(!vk_check_layer_support((tuple_t(uint32_t, ppVkChar_t)){ 1, string_array(1, "VK_LAYER_KHRONOS_validation") })) - throw_exception(VULKAN_LAYER_NOT_SUPPORTED); - - if(!vk_check_extension_support((tuple_t(uint32_t, ppVkChar_t)) { 1, string_array(1, "My Extension") } )) - throw_exception(VULKAN_EXTENSION_NOT_SUPPORTED); - ); -} - - -void vk_dump_physical_devices(tuple_t(uint32_t, pVkPhysicalDevice_t)* physical_devices) -{ - for(uint32_t i = 0; i < physical_devices->value1; i++) - { - VkPhysicalDevice device = physical_devices->value2[i]; - VkPhysicalDeviceProperties properties = vk_get_physical_device_properties(device); - VkPhysicalDeviceMemoryProperties memory_properties = vk_get_physical_device_memory_properties(device); - VkPhysicalDeviceFeatures features = vk_get_physical_device_features(device); - - puts("Physical Device Properties----------------------"); - puts(vk_physical_device_properties_to_string(&properties)); - puts("Physical Device Memory Properties---------------"); - puts(vk_physical_device_memory_properties_to_string(&memory_properties)); - puts("Physical Device Features------------------------"); - puts(vk_physical_device_features_to_string(&features)); - } -} - -void vk_dump_queue_families(tuple_t(uint32_t, pVkQueueFamilyProperties_t)* queue_families) -{ - puts("Physical Device Queue Family::QueueFlags---------"); - for(uint32_t i = 0; i < queue_families->value1; i++) - puts(vk_physical_device_queue_family_to_string(queue_families->value2[i])); -} - -void vk_dump_instance_layers() -{ - tuple_t(uint32_t, pVkLayerProperties_t) layer_properties = vk_get_instance_layer_properties(); - puts("Instance Layer Properties----------------------"); - for(uint32_t i = 0; i < layer_properties.value1; i++) - puts(layer_properties.value2[i].layerName); -} - -void vk_dump_instance_extensions() -{ - tuple_t(uint32_t, pVkExtensionProperties_t) extension_properties = vk_get_instance_extension_properties(); - puts("Instance Extension Properties----------------------"); - for(uint32_t i = 0; i < extension_properties.value1; i++) - puts(extension_properties.value2[i].extensionName); -} - - -const char* vk_physical_device_queue_family_to_string(VkQueueFamilyProperties properties) -{ - char* buffer = GC_NEWV(char, 1024); //1KB - sprintf(buffer, "Queue Count: %u, ", properties.queueCount); - strcat(buffer, "Queue Flags: "); - if(properties.queueFlags & VK_QUEUE_GRAPHICS_BIT) - strcat(buffer, "[VK_QUEUE_GRAPHICS_BIT]"); - if(properties.queueFlags & VK_QUEUE_COMPUTE_BIT) - strcat(buffer, "[VK_QUEUE_COMPUTE_BIT]"); - if(properties.queueFlags & VK_QUEUE_TRANSFER_BIT) - strcat(buffer, "[VK_QUEUE_TRANSFER_BIT]"); - strcat(buffer, ", "); - VkExtent3D extents = properties.minImageTransferGranularity; - sprintf(buffer + strlen(buffer), "minImageTransferGranularity: (%u, %u, %u)", extents.width, extents.height, extents.depth); - return buffer; -} - -const char* vk_physical_device_memory_properties_to_string(VkPhysicalDeviceMemoryProperties* memory_properties) +static VkSwapchainKHR vk_get_swapchain(renderer_t* renderer) { - return string(128, - "Memory Type Count: %u\n", - memory_properties->memoryTypeCount - ); + VkSurfaceCapabilitiesKHR surfaceCapabilities = vk_get_physical_device_surface_capabilities(renderer->vk_physical_device, renderer->vk_surface); + tuple_t(uint32_t, pVkSurfaceFormatKHR_t) formats = vk_get_physical_device_surface_formats(renderer->vk_physical_device, renderer->vk_surface); + tuple_t(uint32_t, pVkPresentModeKHR_t) presentModes = vk_get_physical_device_surface_present_modes(renderer->vk_physical_device, renderer->vk_surface); + +EXCEPTION_BLOCK +( + if(formats.value1 == 0) + throw_exception(VULKAN_ABORTED); + if(presentModes.value1 == 0) + throw_exception(VULKAN_ABORTED); +) + + VkSurfaceFormatKHR format; bool isFormatFound = false; + for(uint32_t i = 0; i < formats.value1; i++) + if((formats.value2[i].format == VK_FORMAT_B8G8R8A8_SRGB) && (formats.value2[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)) + { format = formats.value2[i]; isFormatFound = true; break; } + if(!isFormatFound) + format = formats.value2[0]; + + + VkPresentModeKHR presentMode; bool isModeFound = false; + for(uint32_t i = 0; i < presentModes.value1; i++) + if(presentModes.value2[i] == VK_PRESENT_MODE_MAILBOX_KHR) + { presentMode = presentModes.value2[i]; isModeFound = true; break; } + if(!isModeFound) + presentMode = VK_PRESENT_MODE_FIFO_KHR; + + uint32_t imageCount; + imageCount = surfaceCapabilities.minImageCount + 1; + if(imageCount > surfaceCapabilities.maxImageCount) imageCount = surfaceCapabilities.maxImageCount; + + VkExtent2D extent = surfaceCapabilities.currentExtent; + log_msg("Extent = (%u, %u)", extent.width, extent.height); + log_msg("ImageCount: %u", imageCount); + + renderer->vk_extent = extent; + renderer->vk_format = format.format; + + VkSwapchainCreateInfoKHR createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + createInfo.minImageCount = imageCount; + createInfo.imageFormat = format.format; + createInfo.imageColorSpace = format.colorSpace; + createInfo.imageExtent = extent; + createInfo.imageArrayLayers = 1; + createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + createInfo.queueFamilyIndexCount = 0; + createInfo.pQueueFamilyIndices = NULL; + createInfo.preTransform = surfaceCapabilities.currentTransform; + createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + createInfo.presentMode = presentMode; + createInfo.clipped = VK_TRUE; + createInfo.oldSwapchain = VK_NULL_HANDLE; + createInfo.surface = renderer->vk_surface; + + VkSwapchainKHR swapchain; + vkCall(vkCreateSwapchainKHR(renderer->vk_device, &createInfo, NULL, &swapchain)); + return swapchain; } -const char* vk_physical_device_limits_to_string(VkPhysicalDeviceLimits* device_limits) -{ - return string(512, - "Max Image Dimension 1D [width]: %u\n" - "Max Image Dimension 2D max(width, height): %u\n" - "Max Image Dimension 3D max(width, height, depth): %u\n" - "Max Image Dimension Cube max(width, height): %u\n" - "Max Image Layers: %u\n" - "Max Texel Buffer Elements: %u\n" - , - device_limits->maxImageDimension1D, - device_limits->maxImageDimension2D, - device_limits->maxImageDimension3D, - device_limits->maxImageDimensionCube, - device_limits->maxImageArrayLayers, - device_limits->maxTexelBufferElements - // device_limits->maxUniformBufferRange, - // device_limits->maxStorageBufferRange, - // device_limits->maxPushConstantsSize, - // device_limits->maxMemoryAllocationCount, - // device_limits->maxSamplerAllocationCount, - // device_limits->bufferImageGranularity, - // device_limits->sparseAddressSpaceSize, - // device_limits->maxBoundDescriptorSets, - // device_limits->maxPerStageDescriptorSampler, - ); -} - -const char* vk_physical_device_features_to_string(VkPhysicalDeviceFeatures* device_features) -{ - //2KB of memory - return string(2048, - "robustBufferAccess = %s\n" - "fullDrawIndexUint32 = %s\n" - "imageCubeArray = %s\n" - "independentBlend = %s\n" - "geometryShader = %s\n" - "tessellationShader = %s\n" - "sampleRateShading = %s\n" - "dualSrcBlend = %s\n" - "logicOp = %s\n" - "multiDrawIndirect = %s\n" - "drawIndirectFirstInstance = %s\n" - "depthClamp = %s\n" - "depthBiasClamp = %s\n" - "fillModeNonSolid = %s\n" - "depthBounds = %s\n" - "wideLines = %s\n" - "largePoints = %s\n" - "alphaToOne = %s\n" - "multiViewport = %s\n" - "samplerAnisotropy = %s\n" - "textureCompressionETC2 = %s\n" - "textureCompressionASTC_LDR = %s\n" - "textureCompressionBC = %s\n" - "occlusionQueryPrecise = %s\n" - "pipelineStatisticsQuery = %s\n" - "vertexPipelineStoresAndAtomics = %s\n" - "fragmentStoresAndAtomics = %s\n" - "shaderTessellationAndGeometryPointSize = %s\n" - "shaderImageGatherExtended = %s\n" - "shaderStorageImageExtendedFormats = %s\n" - "shaderStorageImageMultisample = %s\n" - "shaderStorageImageReadWithoutFormat = %s\n" - "shaderStorageImageWriteWithoutFormat = %s\n" - "shaderUniformBufferArrayDynamicIndexing = %s\n" - "shaderSampledImageArrayDynamicIndexing = %s\n" - "shaderStorageBufferArrayDynamicIndexing = %s\n" - "shaderStorageImageArrayDynamicIndexing = %s\n" - "shaderClipDistance = %s\n" - "shaderCullDistance = %s\n" - "shaderFloat64 = %s\n" - "shaderInt64 = %s\n" - "shaderInt16 = %s\n" - "shaderResourceResidency = %s\n" - "shaderResourceMinLod = %s\n" - "sparseBinding = %s\n" - "sparseResidencyBuffer = %s\n" - "sparseResidencyImage2D = %s\n" - "sparseResidencyImage3D = %s\n" - "sparseResidency2Samples = %s\n" - "sparseResidency4Samples = %s\n" - "sparseResidency8Samples = %s\n" - "sparseResidency16Samples = %s\n" - "sparseResidencyAliased = %s\n" - "variableMultisampleRate = %s\n" - "inheritedQueries = %s\n" - ,string_bool(device_features->robustBufferAccess) - ,string_bool(device_features->fullDrawIndexUint32) - ,string_bool(device_features->imageCubeArray) - ,string_bool(device_features->independentBlend) - ,string_bool(device_features->geometryShader) - ,string_bool(device_features->tessellationShader) - ,string_bool(device_features->sampleRateShading) - ,string_bool(device_features->dualSrcBlend) - ,string_bool(device_features->logicOp) - ,string_bool(device_features->multiDrawIndirect) - ,string_bool(device_features->drawIndirectFirstInstance) - ,string_bool(device_features->depthClamp) - ,string_bool(device_features->depthBiasClamp) - ,string_bool(device_features->fillModeNonSolid) - ,string_bool(device_features->depthBounds) - ,string_bool(device_features->wideLines) - ,string_bool(device_features->largePoints) - ,string_bool(device_features->alphaToOne) - ,string_bool(device_features->multiViewport) - ,string_bool(device_features->samplerAnisotropy) - ,string_bool(device_features->textureCompressionETC2) - ,string_bool(device_features->textureCompressionASTC_LDR) - ,string_bool(device_features->textureCompressionBC) - ,string_bool(device_features->occlusionQueryPrecise) - ,string_bool(device_features->pipelineStatisticsQuery) - ,string_bool(device_features->vertexPipelineStoresAndAtomics) - ,string_bool(device_features->fragmentStoresAndAtomics) - ,string_bool(device_features->shaderTessellationAndGeometryPointSize) - ,string_bool(device_features->shaderImageGatherExtended) - ,string_bool(device_features->shaderStorageImageExtendedFormats) - ,string_bool(device_features->shaderStorageImageMultisample) - ,string_bool(device_features->shaderStorageImageReadWithoutFormat) - ,string_bool(device_features->shaderStorageImageWriteWithoutFormat) - ,string_bool(device_features->shaderUniformBufferArrayDynamicIndexing) - ,string_bool(device_features->shaderSampledImageArrayDynamicIndexing) - ,string_bool(device_features->shaderStorageBufferArrayDynamicIndexing) - ,string_bool(device_features->shaderStorageImageArrayDynamicIndexing) - ,string_bool(device_features->shaderClipDistance) - ,string_bool(device_features->shaderCullDistance) - ,string_bool(device_features->shaderFloat64) - ,string_bool(device_features->shaderInt64) - ,string_bool(device_features->shaderInt16) - ,string_bool(device_features->shaderResourceResidency) - ,string_bool(device_features->shaderResourceMinLod) - ,string_bool(device_features->sparseBinding) - ,string_bool(device_features->sparseResidencyBuffer) - ,string_bool(device_features->sparseResidencyImage2D) - ,string_bool(device_features->sparseResidencyImage3D) - ,string_bool(device_features->sparseResidency2Samples) - ,string_bool(device_features->sparseResidency4Samples) - ,string_bool(device_features->sparseResidency8Samples) - ,string_bool(device_features->sparseResidency16Samples) - ,string_bool(device_features->sparseResidencyAliased) - ,string_bool(device_features->variableMultisampleRate) - ,string_bool(device_features->inheritedQueries)); -} - -const char* vk_physical_device_type_to_string(VkPhysicalDeviceType *device_type) +void renderer_terminate(renderer_t* renderer) { - switch(*device_type) - { - case VK_PHYSICAL_DEVICE_TYPE_OTHER: - return "VK_PHYSICAL_DEVICE_TYPE_OTHER"; - case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: - return "VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU"; - case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: - return "VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU"; - case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: - return "VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU"; - case VK_PHYSICAL_DEVICE_TYPE_CPU: - return "VK_PHYSICAL_DEVICE_TYPE_CPU"; - default: - return "(Unknown)"; - } + for(uint32_t i = 0; i < renderer->vk_image_views.value1; i++) + vkDestroyImageView(renderer->vk_device, renderer->vk_image_views.value2[i], NULL); + vkDestroySwapchainKHR(renderer->vk_device, renderer->vk_swapchain, NULL); + vkDestroySurfaceKHR(renderer->vk_instance, renderer->vk_surface, NULL); + vkDestroyDevice(renderer->vk_device, NULL); + vkDestroyInstance(renderer->vk_instance, NULL); } -const char* vk_physical_device_properties_to_string(VkPhysicalDeviceProperties* properties) +static void vk_dump_physical_device_extensions(renderer_t* renderer) { - return string(1024, - "API Version: %d\n" - "Driver Version: %d\n" - "Vendor ID: %d\n" - "Device ID: %d\n" - "Device Name: %s\n" - "Device Type: %s\n" - "Pipeline Cache UUID: %d\n" - "Device Limits: \n" - "%s", - properties->apiVersion, - properties->driverVersion, - properties->vendorID, - properties->deviceID, - properties->deviceName, - vk_physical_device_type_to_string(&(properties->deviceType)), - properties->pipelineCacheUUID, - vk_physical_device_limits_to_string(&(properties->limits))); + log_msg("Physical Device Extensions-----------------------"); + tuple_t(uint32_t, pVkExtensionProperties_t) extensions = vk_get_physical_device_extension_properties(renderer->vk_physical_device); + for(uint32_t i = 0; i < extensions.value1; i++) + log_msg(extensions.value2[i].extensionName); } \ No newline at end of file From 8d196791fb27006e684749deb4e6a96ab1ba8a25 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Tue, 28 Sep 2021 23:28:25 +0530 Subject: [PATCH 07/12] Refactored & added utilities folder Added casting_utility.h and file_utility.h --- include/defs.h | 134 ---------------------------- include/engine/material.h | 2 +- include/utilities.h | 9 -- include/utilities/casting_utility.h | 6 ++ include/utilities/file_utility.h | 7 ++ source/file_utility.c | 108 ++++++++++++++++++++++ 6 files changed, 122 insertions(+), 144 deletions(-) delete mode 100644 include/defs.h delete mode 100644 include/utilities.h create mode 100644 include/utilities/casting_utility.h create mode 100644 include/utilities/file_utility.h create mode 100644 source/file_utility.c diff --git a/include/defs.h b/include/defs.h deleted file mode 100644 index 589fc39f..00000000 --- a/include/defs.h +++ /dev/null @@ -1,134 +0,0 @@ - -#ifndef _DEFS_H_ -#define _DEFS_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -#define DEFS_PRIVATE static - -DEFS_PRIVATE int number_get_digit(int number, int index, int num_digits); -DEFS_PRIVATE char digit_to_char(int digit); -DEFS_PRIVATE void convert_int_to_string(int int_value, char* buffer); - -DEFS_PRIVATE int number_get_digit(int number, int index, int num_digits) -{ - index++; - int _tens = pow(10, num_digits - index); - int value1 = number / _tens; - _tens *= 10; - int value2 = number / _tens; - value2 *= 10; - return (value1 - value2); -} -DEFS_PRIVATE char digit_to_char(int digit) { return 48 + digit; } -DEFS_PRIVATE void convert_int_to_string(int int_value, char* buffer) -{ - int digit_count = 0; - int _value = int_value; - while(_value > 0) - { - ++digit_count; - _value /= 10; - } - int i = 0; - for(; i < digit_count; i++) - buffer[i] = digit_to_char(number_get_digit(int_value, i, digit_count)); - buffer[i] = 0; -} -#endif - -#define TOKEN_BUFFER_SIZE 80 -#define SINGLE_LINE_COMMENT "\\" -#define MULTIPLE_LINE_COMMENT "/**/" -#define VERSION(__version__) - -#define _sizeof(serialized_property) __sizeof(serialized_property) - -#ifdef DEBUG -#define GOTO(label) { printf("Returned from %d\n", __LINE__); goto label; } -#else -#define GOTO(label) { goto label; } -#endif - -#define INCREMENT_CHAR_PTR(ch, amount)\ -do {\ - if((ch == NULL) || (*ch == 0)) { exit(0); puts("FILE ENDED"); }\ - ch += amount;\ - if(*ch == 0) { exit(0); puts("FILE ENDED");} } while (false) - -#ifdef DEBUG -#define throw_error(error_str, line_no, discription)\ -do{\ - printf("[ERROR]: Parsing error at line no %d \n%s: %s\n", line_no, error_str, discription);\ - exit(0);\ -}while(false) -#else -#define throw_error(error_str, line_no, description) -#endif - -typedef enum -{ - STSP_STATIC = 0, - STSP_REGISTER = 1, - STSP_EXTERN = 2, - STSP_NONE = 3 -} _storage_specifiers; - -typedef enum -{ - TYPE_SIGNED_INT8 = 0, //char, signed char - TYPE_SIGNED_INT16 = 1, //short, signed short, short int, signed short int - TYPE_SIGNED_INT32 = 2, //int, signed int, long, long int - TYPE_SIGNED_INT64 = 3, //long long int - - TYPE_UNSIGNED_INT8 = 4, //unsigned char - TYPE_UNSIGNED_INT16 = 5, //unsigned short, unsigned short int - TYPE_UNSIGNED_INT32 = 6, //unsigned int, unsigned long, unsigned long int - TYPE_UNSIGNED_INT64 = 7, //unsigned long long, unsigned long long int - - TYPE_FLOAT = 8, //float - TYPE_DOUBLE = 9, //double - TYPE_LONG_DOUBLE = 10, //long double - TYPE_STRING = 11, - TYPE_NONE = 12, - TYPE_INCOMPLETE = 13, - TYPE_VOID = 14 -} _type_specifiers; - -typedef struct -{ - bool is_pointer; //true if this property is a pointer - bool is_const; //true if this property is a constant property - _storage_specifiers storage; //extern, static, register - _type_specifiers type; //int, short, long ...etc - intptr_t address; //address of the property - char name[TOKEN_BUFFER_SIZE]; //name of the property -} SerializedProperty; - -typedef struct -{ - char name[TOKEN_BUFFER_SIZE]; //name of this struct - bool is_valid; //true, if this SerializedStruct is a valid serialized struct - uint32_t size; //size of the serialized struct in bytes - BUFFER* properties; //list of properties -} SerializedStruct; - -char* load_text_from_file(const char* file_name); -char* load_text_from_file_exclude_comments(const char* file_name); - -int __sizeof(SerializedProperty* property); -bool isstorage(const char* string, _storage_specifiers* storage); -bool istype(const char* string, _type_specifiers* type); - - -#endif \ No newline at end of file diff --git a/include/engine/material.h b/include/engine/material.h index 7cdfc026..dd801ddc 100644 --- a/include/engine/material.h +++ b/include/engine/material.h @@ -2,7 +2,7 @@ #define __MATERIAL_H__ #include -#include +#include #include #define Material_TYPE_ID ((uint64_t)(3)) diff --git a/include/utilities.h b/include/utilities.h deleted file mode 100644 index 54cb7ef6..00000000 --- a/include/utilities.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __UTILITIES_H__ -#define __UTILITIES_H__ - - -#define c_reinterpret_cast(value, target) (*((target*)(&(value)))) -#define c_static_cast(value, target) ((target)(value)) - - -#endif/*__UTILITIES_H__*/ \ No newline at end of file diff --git a/include/utilities/casting_utility.h b/include/utilities/casting_utility.h new file mode 100644 index 00000000..2fa7c9ea --- /dev/null +++ b/include/utilities/casting_utility.h @@ -0,0 +1,6 @@ + +#pragma once + + +#define c_reinterpret_cast(value, target) (*((target*)(&(value)))) +#define c_static_cast(value, target) ((target)(value)) \ No newline at end of file diff --git a/include/utilities/file_utility.h b/include/utilities/file_utility.h new file mode 100644 index 00000000..f40a1cb8 --- /dev/null +++ b/include/utilities/file_utility.h @@ -0,0 +1,7 @@ + +#pragma once + +char* load_text_from_file(const char* file_name); +char* load_binary_from_file(const char* file_name); + +char* load_text_from_file_exclude_comments(const char* file_name); \ No newline at end of file diff --git a/source/file_utility.c b/source/file_utility.c new file mode 100644 index 00000000..d0f85f89 --- /dev/null +++ b/source/file_utility.c @@ -0,0 +1,108 @@ + +#include + +#include +#include +#include +#include + + +static char* load_file(const char* file_name, const char* mode); + +char* load_binary_from_file(const char* file_name) +{ + return load_file(file_name, "rb"); +} + +char* load_text_from_file(const char* file_name) +{ + return load_file(file_name, "r"); +} + +static char* load_file(const char* file_name, const char* mode) +{ + FILE* file = fopen(file_name, mode); + if(file == NULL) + { + #ifdef DEBUG + printf("[Error] File loading failed, file_name: \"%s\", from load_text_from_file\n", file_name); + #endif + return NULL; + } + char bytes[BUF_BUFFER_OBJECT_SIZE]; + BUFFER* memory_buffer = BUFcreate_object(bytes); + BUFcreate(memory_buffer, sizeof(char), 1, 0); + BUFbind(memory_buffer); + char ch = getc(file); + while(ch != EOF) + { + BUFpush(&ch); + ch = getc(file); + } + BUFpush_char(0); + BUFfit(); + fclose(file); + return (char*)BUFget_ptr(); +} + +char* load_text_from_file_exclude_comments(const char* file_name) +{ + FILE* file = fopen(file_name, "r"); + if(file == NULL) + { + #ifdef DEBUG + printf("[Error] File loading failed, file_name: \"%s\", from load_text_from_file_exclude_comments\n", file_name); + #endif + return NULL; + } + + char bytes[BUF_BUFFER_OBJECT_SIZE]; + BUFFER* memory_buffer = BUFcreate_object(bytes); + BUFcreate(memory_buffer, sizeof(char), 1, 0); + BUFbind(memory_buffer); + char ch = getc(file); + char previous_ch = ch; + bool single_line_comment_begin = false; + bool multiple_line_comment_begin = false; + + while(ch != EOF) + { + if(!single_line_comment_begin && !multiple_line_comment_begin) + BUFpush(&ch); + previous_ch = ch; + ch = getc(file); + + if(multiple_line_comment_begin && (previous_ch == '*') && (ch == '/')) + { + multiple_line_comment_begin = false; + BUFpop(NULL); + ch = getc(file); + ch = getc(file); + continue; + } + else if(single_line_comment_begin && (ch == '\n')) + { + single_line_comment_begin = false; + ch = getc(file); + continue; + } + + if(!multiple_line_comment_begin && !single_line_comment_begin && (previous_ch == '/') && (ch == '/')) + { + single_line_comment_begin = true; + BUFpop(NULL); + ch = getc(file); + continue; + } + if(!single_line_comment_begin && !multiple_line_comment_begin && (previous_ch == '/') && (ch == '*')) + { + multiple_line_comment_begin = true; + ch = getc(file); + continue; + } + } + BUFpush_char(0); + BUFfit(); + fclose(file); + return (char*)BUFget_ptr(); +} \ No newline at end of file From 5cdea6389c7a949500471f420fd332b8615e7c99 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Wed, 29 Sep 2021 01:58:14 +0530 Subject: [PATCH 08/12] Copy pasted fixed functions, renderpasses, commandbuffers, and semaphores Added some more typedefs in template_instantiations.h. Modified file_utility.h functions, now they will return tuples instead of just a raw char pointer. Calling renderer_update in engine_update. --- include/engine/renderer/renderer.h | 3 +- include/tuple/template_instantiations.h | 3 + include/utilities/file_utility.h | 10 +- shaders/fragmentShader.frag | 9 + shaders/fragmentShader.spv | Bin 0 -> 456 bytes shaders/vertexShader.spv | Bin 0 -> 1164 bytes shaders/vertexShader.vert | 13 + source/engine.c | 3 +- source/file_utility.c | 29 ++- source/renderer.c | 329 ++++++++++++++++++++++++ 10 files changed, 380 insertions(+), 19 deletions(-) create mode 100644 shaders/fragmentShader.frag create mode 100644 shaders/fragmentShader.spv create mode 100644 shaders/vertexShader.spv create mode 100644 shaders/vertexShader.vert diff --git a/include/engine/renderer/renderer.h b/include/engine/renderer/renderer.h index e682cfc0..ab7ff5c3 100644 --- a/include/engine/renderer/renderer.h +++ b/include/engine/renderer/renderer.h @@ -1,13 +1,12 @@ #pragma once -#include #include typedef struct renderer_t renderer_t; renderer_t* renderer_init(); void renderer_terminate(renderer_t* renderer); - +void renderer_update(renderer_t* renderer); //Graphics API specifics void renderer_init_surface(renderer_t* renderer, void* surface); diff --git a/include/tuple/template_instantiations.h b/include/tuple/template_instantiations.h index 198a73f4..54ad278d 100644 --- a/include/tuple/template_instantiations.h +++ b/include/tuple/template_instantiations.h @@ -3,8 +3,11 @@ #include +#include instantiate_tuple_t(int, pchar_t); +instantiate_tuple_t(uint32_t, pchar_t); +instantiate_tuple_t(uint64_t, pchar_t); instantiate_declaration_tuple_get1(int, pchar_t); instantiate_declaration_tuple_get2(int, pchar_t); diff --git a/include/utilities/file_utility.h b/include/utilities/file_utility.h index f40a1cb8..68b9be30 100644 --- a/include/utilities/file_utility.h +++ b/include/utilities/file_utility.h @@ -1,7 +1,11 @@ #pragma once -char* load_text_from_file(const char* file_name); -char* load_binary_from_file(const char* file_name); +#include +#include -char* load_text_from_file_exclude_comments(const char* file_name); \ No newline at end of file +#include + +tuple_t(uint64_t, pchar_t) load_text_from_file(const char* file_name); +tuple_t(uint64_t, pchar_t) load_binary_from_file(const char* file_name); +tuple_t(uint64_t, pchar_t) load_text_from_file_exclude_comments(const char* file_name); \ No newline at end of file diff --git a/shaders/fragmentShader.frag b/shaders/fragmentShader.frag new file mode 100644 index 00000000..9d2e6551 --- /dev/null +++ b/shaders/fragmentShader.frag @@ -0,0 +1,9 @@ + + +#version 450 + +layout(location = 0) out vec4 outColor; + +void main() { + outColor = vec4(0.1, 0.6, 0.7, 1.0); +} \ No newline at end of file diff --git a/shaders/fragmentShader.spv b/shaders/fragmentShader.spv new file mode 100644 index 0000000000000000000000000000000000000000..19f1502a47abf4ce37bd41199b3451d2b4d5815d GIT binary patch literal 456 zcmYjO!AiqG6daqT*4DO)pm>prN2LgM5;RUWfem!f!vMc$7Y%lRE?PdD_#qxGs&q8II2WUjz!Sw8kke#V zJUzNX7h8-Sa@3Lt%??uyK&Zk{ETd(Omb*Lbc- z@?}~lgk;orh6w%Ma#`J#c{%4g7&7GLNPuULF686bJA$wGS-035G7iX>Utwtv`E4`n zwd!C0VQH#&N-S=N@wr;vtZ|q4{q1nF#@obE6#e5KG4MJ$qpEcK3~6XiT-{&tJ@P6a VI@EeoTEe1Nt46Fr1L)Q_WS9u`d(ydk(XK8%LiGv z%D-mn7N&H0*)7g{(}D=abgw8x;UYcyXT!Y8&&nZw#N1oh&qaEa4L)UqD*HwVTl4zn z#wD=xBfa+-@p)OD;qlB{23h_YkbZ%I~7FMt>8pjg7$; zdSBAm+y?OiHU^$Yy3RcIrF!$&f!j)J>13*;pc(*dwBM8 zw&(25H}g&&`9Clb_BD}j;4WUFu-^`_*Bcb}iGdnscene_manager, object_call_on_pre_render); - scene_manager_for_each_objects_in_all_scenes(engine->scene_manager, object_call_on_post_render); + scene_manager_for_each_objects_in_all_scenes(engine->scene_manager, object_call_on_post_render); + renderer_update(engine->renderer); } bool engine_is_running(engine_t* engine) diff --git a/source/file_utility.c b/source/file_utility.c index d0f85f89..b7c219e9 100644 --- a/source/file_utility.c +++ b/source/file_utility.c @@ -7,31 +7,30 @@ #include -static char* load_file(const char* file_name, const char* mode); +static tuple_t(uint64_t, pchar_t) load_file(const char* file_name, const char* mode); -char* load_binary_from_file(const char* file_name) +tuple_t(uint64_t, pchar_t) load_binary_from_file(const char* file_name) { return load_file(file_name, "rb"); } -char* load_text_from_file(const char* file_name) +tuple_t(uint64_t, pchar_t) load_text_from_file(const char* file_name) { return load_file(file_name, "r"); } -static char* load_file(const char* file_name, const char* mode) +static tuple_t(uint64_t, pchar_t) load_file(const char* file_name, const char* mode) { FILE* file = fopen(file_name, mode); if(file == NULL) { - #ifdef DEBUG printf("[Error] File loading failed, file_name: \"%s\", from load_text_from_file\n", file_name); - #endif - return NULL; + return (tuple_t(uint64_t, pchar_t)) { 0, NULL };; } char bytes[BUF_BUFFER_OBJECT_SIZE]; BUFFER* memory_buffer = BUFcreate_object(bytes); BUFcreate(memory_buffer, sizeof(char), 1, 0); + BUFpush_binded(); BUFbind(memory_buffer); char ch = getc(file); while(ch != EOF) @@ -42,23 +41,25 @@ static char* load_file(const char* file_name, const char* mode) BUFpush_char(0); BUFfit(); fclose(file); - return (char*)BUFget_ptr(); + + tuple_t(uint64_t, pchar_t) string = (tuple_t(uint64_t, pchar_t)) { BUFget_element_count(), (char*)BUFget_ptr() }; + BUFpop_binded(); + return string; } -char* load_text_from_file_exclude_comments(const char* file_name) +tuple_t(uint64_t, pchar_t) load_text_from_file_exclude_comments(const char* file_name) { FILE* file = fopen(file_name, "r"); if(file == NULL) { - #ifdef DEBUG printf("[Error] File loading failed, file_name: \"%s\", from load_text_from_file_exclude_comments\n", file_name); - #endif - return NULL; + return (tuple_t(uint64_t, pchar_t)) { 0, NULL }; } char bytes[BUF_BUFFER_OBJECT_SIZE]; BUFFER* memory_buffer = BUFcreate_object(bytes); BUFcreate(memory_buffer, sizeof(char), 1, 0); + BUFpush_binded(); BUFbind(memory_buffer); char ch = getc(file); char previous_ch = ch; @@ -104,5 +105,7 @@ char* load_text_from_file_exclude_comments(const char* file_name) BUFpush_char(0); BUFfit(); fclose(file); - return (char*)BUFget_ptr(); + BUFpop_binded(); + tuple_t(uint64_t, pchar_t) string = (tuple_t(uint64_t, pchar_t)) { BUFget_element_count(), (char*)BUFget_ptr() }; + return string; } \ No newline at end of file diff --git a/source/renderer.c b/source/renderer.c index 4da04b08..9be4d4b8 100644 --- a/source/renderer.c +++ b/source/renderer.c @@ -18,6 +18,14 @@ #include #include +#include //for load_binary_from_file() + + +typedef VkCommandBuffer* pVkCommandBuffer_t; +instantiate_tuple_t(uint32_t, pVkCommandBuffer_t); + +typedef VkFramebuffer* pVkFramebuffer_t; +instantiate_tuple_t(uint32_t, pVkFramebuffer_t); typedef VkImage* pVkImage_t; instantiate_tuple_t(uint32_t, pVkImage_t); @@ -37,6 +45,7 @@ declare_exception(VULKAN_PHYSICAL_DEVICE_EXTENSION_NOT_SUPPORTED); static void vk_dump_physical_device_extensions(renderer_t* renderer); static tuple_t(uint32_t, pVkImage_t) vk_get_images(renderer_t* renderer); static tuple_t(uint32_t, pVkImageView_t) vk_get_image_views(renderer_t* renderer); +static VkShaderModule vk_get_shader_module(renderer_t* renderer, const char* file_name); typedef struct renderer_t { @@ -49,8 +58,16 @@ typedef struct renderer_t uint32_t vk_graphics_queue_index; tuple_t(uint32_t, pVkImage_t) vk_images; tuple_t(uint32_t, pVkImageView_t) vk_image_views; + tuple_t(uint32_t, pVkFramebuffer_t) vk_framebuffers; + tuple_t(uint32_t, pVkCommandBuffer_t) vk_command_buffers; VkFormat vk_format; VkExtent2D vk_extent; + VkPipelineLayout vk_pipeline_layout; + VkRenderPass vk_render_pass; + VkPipeline vk_pipeline; + VkCommandPool vk_command_pool; + VkSemaphore vk_image_available_semaphore; + VkSemaphore vk_render_finished_semaphore; } renderer_t; void* renderer_get_vulkan_instance(renderer_t* renderer) { return (void*)(&(renderer->vk_instance)); } @@ -149,6 +166,310 @@ EXCEPTION_BLOCK renderer->vk_swapchain = vk_get_swapchain(renderer); renderer->vk_images = vk_get_images(renderer); renderer->vk_image_views = vk_get_image_views(renderer); + + VkShaderModule vertexShaderModule = vk_get_shader_module(renderer, "shaders/vertexShader.spv"); + VkShaderModule fragmentShaderModule = vk_get_shader_module(renderer, "shaders/fragmentShader.spv"); + + VkPipelineShaderStageCreateInfo vertexShaderStageInfo = { }; + vertexShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + vertexShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; + vertexShaderStageInfo.module = vertexShaderModule; + vertexShaderStageInfo.pName = "main"; + + VkPipelineShaderStageCreateInfo fragmentShaderStageInfo = { }; + fragmentShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + fragmentShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + fragmentShaderStageInfo.module = fragmentShaderModule; + fragmentShaderStageInfo.pName = "main"; + + VkPipelineShaderStageCreateInfo shaderStages[] = { vertexShaderStageInfo, fragmentShaderStageInfo}; + + VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; + vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertexInputInfo.vertexBindingDescriptionCount = 0; + vertexInputInfo.pVertexBindingDescriptions = NULL; // Optional + vertexInputInfo.vertexAttributeDescriptionCount = 0; + vertexInputInfo.pVertexAttributeDescriptions = NULL; + + //Fixed functions configuration + VkPipelineInputAssemblyStateCreateInfo inputAssembly = {}; + inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + inputAssembly.primitiveRestartEnable = VK_FALSE; + + VkViewport viewport = {}; + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = (float) renderer->vk_extent.width; + viewport.height = (float) renderer->vk_extent.height; + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + + VkRect2D scissor = {}; + scissor.offset = (VkOffset2D) {0, 0}; + scissor.extent = renderer->vk_extent; + + VkPipelineViewportStateCreateInfo viewportState = {}; + viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewportState.viewportCount = 1; + viewportState.pViewports = &viewport; + viewportState.scissorCount = 1; + viewportState.pScissors = &scissor; + + VkPipelineRasterizationStateCreateInfo rasterizer = {}; + rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterizer.depthClampEnable = VK_FALSE; + rasterizer.rasterizerDiscardEnable = VK_FALSE; + rasterizer.polygonMode = VK_POLYGON_MODE_FILL; + rasterizer.lineWidth = 1.0f; + rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; + rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; + rasterizer.depthBiasEnable = VK_FALSE; + rasterizer.depthBiasConstantFactor = 0.0f; // Optional + rasterizer.depthBiasClamp = 0.0f; // Optional + rasterizer.depthBiasSlopeFactor = 0.0f; // Optional + + VkPipelineMultisampleStateCreateInfo multisampling = {}; + multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisampling.sampleShadingEnable = VK_FALSE; + multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + multisampling.minSampleShading = 1.0f; // Optional + multisampling.pSampleMask = NULL; // Optional + multisampling.alphaToCoverageEnable = VK_FALSE; // Optional + multisampling.alphaToOneEnable = VK_FALSE; // Optional + + VkPipelineColorBlendAttachmentState colorBlendAttachment = {}; + colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + colorBlendAttachment.blendEnable = VK_FALSE; + colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // Optional + colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional + colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; // Optional + colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // Optional + colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional + colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; // Optional + + + VkPipelineColorBlendStateCreateInfo colorBlending = {}; + colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + colorBlending.logicOpEnable = VK_FALSE; + colorBlending.logicOp = VK_LOGIC_OP_COPY; // Optional + colorBlending.attachmentCount = 1; + colorBlending.pAttachments = &colorBlendAttachment; + colorBlending.blendConstants[0] = 0.0f; // Optional + colorBlending.blendConstants[1] = 0.0f; // Optional + colorBlending.blendConstants[2] = 0.0f; // Optional + colorBlending.blendConstants[3] = 0.0f; // Optional + + VkDynamicState dynamicStates[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_LINE_WIDTH + }; + + VkPipelineDynamicStateCreateInfo dynamicState = {}; + dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamicState.dynamicStateCount = 2; + dynamicState.pDynamicStates = dynamicStates; + + VkPipelineLayout pipelineLayout; + + VkPipelineLayoutCreateInfo pipelineLayoutInfo = {}; + pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutInfo.setLayoutCount = 0; // Optional + pipelineLayoutInfo.pSetLayouts = NULL; // Optional + pipelineLayoutInfo.pushConstantRangeCount = 0; // Optional + pipelineLayoutInfo.pPushConstantRanges = NULL; // Optional + + vkCall(vkCreatePipelineLayout(renderer->vk_device, &pipelineLayoutInfo, NULL, &pipelineLayout)); + + renderer->vk_pipeline_layout = pipelineLayout; + + VkAttachmentDescription colorAttachment = {}; + colorAttachment.format = renderer->vk_format; + colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; + colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + + VkAttachmentReference colorAttachmentRef = {}; + colorAttachmentRef.attachment = 0; + colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + VkSubpassDescription subpass = {}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &colorAttachmentRef; + + VkSubpassDependency dependency = {}; + dependency.srcSubpass = VK_SUBPASS_EXTERNAL; + dependency.dstSubpass = 0; + dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.srcAccessMask = 0; + dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + VkRenderPass renderPass; + VkRenderPassCreateInfo renderPassCreateInfo = {}; + renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + renderPassCreateInfo.attachmentCount = 1; + renderPassCreateInfo.pAttachments = &colorAttachment; + renderPassCreateInfo.subpassCount = 1; + renderPassCreateInfo.pSubpasses = &subpass; + renderPassCreateInfo.dependencyCount = 1; + renderPassCreateInfo.pDependencies = &dependency; + vkCall(vkCreateRenderPass(renderer->vk_device, &renderPassCreateInfo, NULL, &renderPass)); + renderer->vk_render_pass = renderPass; + + VkGraphicsPipelineCreateInfo pipelineInfo = {}; + pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipelineInfo.stageCount = 2; + pipelineInfo.pStages = shaderStages; + + pipelineInfo.pVertexInputState = &vertexInputInfo; + pipelineInfo.pInputAssemblyState = &inputAssembly; + pipelineInfo.pViewportState = &viewportState; + pipelineInfo.pRasterizationState = &rasterizer; + pipelineInfo.pMultisampleState = &multisampling; + pipelineInfo.pDepthStencilState = NULL; // Optional + pipelineInfo.pColorBlendState = &colorBlending; + pipelineInfo.pDynamicState = NULL; // Optional + pipelineInfo.layout = pipelineLayout; + pipelineInfo.renderPass = renderPass; + pipelineInfo.subpass = 0; + pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; // Optional + pipelineInfo.basePipelineIndex = -1; // Optional + + VkPipeline graphicsPipeline; + vkCall(vkCreateGraphicsPipelines(renderer->vk_device, VK_NULL_HANDLE, 1, &pipelineInfo, NULL, &graphicsPipeline)); + renderer->vk_pipeline = graphicsPipeline; + + + tuple_t(uint32_t, pVkFramebuffer_t) swapChainFramebuffers = (tuple_t(uint32_t, pVkFramebuffer_t)) { renderer->vk_images.value1, GC_NEWV(VkFramebuffer, renderer->vk_images.value1) }; + for(uint32_t i = 0; i < swapChainFramebuffers.value1; i++) + { + VkImageView attachments[] = { + renderer->vk_image_views.value2[i] + }; + + VkFramebufferCreateInfo framebufferInfo = {}; + framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebufferInfo.renderPass = renderPass; + framebufferInfo.attachmentCount = 1; + framebufferInfo.pAttachments = attachments; + framebufferInfo.width = renderer->vk_extent.width; + framebufferInfo.height = renderer->vk_extent.height; + framebufferInfo.layers = 1; + vkCall(vkCreateFramebuffer(renderer->vk_device, &framebufferInfo, NULL, &(swapChainFramebuffers.value2[i]))); + } + renderer->vk_framebuffers = swapChainFramebuffers; + + VkCommandPool commandPool; + VkCommandPoolCreateInfo poolInfo = {}; + poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + poolInfo.queueFamilyIndex = renderer->vk_graphics_queue_index; + poolInfo.flags = 0; // Optional + vkCall(vkCreateCommandPool(renderer->vk_device, &poolInfo, NULL, &commandPool)); + renderer->vk_command_pool = commandPool; + + tuple_t(uint32_t, pVkCommandBuffer_t) commandBuffers = (tuple_t(uint32_t, pVkCommandBuffer_t)) { renderer->vk_framebuffers.value1, GC_NEWV(VkCommandBuffer, renderer->vk_framebuffers.value1) }; + VkCommandBufferAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocInfo.commandPool = commandPool; + allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocInfo.commandBufferCount = (uint32_t) commandBuffers.value1; + vkCall(vkAllocateCommandBuffers(renderer->vk_device, &allocInfo, commandBuffers.value2)); + + for (uint32_t i = 0; i < commandBuffers.value1; i++) + { + VkCommandBufferBeginInfo beginInfo = {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = 0; // Optional + beginInfo.pInheritanceInfo = NULL; // Optional + vkCall(vkBeginCommandBuffer(commandBuffers.value2[i], &beginInfo)); + + VkRenderPassBeginInfo renderPassInfo = {}; + renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + renderPassInfo.renderPass = renderPass; + renderPassInfo.framebuffer = renderer->vk_framebuffers.value2[i]; + renderPassInfo.renderArea.offset = (VkOffset2D) {0, 0}; + renderPassInfo.renderArea.extent = renderer->vk_extent; + + VkClearValue clearColor = {{{0.0f, 0.0f, 0.0f, 1.0f}}}; + renderPassInfo.clearValueCount = 1; + renderPassInfo.pClearValues = &clearColor; + + vkCmdBeginRenderPass(commandBuffers.value2[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); + vkCmdBindPipeline(commandBuffers.value2[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline); + vkCmdDraw(commandBuffers.value2[i], 3, 1, 0, 0); + vkCmdEndRenderPass(commandBuffers.value2[i]); + vkCall(vkEndCommandBuffer(commandBuffers.value2[i])); + } + + renderer->vk_command_buffers = commandBuffers; + + VkSemaphore imageAvailableSemaphore; + VkSemaphore renderFinishedSemaphore; + + VkSemaphoreCreateInfo semaphoreInfo = {}; + semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + + vkCall(vkCreateSemaphore(renderer->vk_device, &semaphoreInfo, NULL, &imageAvailableSemaphore)); + vkCall(vkCreateSemaphore(renderer->vk_device, &semaphoreInfo, NULL, &renderFinishedSemaphore)); + + renderer->vk_image_available_semaphore = imageAvailableSemaphore; + renderer->vk_render_finished_semaphore = renderFinishedSemaphore; +} + +void renderer_update(renderer_t* renderer) +{ + uint32_t imageIndex; + vkAcquireNextImageKHR(renderer->vk_device, renderer->vk_swapchain, UINT64_MAX, renderer->vk_image_available_semaphore, VK_NULL_HANDLE, &imageIndex); + + + VkSubmitInfo submitInfo = {}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + + VkSemaphore waitSemaphores[] = { renderer->vk_image_available_semaphore }; + VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + + submitInfo.waitSemaphoreCount = 1; + submitInfo.pWaitSemaphores = waitSemaphores; + submitInfo.pWaitDstStageMask = waitStages; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &(renderer->vk_command_buffers.value2[imageIndex]); + + VkSemaphore signalSemaphores[] = { renderer->vk_render_finished_semaphore }; + submitInfo.signalSemaphoreCount = 1; + submitInfo.pSignalSemaphores = signalSemaphores; + + vkCall(vkQueueSubmit(renderer->vk_graphics_queue, 1, &submitInfo, VK_NULL_HANDLE)); + + VkPresentInfoKHR presentInfo = {}; + presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + presentInfo.waitSemaphoreCount = 1; + presentInfo.pWaitSemaphores = signalSemaphores; + + VkSwapchainKHR swapChains[] = { renderer->vk_swapchain }; + presentInfo.swapchainCount = 1; + presentInfo.pSwapchains = swapChains; + presentInfo.pImageIndices = &imageIndex; + presentInfo.pResults = NULL; // Optional + + vkQueuePresentKHR(renderer->vk_graphics_queue, &presentInfo); +} + +static VkShaderModule vk_get_shader_module(renderer_t* renderer, const char* file_name) +{ + tuple_t(uint64_t, pchar_t) shader_bytes = load_binary_from_file(file_name); + VkShaderModuleCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + createInfo.codeSize = shader_bytes.value1; + createInfo.pCode = (const uint32_t*)shader_bytes.value2; //convert from char* to uint32_t* + VkShaderModule shaderModule; + vkCreateShaderModule(renderer->vk_device, &createInfo, NULL, &shaderModule); + return shaderModule; } static tuple_t(uint32_t, pVkImageView_t) vk_get_image_views(renderer_t* renderer) @@ -249,6 +570,14 @@ EXCEPTION_BLOCK void renderer_terminate(renderer_t* renderer) { + vkDestroySemaphore(renderer->vk_device, renderer->vk_image_available_semaphore, NULL); + vkDestroySemaphore(renderer->vk_device, renderer->vk_render_finished_semaphore, NULL); + vkDestroyCommandPool(renderer->vk_device, renderer->vk_command_pool, NULL); + for(uint32_t i = 0; i < renderer->vk_framebuffers.value1; i++) + vkDestroyFramebuffer(renderer->vk_device, renderer->vk_framebuffers.value2[i], NULL); + vkDestroyPipeline(renderer->vk_device, renderer->vk_pipeline, NULL); + vkDestroyRenderPass(renderer->vk_device, renderer->vk_render_pass, NULL); + vkDestroyPipelineLayout(renderer->vk_device, renderer->vk_pipeline_layout, NULL); for(uint32_t i = 0; i < renderer->vk_image_views.value1; i++) vkDestroyImageView(renderer->vk_device, renderer->vk_image_views.value2[i], NULL); vkDestroySwapchainKHR(renderer->vk_device, renderer->vk_swapchain, NULL); From fca1d6b32ff47e9be61e3ed1b501b663551ddf92 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Thu, 30 Sep 2021 00:05:51 +0530 Subject: [PATCH 09/12] Added build rule for vertex and fragment shaders in the makefile --- makefile | 28 ++++++++++++++++++++++------ shaders/fragmentShader.frag | 2 +- shaders/fragmentShader.spv | Bin 456 -> 0 bytes shaders/vertexShader.spv | Bin 1164 -> 0 bytes 4 files changed, 23 insertions(+), 7 deletions(-) delete mode 100644 shaders/fragmentShader.spv delete mode 100644 shaders/vertexShader.spv diff --git a/makefile b/makefile index 50f4e757..4dc9b430 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ -DEFINES= -DHPML_DEBUG_MODE -DLOG_DEBUG -DGLOBAL_DEBUG -DDEBUG -# DEFINES= -DHPML_RELEASE_MODE -DLOG_RELEASE -DGLOBAL_RELEASE -DRELEASE +# DEFINES= -DHPML_DEBUG_MODE -DLOG_DEBUG -DGLOBAL_DEBUG -DDEBUG +DEFINES= -DHPML_RELEASE_MODE -DLOG_RELEASE -DGLOBAL_RELEASE -DRELEASE COMPILATION_CONFIG= -m64 @@ -11,15 +11,31 @@ SOURCES= $(wildcard source/*.c) SCRIPT_OBJECTS = $(addsuffix .o, $(basename $(SCRIPT_FILES))) OBJECTS= $(addsuffix .o, $(basename $(SOURCES))) +FRAGMENT_SHADERS = $(wildcard ./shaders/*.frag) +VERTEX_SHADERS = $(wildcard ./shaders/*.vert) -all: main +FRAGMENT_SPIRV_SHADERS = $(addsuffix .spv, $(basename $(FRAGMENT_SHADERS))) +VERTEX_SPIRV_SHADERS = $(addsuffix .spv, $(basename $(VERTEX_SHADERS))) + + +all: main shader .PHONY: recompile -recompile: clean main +recompile: clean main shader + +%.spv : %.frag + glslc $< -o $@ +%.spv : %.vert + glslc $< -o $@ + +.PHONY : shader + +shader : $(FRAGMENT_SPIRV_SHADERS) $(VERTEX_SPIRV_SHADERS) + %.o : %.c - gcc $(COMPILATION_CONFIG) $(DEFINES) $(INCLUDES) -c $^ -o $@ + gcc $(COMPILATION_CONFIG) $(DEFINES) $(INCLUDES) -c $< -o $@ .PHONY: main @@ -29,4 +45,4 @@ main: $(OBJECTS) $(SCRIPT_OBJECTS) .PHONY: clean clean: - del $(addprefix source\, $(notdir $(OBJECTS))) $(addprefix scripts\, $(notdir $(SCRIPT_OBJECTS))) main.exe \ No newline at end of file + del $(addprefix source\, $(notdir $(OBJECTS))) $(addprefix scripts\, $(notdir $(SCRIPT_OBJECTS))) $(addprefix shaders\, $(notdir $(FRAGMENT_SPIRV_SHADERS) $(VERTEX_SPIRV_SHADERS))) main.exe \ No newline at end of file diff --git a/shaders/fragmentShader.frag b/shaders/fragmentShader.frag index 9d2e6551..99e211ea 100644 --- a/shaders/fragmentShader.frag +++ b/shaders/fragmentShader.frag @@ -5,5 +5,5 @@ layout(location = 0) out vec4 outColor; void main() { - outColor = vec4(0.1, 0.6, 0.7, 1.0); + outColor = vec4(0.6, 0.2, 0.3, 1.0); } \ No newline at end of file diff --git a/shaders/fragmentShader.spv b/shaders/fragmentShader.spv deleted file mode 100644 index 19f1502a47abf4ce37bd41199b3451d2b4d5815d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 456 zcmYjO!AiqG6daqT*4DO)pm>prN2LgM5;RUWfem!f!vMc$7Y%lRE?PdD_#qxGs&q8II2WUjz!Sw8kke#V zJUzNX7h8-Sa@3Lt%??uyK&Zk{ETd(Omb*Lbc- z@?}~lgk;orh6w%Ma#`J#c{%4g7&7GLNPuULF686bJA$wGS-035G7iX>Utwtv`E4`n zwd!C0VQH#&N-S=N@wr;vtZ|q4{q1nF#@obE6#e5KG4MJ$qpEcK3~6XiT-{&tJ@P6a VI@EeoTEe1Nt46Fr1L)Q_WS9u`d(ydk(XK8%LiGv z%D-mn7N&H0*)7g{(}D=abgw8x;UYcyXT!Y8&&nZw#N1oh&qaEa4L)UqD*HwVTl4zn z#wD=xBfa+-@p)OD;qlB{23h_YkbZ%I~7FMt>8pjg7$; zdSBAm+y?OiHU^$Yy3RcIrF!$&f!j)J>13*;pc(*dwBM8 zw&(25H}g&&`9Clb_BD}j;4WUFu-^`_*Bcb}iGdn Date: Fri, 1 Oct 2021 00:26:39 +0530 Subject: [PATCH 10/12] Refactored some of the pipeline setup --- source/renderer.c | 423 +++++++++++++++++++++++++++++----------------- 1 file changed, 270 insertions(+), 153 deletions(-) diff --git a/source/renderer.c b/source/renderer.c index 9be4d4b8..b05d6eac 100644 --- a/source/renderer.c +++ b/source/renderer.c @@ -42,10 +42,6 @@ declare_exception(VULKAN_SURFACE_NOT_SUPPORTED); define_exception(VULKAN_PHYSICAL_DEVICE_EXTENSION_NOT_SUPPORTED); declare_exception(VULKAN_PHYSICAL_DEVICE_EXTENSION_NOT_SUPPORTED); -static void vk_dump_physical_device_extensions(renderer_t* renderer); -static tuple_t(uint32_t, pVkImage_t) vk_get_images(renderer_t* renderer); -static tuple_t(uint32_t, pVkImageView_t) vk_get_image_views(renderer_t* renderer); -static VkShaderModule vk_get_shader_module(renderer_t* renderer, const char* file_name); typedef struct renderer_t { @@ -70,12 +66,38 @@ typedef struct renderer_t VkSemaphore vk_render_finished_semaphore; } renderer_t; +typedef enum +{ + VERTEX_SHADER, + FRAGMENT_SHADER +} shader_type_t; + void* renderer_get_vulkan_instance(renderer_t* renderer) { return (void*)(&(renderer->vk_instance)); } void* renderer_get_vulkan_device(renderer_t* renderer) { return (void*)(&(renderer->vk_device)); } void* renderer_get_vulkan_surface(renderer_t* renderer) { return (void*)(&(renderer->vk_surface)); } void* renderer_get_vulkan_swapchain(renderer_t* renderer) { return (void*)(&(renderer->vk_swapchain)); } static VkSwapchainKHR vk_get_swapchain(renderer_t* renderer); - +static void vk_dump_physical_device_extensions(renderer_t* renderer); +static tuple_t(uint32_t, pVkImage_t) vk_get_images(renderer_t* renderer); +static tuple_t(uint32_t, pVkImageView_t) vk_get_image_views(renderer_t* renderer); +static VkShaderModule vk_get_shader_module(renderer_t* renderer, const char* file_name); +static VkPipelineShaderStageCreateInfo vk_get_pipeline_shader_stage_create_info(VkShaderModule shader_module, shader_type_t shader_type, const char* entry_point); +static VkPipelineVertexInputStateCreateInfo vk_get_pipeline_vertex_input_state_create_info(void); +static VkPipelineInputAssemblyStateCreateInfo vk_get_pipeline_input_assembly_state_create_info(void); +static VkPipelineViewportStateCreateInfo vk_get_pipeline_viewport_state_create_info(uint32_t viewportWidth, uint32_t viewportHeight); +static VkPipelineRasterizationStateCreateInfo vk_get_pipeline_rasterization_state_create_info(void); +static VkPipelineMultisampleStateCreateInfo vk_get_pipeline_multisample_state_create_info(void); +static VkPipelineColorBlendStateCreateInfo vk_get_pipeline_color_blend_state_create_info(void); +static VkPipelineColorBlendAttachmentState vk_get_pipeline_color_blend_attachment_state(void); +static VkPipelineDynamicStateCreateInfo vk_get_pipeline_dynamic_state_create_info(void); +static VkAttachmentReference vk_get_attachment_reference(void); +static VkSubpassDependency vk_get_subpass_dependency(void); +static VkAttachmentDescription vk_get_attachment_description(VkFormat image_format); +static VkSubpassDescription vk_get_subpass_description(VkAttachmentReference attachment_reference); +static VkRenderPass vk_get_render_pass(renderer_t* renderer, const VkAttachmentDescription* attachments, const VkSubpassDescription* subpasses, const VkSubpassDependency* subpassDependencies); +static VkPipelineLayout vk_get_pipeline_layout(renderer_t* renderer); +static VkViewport vk_get_viewport(uint32_t width, uint32_t height); +static void vk_setup_fixed_function_pipline(renderer_t* renderer); renderer_t* renderer_init() { @@ -166,152 +188,33 @@ EXCEPTION_BLOCK renderer->vk_swapchain = vk_get_swapchain(renderer); renderer->vk_images = vk_get_images(renderer); renderer->vk_image_views = vk_get_image_views(renderer); - - VkShaderModule vertexShaderModule = vk_get_shader_module(renderer, "shaders/vertexShader.spv"); - VkShaderModule fragmentShaderModule = vk_get_shader_module(renderer, "shaders/fragmentShader.spv"); - - VkPipelineShaderStageCreateInfo vertexShaderStageInfo = { }; - vertexShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vertexShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; - vertexShaderStageInfo.module = vertexShaderModule; - vertexShaderStageInfo.pName = "main"; - - VkPipelineShaderStageCreateInfo fragmentShaderStageInfo = { }; - fragmentShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - fragmentShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - fragmentShaderStageInfo.module = fragmentShaderModule; - fragmentShaderStageInfo.pName = "main"; - - VkPipelineShaderStageCreateInfo shaderStages[] = { vertexShaderStageInfo, fragmentShaderStageInfo}; - - VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; - vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertexInputInfo.vertexBindingDescriptionCount = 0; - vertexInputInfo.pVertexBindingDescriptions = NULL; // Optional - vertexInputInfo.vertexAttributeDescriptionCount = 0; - vertexInputInfo.pVertexAttributeDescriptions = NULL; - - //Fixed functions configuration - VkPipelineInputAssemblyStateCreateInfo inputAssembly = {}; - inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - inputAssembly.primitiveRestartEnable = VK_FALSE; - - VkViewport viewport = {}; - viewport.x = 0.0f; - viewport.y = 0.0f; - viewport.width = (float) renderer->vk_extent.width; - viewport.height = (float) renderer->vk_extent.height; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - - VkRect2D scissor = {}; - scissor.offset = (VkOffset2D) {0, 0}; - scissor.extent = renderer->vk_extent; - - VkPipelineViewportStateCreateInfo viewportState = {}; - viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewportState.viewportCount = 1; - viewportState.pViewports = &viewport; - viewportState.scissorCount = 1; - viewportState.pScissors = &scissor; - - VkPipelineRasterizationStateCreateInfo rasterizer = {}; - rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterizer.depthClampEnable = VK_FALSE; - rasterizer.rasterizerDiscardEnable = VK_FALSE; - rasterizer.polygonMode = VK_POLYGON_MODE_FILL; - rasterizer.lineWidth = 1.0f; - rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; - rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; - rasterizer.depthBiasEnable = VK_FALSE; - rasterizer.depthBiasConstantFactor = 0.0f; // Optional - rasterizer.depthBiasClamp = 0.0f; // Optional - rasterizer.depthBiasSlopeFactor = 0.0f; // Optional - - VkPipelineMultisampleStateCreateInfo multisampling = {}; - multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampling.sampleShadingEnable = VK_FALSE; - multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - multisampling.minSampleShading = 1.0f; // Optional - multisampling.pSampleMask = NULL; // Optional - multisampling.alphaToCoverageEnable = VK_FALSE; // Optional - multisampling.alphaToOneEnable = VK_FALSE; // Optional - - VkPipelineColorBlendAttachmentState colorBlendAttachment = {}; - colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - colorBlendAttachment.blendEnable = VK_FALSE; - colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // Optional - colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional - colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; // Optional - colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // Optional - colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional - colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; // Optional - - - VkPipelineColorBlendStateCreateInfo colorBlending = {}; - colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - colorBlending.logicOpEnable = VK_FALSE; - colorBlending.logicOp = VK_LOGIC_OP_COPY; // Optional - colorBlending.attachmentCount = 1; - colorBlending.pAttachments = &colorBlendAttachment; - colorBlending.blendConstants[0] = 0.0f; // Optional - colorBlending.blendConstants[1] = 0.0f; // Optional - colorBlending.blendConstants[2] = 0.0f; // Optional - colorBlending.blendConstants[3] = 0.0f; // Optional - - VkDynamicState dynamicStates[] = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_LINE_WIDTH + + VkPipelineShaderStageCreateInfo shaderStages[] = + { + vk_get_pipeline_shader_stage_create_info(vk_get_shader_module(renderer, "shaders/vertexShader.spv"), VERTEX_SHADER, "main"), + vk_get_pipeline_shader_stage_create_info(vk_get_shader_module(renderer, "shaders/fragmentShader.spv"), FRAGMENT_SHADER, "main") }; - VkPipelineDynamicStateCreateInfo dynamicState = {}; - dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamicState.dynamicStateCount = 2; - dynamicState.pDynamicStates = dynamicStates; - - VkPipelineLayout pipelineLayout; - - VkPipelineLayoutCreateInfo pipelineLayoutInfo = {}; - pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipelineLayoutInfo.setLayoutCount = 0; // Optional - pipelineLayoutInfo.pSetLayouts = NULL; // Optional - pipelineLayoutInfo.pushConstantRangeCount = 0; // Optional - pipelineLayoutInfo.pPushConstantRanges = NULL; // Optional - - vkCall(vkCreatePipelineLayout(renderer->vk_device, &pipelineLayoutInfo, NULL, &pipelineLayout)); + VkPipelineVertexInputStateCreateInfo vertexInputInfo = vk_get_pipeline_vertex_input_state_create_info(); - renderer->vk_pipeline_layout = pipelineLayout; + vk_setup_fixed_function_pipline(renderer); - VkAttachmentDescription colorAttachment = {}; - colorAttachment.format = renderer->vk_format; - colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; - colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - VkAttachmentReference colorAttachmentRef = {}; - colorAttachmentRef.attachment = 0; - colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass = {}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &colorAttachmentRef; - - VkSubpassDependency dependency = {}; - dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.dstSubpass = 0; - dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependency.srcAccessMask = 0; - dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - VkRenderPass renderPass; - VkRenderPassCreateInfo renderPassCreateInfo = {}; + //Fixed functions configuration + VkPipelineInputAssemblyStateCreateInfo inputAssembly = vk_get_pipeline_input_assembly_state_create_info(); + VkPipelineViewportStateCreateInfo viewportState = vk_get_pipeline_viewport_state_create_info(renderer->vk_extent.width, renderer->vk_extent.height); + VkPipelineRasterizationStateCreateInfo rasterizer = vk_get_pipeline_rasterization_state_create_info(); + VkPipelineMultisampleStateCreateInfo multisampling = vk_get_pipeline_multisample_state_create_info(); + VkPipelineColorBlendStateCreateInfo colorBlending = vk_get_pipeline_color_blend_state_create_info(); + VkPipelineDynamicStateCreateInfo dynamicState = vk_get_pipeline_dynamic_state_create_info(); + renderer->vk_pipeline_layout = vk_get_pipeline_layout(renderer); + VkAttachmentDescription colorAttachment = vk_get_attachment_description(renderer->vk_format); + VkAttachmentReference colorAttachmentRef = vk_get_attachment_reference(); + VkSubpassDescription subpass = vk_get_subpass_description(colorAttachmentRef); + VkSubpassDependency dependency = vk_get_subpass_dependency(); + + //TODO: why calling vk_get_render_pass isn't working? fix that + //renderer->vk_render_pass = vk_get_render_pass(renderer, &colorAttachment, &subpass, &dependency); + VkRenderPassCreateInfo renderPassCreateInfo = {}; renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassCreateInfo.attachmentCount = 1; renderPassCreateInfo.pAttachments = &colorAttachment; @@ -319,8 +222,7 @@ EXCEPTION_BLOCK renderPassCreateInfo.pSubpasses = &subpass; renderPassCreateInfo.dependencyCount = 1; renderPassCreateInfo.pDependencies = &dependency; - vkCall(vkCreateRenderPass(renderer->vk_device, &renderPassCreateInfo, NULL, &renderPass)); - renderer->vk_render_pass = renderPass; + vkCall(vkCreateRenderPass(renderer->vk_device, &renderPassCreateInfo, NULL, &(renderer->vk_render_pass))); VkGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; @@ -335,8 +237,8 @@ EXCEPTION_BLOCK pipelineInfo.pDepthStencilState = NULL; // Optional pipelineInfo.pColorBlendState = &colorBlending; pipelineInfo.pDynamicState = NULL; // Optional - pipelineInfo.layout = pipelineLayout; - pipelineInfo.renderPass = renderPass; + pipelineInfo.layout = renderer->vk_pipeline_layout; + pipelineInfo.renderPass = renderer->vk_render_pass; pipelineInfo.subpass = 0; pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; // Optional pipelineInfo.basePipelineIndex = -1; // Optional @@ -355,7 +257,7 @@ EXCEPTION_BLOCK VkFramebufferCreateInfo framebufferInfo = {}; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebufferInfo.renderPass = renderPass; + framebufferInfo.renderPass = renderer->vk_render_pass; framebufferInfo.attachmentCount = 1; framebufferInfo.pAttachments = attachments; framebufferInfo.width = renderer->vk_extent.width; @@ -391,7 +293,7 @@ EXCEPTION_BLOCK VkRenderPassBeginInfo renderPassInfo = {}; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - renderPassInfo.renderPass = renderPass; + renderPassInfo.renderPass = renderer->vk_render_pass; renderPassInfo.framebuffer = renderer->vk_framebuffers.value2[i]; renderPassInfo.renderArea.offset = (VkOffset2D) {0, 0}; renderPassInfo.renderArea.extent = renderer->vk_extent; @@ -460,6 +362,221 @@ void renderer_update(renderer_t* renderer) vkQueuePresentKHR(renderer->vk_graphics_queue, &presentInfo); } +static void vk_setup_fixed_function_pipline(renderer_t* renderer) +{ + VkPipelineInputAssemblyStateCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + createInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + createInfo.primitiveRestartEnable = VK_FALSE; + +} + + + static VkRenderPass vk_get_render_pass(renderer_t* renderer, const VkAttachmentDescription* attachments, const VkSubpassDescription* subpasses, const VkSubpassDependency* subpassDependencies) + { + VkRenderPass renderPass; + VkRenderPassCreateInfo renderPassCreateInfo = {}; + renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + renderPassCreateInfo.attachmentCount = 1; + renderPassCreateInfo.pAttachments = attachments; + renderPassCreateInfo.subpassCount = 1; + renderPassCreateInfo.pSubpasses = subpasses; + renderPassCreateInfo.dependencyCount = 1; + renderPassCreateInfo.pDependencies = subpassDependencies; + vkCall(vkCreateRenderPass(renderer->vk_device, &renderPassCreateInfo, NULL, &renderPass)); + log_msg("vk_get_render_pass"); + return renderPass; + } + +static VkSubpassDependency vk_get_subpass_dependency() +{ + VkSubpassDependency dependency = {}; + dependency.srcSubpass = VK_SUBPASS_EXTERNAL; + dependency.dstSubpass = 0; + dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.srcAccessMask = 0; + dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + return dependency; +} + +static VkSubpassDescription vk_get_subpass_description(VkAttachmentReference attachment_reference) +{ + VkSubpassDescription subpass = {}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &attachment_reference; + return subpass; +} + +static VkAttachmentReference vk_get_attachment_reference() +{ + VkAttachmentReference colorAttachmentRef = {}; + colorAttachmentRef.attachment = 0; + colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + return colorAttachmentRef; +} + +static VkAttachmentDescription vk_get_attachment_description(VkFormat image_format) +{ + VkAttachmentDescription colorAttachment = {}; + colorAttachment.format = image_format; + colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; + colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + return colorAttachment; +} + +static VkPipelineLayout vk_get_pipeline_layout(renderer_t* renderer) +{ + VkPipelineLayout pipelineLayout; + + VkPipelineLayoutCreateInfo pipelineLayoutInfo = {}; + pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutInfo.setLayoutCount = 0; // Optional + pipelineLayoutInfo.pSetLayouts = NULL; // Optional + pipelineLayoutInfo.pushConstantRangeCount = 0; // Optional + pipelineLayoutInfo.pPushConstantRanges = NULL; // Optional + + vkCall(vkCreatePipelineLayout(renderer->vk_device, &pipelineLayoutInfo, NULL, &pipelineLayout)); + return pipelineLayout; +} + +static VkPipelineDynamicStateCreateInfo vk_get_pipeline_dynamic_state_create_info(void) +{ + VkDynamicState* dynamicStates = GC_NEWV(VkDynamicState, 2); + dynamicStates[0] = VK_DYNAMIC_STATE_VIEWPORT; + dynamicStates[1] = VK_DYNAMIC_STATE_LINE_WIDTH; + + VkPipelineDynamicStateCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + createInfo.dynamicStateCount = 1; + createInfo.pDynamicStates = dynamicStates; + return createInfo; +} + +static VkPipelineColorBlendStateCreateInfo vk_get_pipeline_color_blend_state_create_info(void) +{ + VkPipelineColorBlendStateCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + createInfo.logicOpEnable = VK_FALSE; + createInfo.logicOp = VK_LOGIC_OP_COPY; // Optional + createInfo.attachmentCount = 1; + VkPipelineColorBlendAttachmentState* state = GC_NEW(VkPipelineColorBlendAttachmentState); + *state = vk_get_pipeline_color_blend_attachment_state(); + createInfo.pAttachments = state; + createInfo.blendConstants[0] = 0.0f; // Optional + createInfo.blendConstants[1] = 0.0f; // Optional + createInfo.blendConstants[2] = 0.0f; // Optional + createInfo.blendConstants[3] = 0.0f; // Optional + return createInfo; +} + +static VkPipelineColorBlendAttachmentState vk_get_pipeline_color_blend_attachment_state(void) +{ + VkPipelineColorBlendAttachmentState colorBlendAttachment = {}; + colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + colorBlendAttachment.blendEnable = VK_FALSE; + colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // Optional + colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional + colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; // Optional + colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // Optional + colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional + colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; // Optional + return colorBlendAttachment; +} + +static VkPipelineMultisampleStateCreateInfo vk_get_pipeline_multisample_state_create_info(void) +{ + VkPipelineMultisampleStateCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + createInfo.sampleShadingEnable = VK_FALSE; + createInfo.rasterizationSamples = VK_SAMPLE_COUNT_2_BIT; + createInfo.minSampleShading = 1.0f; // Optional + createInfo.pSampleMask = NULL; // Optional + createInfo.alphaToCoverageEnable = VK_FALSE; // Optional + createInfo.alphaToOneEnable = VK_FALSE; // Optional + return createInfo; +} + +static VkPipelineRasterizationStateCreateInfo vk_get_pipeline_rasterization_state_create_info(void) +{ + VkPipelineRasterizationStateCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + createInfo.depthClampEnable = VK_FALSE; + createInfo.rasterizerDiscardEnable = VK_FALSE; + createInfo.polygonMode = VK_POLYGON_MODE_FILL; + createInfo.lineWidth = 1.0f; + createInfo.cullMode = VK_CULL_MODE_BACK_BIT; + createInfo.frontFace = VK_FRONT_FACE_CLOCKWISE; + createInfo.depthBiasEnable = VK_FALSE; + createInfo.depthBiasConstantFactor = 0.0f; // Optional + createInfo.depthBiasClamp = 0.0f; // Optional + createInfo.depthBiasSlopeFactor = 0.0f; // Optional + return createInfo; +} + +static VkPipelineViewportStateCreateInfo vk_get_pipeline_viewport_state_create_info(uint32_t viewportWidth, uint32_t viewportHeight) +{ + VkPipelineViewportStateCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + createInfo.viewportCount = 1; + VkViewport* viewport = GC_NEW(VkViewport); + *viewport = vk_get_viewport(viewportWidth, viewportHeight); + VkRect2D* scissor = GC_NEW(VkRect2D); + *scissor = (VkRect2D) { .offset = { 0, 0 }, .extent = { viewportWidth, viewportHeight } }; + createInfo.pViewports = viewport; + createInfo.scissorCount = 1; + createInfo.pScissors = scissor; + return createInfo; +} + +static VkPipelineInputAssemblyStateCreateInfo vk_get_pipeline_input_assembly_state_create_info() +{ + VkPipelineInputAssemblyStateCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + createInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + createInfo.primitiveRestartEnable = VK_FALSE; + return createInfo; +} + +static VkViewport vk_get_viewport(uint32_t width, uint32_t height) +{ + VkViewport viewport = { }; + viewport.x = 0; + viewport.y = 0; + viewport.width = width; + viewport.height = height; + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + return viewport; +} + +static VkPipelineVertexInputStateCreateInfo vk_get_pipeline_vertex_input_state_create_info() +{ + VkPipelineVertexInputStateCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + createInfo.vertexBindingDescriptionCount = 0; + createInfo.pVertexBindingDescriptions = NULL; + createInfo.vertexAttributeDescriptionCount = 0; + createInfo.pVertexAttributeDescriptions = NULL; + return createInfo; +} + +static VkPipelineShaderStageCreateInfo vk_get_pipeline_shader_stage_create_info(VkShaderModule shader_module, shader_type_t shader_type, const char* entry_point) +{ + VkPipelineShaderStageCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + createInfo.pName = entry_point; + createInfo.module = shader_module; + createInfo.stage = (shader_type == VERTEX_SHADER) ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT; + return createInfo; +} + static VkShaderModule vk_get_shader_module(renderer_t* renderer, const char* file_name) { tuple_t(uint64_t, pchar_t) shader_bytes = load_binary_from_file(file_name); From be3f61daaf8b47a4860580eb1cfcbe09ee569b00 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Sat, 2 Oct 2021 01:20:23 +0530 Subject: [PATCH 11/12] Refactored CommandBuffer creation & and recording --- source/renderer.c | 245 +++++++++++++++++++++++++--------------------- 1 file changed, 136 insertions(+), 109 deletions(-) diff --git a/source/renderer.c b/source/renderer.c index b05d6eac..a87a1285 100644 --- a/source/renderer.c +++ b/source/renderer.c @@ -90,14 +90,26 @@ static VkPipelineMultisampleStateCreateInfo vk_get_pipeline_multisample_state_cr static VkPipelineColorBlendStateCreateInfo vk_get_pipeline_color_blend_state_create_info(void); static VkPipelineColorBlendAttachmentState vk_get_pipeline_color_blend_attachment_state(void); static VkPipelineDynamicStateCreateInfo vk_get_pipeline_dynamic_state_create_info(void); +static VkPipeline vk_get_graphics_pipeline(renderer_t* renderer, VkPipelineLayout pipelineLayout, VkRenderPass renderPass, + VkPipelineShaderStageCreateInfo* shaderStages, + VkPipelineVertexInputStateCreateInfo* vertexInputState, + VkPipelineInputAssemblyStateCreateInfo* inputAssemblyState, + VkPipelineViewportStateCreateInfo* viewportState, + VkPipelineRasterizationStateCreateInfo* rasterizationState, + VkPipelineMultisampleStateCreateInfo* multisampleState, + VkPipelineColorBlendStateCreateInfo* colorBlendState); +static tuple_t(uint32_t, pVkFramebuffer_t) vk_get_framebuffers(renderer_t* renderer); +static tuple_t(uint32_t, pVkCommandBuffer_t) vk_get_commandbuffers(renderer_t* renderer); static VkAttachmentReference vk_get_attachment_reference(void); static VkSubpassDependency vk_get_subpass_dependency(void); +static VkSemaphore vk_get_semaphore(renderer_t* renderer); static VkAttachmentDescription vk_get_attachment_description(VkFormat image_format); static VkSubpassDescription vk_get_subpass_description(VkAttachmentReference attachment_reference); -static VkRenderPass vk_get_render_pass(renderer_t* renderer, const VkAttachmentDescription* attachments, const VkSubpassDescription* subpasses, const VkSubpassDependency* subpassDependencies); +static VkRenderPass vk_get_render_pass(renderer_t* renderer, VkAttachmentDescription* attachments, VkSubpassDescription* subpasses, VkSubpassDependency* subpassDependencies); static VkPipelineLayout vk_get_pipeline_layout(renderer_t* renderer); static VkViewport vk_get_viewport(uint32_t width, uint32_t height); static void vk_setup_fixed_function_pipline(renderer_t* renderer); +static void record_commands(renderer_t* renderer, tuple_t(uint32_t, pVkCommandBuffer_t) commandBuffers); renderer_t* renderer_init() { @@ -197,8 +209,6 @@ EXCEPTION_BLOCK VkPipelineVertexInputStateCreateInfo vertexInputInfo = vk_get_pipeline_vertex_input_state_create_info(); - vk_setup_fixed_function_pipline(renderer); - //Fixed functions configuration VkPipelineInputAssemblyStateCreateInfo inputAssembly = vk_get_pipeline_input_assembly_state_create_info(); VkPipelineViewportStateCreateInfo viewportState = vk_get_pipeline_viewport_state_create_info(renderer->vk_extent.width, renderer->vk_extent.height); @@ -206,14 +216,16 @@ EXCEPTION_BLOCK VkPipelineMultisampleStateCreateInfo multisampling = vk_get_pipeline_multisample_state_create_info(); VkPipelineColorBlendStateCreateInfo colorBlending = vk_get_pipeline_color_blend_state_create_info(); VkPipelineDynamicStateCreateInfo dynamicState = vk_get_pipeline_dynamic_state_create_info(); + renderer->vk_pipeline_layout = vk_get_pipeline_layout(renderer); + VkAttachmentDescription colorAttachment = vk_get_attachment_description(renderer->vk_format); VkAttachmentReference colorAttachmentRef = vk_get_attachment_reference(); VkSubpassDescription subpass = vk_get_subpass_description(colorAttachmentRef); VkSubpassDependency dependency = vk_get_subpass_dependency(); //TODO: why calling vk_get_render_pass isn't working? fix that - //renderer->vk_render_pass = vk_get_render_pass(renderer, &colorAttachment, &subpass, &dependency); + // renderer->vk_render_pass = vk_get_render_pass(renderer, &colorAttachment, &subpass, &dependency); VkRenderPassCreateInfo renderPassCreateInfo = {}; renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassCreateInfo.attachmentCount = 1; @@ -224,104 +236,21 @@ EXCEPTION_BLOCK renderPassCreateInfo.pDependencies = &dependency; vkCall(vkCreateRenderPass(renderer->vk_device, &renderPassCreateInfo, NULL, &(renderer->vk_render_pass))); - VkGraphicsPipelineCreateInfo pipelineInfo = {}; - pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipelineInfo.stageCount = 2; - pipelineInfo.pStages = shaderStages; - - pipelineInfo.pVertexInputState = &vertexInputInfo; - pipelineInfo.pInputAssemblyState = &inputAssembly; - pipelineInfo.pViewportState = &viewportState; - pipelineInfo.pRasterizationState = &rasterizer; - pipelineInfo.pMultisampleState = &multisampling; - pipelineInfo.pDepthStencilState = NULL; // Optional - pipelineInfo.pColorBlendState = &colorBlending; - pipelineInfo.pDynamicState = NULL; // Optional - pipelineInfo.layout = renderer->vk_pipeline_layout; - pipelineInfo.renderPass = renderer->vk_render_pass; - pipelineInfo.subpass = 0; - pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; // Optional - pipelineInfo.basePipelineIndex = -1; // Optional - - VkPipeline graphicsPipeline; - vkCall(vkCreateGraphicsPipelines(renderer->vk_device, VK_NULL_HANDLE, 1, &pipelineInfo, NULL, &graphicsPipeline)); - renderer->vk_pipeline = graphicsPipeline; + renderer->vk_pipeline = vk_get_graphics_pipeline(renderer, renderer->vk_pipeline_layout, renderer->vk_render_pass, + shaderStages, + &vertexInputInfo, + &inputAssembly, + &viewportState, + &rasterizer, + &multisampling, + &colorBlending); + renderer->vk_framebuffers = vk_get_framebuffers(renderer); //swapchainFramebuffers - tuple_t(uint32_t, pVkFramebuffer_t) swapChainFramebuffers = (tuple_t(uint32_t, pVkFramebuffer_t)) { renderer->vk_images.value1, GC_NEWV(VkFramebuffer, renderer->vk_images.value1) }; - for(uint32_t i = 0; i < swapChainFramebuffers.value1; i++) - { - VkImageView attachments[] = { - renderer->vk_image_views.value2[i] - }; - - VkFramebufferCreateInfo framebufferInfo = {}; - framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebufferInfo.renderPass = renderer->vk_render_pass; - framebufferInfo.attachmentCount = 1; - framebufferInfo.pAttachments = attachments; - framebufferInfo.width = renderer->vk_extent.width; - framebufferInfo.height = renderer->vk_extent.height; - framebufferInfo.layers = 1; - vkCall(vkCreateFramebuffer(renderer->vk_device, &framebufferInfo, NULL, &(swapChainFramebuffers.value2[i]))); - } - renderer->vk_framebuffers = swapChainFramebuffers; - - VkCommandPool commandPool; - VkCommandPoolCreateInfo poolInfo = {}; - poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - poolInfo.queueFamilyIndex = renderer->vk_graphics_queue_index; - poolInfo.flags = 0; // Optional - vkCall(vkCreateCommandPool(renderer->vk_device, &poolInfo, NULL, &commandPool)); - renderer->vk_command_pool = commandPool; + record_commands(renderer, vk_get_commandbuffers(renderer)); - tuple_t(uint32_t, pVkCommandBuffer_t) commandBuffers = (tuple_t(uint32_t, pVkCommandBuffer_t)) { renderer->vk_framebuffers.value1, GC_NEWV(VkCommandBuffer, renderer->vk_framebuffers.value1) }; - VkCommandBufferAllocateInfo allocInfo = {}; - allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - allocInfo.commandPool = commandPool; - allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocInfo.commandBufferCount = (uint32_t) commandBuffers.value1; - vkCall(vkAllocateCommandBuffers(renderer->vk_device, &allocInfo, commandBuffers.value2)); - - for (uint32_t i = 0; i < commandBuffers.value1; i++) - { - VkCommandBufferBeginInfo beginInfo = {}; - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = 0; // Optional - beginInfo.pInheritanceInfo = NULL; // Optional - vkCall(vkBeginCommandBuffer(commandBuffers.value2[i], &beginInfo)); - - VkRenderPassBeginInfo renderPassInfo = {}; - renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - renderPassInfo.renderPass = renderer->vk_render_pass; - renderPassInfo.framebuffer = renderer->vk_framebuffers.value2[i]; - renderPassInfo.renderArea.offset = (VkOffset2D) {0, 0}; - renderPassInfo.renderArea.extent = renderer->vk_extent; - - VkClearValue clearColor = {{{0.0f, 0.0f, 0.0f, 1.0f}}}; - renderPassInfo.clearValueCount = 1; - renderPassInfo.pClearValues = &clearColor; - - vkCmdBeginRenderPass(commandBuffers.value2[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); - vkCmdBindPipeline(commandBuffers.value2[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline); - vkCmdDraw(commandBuffers.value2[i], 3, 1, 0, 0); - vkCmdEndRenderPass(commandBuffers.value2[i]); - vkCall(vkEndCommandBuffer(commandBuffers.value2[i])); - } - - renderer->vk_command_buffers = commandBuffers; - - VkSemaphore imageAvailableSemaphore; - VkSemaphore renderFinishedSemaphore; - - VkSemaphoreCreateInfo semaphoreInfo = {}; - semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - - vkCall(vkCreateSemaphore(renderer->vk_device, &semaphoreInfo, NULL, &imageAvailableSemaphore)); - vkCall(vkCreateSemaphore(renderer->vk_device, &semaphoreInfo, NULL, &renderFinishedSemaphore)); - - renderer->vk_image_available_semaphore = imageAvailableSemaphore; - renderer->vk_render_finished_semaphore = renderFinishedSemaphore; + renderer->vk_image_available_semaphore = vk_get_semaphore(renderer); + renderer->vk_render_finished_semaphore = vk_get_semaphore(renderer); } void renderer_update(renderer_t* renderer) @@ -362,19 +291,118 @@ void renderer_update(renderer_t* renderer) vkQueuePresentKHR(renderer->vk_graphics_queue, &presentInfo); } -static void vk_setup_fixed_function_pipline(renderer_t* renderer) +static VkSemaphore vk_get_semaphore(renderer_t* renderer) +{ + VkSemaphore semaphore; + VkSemaphoreCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + vkCall(vkCreateSemaphore(renderer->vk_device, &createInfo, NULL, &semaphore)) + return semaphore; +} + +static void record_commands(renderer_t* renderer, tuple_t(uint32_t, pVkCommandBuffer_t) commandBuffers) { - VkPipelineInputAssemblyStateCreateInfo createInfo = { }; - createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - createInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - createInfo.primitiveRestartEnable = VK_FALSE; + for (uint32_t i = 0; i < commandBuffers.value1; i++) + { + VkCommandBufferBeginInfo beginInfo = {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = 0; // Optional + beginInfo.pInheritanceInfo = NULL; // Optional + vkCall(vkBeginCommandBuffer(commandBuffers.value2[i], &beginInfo)); + + VkRenderPassBeginInfo renderPassInfo = {}; + renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + renderPassInfo.renderPass = renderer->vk_render_pass; + renderPassInfo.framebuffer = renderer->vk_framebuffers.value2[i]; + renderPassInfo.renderArea.offset = (VkOffset2D) {0, 0}; + renderPassInfo.renderArea.extent = renderer->vk_extent; + VkClearValue clearColor = {{{0.1f, 0.05f, 0.1f, 1.0f}}}; + renderPassInfo.clearValueCount = 1; + renderPassInfo.pClearValues = &clearColor; + + vkCmdBeginRenderPass(commandBuffers.value2[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); + vkCmdBindPipeline(commandBuffers.value2[i], VK_PIPELINE_BIND_POINT_GRAPHICS, renderer->vk_pipeline); + vkCmdDraw(commandBuffers.value2[i], 3, 1, 0, 0); + vkCmdEndRenderPass(commandBuffers.value2[i]); + vkCall(vkEndCommandBuffer(commandBuffers.value2[i])); + } +} + +static tuple_t(uint32_t, pVkCommandBuffer_t) vk_get_commandbuffers(renderer_t* renderer) +{ + tuple_t(uint32_t, pVkCommandBuffer_t) commandBuffers = (tuple_t(uint32_t, pVkCommandBuffer_t)) { renderer->vk_framebuffers.value1, GC_NEWV(VkCommandBuffer, renderer->vk_framebuffers.value1) }; + VkCommandPool commandPool; + VkCommandPoolCreateInfo commandPoolCreateInfo = { } ; + commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + commandPoolCreateInfo.queueFamilyIndex = renderer->vk_graphics_queue_index; + vkCall(vkCreateCommandPool(renderer->vk_device, &commandPoolCreateInfo, NULL, &commandPool)); + VkCommandBufferAllocateInfo allocInfo = { }; + allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocInfo.commandPool = commandPool; + allocInfo.commandBufferCount = commandBuffers.value1; + allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + vkAllocateCommandBuffers(renderer->vk_device, &allocInfo, commandBuffers.value2); + renderer->vk_command_pool = commandPool; + renderer->vk_command_buffers = commandBuffers; + return commandBuffers; +} + +static tuple_t(uint32_t, pVkFramebuffer_t) vk_get_framebuffers(renderer_t* renderer) +{ + tuple_t(uint32_t, pVkFramebuffer_t) swapchainFramebuffers = (tuple_t(uint32_t, pVkFramebuffer_t)) { renderer->vk_images.value1, GC_NEWV(VkFramebuffer, renderer->vk_images.value1) }; + for(uint32_t i = 0; i < swapchainFramebuffers.value1; i++) + { + VkFramebufferCreateInfo createInfo = { }; + createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + createInfo.renderPass = renderer->vk_render_pass; + createInfo.pAttachments = &(renderer->vk_image_views.value2[i]); + createInfo.attachmentCount = 1; + createInfo.width = renderer->vk_extent.width; + createInfo.height = renderer->vk_extent.height; + createInfo.layers = 1; + vkCall(vkCreateFramebuffer(renderer->vk_device, &createInfo, NULL, &(swapchainFramebuffers.value2[i]))); + } + return swapchainFramebuffers; } - static VkRenderPass vk_get_render_pass(renderer_t* renderer, const VkAttachmentDescription* attachments, const VkSubpassDescription* subpasses, const VkSubpassDependency* subpassDependencies) - { - VkRenderPass renderPass; +static VkPipeline vk_get_graphics_pipeline(renderer_t* renderer, VkPipelineLayout pipelineLayout, VkRenderPass renderPass, + VkPipelineShaderStageCreateInfo* shaderStages, + VkPipelineVertexInputStateCreateInfo* vertexInputState, + VkPipelineInputAssemblyStateCreateInfo* inputAssemblyState, + VkPipelineViewportStateCreateInfo* viewportState, + VkPipelineRasterizationStateCreateInfo* rasterizationState, + VkPipelineMultisampleStateCreateInfo* multisampleState, + VkPipelineColorBlendStateCreateInfo* colorBlendState) +{ + VkGraphicsPipelineCreateInfo pipelineInfo = {}; + pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipelineInfo.stageCount = 2; + pipelineInfo.pStages = shaderStages; + pipelineInfo.pVertexInputState = vertexInputState; + pipelineInfo.pInputAssemblyState = inputAssemblyState; + pipelineInfo.pViewportState = viewportState; + pipelineInfo.pRasterizationState = rasterizationState; + pipelineInfo.pMultisampleState = multisampleState; + pipelineInfo.pDepthStencilState = NULL; // Optional + pipelineInfo.pColorBlendState = colorBlendState; + pipelineInfo.pDynamicState = NULL; // Optional + pipelineInfo.layout = pipelineLayout; + pipelineInfo.renderPass = renderPass; + pipelineInfo.subpass = 0; + pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; // Optional + pipelineInfo.basePipelineIndex = -1; // Optional + + VkPipeline graphicsPipeline; + vkCall(vkCreateGraphicsPipelines(renderer->vk_device, VK_NULL_HANDLE, 1, &pipelineInfo, NULL, &graphicsPipeline)); + return graphicsPipeline; +} + + +static VkRenderPass vk_get_render_pass(renderer_t* renderer, VkAttachmentDescription* attachments, VkSubpassDescription* subpasses, VkSubpassDependency* subpassDependencies) +{ + VkRenderPass renderPass; VkRenderPassCreateInfo renderPassCreateInfo = {}; renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassCreateInfo.attachmentCount = 1; @@ -384,9 +412,8 @@ static void vk_setup_fixed_function_pipline(renderer_t* renderer) renderPassCreateInfo.dependencyCount = 1; renderPassCreateInfo.pDependencies = subpassDependencies; vkCall(vkCreateRenderPass(renderer->vk_device, &renderPassCreateInfo, NULL, &renderPass)); - log_msg("vk_get_render_pass"); return renderPass; - } +} static VkSubpassDependency vk_get_subpass_dependency() { From a707316b875399af619e1d35f0baeef3bfcab2d2 Mon Sep 17 00:00:00 2001 From: ravi688 Date: Sat, 2 Oct 2021 01:23:49 +0530 Subject: [PATCH 12/12] Added DEBUG and RELEASE support for vkCall in vulkan_wrapper.h --- include/vulkan/vulkan_wrapper.h | 8 ++++++-- source/renderer.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/vulkan/vulkan_wrapper.h b/include/vulkan/vulkan_wrapper.h index 007863b3..ea54546f 100644 --- a/include/vulkan/vulkan_wrapper.h +++ b/include/vulkan/vulkan_wrapper.h @@ -7,8 +7,8 @@ #include #include - -#define vkCall(call)\ +#ifdef DEBUG +# define vkCall(call)\ {\ VkResult result = call;\ EXCEPTION_BLOCK\ @@ -18,6 +18,10 @@ )\ } +#else +# define vkCall(call) call +#endif + declare_exception(VULKAN_EXTENSION_NOT_SUPPORTED); declare_exception(VULKAN_LAYER_NOT_SUPPORTED); diff --git a/source/renderer.c b/source/renderer.c index a87a1285..b3757359 100644 --- a/source/renderer.c +++ b/source/renderer.c @@ -296,7 +296,7 @@ static VkSemaphore vk_get_semaphore(renderer_t* renderer) VkSemaphore semaphore; VkSemaphoreCreateInfo createInfo = { }; createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - vkCall(vkCreateSemaphore(renderer->vk_device, &createInfo, NULL, &semaphore)) + vkCall(vkCreateSemaphore(renderer->vk_device, &createInfo, NULL, &semaphore)); return semaphore; }