From b443b5173c43fb887451829a4eb9e4eec429b770 Mon Sep 17 00:00:00 2001 From: Greg Wells Date: Wed, 28 May 2025 14:57:41 -0400 Subject: [PATCH] gryphn+vulkan render pass descriptors --- include/gryphn/gryphn.h | 1 + .../vulkan_render_pass_descriptor.c | 81 +++++++++++++++++++ .../vulkan_render_pass_descriptor.h | 7 ++ src/core/gryphn_platform_functions.h | 4 + src/core/instance/init/gryphn_init.c | 2 + .../gryphn_render_pass_descriptor.c | 11 +++ .../gryphn_render_pass_descriptor.h | 52 ++++++++++++ src/utils/gryphn_error_code.h | 4 +- src/utils/types/gryphn_image_format.h | 4 + 9 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 rendering_api/vulkan/src/renderpass/vulkan_render_pass_descriptor.c create mode 100644 rendering_api/vulkan/src/renderpass/vulkan_render_pass_descriptor.h create mode 100644 src/core/renderpass/gryphn_render_pass_descriptor.c create mode 100644 src/core/renderpass/gryphn_render_pass_descriptor.h diff --git a/include/gryphn/gryphn.h b/include/gryphn/gryphn.h index 1d03abd..9dd774e 100644 --- a/include/gryphn/gryphn.h +++ b/include/gryphn/gryphn.h @@ -10,3 +10,4 @@ #include #include #include +#include diff --git a/rendering_api/vulkan/src/renderpass/vulkan_render_pass_descriptor.c b/rendering_api/vulkan/src/renderpass/vulkan_render_pass_descriptor.c new file mode 100644 index 0000000..7ca8713 --- /dev/null +++ b/rendering_api/vulkan/src/renderpass/vulkan_render_pass_descriptor.c @@ -0,0 +1,81 @@ +#include "vulkan_render_pass_descriptor.h" +#include "vulkan_surface/vulkan_surface.h" +#include "output_device/vulkan_output_devices.h" + +VkAttachmentLoadOp vkGryphnLoadOperation(enum gnLoadOperation_e loadOperation) { + switch(loadOperation) { + case GN_LOAD_OPERATION_LOAD: return VK_ATTACHMENT_LOAD_OP_LOAD; + case GN_LOAD_OPERATION_CLEAR: return VK_ATTACHMENT_LOAD_OP_CLEAR; + case GN_LOAD_OPERATION_DONT_CARE: return VK_ATTACHMENT_LOAD_OP_DONT_CARE; + } +} + +VkAttachmentStoreOp vkGryphnStoreOperation(enum gnStoreOperation_e storeOperation) { + switch (storeOperation) { + case GN_STORE_OPERATION_STORE: return VK_ATTACHMENT_STORE_OP_STORE; + case GN_STORE_OPERATION_DONT_CARE: return VK_ATTACHMENT_STORE_OP_DONT_CARE; + } +} + +VkImageLayout vkGryphnImageLayout(enum gnImageLayout_e layout) { + switch(layout) { + case GN_LAYOUT_UNDEFINED: return VK_IMAGE_LAYOUT_UNDEFINED; + case GN_LAYOUT_PRESENTATION_QUEUE_IMAGE: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + case GN_LAYOUT_TRANSFER_DESTINATION: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + case GN_COLOR_ATTACHMENT: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + } +} + +gnReturnCode gnCreateRenderPassDescriptorFn(struct gnRenderPassDescriptor_t* renderPass, struct gnOutputDevice_t* device, struct gnRenderPassDescriptorInfo_t info) { + renderPass->renderPassDescriptor = malloc(sizeof(gnPlatformRenderPassDescriptor)); + + VkAttachmentDescription* attachments = malloc(sizeof(VkAttachmentDescription) * info.attachmentCount); + for (int i = 0; i < info.attachmentCount; i++) { + attachments[i].format = vkGryphnFormatToVulkanFormat(info.attachmentInfos[i].format); + attachments[i].samples = VK_SAMPLE_COUNT_1_BIT; + + attachments[i].loadOp = vkGryphnLoadOperation(info.attachmentInfos[i].loadOperation); + attachments[i].storeOp = vkGryphnStoreOperation(info.attachmentInfos[i].storeOperation); + + attachments[i].stencilLoadOp = vkGryphnLoadOperation(info.attachmentInfos[i].stencilLoadOperation); + attachments[i].stencilStoreOp = vkGryphnStoreOperation(info.attachmentInfos[i].stencilStoreOperation); + + attachments[i].initialLayout = vkGryphnImageLayout(info.attachmentInfos[i].initialLayout); + attachments[i].finalLayout = vkGryphnImageLayout(info.attachmentInfos[i].finalLayout); + } + + VkSubpassDescription* subpasses = malloc(sizeof(VkSubpassDescription) * info.subpassCount); + + for (int i = 0; i < info.subpassCount; i++) { + subpasses[i].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpasses[i].colorAttachmentCount = info.subpassInfos[i].colorAttachmentCount; + VkAttachmentReference* colorAttachments = malloc(sizeof(VkAttachmentReference) * info.subpassInfos[i].colorAttachmentCount); + for (int c = 0; c < info.subpassInfos[i].colorAttachmentCount; c++) { + colorAttachments[c].attachment = info.subpassInfos[i].colorAttachments[c].index; + colorAttachments[c].layout = vkGryphnImageLayout(info.subpassInfos[i].colorAttachments[c].imageLayout); + } + subpasses[i].pColorAttachments = colorAttachments; + } + + VkRenderPassCreateInfo renderPassInfo = (VkRenderPassCreateInfo){ + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .attachmentCount = info.attachmentCount, + .pAttachments = attachments, + .subpassCount = info.subpassCount, + .pSubpasses = subpasses + }; + + if (vkCreateRenderPass(device->outputDevice->device, &renderPassInfo, NULL, &renderPass->renderPassDescriptor->renderPass) != VK_SUCCESS) { + return GN_FAILED_TO_CREATE_RENDER_PASS; + } + + free(attachments); + free(subpasses); + + return GN_SUCCESS; +} + + +void gnDestroyRenderPassDescriptorFn(struct gnRenderPassDescriptor_t* renderPass) { + vkDestroyRenderPass(renderPass->device->outputDevice->device, renderPass->renderPassDescriptor->renderPass, NULL); +} diff --git a/rendering_api/vulkan/src/renderpass/vulkan_render_pass_descriptor.h b/rendering_api/vulkan/src/renderpass/vulkan_render_pass_descriptor.h new file mode 100644 index 0000000..e65edbd --- /dev/null +++ b/rendering_api/vulkan/src/renderpass/vulkan_render_pass_descriptor.h @@ -0,0 +1,7 @@ +#pragma once +#include "core/renderpass/gryphn_render_pass_descriptor.h" +#include + +typedef struct gnPlatformRenderPassDescriptor_t { + VkRenderPass renderPass; +} gnPlatformRenderPassDescriptor; diff --git a/src/core/gryphn_platform_functions.h b/src/core/gryphn_platform_functions.h index 6be3505..25ec9e8 100644 --- a/src/core/gryphn_platform_functions.h +++ b/src/core/gryphn_platform_functions.h @@ -9,6 +9,7 @@ #include "window_surface/gryphn_surface_create_functions.h" #include "shader_module/gryphn_shader_module.h" #include "pipelines/graphics_pipeline/gryphn_graphics_pipeline.h" +#include "renderpass/gryphn_render_pass_descriptor.h" typedef struct gnFunctions_t { gnReturnCode (*_gnCreateInstance)(gnInstance* instance, struct gnInstanceInfo_t info); @@ -56,6 +57,9 @@ typedef struct gnDeviceFunctions_t { gnReturnCode (*_gnCreateShaderModule)(struct gnShaderModule_t* module, struct gnOutputDevice_t* device, struct gnShaderModuleInfo_t shaderModuleInfo); void (*_gnDestroyShaderModule)(struct gnShaderModule_t* module); + gnReturnCode (*_gnCreateRenderPassDescriptor)(struct gnRenderPassDescriptor_t* renderPass, struct gnOutputDevice_t* device, struct gnRenderPassDescriptorInfo_t info); + void (*_gnDestroyRenderPassDescriptor)(struct gnRenderPassDescriptor_t* renderPass); + gnReturnCode (*_gnCreateGraphicsPipeline)(struct gnGraphicsPipeline_t* pipeline, struct gnOutputDevice_t* device, struct gnGraphicsPipelineInfo_t pipelineInfo); void (*_gnDestroyGraphicsPipeline)(struct gnGraphicsPipeline_t* pipeline); } gnDeviceFunctions; diff --git a/src/core/instance/init/gryphn_init.c b/src/core/instance/init/gryphn_init.c index b72f266..ec56b57 100644 --- a/src/core/instance/init/gryphn_init.c +++ b/src/core/instance/init/gryphn_init.c @@ -73,6 +73,8 @@ void gnLoadDeviceFunctions(struct gnDynamicLibrary_t* lib, struct gnDeviceFuncti gnLoadDLLFunction(lib, functions->_gnDestroyPresentationQueue, "gnDestroyPresentationQueueFn"); gnLoadDLLFunction(lib, functions->_gnCreateShaderModule, "gnCreateShaderModuleFn"); gnLoadDLLFunction(lib, functions->_gnDestroyShaderModule, "gnDestroyShaderModuleFn"); + gnLoadDLLFunction(lib, functions->_gnCreateRenderPassDescriptor, "gnCreateRenderPassDescriptorFn"); + gnLoadDLLFunction(lib, functions->_gnDestroyRenderPassDescriptor, "gnDestroyRenderPassDescriptorFn"); gnLoadDLLFunction(lib, functions->_gnCreateGraphicsPipeline, "gnCreateGraphicsPipelineFn"); gnLoadDLLFunction(lib, functions->_gnDestroyGraphicsPipeline, "gnDestroyGraphicsPipelineFn"); } diff --git a/src/core/renderpass/gryphn_render_pass_descriptor.c b/src/core/renderpass/gryphn_render_pass_descriptor.c new file mode 100644 index 0000000..d282125 --- /dev/null +++ b/src/core/renderpass/gryphn_render_pass_descriptor.c @@ -0,0 +1,11 @@ +#include "gryphn_render_pass_descriptor.h" +#include "core/gryphn_platform_functions.h" + +gnReturnCode gnCreateRenderPassDescriptor(struct gnRenderPassDescriptor_t* renderPass, struct gnOutputDevice_t* device, struct gnRenderPassDescriptorInfo_t info) { + renderPass->device = device; + return device->deviceFunctions->_gnCreateRenderPassDescriptor(renderPass, device, info); +} + +void gnDestroyRenderPassDescriptor(struct gnRenderPassDescriptor_t* renderPass) { + renderPass->device->deviceFunctions->_gnDestroyRenderPassDescriptor(renderPass); +} diff --git a/src/core/renderpass/gryphn_render_pass_descriptor.h b/src/core/renderpass/gryphn_render_pass_descriptor.h new file mode 100644 index 0000000..5fb9d26 --- /dev/null +++ b/src/core/renderpass/gryphn_render_pass_descriptor.h @@ -0,0 +1,52 @@ +#pragma once +#include "utils/types/gryphn_image_format.h" +#include "stdint.h" +#include "core/output_device/gryphn_output_device.h" + +typedef enum gnLoadOperation_e { + GN_LOAD_OPERATION_LOAD, GN_LOAD_OPERATION_CLEAR, GN_LOAD_OPERATION_DONT_CARE +} gnLoadOperation; + +typedef enum gnStoreOperation_e { + GN_STORE_OPERATION_STORE, GN_STORE_OPERATION_DONT_CARE +} gnStoreOperation; + +typedef struct gnRenderPassAttachmentInfo_t { + enum gnImageFormat_e format; + enum gnLoadOperation_e loadOperation; + enum gnStoreOperation_e storeOperation; + + enum gnLoadOperation_e stencilLoadOperation; + enum gnStoreOperation_e stencilStoreOperation; + + enum gnImageLayout_e initialLayout; + enum gnImageLayout_e finalLayout; +} gnRenderPassAttachmentInfo; + +typedef struct gnSubpassAttachmentInfo_t { + uint32_t index; + enum gnImageLayout_e imageLayout; +} gnSubpassAttachmentInfo; + +typedef struct gnSubpassInfo_t { + uint32_t colorAttachmentCount; + struct gnSubpassAttachmentInfo_t* colorAttachments; +} gnSubpassInfo; + +typedef struct gnRenderPassDescriptorInfo_t { + uint32_t attachmentCount; + struct gnRenderPassAttachmentInfo_t* attachmentInfos; + + uint32_t subpassCount; + struct gnSubpassInfo_t* subpassInfos; +} gnRenderPassDescriptorInfo; + +struct gnPlatformRenderPassDescriptor_t; + +typedef struct gnRenderPassDescriptor_t { + struct gnPlatformRenderPassDescriptor_t* renderPassDescriptor; + struct gnOutputDevice_t* device; +} gnRenderPassDescriptor; + +gnReturnCode gnCreateRenderPassDescriptor(struct gnRenderPassDescriptor_t* renderPass, struct gnOutputDevice_t* device, struct gnRenderPassDescriptorInfo_t info); +void gnDestroyRenderPassDescriptor(struct gnRenderPassDescriptor_t* renderPass); diff --git a/src/utils/gryphn_error_code.h b/src/utils/gryphn_error_code.h index 35e147d..4c5e8cf 100644 --- a/src/utils/gryphn_error_code.h +++ b/src/utils/gryphn_error_code.h @@ -20,7 +20,8 @@ typedef enum gnReturnCode_t { GN_FAILED_TO_CREATE_SHADER_MODULE, GN_FAILED_TO_CONVERT_SHADER_CODE, GN_FAILED_TO_FIND_ENTRY_POINT, - GN_FAILED_TO_CREATE_UNIFORM_LAYOUT + GN_FAILED_TO_CREATE_UNIFORM_LAYOUT, + GN_FAILED_TO_CREATE_RENDER_PASS // GN_UNKNOWN_FRAMEBUFFER_ATTACHMENT, // GN_UNKNOWN_FUNCTION, @@ -54,5 +55,6 @@ static const char* gnErrorCodeToCString(enum gnReturnCode_t returnCode) { case GN_FAILED_TO_CONVERT_SHADER_CODE: return "GN_FAILED_TO_CONVERT_SHADER_CODE"; case GN_FAILED_TO_FIND_ENTRY_POINT: return "GN_FAILED_TO_FIND_ENTRY_POINT"; case GN_FAILED_TO_CREATE_UNIFORM_LAYOUT: return "GN_FAILED_TO_CREATE_UNIFORM_LAYOUT"; + case GN_FAILED_TO_CREATE_RENDER_PASS: return "GN_FAILED_TO_CREATE_RENDER_PASS"; } } diff --git a/src/utils/types/gryphn_image_format.h b/src/utils/types/gryphn_image_format.h index 92d21bc..74d34cd 100644 --- a/src/utils/types/gryphn_image_format.h +++ b/src/utils/types/gryphn_image_format.h @@ -12,3 +12,7 @@ typedef enum gnColorSpace_e { typedef enum gnImageSharingMode_e { GN_SHARING_MODE_EXCLUSIVE, GN_SHARING_MODE_CONCURRENT } gnImageSharingMode; + +typedef enum gnImageLayout_e { + GN_LAYOUT_UNDEFINED, GN_LAYOUT_PRESENTATION_QUEUE_IMAGE, GN_LAYOUT_TRANSFER_DESTINATION, GN_COLOR_ATTACHMENT +} gnImageLayout;