Mercurial > games > semicongine
view semicongine/rendering.nim @ 1429:ab01c577d91c
fix: some more import-stuff
author | sam <sam@basx.dev> |
---|---|
date | Sat, 11 Jan 2025 15:34:21 +0700 |
parents | 676fc13685a9 |
children |
line wrap: on
line source
import std/logging import std/hashes import std/macros import std/os import std/sequtils import std/strformat import std/strutils import std/typetraits import ./core import ./images # in this file: # - const defintions for rendering # - custom pragma defintions for rendering # - type defintions for rendering # - some utils code that is used in mutiple rendering files # - inclusion of all rendering files # there is a big, bad global vulkan object # believe me, this makes everything much, much easier when defined(windows): include ./rendering/platform/windows when defined(linux): include ./rendering/platform/linux import ../semicongine/rendering/memory import ../semicongine/rendering/renderer import ../semicongine/rendering/swapchain import ../semicongine/rendering/shaders import ../semicongine/rendering/renderpasses import ../semicongine/rendering/vulkan_wrappers export memory export renderer export swapchain export shaders export renderpasses export vulkan_wrappers proc debugCallback( messageSeverity: VkDebugUtilsMessageSeverityFlagBitsEXT, messageTypes: VkDebugUtilsMessageTypeFlagsEXT, pCallbackData: ptr VkDebugUtilsMessengerCallbackDataEXT, userData: pointer, ): VkBool32 {.cdecl.} = const LOG_LEVEL_MAPPING = { VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: lvlDebug, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: lvlInfo, VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: lvlWarn, VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: lvlError, }.toTable log LOG_LEVEL_MAPPING[messageSeverity], &"{toEnums messageTypes}: {pCallbackData.pMessage}" if messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: stderr.writeLine "-----------------------------------" stderr.write getStackTrace() stderr.writeLine LOG_LEVEL_MAPPING[messageSeverity], &"{toEnums messageTypes}: {pCallbackData.pMessage}" stderr.writeLine "-----------------------------------" let errorMsg = getStackTrace() & &"\n{toEnums messageTypes}: {pCallbackData.pMessage}" raise newException(Exception, errorMsg) return false proc initVulkan*(appName: string = "semicongine app"): VulkanObject = # instance creation # enagle all kind of debug stuff when not defined(release): let requiredExtensions = REQUIRED_PLATFORM_EXTENSIONS & @["VK_KHR_surface", "VK_EXT_debug_utils"] let layers: seq[string] = if hasValidationLayer(): @["VK_LAYER_KHRONOS_validation"] else: @[] putEnv( "VK_LAYER_ENABLES", "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_AMD,VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_NVIDIA,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXTVK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT", ) else: let requiredExtensions = REQUIRED_PLATFORM_EXTENSIONS & @["VK_KHR_surface"] let layers: seq[string] = @[] var layersC = allocCStringArray(layers) instanceExtensionsC = allocCStringArray(requiredExtensions) defer: deallocCStringArray(layersC) deallocCStringArray(instanceExtensionsC) var appinfo = VkApplicationInfo( sType: VK_STRUCTURE_TYPE_APPLICATION_INFO, pApplicationName: appName, pEngineName: "semicongine", apiVersion: VK_MAKE_API_VERSION(0, 1, 3, 0), ) createinfo = VkInstanceCreateInfo( sType: VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, pApplicationInfo: addr(appinfo), enabledLayerCount: layers.len.uint32, ppEnabledLayerNames: layersC, enabledExtensionCount: requiredExtensions.len.uint32, ppEnabledExtensionNames: instanceExtensionsC, ) checkVkResult vkCreateInstance(addr(createinfo), nil, addr(result.instance)) loadVulkan(result.instance) # load extensions # for extension in requiredExtensions: loadExtension(result.instance, $extension) result.window = createWindow(appName) result.surface = createNativeSurface(result.instance, result.window) # logical device creation # TODO: allowing support for physical devices without hasUniformBufferStandardLayout # would require us to ship different shaders, so we don't support standard layout # if that will be added, check the function vulkan/shaders.nim:glslUniforms and update accordingly # let hasUniformBufferStandardLayout = "VK_KHR_uniform_buffer_standard_layout" in physicalDevice.getExtensions() # var deviceExtensions = @["VK_KHR_swapchain", "VK_KHR_uniform_buffer_standard_layout"] var deviceExtensions = @["VK_KHR_swapchain"] for extension in deviceExtensions: loadExtension(result.instance, extension) when not defined(release): var debugMessengerCreateInfo = VkDebugUtilsMessengerCreateInfoEXT( sType: VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, messageSeverity: VkDebugUtilsMessageSeverityFlagBitsEXT.items.toSeq.toBits, messageType: VkDebugUtilsMessageTypeFlagBitsEXT.items.toSeq.toBits, pfnUserCallback: debugCallback, pUserData: nil, ) checkVkResult vkCreateDebugUtilsMessengerEXT( result.instance, addr(debugMessengerCreateInfo), nil, addr(result.debugMessenger) ) # get physical device and graphics queue family result.physicalDevice = getBestPhysicalDevice(result.instance) result.graphicsQueueFamily = getQueueFamily(result.physicalDevice, result.surface, VK_QUEUE_GRAPHICS_BIT) let priority = cfloat(1) queueInfo = VkDeviceQueueCreateInfo( sType: VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, queueFamilyIndex: result.graphicsQueueFamily, queueCount: 1, pQueuePriorities: addr(priority), ) deviceExtensionsC = allocCStringArray(deviceExtensions) defer: deallocCStringArray(deviceExtensionsC) let enabledFeatures = VkPhysicalDeviceFeatures( fillModeNonSolid: true, depthClamp: true, wideLines: true, largePoints: true ) var createDeviceInfo = VkDeviceCreateInfo( sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, queueCreateInfoCount: 1, pQueueCreateInfos: addr(queueInfo), enabledLayerCount: 0, ppEnabledLayerNames: nil, enabledExtensionCount: uint32(deviceExtensions.len), ppEnabledExtensionNames: deviceExtensionsC, pEnabledFeatures: addr(enabledFeatures), ) checkVkResult vkCreateDevice( physicalDevice = result.physicalDevice, pCreateInfo = addr createDeviceInfo, pAllocator = nil, pDevice = addr result.device, ) result.graphicsQueue = svkGetDeviceQueue(result.device, result.graphicsQueueFamily, VK_QUEUE_GRAPHICS_BIT) proc destroyVulkan*() = if engine().vulkan.swapchain != nil: clearSwapchain() vkDestroyDevice(engine().vulkan.device, nil) vkDestroySurfaceKHR(engine().vulkan.instance, engine().vulkan.surface, nil) if engine().vulkan.debugMessenger.Valid: vkDestroyDebugUtilsMessengerEXT( engine().vulkan.instance, engine().vulkan.debugMessenger, nil ) vkDestroyInstance(engine().vulkan.instance, nil) destroyWindow(engine().vulkan.window) proc showSystemCursor*(value: bool) = engine().vulkan.window.showSystemCursor(value) proc fullscreen*(): bool = engine().vulkan.fullscreen_internal proc setFullscreen*(enable: bool) = if enable != engine().vulkan.fullscreen_internal: engine().vulkan.fullscreen_internal = enable engine().vulkan.window.setFullscreen(engine().vulkan.fullscreen_internal) proc maxFramebufferSampleCount*( maxSamples = VK_SAMPLE_COUNT_8_BIT ): VkSampleCountFlagBits = let limits = svkGetPhysicalDeviceProperties().limits let available = VkSampleCountFlags( limits.framebufferColorSampleCounts.uint32 and limits.framebufferDepthSampleCounts.uint32 ).toEnums return min(max(available), maxSamples)