diff --git a/Regex.txt b/Regex.txt new file mode 100644 index 0000000..62641ae --- /dev/null +++ b/Regex.txt @@ -0,0 +1,2 @@ +(?[A-Z_]*) = [0-9]*, +case SE_${enum}:\nreturn VK_${enum}; \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/CMakeLists.txt b/src/Engine/Graphics/Vulkan/CMakeLists.txt index 3a82d43..690802b 100644 --- a/src/Engine/Graphics/Vulkan/CMakeLists.txt +++ b/src/Engine/Graphics/Vulkan/CMakeLists.txt @@ -1,4 +1,9 @@ target_sources(SeeleEngine PRIVATE VulkanGraphics.h - VulkanGraphics.cpp) \ No newline at end of file + VulkanGraphics.cpp + VulkanGraphicsResources.h + VulkanDescriptorSets.cpp + VulkanGraphicsEnums.h + VulkanInitializer.h + VulkanInitializer.cpp) \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp new file mode 100644 index 0000000..1b21e5b --- /dev/null +++ b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp @@ -0,0 +1,46 @@ +#include "VulkanGraphicsResources.h" +#include "VulkanGraphicsEnums.h" +#include "VulkanGraphics.h" +#include "VulkanInitializer.h" +#include + +Seele::VulkanDescriptorLayout::~VulkanDescriptorLayout() +{ + if (layoutHandle != VK_NULL_HANDLE) + { + vkDestroyDescriptorSetLayout(graphics->getDevice(), layoutHandle, nullptr); + } +} + +void Seele::VulkanDescriptorLayout::create() +{ + if (layoutHandle != VK_NULL_HANDLE) + { + return; + } + bindings.resize(descriptorBindings.size()); + for (size_t i = 0; i < descriptorBindings.size(); ++i) + { + VkDescriptorSetLayoutBinding& binding = bindings[i]; + const DescriptorBinding& rhiBinding = descriptorBindings[i]; + binding.binding = rhiBinding.binding; + binding.descriptorCount = rhiBinding.descriptorCount; + binding.descriptorType = cast(rhiBinding.descriptorType); + binding.stageFlags = rhiBinding.shaderStages; + binding.pImmutableSamplers = nullptr; + } + VkDescriptorSetLayoutCreateInfo createInfo = + init::DescriptorSetLayoutCreateInfo(bindings.data(), bindings.size()); + VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); + + allocator = new VulkanDescriptorAllocator(graphics, *this); +} + +void Seele::VulkanPipelineLayout::create() +{ + vulkanDescriptorLayouts.resize(descriptorSetLayouts.size()); + for (size_t i = 0; i < descriptorSetLayouts.size(); ++i) + { + PVulkanDescriptorLayout layout = descriptorSetLayouts[i].cast(); + } +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.h b/src/Engine/Graphics/Vulkan/VulkanGraphics.h index 46b2a9b..73e312c 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.h @@ -5,6 +5,8 @@ namespace Seele class VulkanGraphics : public Graphics { public: + VkDevice getDevice() const; + // Inherited via Graphics virtual void init(GraphicsInitializer initializer) override; virtual void beginFrame(void* windowHandle) override; diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.h b/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.h new file mode 100644 index 0000000..026c49c --- /dev/null +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.h @@ -0,0 +1,87 @@ +#pragma once +#include "Graphics/GraphicsEnums.h" +#include + +#define VK_CHECK(f) \ +{ \ + VkResult res = (f); \ + if (res != VK_SUCCESS) \ + { \ + std::cout << "Fatal : VkResult is \"" << res << "\" in " << __FILE__ << " at line " << __LINE__ << std::endl; \ + assert(res == VK_SUCCESS); \ + } \ +} + +namespace Seele +{ + VkDescriptorType cast(const SeDescriptorType& descriptorType) + { + switch (descriptorType) + { + case SE_DESCRIPTOR_TYPE_SAMPLER: + return VK_DESCRIPTOR_TYPE_SAMPLER; + case SE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + case SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + case SE_DESCRIPTOR_TYPE_STORAGE_IMAGE: + return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + case SE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + case SE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + case SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + case SE_DESCRIPTOR_TYPE_STORAGE_BUFFER: + return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + case SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + case SE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; + case SE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + return VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; + case SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: + return VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT; + case SE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: + return VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV; + default: + break; + } + } + SeDescriptorType cast(const VkDescriptorType& descriptorType) + { + switch (descriptorType) + { + + case VK_DESCRIPTOR_TYPE_SAMPLER: + return SE_DESCRIPTOR_TYPE_SAMPLER; + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + return SE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + return SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + return SE_DESCRIPTOR_TYPE_STORAGE_IMAGE; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + return SE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + return SE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + return SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + return SE_DESCRIPTOR_TYPE_STORAGE_BUFFER; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + return SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + return SE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + return SE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: + return SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT; + case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: + return SE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV; + default: + break; + } + } + +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h index 6f70f09..9c89679 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h @@ -1 +1,99 @@ #pragma once +#include "Graphics/GraphicsResources.h" + +namespace Seele +{ + DECLARE_REF(VulkanDescriptorAllocator); + DECLARE_REF(VulkanGraphics); + class VulkanDescriptorLayout : public DescriptorLayout + { + public: + VulkanDescriptorLayout(PVulkanGraphics graphics) + : graphics(graphics) + {} + virtual ~VulkanDescriptorLayout(); + virtual void create(); + inline VkDescriptorSetLayout getHandle() const + { + return layoutHandle; + } + private: + PVulkanGraphics graphics; + Array bindings; + VkDescriptorSetLayout layoutHandle; + friend class VulkanPipelineStateCacheManager; + }; + DEFINE_REF(VulkanDescriptorLayout); + class VulkanPipelineLayout : public PipelineLayout + { + public: + VulkanPipelineLayout(PVulkanGraphics graphics) + : graphics(graphics) + {} + virtual ~VulkanPipelineLayout() + { + if (layoutHandle != VK_NULL_HANDLE) + { + vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr); + } + } + virtual void create(); + inline VkPipelineLayout getHandle() const + { + return layoutHandle; + } + virtual uint32 getHash() const; + private: + Array vulkanDescriptorLayouts; + uint32 layoutHash; + VkPipelineLayout layoutHandle; + PVulkanGraphics graphics; + friend class VulkanPipelineStateCacheManager; + }; + DEFINE_REF(VulkanPipelineLayout); + + class VulkanDescriptorSet : public DescriptorSet + { + public: + VulkanDescriptorSet(PVulkanGraphics device, PVulkanDescriptorAllocator owner) : device(device), owner(owner) {} + virtual ~VulkanDescriptorSet(); + virtual void updateBuffer(uint32_t binding, PUniformBuffer uniformBuffer); + virtual void updateBuffer(uint32_t binding, PStructuredBuffer uniformBuffer); + virtual void updateSampler(uint32_t binding, PSamplerState samplerState); + virtual void updateTexture(uint32_t binding, PTexture texture, PSamplerState sampler = nullptr); + virtual bool operator<(PDescriptorSet other); + inline VkDescriptorSet getHandle() const + { + return setHandle; + } + private: + virtual void writeChanges(); + Array imageInfos; + Array bufferInfos; + Array writeDescriptors; + VkDescriptorSet setHandle; + PVulkanDescriptorAllocator owner; + PVulkanGraphics device; + friend class VulkanDescriptorAllocator; + }; + DEFINE_REF(VulkanDescriptorSet); + + class VulkanDescriptorAllocator : public DescriptorAllocator + { + public: + VulkanDescriptorAllocator(PVulkanGraphics device, VulkanDescriptorLayout& layout); + ~VulkanDescriptorAllocator(); + virtual void allocateDescriptorSet(PDescriptorSet& descriptorSet); + + inline VkDescriptorPool getHandle() + { + return poolHandle; + } + private: + PVulkanGraphics device; + int maxSets = 512; + VkDescriptorPool poolHandle; + VulkanDescriptorLayout& layout; + }; + DEFINE_REF(VulkanDescriptorAllocator); +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp b/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp new file mode 100644 index 0000000..5593340 --- /dev/null +++ b/src/Engine/Graphics/Vulkan/VulkanInitializer.cpp @@ -0,0 +1,765 @@ +#include "VulkanInitializer.h" +#include + +VkApplicationInfo Seele::init::ApplicationInfo(const char* appName, uint32_t appVersion, const char* engineName, uint32_t engineVersion, uint32_t apiVersion) +{ + VkApplicationInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + info.pApplicationName = appName; + info.applicationVersion = appVersion; + info.pEngineName = engineName; + info.engineVersion = engineVersion; + return info; +} + +VkInstanceCreateInfo Seele::init::InstanceCreateInfo(VkApplicationInfo* appInfo, const Array& extensions, const Array& layers) +{ + VkInstanceCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + info.pApplicationInfo = appInfo; + info.enabledExtensionCount = (uint32_t)extensions.size(); + info.ppEnabledExtensionNames = extensions.data(); + info.enabledLayerCount = (uint32_t)layers.size(); + info.ppEnabledLayerNames = layers.data(); + return info; +} + +VkDebugReportCallbackCreateInfoEXT Seele::init::DebugReportCallbackCreateInfo(VkDebugReportFlagsEXT flags) +{ + VkDebugReportCallbackCreateInfoEXT createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; + createInfo.flags = flags; + createInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)debugCallback; + return createInfo; +} + +VkDeviceQueueCreateInfo Seele::init::DeviceQueueCreateInfo(int queueFamilyIndex, int queueCount) +{ + float priority = 1.0f; + return DeviceQueueCreateInfo(queueFamilyIndex, queueCount, &priority); +} + +VkDeviceQueueCreateInfo Seele::init::DeviceQueueCreateInfo(int queueFamilyIndex, int queueCount, float* queuePriority) +{ + VkDeviceQueueCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + createInfo.queueFamilyIndex = queueFamilyIndex; + createInfo.queueCount = 1; + createInfo.pQueuePriorities = queuePriority; + return createInfo; +} + +VkDeviceCreateInfo Seele::init::DeviceCreateInfo(VkDeviceQueueCreateInfo* queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures* features) +{ + return DeviceCreateInfo(queueInfos, queueCount, features, nullptr, 0, nullptr, 0); +} + +VkSwapchainCreateInfoKHR Seele::init::SwapchainCreateInfo(VkSurfaceKHR surface, uint32_t minImageCount, VkFormat imageFormat, VkColorSpaceKHR colorSpace, VkExtent2D extent, uint32_t arrayLayers, VkImageUsageFlags usage, VkSurfaceTransformFlagBitsKHR Transform, VkCompositeAlphaFlagBitsKHR alpha, VkPresentModeKHR presentMode, VkBool32 clipped) +{ + VkSwapchainCreateInfoKHR createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + createInfo.surface = surface; + createInfo.minImageCount = minImageCount; + createInfo.imageFormat = imageFormat; + createInfo.imageColorSpace = colorSpace; + createInfo.imageExtent = extent; + createInfo.imageArrayLayers = arrayLayers; + createInfo.imageUsage = usage; + createInfo.preTransform = Transform; + createInfo.compositeAlpha = alpha; + createInfo.presentMode = presentMode; + createInfo.clipped = clipped; + return createInfo; +} + +VkSwapchainCreateInfoKHR Seele::init::SwapchainCreateInfo(VkSurfaceKHR surface, uint32_t minImageCount, VkFormat imageFormat, VkColorSpaceKHR colorSpace, uint32_t width, uint32_t height, uint32_t arrayLayers, VkImageUsageFlags usage, VkSurfaceTransformFlagBitsKHR Transform, VkCompositeAlphaFlagBitsKHR alpha, VkPresentModeKHR presentMode, VkBool32 clipped) +{ + VkSwapchainCreateInfoKHR createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + createInfo.surface = surface; + createInfo.minImageCount = minImageCount; + createInfo.imageFormat = imageFormat; + createInfo.imageColorSpace = colorSpace; + createInfo.imageExtent.width = width; + createInfo.imageExtent.height = height; + createInfo.imageArrayLayers = arrayLayers; + createInfo.imageUsage = usage; + createInfo.preTransform = Transform; + createInfo.compositeAlpha = alpha; + createInfo.presentMode = presentMode; + createInfo.clipped = clipped; + return createInfo; +} + +VkFramebufferCreateInfo Seele::init::FramebufferCreateInfo(VkRenderPass renderPass, uint32_t attachmentCount, VkImageView* attachments, uint32_t width, uint32_t height, uint32_t layers) +{ + VkFramebufferCreateInfo frameBufferCreateInfo = {}; + frameBufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + frameBufferCreateInfo.pNext = nullptr; + frameBufferCreateInfo.renderPass = renderPass; + frameBufferCreateInfo.attachmentCount = attachmentCount; + frameBufferCreateInfo.pAttachments = attachments; + frameBufferCreateInfo.width = width; + frameBufferCreateInfo.height = height; + frameBufferCreateInfo.layers = layers; + return frameBufferCreateInfo; +} + +VkAttachmentDescription Seele::init::AttachmentDescription(VkFormat format, VkSampleCountFlagBits sample, VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp, VkAttachmentLoadOp stencilLoadOp, VkAttachmentStoreOp stencilStoreOp, VkImageLayout imageLayout, VkImageLayout finalLayout) +{ + VkAttachmentDescription desc = {}; + desc.format = format; + desc.samples = sample; + desc.loadOp = loadOp; + desc.storeOp = storeOp; + desc.stencilLoadOp = stencilLoadOp; + desc.stencilStoreOp = stencilStoreOp; + desc.initialLayout = imageLayout; + desc.finalLayout = finalLayout; + return desc; +} + +VkSubpassDescription Seele::init::SubpassDescription(VkPipelineBindPoint bindPoint, uint32_t colorAttachmentCount, VkAttachmentReference* colorReference, uint32_t depthAttachmentCount, VkAttachmentReference* depthReference, uint32_t inputAttachmentCount, VkAttachmentReference* inputReference, uint32_t resolveAttachmentCount, VkAttachmentReference* resolveReference, uint32_t preserveAttachmentCount, VkAttachmentReference* preserveReference) +{ + VkSubpassDescription desc = {}; + desc.pipelineBindPoint = bindPoint; + desc.colorAttachmentCount = colorAttachmentCount; + desc.pColorAttachments = colorReference; + return desc; +} + +VkRenderPassCreateInfo Seele::init::RenderPassCreateInfo(uint32_t attachmentCount, const VkAttachmentDescription* attachments, uint32_t subpassCount, const VkSubpassDescription* subpasses, uint32_t dependencyCount, const VkSubpassDependency* subpassDependencies) +{ + VkRenderPassCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + info.attachmentCount = attachmentCount; + info.pAttachments = attachments; + info.subpassCount = subpassCount; + info.pSubpasses = subpasses; + info.dependencyCount = dependencyCount; + info.pDependencies = subpassDependencies; + + return info; +} +VkDeviceCreateInfo Seele::init::DeviceCreateInfo(VkDeviceQueueCreateInfo* queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures* features, const char* const* deviceExtensions, uint32_t deviceExtensionCount, const char* const* layers, uint32_t layerCount) +{ + VkDeviceCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + createInfo.pQueueCreateInfos = queueInfos; + createInfo.queueCreateInfoCount = queueCount; + + createInfo.pEnabledFeatures = features; + + createInfo.ppEnabledExtensionNames = deviceExtensions; + createInfo.enabledExtensionCount = deviceExtensionCount; + +#ifdef ENABLE_VALIDATION + createInfo.enabledLayerCount = layerCount; + createInfo.ppEnabledLayerNames = layers; +#else + createInfo.enabledLayerCount = 0; +#endif // ENABLE_VALIDATION + + return createInfo; +} + +VkMemoryAllocateInfo Seele::init::MemoryAllocateInfo() +{ + VkMemoryAllocateInfo memAllocInfo = {}; + memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memAllocInfo.pNext = NULL; + return memAllocInfo; +} + +VkCommandBufferAllocateInfo Seele::init::CommandBufferAllocateInfo(VkCommandPool commandPool, VkCommandBufferLevel level, uint32_t bufferCount) +{ + VkCommandBufferAllocateInfo commandBufferAllocateInfo = {}; + commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + commandBufferAllocateInfo.commandPool = commandPool; + commandBufferAllocateInfo.level = level; + commandBufferAllocateInfo.commandBufferCount = bufferCount; + return commandBufferAllocateInfo; +} + +VkCommandPoolCreateInfo Seele::init::CommandPoolCreateInfo() +{ + VkCommandPoolCreateInfo cmdPoolCreateInfo = {}; + cmdPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + return cmdPoolCreateInfo; +} + +VkCommandBufferBeginInfo Seele::init::CommandBufferBeginInfo() +{ + VkCommandBufferBeginInfo cmdBufferBeginInfo = {}; + cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cmdBufferBeginInfo.pNext = NULL; + return cmdBufferBeginInfo; +} + +VkCommandBufferInheritanceInfo Seele::init::CommandBufferInheritanceInfo() +{ + VkCommandBufferInheritanceInfo cmdBufferInheritanceInfo = {}; + cmdBufferInheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; + return cmdBufferInheritanceInfo; +} + +VkRenderPassBeginInfo Seele::init::RenderPassBeginInfo() +{ + VkRenderPassBeginInfo renderPassBeginInfo = {}; + renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + renderPassBeginInfo.pNext = NULL; + return renderPassBeginInfo; +} + +VkRenderPassCreateInfo Seele::init::RenderPassCreateInfo() +{ + VkRenderPassCreateInfo renderPassCreateInfo = {}; + renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + renderPassCreateInfo.pNext = NULL; + return renderPassCreateInfo; +} + +VkImageMemoryBarrier Seele::init::ImageMemoryBarrier(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t srcQueue, uint32_t dstQueue) +{ + VkImageMemoryBarrier barrier = {}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.oldLayout = oldLayout; + barrier.newLayout = newLayout; + barrier.srcQueueFamilyIndex = srcQueue; + barrier.dstQueueFamilyIndex = dstQueue; + barrier.image = image; + if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + } + else { + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + } + barrier.subresourceRange.baseMipLevel = 0; + barrier.subresourceRange.levelCount = 1; + barrier.subresourceRange.baseArrayLayer = 0; + barrier.subresourceRange.layerCount = 1; + if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) { + barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { + barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { + barrier.srcAccessMask = 0; + barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { + barrier.srcAccessMask = 0; + barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + } + return barrier; +} + +VkImageMemoryBarrier Seele::init::ImageMemoryBarrier() +{ + VkImageMemoryBarrier barrier = {}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.pNext = nullptr; + return barrier; +} + +VkBufferMemoryBarrier Seele::init::BufferMemoryBarrier() +{ + VkBufferMemoryBarrier bufferMemoryBarrier = {}; + bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + bufferMemoryBarrier.pNext = NULL; + return bufferMemoryBarrier; +} + +VkMemoryBarrier Seele::init::MemoryBarrier() +{ + VkMemoryBarrier memoryBarrier = {}; + memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; + memoryBarrier.pNext = NULL; + return memoryBarrier; +} + +VkImageCreateInfo Seele::init::ImageCreateInfo() +{ + VkImageCreateInfo imageCreateInfo = {}; + imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageCreateInfo.pNext = NULL; + return imageCreateInfo; +} + +VkSamplerCreateInfo Seele::init::SamplerCreateInfo() +{ + VkSamplerCreateInfo samplerCreateInfo = {}; + samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerCreateInfo.pNext = NULL; + samplerCreateInfo.magFilter = VK_FILTER_LINEAR; + samplerCreateInfo.minFilter = VK_FILTER_LINEAR; + samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + + samplerCreateInfo.anisotropyEnable = VK_FALSE; + samplerCreateInfo.maxAnisotropy = 1.0f; + samplerCreateInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; + samplerCreateInfo.unnormalizedCoordinates = VK_FALSE; + samplerCreateInfo.compareEnable = VK_FALSE; + samplerCreateInfo.compareOp = VK_COMPARE_OP_ALWAYS; + + samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + samplerCreateInfo.mipLodBias = 0.0f; + samplerCreateInfo.minLod = 0.0f; + samplerCreateInfo.maxLod = 0.0f; + return samplerCreateInfo; +} + +VkImageViewCreateInfo Seele::init::ImageViewCreateInfo() +{ + VkImageViewCreateInfo imageViewCreateInfo = {}; + imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + imageViewCreateInfo.pNext = NULL; + return imageViewCreateInfo; +} + +VkSemaphoreCreateInfo Seele::init::SemaphoreCreateInfo() +{ + VkSemaphoreCreateInfo semaphoreCreateInfo = {}; + semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + semaphoreCreateInfo.pNext = NULL; + semaphoreCreateInfo.flags = 0; + return semaphoreCreateInfo; +} + +VkFenceCreateInfo Seele::init::FenceCreateInfo(VkFenceCreateFlags flags) +{ + VkFenceCreateInfo fenceCreateInfo = {}; + fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceCreateInfo.flags = flags; + return fenceCreateInfo; +} + +VkEventCreateInfo Seele::init::EventCreateInfo() +{ + VkEventCreateInfo eventCreateInfo = {}; + eventCreateInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; + return eventCreateInfo; +} + +VkSubmitInfo Seele::init::SubmitInfo() +{ + VkSubmitInfo submitInfo = {}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.pNext = NULL; + return submitInfo; +} + +VkImageSubresourceRange Seele::init::ImageSubresourceRange(VkImageAspectFlags aspect, uint32_t startMip) +{ + VkImageSubresourceRange range; + std::memset(&range, 0, sizeof(VkImageSubresourceRange)); + range.aspectMask = aspect; + range.baseMipLevel = startMip; + range.levelCount = 1; + range.baseArrayLayer = 0; + range.layerCount = 1; + return range; +} + +VkViewport Seele::init::Viewport( + float width, + float height, + float minDepth, + float maxDepth) +{ + VkViewport viewport = {}; + viewport.width = width; + viewport.height = height; + viewport.minDepth = minDepth; + viewport.maxDepth = maxDepth; + return viewport; +} + +VkRect2D Seele::init::Rect2D( + int32_t width, + int32_t height, + int32_t offsetX, + int32_t offsetY) +{ + VkRect2D rect2D = {}; + rect2D.extent.width = width; + rect2D.extent.height = height; + rect2D.offset.x = offsetX; + rect2D.offset.y = offsetY; + return rect2D; +} + +VkBufferCreateInfo Seele::init::BufferCreateInfo() +{ + VkBufferCreateInfo bufCreateInfo = {}; + bufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + return bufCreateInfo; +} + +VkBufferCreateInfo Seele::init::BufferCreateInfo( + VkBufferUsageFlags usage, + VkDeviceSize size) +{ + VkBufferCreateInfo bufCreateInfo = {}; + bufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufCreateInfo.pNext = NULL; + bufCreateInfo.usage = usage; + bufCreateInfo.size = size; + bufCreateInfo.flags = 0; + return bufCreateInfo; +} + +VkDescriptorPoolCreateInfo Seele::init::DescriptorPoolCreateInfo( + uint32_t poolSizeCount, + VkDescriptorPoolSize* pPoolSizes, + uint32_t maxSets) +{ + VkDescriptorPoolCreateInfo descriptorPoolInfo = {}; + descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptorPoolInfo.pNext = NULL; + descriptorPoolInfo.poolSizeCount = poolSizeCount; + descriptorPoolInfo.pPoolSizes = pPoolSizes; + descriptorPoolInfo.maxSets = maxSets; + return descriptorPoolInfo; +} + +VkDescriptorPoolSize Seele::init::DescriptorPoolSize( + VkDescriptorType type, + uint32_t descriptorCount) +{ + VkDescriptorPoolSize descriptorPoolSize = {}; + descriptorPoolSize.type = type; + descriptorPoolSize.descriptorCount = descriptorCount; + return descriptorPoolSize; +} + +VkDescriptorSetLayoutBinding Seele::init::DescriptorSetLayoutBinding( + VkDescriptorType type, + VkShaderStageFlags stageFlags, + uint32_t binding, + uint32_t count) +{ + VkDescriptorSetLayoutBinding setLayoutBinding = {}; + setLayoutBinding.descriptorType = type; + setLayoutBinding.stageFlags = stageFlags; + setLayoutBinding.binding = binding; + setLayoutBinding.descriptorCount = count; + return setLayoutBinding; +} + +VkDescriptorSetLayoutCreateInfo Seele::init::DescriptorSetLayoutCreateInfo( + const VkDescriptorSetLayoutBinding* pBindings, + uint32_t bindingCount) +{ + VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {}; + descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptorSetLayoutCreateInfo.pNext = NULL; + descriptorSetLayoutCreateInfo.pBindings = pBindings; + descriptorSetLayoutCreateInfo.bindingCount = bindingCount; + return descriptorSetLayoutCreateInfo; +} + +VkPipelineLayoutCreateInfo Seele::init::PipelineLayoutCreateInfo( + const VkDescriptorSetLayout* pSetLayouts, + uint32_t setLayoutCount) +{ + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {}; + pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutCreateInfo.pNext = NULL; + pipelineLayoutCreateInfo.setLayoutCount = setLayoutCount; + pipelineLayoutCreateInfo.pSetLayouts = pSetLayouts; + return pipelineLayoutCreateInfo; +} + +VkDescriptorSetAllocateInfo Seele::init::DescriptorSetAllocateInfo( + VkDescriptorPool descriptorPool, + const VkDescriptorSetLayout* pSetLayouts, + uint32_t descriptorSetCount) +{ + VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {}; + descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + descriptorSetAllocateInfo.pNext = NULL; + descriptorSetAllocateInfo.descriptorPool = descriptorPool; + descriptorSetAllocateInfo.pSetLayouts = pSetLayouts; + descriptorSetAllocateInfo.descriptorSetCount = descriptorSetCount; + return descriptorSetAllocateInfo; +} + +VkDescriptorBufferInfo Seele::init::DescriptorBufferInfo(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range) +{ + VkDescriptorBufferInfo bufferInfo = {}; + bufferInfo.buffer = buffer; + bufferInfo.offset = offset; + bufferInfo.range = range; + + return bufferInfo; +} + +VkDescriptorImageInfo Seele::init::DescriptorImageInfo( + VkSampler sampler, + VkImageView imageView, + VkImageLayout imageLayout) +{ + VkDescriptorImageInfo descriptorImageInfo = {}; + descriptorImageInfo.sampler = sampler; + descriptorImageInfo.imageView = imageView; + descriptorImageInfo.imageLayout = imageLayout; + return descriptorImageInfo; +} + +VkWriteDescriptorSet Seele::init::WriteDescriptorSet( + VkDescriptorSet dstSet, + VkDescriptorType type, + uint32_t binding, + VkDescriptorBufferInfo* bufferInfo) +{ + VkWriteDescriptorSet writeDescriptorSet = {}; + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.pNext = NULL; + writeDescriptorSet.dstSet = dstSet; + writeDescriptorSet.descriptorType = type; + writeDescriptorSet.dstBinding = binding; + writeDescriptorSet.pBufferInfo = bufferInfo; + // Default value in all examples + writeDescriptorSet.descriptorCount = 1; + return writeDescriptorSet; +} + +VkWriteDescriptorSet Seele::init::WriteDescriptorSet( + VkDescriptorSet dstSet, + VkDescriptorType type, + uint32_t binding, + VkDescriptorImageInfo* bufferInfo) +{ + VkWriteDescriptorSet writeDescriptorSet = {}; + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.pNext = NULL; + writeDescriptorSet.dstSet = dstSet; + writeDescriptorSet.descriptorType = type; + writeDescriptorSet.dstBinding = binding; + writeDescriptorSet.pImageInfo = bufferInfo; + // Default value in all examples + writeDescriptorSet.descriptorCount = 1; + return writeDescriptorSet; +} + +VkVertexInputBindingDescription Seele::init::VertexInputBindingDescription( + uint32_t binding, + uint32_t stride, + VkVertexInputRate inputRate) +{ + VkVertexInputBindingDescription vInputBindDescription = {}; + vInputBindDescription.binding = binding; + vInputBindDescription.stride = stride; + vInputBindDescription.inputRate = inputRate; + return vInputBindDescription; +} + +VkVertexInputAttributeDescription Seele::init::VertexInputAttributeDescription( + uint32_t binding, + uint32_t location, + VkFormat format, + uint32_t offset) +{ + VkVertexInputAttributeDescription vInputAttribDescription = {}; + vInputAttribDescription.location = location; + vInputAttribDescription.binding = binding; + vInputAttribDescription.format = format; + vInputAttribDescription.offset = offset; + return vInputAttribDescription; +} + +VkPipelineVertexInputStateCreateInfo Seele::init::PipelineVertexInputStateCreateInfo() +{ + VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = {}; + pipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + pipelineVertexInputStateCreateInfo.pNext = NULL; + return pipelineVertexInputStateCreateInfo; +} + +VkPipelineInputAssemblyStateCreateInfo Seele::init::PipelineInputAssemblyStateCreateInfo( + VkPrimitiveTopology topology, + VkPipelineInputAssemblyStateCreateFlags flags, + VkBool32 primitiveRestartEnable) +{ + VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo = {}; + pipelineInputAssemblyStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + pipelineInputAssemblyStateCreateInfo.topology = topology; + pipelineInputAssemblyStateCreateInfo.flags = flags; + pipelineInputAssemblyStateCreateInfo.primitiveRestartEnable = primitiveRestartEnable; + return pipelineInputAssemblyStateCreateInfo; +} + +VkPipelineRasterizationStateCreateInfo Seele::init::PipelineRasterizationStateCreateInfo( + VkPolygonMode polygonMode, + VkCullModeFlags cullMode, + VkFrontFace frontFace, + VkPipelineRasterizationStateCreateFlags flags) +{ + VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo = {}; + pipelineRasterizationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + pipelineRasterizationStateCreateInfo.polygonMode = polygonMode; + pipelineRasterizationStateCreateInfo.cullMode = cullMode; + pipelineRasterizationStateCreateInfo.frontFace = frontFace; + pipelineRasterizationStateCreateInfo.flags = flags; + pipelineRasterizationStateCreateInfo.depthClampEnable = VK_FALSE; + pipelineRasterizationStateCreateInfo.lineWidth = 1.0f; + return pipelineRasterizationStateCreateInfo; +} + +VkPipelineColorBlendAttachmentState Seele::init::PipelineColorBlendAttachmentState( + VkColorComponentFlags colorWriteMask, + VkBool32 blendEnable) +{ + VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = {}; + pipelineColorBlendAttachmentState.colorWriteMask = colorWriteMask; + pipelineColorBlendAttachmentState.blendEnable = blendEnable; + return pipelineColorBlendAttachmentState; +} + +VkPipelineColorBlendStateCreateInfo Seele::init::PipelineColorBlendStateCreateInfo( + uint32_t attachmentCount, + const VkPipelineColorBlendAttachmentState* pAttachments) +{ + VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = {}; + pipelineColorBlendStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + pipelineColorBlendStateCreateInfo.pNext = NULL; + pipelineColorBlendStateCreateInfo.attachmentCount = attachmentCount; + pipelineColorBlendStateCreateInfo.pAttachments = pAttachments; + return pipelineColorBlendStateCreateInfo; +} + +VkPipelineDepthStencilStateCreateInfo Seele::init::PipelineDepthStencilStateCreateInfo( + VkBool32 depthTestEnable, + VkBool32 depthWriteEnable, + VkCompareOp depthCompareOp) +{ + VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo = {}; + pipelineDepthStencilStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + pipelineDepthStencilStateCreateInfo.depthTestEnable = depthTestEnable; + pipelineDepthStencilStateCreateInfo.depthWriteEnable = depthWriteEnable; + pipelineDepthStencilStateCreateInfo.depthCompareOp = depthCompareOp; + pipelineDepthStencilStateCreateInfo.front = pipelineDepthStencilStateCreateInfo.back; + pipelineDepthStencilStateCreateInfo.back.compareOp = VK_COMPARE_OP_ALWAYS; + return pipelineDepthStencilStateCreateInfo; +} + +VkPipelineViewportStateCreateInfo Seele::init::PipelineViewportStateCreateInfo( + uint32_t viewportCount, + uint32_t scissorCount, + VkPipelineViewportStateCreateFlags flags) +{ + VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo = {}; + pipelineViewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + pipelineViewportStateCreateInfo.viewportCount = viewportCount; + pipelineViewportStateCreateInfo.scissorCount = scissorCount; + pipelineViewportStateCreateInfo.flags = flags; + return pipelineViewportStateCreateInfo; +} + +VkPipelineMultisampleStateCreateInfo Seele::init::PipelineMultisampleStateCreateInfo( + VkSampleCountFlagBits rasterizationSamples, + VkPipelineMultisampleStateCreateFlags flags) +{ + VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = {}; + pipelineMultisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + pipelineMultisampleStateCreateInfo.rasterizationSamples = rasterizationSamples; + return pipelineMultisampleStateCreateInfo; +} + +VkPipelineDynamicStateCreateInfo Seele::init::PipelineDynamicStateCreateInfo( + const VkDynamicState* pDynamicStates, + uint32_t dynamicStateCount, + VkPipelineDynamicStateCreateFlags flags) +{ + VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {}; + pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + pipelineDynamicStateCreateInfo.pDynamicStates = pDynamicStates; + pipelineDynamicStateCreateInfo.dynamicStateCount = dynamicStateCount; + return pipelineDynamicStateCreateInfo; +} + +VkPipelineTessellationStateCreateInfo Seele::init::PipelineTessellationStateCreateInfo(uint32_t patchControlPoints) +{ + VkPipelineTessellationStateCreateInfo pipelineTessellationStateCreateInfo = {}; + pipelineTessellationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; + pipelineTessellationStateCreateInfo.patchControlPoints = patchControlPoints; + return pipelineTessellationStateCreateInfo; +} + +VkGraphicsPipelineCreateInfo Seele::init::PipelineCreateInfo( + VkPipelineLayout layout, + VkRenderPass renderPass, + VkPipelineCreateFlags flags) +{ + VkGraphicsPipelineCreateInfo pipelineCreateInfo = {}; + pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipelineCreateInfo.pNext = NULL; + pipelineCreateInfo.layout = layout; + pipelineCreateInfo.renderPass = renderPass; + pipelineCreateInfo.flags = flags; + return pipelineCreateInfo; +} + +VkComputePipelineCreateInfo Seele::init::ComputePipelineCreateInfo(VkPipelineLayout layout, VkPipelineCreateFlags flags) +{ + VkComputePipelineCreateInfo computePipelineCreateInfo = {}; + computePipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + computePipelineCreateInfo.layout = layout; + computePipelineCreateInfo.flags = flags; + return computePipelineCreateInfo; +} + +VkPushConstantRange Seele::init::PushConstantRange( + VkShaderStageFlags stageFlags, + uint32_t size, + uint32_t offset) +{ + VkPushConstantRange pushConstantRange = {}; + pushConstantRange.stageFlags = stageFlags; + pushConstantRange.offset = offset; + pushConstantRange.size = size; + return pushConstantRange; +} + +VkPipelineShaderStageCreateInfo Seele::init::PipelineShaderStageCreateInfo(VkShaderStageFlagBits stage, VkShaderModule module, const char* entryName) +{ + VkPipelineShaderStageCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + info.module = module; + info.stage = stage; + info.pName = entryName; + return info; +} + + +VkBool32 __stdcall Seele::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userDataManager) { + std::cerr << layerPrefix << ": " << msg << std::endl; + return VK_FALSE; +} +VkResult Seele::CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) { + auto func = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); + if (func != nullptr) { + return func(instance, pCreateInfo, pAllocator, pCallback); + } + else { + return VK_ERROR_EXTENSION_NOT_PRESENT; + } +} + +void Seele::DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT pCallback) +{ + auto func = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); + if (func != nullptr) { + func(instance, pCallback, pAllocator); + } +} diff --git a/src/Engine/Graphics/Vulkan/VulkanInitializer.h b/src/Engine/Graphics/Vulkan/VulkanInitializer.h new file mode 100644 index 0000000..5f54cbe --- /dev/null +++ b/src/Engine/Graphics/Vulkan/VulkanInitializer.h @@ -0,0 +1,301 @@ +#include "Containers/Array.h" +#include + +namespace Seele +{ + VkBool32 __stdcall debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userData); + + VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); + void DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT pCallback); + + namespace init + { + VkApplicationInfo ApplicationInfo( + const char* appName, + uint32_t appVersion, + const char* engineName, + uint32_t engineVersion, + uint32_t apiVersion); + + VkInstanceCreateInfo InstanceCreateInfo( + VkApplicationInfo* appInfo, + const Array& extensions, + const Array& layers); + + VkDebugReportCallbackCreateInfoEXT DebugReportCallbackCreateInfo( + VkDebugReportFlagsEXT flags); + + VkDeviceQueueCreateInfo DeviceQueueCreateInfo( + int queueFamilyIndex, + int queueCount); + + VkDeviceQueueCreateInfo DeviceQueueCreateInfo( + int queueFamilyIndex, + int queueCount, + float* queuePriority); + + VkDeviceCreateInfo DeviceCreateInfo( + VkDeviceQueueCreateInfo* queueInfos, + uint32_t queueCount, + VkPhysicalDeviceFeatures* features, + const char* const* deviceExtensions, + uint32_t deviceExtensionCount, + const char* const* layers, + uint32_t layerCount); + + VkDeviceCreateInfo DeviceCreateInfo( + VkDeviceQueueCreateInfo* queueInfos, + uint32_t queueCount, + VkPhysicalDeviceFeatures* features); + + VkSwapchainCreateInfoKHR SwapchainCreateInfo( + VkSurfaceKHR surface, + uint32_t minImageCount, + VkFormat imageFormat, + VkColorSpaceKHR colorSpace, + VkExtent2D extent, + uint32_t arrayLayers, + VkImageUsageFlags usage, + VkSurfaceTransformFlagBitsKHR Transform, + VkCompositeAlphaFlagBitsKHR alpha, + VkPresentModeKHR presentMode, + VkBool32 clipped); + + VkSwapchainCreateInfoKHR SwapchainCreateInfo( + VkSurfaceKHR surface, + uint32_t minImageCount, + VkFormat imageFormat, + VkColorSpaceKHR colorSpace, + uint32_t width, + uint32_t height, + uint32_t arrayLayers, + VkImageUsageFlags usage, + VkSurfaceTransformFlagBitsKHR Transform, + VkCompositeAlphaFlagBitsKHR alpha, + VkPresentModeKHR presentMode, + VkBool32 clipped); + + VkFramebufferCreateInfo FramebufferCreateInfo( + VkRenderPass renderPass, + uint32_t attachmentCount, + VkImageView* attachments, + uint32_t width, + uint32_t height, + uint32_t layers); + + VkAttachmentDescription AttachmentDescription( + VkFormat format, + VkSampleCountFlagBits sample, + VkAttachmentLoadOp loadOp, + VkAttachmentStoreOp storeOp, + VkAttachmentLoadOp stencilLoadOp, + VkAttachmentStoreOp stencilStoreOp, + VkImageLayout imageLayout, + VkImageLayout finalLayout); + + VkSubpassDescription SubpassDescription( + VkPipelineBindPoint bindPoint, + uint32_t colorAttachmentCount, + VkAttachmentReference* colorReference, + uint32_t depthAttachmentCount = 0, + VkAttachmentReference* depthReference = nullptr, + uint32_t inputAttachmentCount = 0, + VkAttachmentReference* inputReference = nullptr, + uint32_t resolveAttachmentCount = 0, + VkAttachmentReference* resolveReference = nullptr, + uint32_t preserveAttachmentCount = 0, + VkAttachmentReference* preserveReference = nullptr); + + VkRenderPassCreateInfo RenderPassCreateInfo( + uint32_t attachmentCount, + const VkAttachmentDescription* attachments, + uint32_t subpassCount, + const VkSubpassDescription* subpasses, + uint32_t dependencyCount, + const VkSubpassDependency* subpassDependencies); + + VkMemoryAllocateInfo MemoryAllocateInfo(); + + VkCommandBufferAllocateInfo CommandBufferAllocateInfo( + VkCommandPool cmdPool, + VkCommandBufferLevel level, + uint32_t bufferCount); + + VkCommandPoolCreateInfo CommandPoolCreateInfo(); + + VkCommandBufferBeginInfo CommandBufferBeginInfo(); + + VkCommandBufferInheritanceInfo CommandBufferInheritanceInfo(); + + VkRenderPassBeginInfo RenderPassBeginInfo(); + + VkRenderPassCreateInfo RenderPassCreateInfo(); + + VkImageMemoryBarrier ImageMemoryBarrier(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t srcQueue = VK_QUEUE_FAMILY_IGNORED, uint32_t dstQueue = VK_QUEUE_FAMILY_IGNORED); + VkImageMemoryBarrier ImageMemoryBarrier(); + + VkBufferMemoryBarrier BufferMemoryBarrier(); + + VkMemoryBarrier MemoryBarrier(); + + VkImageCreateInfo ImageCreateInfo(); + + VkSamplerCreateInfo SamplerCreateInfo(); + + VkImageViewCreateInfo ImageViewCreateInfo(); + + VkSemaphoreCreateInfo SemaphoreCreateInfo(); + + VkFenceCreateInfo FenceCreateInfo( + VkFenceCreateFlags flags); + + VkEventCreateInfo EventCreateInfo(); + + VkSubmitInfo SubmitInfo(); + + VkImageSubresourceRange ImageSubresourceRange( + VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT, + uint32_t startMip = 0); + + VkViewport Viewport( + float width, + float height, + float minDepth, + float maxDepth); + + VkRect2D Rect2D( + int32_t width, + int32_t height, + int32_t offsetX, + int32_t offsetY); + + VkBufferCreateInfo BufferCreateInfo(); + + VkBufferCreateInfo BufferCreateInfo( + VkBufferUsageFlags usage, + VkDeviceSize size); + + VkDescriptorPoolCreateInfo DescriptorPoolCreateInfo( + uint32_t poolSizeCount, + VkDescriptorPoolSize* pPoolSizes, + uint32_t maxSets); + + VkDescriptorPoolSize DescriptorPoolSize( + VkDescriptorType type, + uint32_t descriptorCount); + + VkDescriptorSetLayoutBinding DescriptorSetLayoutBinding( + VkDescriptorType type, + VkShaderStageFlags stageFlags, + uint32_t binding, + uint32_t count); + + VkDescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo( + const VkDescriptorSetLayoutBinding* pBindings, + uint32_t bindingCount); + + VkPipelineLayoutCreateInfo PipelineLayoutCreateInfo( + const VkDescriptorSetLayout* pSetLayouts, + uint32_t setLayoutCount); + + VkDescriptorSetAllocateInfo DescriptorSetAllocateInfo( + VkDescriptorPool descriptorPool, + const VkDescriptorSetLayout* pSetLayouts, + uint32_t descriptorSetCount); + + VkDescriptorBufferInfo DescriptorBufferInfo( + VkBuffer buffer, + VkDeviceSize offset, + VkDeviceSize range); + VkDescriptorImageInfo DescriptorImageInfo( + VkSampler sampler, + VkImageView imageView, + VkImageLayout imageLayout); + + VkWriteDescriptorSet WriteDescriptorSet( + VkDescriptorSet dstSet, + VkDescriptorType type, + uint32_t binding, + VkDescriptorBufferInfo* bufferInfo); + + VkWriteDescriptorSet WriteDescriptorSet( + VkDescriptorSet dstSet, + VkDescriptorType type, + uint32_t binding, + VkDescriptorImageInfo* bufferInfo); + + + VkVertexInputBindingDescription VertexInputBindingDescription( + uint32_t binding, + uint32_t stride, + VkVertexInputRate inputRate); + + VkVertexInputAttributeDescription VertexInputAttributeDescription( + uint32_t binding, + uint32_t location, + VkFormat format, + uint32_t offset); + + VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo(); + + VkPipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo( + VkPrimitiveTopology topology, + VkPipelineInputAssemblyStateCreateFlags flags, + VkBool32 primitiveRestartEnable); + + VkPipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo( + VkPolygonMode polygonMode, + VkCullModeFlags cullMode, + VkFrontFace frontFace, + VkPipelineRasterizationStateCreateFlags flags); + + VkPipelineColorBlendAttachmentState PipelineColorBlendAttachmentState( + VkColorComponentFlags colorWriteMask, + VkBool32 blendEnable); + + VkPipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo( + uint32_t attachmentCount, + const VkPipelineColorBlendAttachmentState* pAttachments); + + VkPipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo( + VkBool32 depthTestEnable, + VkBool32 depthWriteEnable, + VkCompareOp depthCompareOp); + + VkPipelineViewportStateCreateInfo PipelineViewportStateCreateInfo( + uint32_t viewportCount, + uint32_t scissorCount, + VkPipelineViewportStateCreateFlags flags); + + VkPipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo( + VkSampleCountFlagBits rasterizationSamples, + VkPipelineMultisampleStateCreateFlags flags); + + VkPipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo( + const VkDynamicState* pDynamicStates, + uint32_t dynamicStateCount, + VkPipelineDynamicStateCreateFlags flags); + + VkPipelineTessellationStateCreateInfo PipelineTessellationStateCreateInfo( + uint32_t patchControlPoints); + + VkGraphicsPipelineCreateInfo PipelineCreateInfo( + VkPipelineLayout layout, + VkRenderPass renderPass, + VkPipelineCreateFlags flags); + + VkComputePipelineCreateInfo ComputePipelineCreateInfo( + VkPipelineLayout layout, + VkPipelineCreateFlags flags); + + VkPushConstantRange PushConstantRange( + VkShaderStageFlags stageFlags, + uint32_t size, + uint32_t offset); + + VkPipelineShaderStageCreateInfo PipelineShaderStageCreateInfo( + VkShaderStageFlagBits stage, + VkShaderModule module, + const char* entryName); + } +} \ No newline at end of file diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index 7a26c74..61bca2c 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -26,6 +26,51 @@ namespace Seele typedef int16_t int16; typedef int8_t int8; + template + class RefObject + { + public: + RefObject(T* ptr) + : handle(ptr) + , refCount(1) + { + } + RefObject(const RefObject& rhs) + : handle(rhs.handle) + , refCount(rhs.refCount) + { + + } + + ~RefObject() + {} + bool operator==(const RefObject& other) const + { + return handle == other.handle && refCount == other.refCount; + } + void addRef() + { + refCount++; + } + void removeRef() + { + refCount--; + if (refCount.load() <= 0) + { + delete handle; + handle = nullptr; + delete this; + } + } + inline T* getHandle() const + { + return handle; + } + private: + T* handle; + std::atomic_uint64_t refCount; + }; + template class RefPtr { @@ -36,13 +81,41 @@ namespace Seele } RefPtr(T* ptr) { - object = new RefObject(ptr); + object = new RefObject(ptr); + } + explicit RefPtr(RefObject* other) + : object(other) + { + object->addRef(); } RefPtr(const RefPtr& other) : object(other.object) { object->addRef(); } + template + RefPtr(const RefPtr& other) + { + F* f = other.getObject()->getHandle(); + T* t = static_cast(f); + object = (RefObject*)other.getObject(); + object->addRef(); + } + + template + RefPtr& cast() + { + T* t = object->getHandle(); + F* f = dynamic_cast(t); + if (f == nullptr) + { + return RefPtr(); + } + RefObject* newObject = static_cast*>(object); + RefPtr result(newObject); + return result; + } + RefPtr& operator=(const RefPtr& other) { if (this != &other) @@ -78,53 +151,12 @@ namespace Seele assert(object != nullptr); return object->getHandle(); } - private: - - class RefObject + RefObject* getObject() const { - public: - RefObject(T* ptr) - : handle(ptr) - , refCount(1) - { - } - RefObject(const RefObject& rhs) - : handle(rhs.handle) - , refCount(rhs.refCount) - { - - } - ~RefObject() - {} - bool operator==(const RefObject& other) const - { - return handle == other.handle && refCount == other.refCount; - } - void addRef() - { - refCount++; - } - void removeRef() - { - refCount--; - if (refCount.load() <= 0) - { - delete handle; - handle = nullptr; - delete this; - } - } - inline T* getHandle() const - { - return handle; - } - private: - T* handle; - std::atomic_uint64_t refCount; - }; - RefObject* object; - template - friend class WeakPtr; + return object; + } + private: + RefObject* object; }; template class WeakPtr @@ -152,7 +184,7 @@ namespace Seele return temp; } private: - RefPtr::RefObject* pointer; + RefObject* pointer; }; template class UniquePtr diff --git a/test/Engine/EngineTest.cpp b/test/Engine/EngineTest.cpp index b3b1d6b..7006305 100644 --- a/test/Engine/EngineTest.cpp +++ b/test/Engine/EngineTest.cpp @@ -31,6 +31,23 @@ BOOST_AUTO_TEST_CASE(basic_refcount) } } +struct DerivedStruct : public TestStruct +{ + +}; + +BOOST_AUTO_TEST_CASE(inheritance_cast) +{ + Seele::RefPtr backCast; + { + Seele::RefPtr derived = new DerivedStruct(); + Seele::RefPtr base = derived; + BOOST_REQUIRE_EQUAL(base->data, 10); + backCast = base.cast(); + } + BOOST_REQUIRE_EQUAL(backCast->data, 10); +} + BOOST_AUTO_TEST_CASE(unique_ptr) { UniquePtr uptr = new TestStruct();