From 012e842e1d513fc10ded16a9f5a15c79c4bbca5a Mon Sep 17 00:00:00 2001 From: Gregory Wells Date: Sat, 14 Jun 2025 21:46:32 -0400 Subject: [PATCH] samplers and image views --- .../src/output_device/vulkan_output_device.c | 28 ++++---- .../vulkan/src/textures/vulkan_texture.c | 67 ++++++++++++++++++- .../vulkan/src/textures/vulkan_texture.h | 1 + src/core/textures/gryphn_texture.h | 10 +++ 4 files changed, 91 insertions(+), 15 deletions(-) diff --git a/rendering_api/vulkan/src/output_device/vulkan_output_device.c b/rendering_api/vulkan/src/output_device/vulkan_output_device.c index aa487f8..8189334 100644 --- a/rendering_api/vulkan/src/output_device/vulkan_output_device.c +++ b/rendering_api/vulkan/src/output_device/vulkan_output_device.c @@ -18,28 +18,30 @@ gnReturnCode gnCreateOutputDeviceFn(gnOutputDeviceHandle outputDevice, gnInstanc queueCreateInfos[i].pQueuePriorities = &queuePriority; } - VkPhysicalDeviceFeatures deviceFeatures = {}; + VkPhysicalDeviceFeatures deviceFeatures = { + .samplerAnisotropy = VK_TRUE + }; - VkDeviceCreateInfo createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - createInfo.queueCreateInfoCount = deviceInfo.queueInfoCount; - createInfo.pQueueCreateInfos = queueCreateInfos; - createInfo.pEnabledFeatures = &deviceFeatures; + VkDeviceCreateInfo deviceCreateInfo = { + .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .queueCreateInfoCount = deviceInfo.queueInfoCount, + .pQueueCreateInfos = queueCreateInfos, + .pEnabledFeatures = &deviceFeatures, - createInfo.enabledExtensionCount = deviceExtensionCount; - createInfo.ppEnabledExtensionNames = deviceExtensions; + .enabledExtensionCount = deviceExtensionCount, + .ppEnabledExtensionNames = deviceExtensions, + }; if (instance->debugger == NULL) - createInfo.enabledLayerCount = 0; + deviceCreateInfo.enabledLayerCount = 0; else { const char* validation_layers[1] = { "VK_LAYER_KHRONOS_validation" }; - createInfo.enabledLayerCount = 1; - createInfo.ppEnabledLayerNames = validation_layers; + deviceCreateInfo.enabledLayerCount = 1; + deviceCreateInfo.ppEnabledLayerNames = validation_layers; } - if (vkCreateDevice(deviceInfo.physicalDevice.physicalDevice->device, &createInfo, NULL, &outputDevice->outputDevice->device) != VK_SUCCESS) { + if (vkCreateDevice(deviceInfo.physicalDevice.physicalDevice->device, &deviceCreateInfo, NULL, &outputDevice->outputDevice->device) != VK_SUCCESS) return GN_FAILED_TO_CREATE_DEVICE; - } outputDevice->outputDevice->queues = malloc(sizeof(VkQueue) * deviceInfo.queueInfoCount); for (int i = 0; i < deviceInfo.queueInfoCount; i++) { diff --git a/rendering_api/vulkan/src/textures/vulkan_texture.c b/rendering_api/vulkan/src/textures/vulkan_texture.c index 80b01af..7d8777f 100644 --- a/rendering_api/vulkan/src/textures/vulkan_texture.c +++ b/rendering_api/vulkan/src/textures/vulkan_texture.c @@ -5,9 +5,24 @@ #include "core/debugger/gryphn_debugger.h" VkImageType vkGryphnTextureType(gnTextureType type) { -switch(type) { -case GN_TEXTURE_2D: return VK_IMAGE_TYPE_3D; + switch(type) { + case GN_TEXTURE_2D: return VK_IMAGE_TYPE_2D; + } } + +VkImageViewType vkGryphnTextureTypeView(gnTextureType type) { + switch(type) { + case GN_TEXTURE_2D: return VK_IMAGE_VIEW_TYPE_2D; + } +} + +VkSamplerAddressMode vkGryphnTextureWrap(gnTextureWrap wrap) { + switch(wrap) { + case GN_REPEAT: return VK_SAMPLER_ADDRESS_MODE_REPEAT; + case GN_MIRRORED_REPEAT: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + case GN_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case GN_CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + } } void VkTransitionImageLayout(gnDevice device, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) { @@ -149,6 +164,51 @@ gnReturnCode gnCreateTextureFn(gnTexture texture, gnDevice device, const gnTextu texture->texture->beenWrittenToo = gnFalse; + VkImageViewCreateInfo viewInfo = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = texture->texture->image.image, + .viewType = vkGryphnTextureTypeView(info.type), + .format = vkGryphnFormatToVulkanFormat(info.format), + + .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .subresourceRange.baseMipLevel = 0, + .subresourceRange.levelCount = 1, + .subresourceRange.baseArrayLayer = 0, + .subresourceRange.layerCount = 1, + }; + + if (vkCreateImageView(device->outputDevice->device, &viewInfo, NULL, &texture->texture->image.imageView) != VK_SUCCESS) + return GN_FAILED_TO_CREATE_IMAGE_VIEW; + + VkPhysicalDeviceProperties properties = {}; + vkGetPhysicalDeviceProperties(device->physicalDevice.physicalDevice->device, &properties); + + VkSamplerCreateInfo samplerInfo = { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .minFilter = (info.minFilter == GN_FILTER_LINEAR) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST, + .magFilter = (info.magFilter == GN_FILTER_LINEAR) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST, + + .addressModeU = vkGryphnTextureWrap(info.wrapU), + .addressModeV = vkGryphnTextureWrap(info.wrapV), + .addressModeW = vkGryphnTextureWrap(info.wrapW), + + .anisotropyEnable = VK_TRUE, + .maxAnisotropy = properties.limits.maxSamplerAnisotropy, + .borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK, + .unnormalizedCoordinates = VK_FALSE, + + .compareEnable = VK_FALSE, + .compareOp = VK_COMPARE_OP_ALWAYS, + + .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR, + .mipLodBias = 0.0f, + .minLod = 0.0f, + .maxLod = 0.0f, + }; + + if (vkCreateSampler(device->outputDevice->device, &samplerInfo, NULL, &texture->texture->sampler) != VK_SUCCESS) + return GN_FAILED_TO_CREATE_SAMPLER; + return GN_SUCCESS; } @@ -174,10 +234,13 @@ void gnTextureDataFn(gnTextureHandle texture, void* pixelData) { void gnDestroyVulkanImage(VkGryphnImage* image, VkDevice device) { vkDestroyImage(device, image->image, NULL); + vkDestroyImageView(device, image->imageView, NULL); vkFreeMemory(device, image->memory, NULL); } void gnDestroyTextureFn(gnTexture texture) { + vkDestroySampler(texture->device->outputDevice->device, texture->texture->sampler, NULL); + gnDestroyVulkanBuffer(&texture->texture->buffer, texture->device->outputDevice->device); gnDestroyVulkanImage(&texture->texture->image, texture->device->outputDevice->device); } diff --git a/rendering_api/vulkan/src/textures/vulkan_texture.h b/rendering_api/vulkan/src/textures/vulkan_texture.h index b11e17d..68c4496 100644 --- a/rendering_api/vulkan/src/textures/vulkan_texture.h +++ b/rendering_api/vulkan/src/textures/vulkan_texture.h @@ -13,6 +13,7 @@ void gnDestroyVulkanImage(VkGryphnImage* image, VkDevice device); typedef struct gnPlatformTexture_t { VkGryphnBuffer buffer; VkGryphnImage image; + VkSampler sampler; size_t size; uint32_t width, height; diff --git a/src/core/textures/gryphn_texture.h b/src/core/textures/gryphn_texture.h index ddb5672..8f82c4c 100644 --- a/src/core/textures/gryphn_texture.h +++ b/src/core/textures/gryphn_texture.h @@ -8,11 +8,21 @@ typedef enum gnTextureType { GN_TEXTURE_2D } gnTextureType; +typedef enum gnTextureFilter { + GN_FILTER_LINEAR, GN_FILTER_NEAREST +} gnTextureFilter; + +typedef enum gnTextureWrap { + GN_REPEAT, GN_MIRRORED_REPEAT, GN_CLAMP_TO_EDGE, GN_CLAMP_TO_BORDER +} gnTextureWrap; + typedef struct gnTextureInfo { uint32_t width; uint32_t height; gnTextureType type; gnImageFormat format; + gnTextureFilter minFilter, magFilter; + gnTextureWrap wrapU, wrapV, wrapW; } gnTextureInfo; #ifdef GN_REVEAL_IMPL