16#include "VulkanWindow.hpp"
17#include "VulkanRenderer.hpp"
18#include "VulkanPipeline.hpp"
19#include "VulkanMaterial.hpp"
20#include "VulkanUtilities.hpp"
21#include "VulkanMesh.hpp"
30#include "aeongames/Material.hpp"
31#include "aeongames/Pipeline.hpp"
32#include "aeongames/Mesh.hpp"
35#include "aeongames/Node.hpp"
36#include "aeongames/Mesh.hpp"
37#include "aeongames/Pipeline.hpp"
38#include "aeongames/Material.hpp"
40#include "aeongames/MemoryPool.hpp"
44extern "C" void* GetMetalLayerFromNSView (
void* nsview_ptr );
50 mVulkanRenderer { aVulkanRenderer }, mWindowId{aWindowId},
51 mMemoryPoolBuffer{mVulkanRenderer, 64_kb},
52 mMatrices { aVulkanRenderer }
54 std::cout <<
LogLevel::Info <<
"Creating VulkanWindow." << std::endl;
67 mVulkanRenderer { aVulkanWindow.mVulkanRenderer },
68 mMemoryPoolBuffer{
std::move ( aVulkanWindow.mMemoryPoolBuffer ) },
69 mMatrices{
std::move ( aVulkanWindow.mMatrices ) }
72 std::swap ( mWindowId, aVulkanWindow.mWindowId );
73 std::swap ( mFrustum, aVulkanWindow.mFrustum );
74 std::swap ( mProjectionMatrix, aVulkanWindow.mProjectionMatrix );
75 std::swap ( mViewMatrix, aVulkanWindow.mViewMatrix );
76 std::swap ( mVkSurfaceKHR, aVulkanWindow.mVkSurfaceKHR );
77 std::swap ( mVkSurfaceCapabilitiesKHR, aVulkanWindow.mVkSurfaceCapabilitiesKHR );
78 std::swap ( mSwapchainImageCount, aVulkanWindow.mSwapchainImageCount );
79 std::swap ( mVkSwapchainKHR, aVulkanWindow.mVkSwapchainKHR );
80 std::swap ( mVkDepthStencilImage, aVulkanWindow.mVkDepthStencilImage );
81 std::swap ( mVkDepthStencilImageMemory, aVulkanWindow.mVkDepthStencilImageMemory );
82 std::swap ( mVkDepthStencilImageView, aVulkanWindow.mVkDepthStencilImageView );
83 std::swap ( mHasStencil, aVulkanWindow.mHasStencil );
84 std::swap ( mActiveImageIndex, aVulkanWindow.mActiveImageIndex );
85 std::swap ( mVkViewport, aVulkanWindow.mVkViewport );
86 std::swap ( mVkScissor, aVulkanWindow.mVkScissor );
87 std::swap ( mVkDepthStencilFormat, aVulkanWindow.mVkDepthStencilFormat );
88 std::swap ( mVkSurfaceFormatKHR, aVulkanWindow.mVkSurfaceFormatKHR );
89 std::swap ( mVkRenderPass, aVulkanWindow.mVkRenderPass );
90 std::swap ( mMatricesDescriptorPool, aVulkanWindow.mMatricesDescriptorPool );
91 std::swap ( mMatricesDescriptorSet, aVulkanWindow.mMatricesDescriptorSet );
92 std::swap ( mVkCommandPool, aVulkanWindow.mVkCommandPool );
93 std::swap ( mVkCommandBuffer, aVulkanWindow.mVkCommandBuffer );
94 std::swap ( mVkAcquireSemaphore, aVulkanWindow.mVkAcquireSemaphore );
95 std::swap ( mVkFence, aVulkanWindow.mVkFence );
96 mVkSwapchainImages.swap ( aVulkanWindow.mVkSwapchainImages );
97 mVkSwapchainImageViews.swap ( aVulkanWindow.mVkSwapchainImageViews );
98 mVkFramebuffers.swap ( aVulkanWindow.mVkFramebuffers );
99 mVkSubmitSemaphores.swap ( aVulkanWindow.mVkSubmitSemaphores );
102 VulkanWindow::~VulkanWindow()
104 std::cout <<
LogLevel::Info <<
"Destroying VulkanWindow." << std::endl;
108 void VulkanWindow::InitializeSurface()
110#if defined ( VK_USE_PLATFORM_WIN32_KHR )
111 VkWin32SurfaceCreateInfoKHR win32_surface_create_info_khr {};
112 win32_surface_create_info_khr.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
113 win32_surface_create_info_khr.hwnd =
reinterpret_cast<HWND
> ( mWindowId );
114 win32_surface_create_info_khr.hinstance =
reinterpret_cast<HINSTANCE
> ( GetWindowLongPtr ( win32_surface_create_info_khr.hwnd, GWLP_HINSTANCE ) );
115 if ( VkResult result = vkCreateWin32SurfaceKHR ( mVulkanRenderer.GetInstance(), &win32_surface_create_info_khr,
nullptr, &mVkSurfaceKHR ) )
117 std::ostringstream stream;
120 throw std::runtime_error ( stream.str().c_str() );
122#elif defined( VK_USE_PLATFORM_METAL_EXT )
123 VkMetalSurfaceCreateInfoEXT metal_surface_create_info_ext {};
124 metal_surface_create_info_ext.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
125 metal_surface_create_info_ext.pLayer =
reinterpret_cast<CAMetalLayer*
> ( GetMetalLayerFromNSView ( mWindowId ) );
126 if ( VkResult result = vkCreateMetalSurfaceEXT ( mVulkanRenderer.GetInstance(), &metal_surface_create_info_ext,
nullptr, &mVkSurfaceKHR ) )
128 std::ostringstream stream;
131 throw std::runtime_error ( stream.str().c_str() );
133#elif defined( VK_USE_PLATFORM_XLIB_KHR )
134 VkXlibSurfaceCreateInfoKHR xlib_surface_create_info_khr {};
135 xlib_surface_create_info_khr.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
136 xlib_surface_create_info_khr.dpy = mVulkanRenderer.GetDisplay();
137 xlib_surface_create_info_khr.window =
reinterpret_cast<::Window
> ( mWindowId );
138 if ( VkResult result = vkCreateXlibSurfaceKHR ( mVulkanRenderer.GetInstance(), &xlib_surface_create_info_khr,
nullptr, &mVkSurfaceKHR ) )
140 std::ostringstream stream;
143 throw std::runtime_error ( stream.str().c_str() );
146 VkBool32 wsi_supported =
false;
147 vkGetPhysicalDeviceSurfaceSupportKHR ( mVulkanRenderer.GetPhysicalDevice(), mVulkanRenderer.GetQueueFamilyIndex(), mVkSurfaceKHR, &wsi_supported );
148 if ( !wsi_supported )
150 std::ostringstream stream;
151 stream <<
"WSI not supported.";
153 throw std::runtime_error ( stream.str().c_str() );
157 void VulkanWindow::InitializeSwapchain()
159 std::cout <<
LogLevel::Debug <<
"Initializing VulkanWindow Swapchain." << std::endl;
160 vkGetPhysicalDeviceSurfaceCapabilitiesKHR ( mVulkanRenderer.GetPhysicalDevice(), mVkSurfaceKHR, &mVkSurfaceCapabilitiesKHR );
162 if ( mVkSurfaceCapabilitiesKHR.currentExtent.width == 0 ||
163 mVkSurfaceCapabilitiesKHR.currentExtent.height == 0 )
165 std::ostringstream stream;
166 stream <<
"Cannot create swapchain with zero area. (" << mVkSurfaceCapabilitiesKHR.currentExtent.width <<
"x" << mVkSurfaceCapabilitiesKHR.currentExtent.height <<
")" << std::endl;
168 throw std::runtime_error ( stream.str().c_str() );
171 if ( mSwapchainImageCount < mVkSurfaceCapabilitiesKHR.minImageCount )
173 mSwapchainImageCount = mVkSurfaceCapabilitiesKHR.minImageCount;
175 if ( ( mVkSurfaceCapabilitiesKHR.maxImageCount > 0 ) &&
176 ( mSwapchainImageCount > mVkSurfaceCapabilitiesKHR.maxImageCount ) )
178 mSwapchainImageCount = mVkSurfaceCapabilitiesKHR.maxImageCount;
180 VkSwapchainCreateInfoKHR swapchain_create_info{};
181 swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
182 swapchain_create_info.surface = mVkSurfaceKHR;
183 swapchain_create_info.minImageCount = mSwapchainImageCount;
184 swapchain_create_info.imageFormat = mVkSurfaceFormatKHR.format;
185 swapchain_create_info.imageColorSpace = mVkSurfaceFormatKHR.colorSpace;
186 swapchain_create_info.imageExtent.width = mVkSurfaceCapabilitiesKHR.currentExtent.width;
187 swapchain_create_info.imageExtent.height = mVkSurfaceCapabilitiesKHR.currentExtent.height;
188 swapchain_create_info.imageArrayLayers = 1;
189 swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
190 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
191 swapchain_create_info.queueFamilyIndexCount = 0;
192 swapchain_create_info.pQueueFamilyIndices =
nullptr;
193 swapchain_create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
194 swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
195 swapchain_create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR;
196 swapchain_create_info.clipped = VK_TRUE;
197 swapchain_create_info.oldSwapchain = mVkSwapchainKHR;
199 uint32_t present_mode_count = 0;
200 vkGetPhysicalDeviceSurfacePresentModesKHR ( mVulkanRenderer.GetPhysicalDevice(), mVkSurfaceKHR, &present_mode_count,
nullptr );
201 std::vector<VkPresentModeKHR> present_mode_list ( present_mode_count );
202 vkGetPhysicalDeviceSurfacePresentModesKHR ( mVulkanRenderer.GetPhysicalDevice(), mVkSurfaceKHR, &present_mode_count, present_mode_list.data() );
203 for (
auto& i : present_mode_list )
205 if ( i == VK_PRESENT_MODE_MAILBOX_KHR )
207 swapchain_create_info.presentMode = i;
212 if ( VkResult result = vkCreateSwapchainKHR ( mVulkanRenderer.GetDevice(), &swapchain_create_info,
nullptr, &mVkSwapchainKHR ) )
214 std::ostringstream stream;
217 throw std::runtime_error ( stream.str().c_str() );
219 if ( swapchain_create_info.oldSwapchain != VK_NULL_HANDLE )
221 vkDestroySwapchainKHR ( mVulkanRenderer.GetDevice(), swapchain_create_info.oldSwapchain,
nullptr );
224 std::cout <<
LogLevel::Debug <<
"VulkanWindow Swapchain created with " << mSwapchainImageCount <<
" images." << std::endl;
226 VkSemaphoreCreateInfo semaphore_create_info{};
227 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
228 if ( VkResult result = vkCreateSemaphore ( mVulkanRenderer.GetDevice(), &semaphore_create_info,
nullptr, &mVkAcquireSemaphore ) )
230 std::ostringstream stream;
231 stream <<
"Could not create VulkanRenderer semaphore. error code: ( " <<
GetVulkanResultString ( result ) <<
" )";
232 throw std::runtime_error ( stream.str().c_str() );
234 std::cout <<
LogLevel::Debug <<
"Created Acquire Semaphore " << std::hex << mVkAcquireSemaphore << std::endl;
235 mVkSubmitSemaphores.resize ( mSwapchainImageCount );
236 for (
size_t i = 0; i < mSwapchainImageCount; ++i )
238 if ( VkResult result = vkCreateSemaphore ( mVulkanRenderer.GetDevice(), &semaphore_create_info,
nullptr, &mVkSubmitSemaphores[i] ) )
240 std::ostringstream stream;
241 stream <<
"Could not create VulkanRenderer semaphore. error code: ( " <<
GetVulkanResultString ( result ) <<
" )";
242 throw std::runtime_error ( stream.str().c_str() );
244 std::cout <<
LogLevel::Debug <<
"Created Submit Semaphore " << std::hex << mVkSubmitSemaphores[i] << std::endl;
246 VkFenceCreateInfo fence_create_info{};
247 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
248 fence_create_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
249 vkCreateFence ( mVulkanRenderer.GetDevice(), &fence_create_info,
nullptr, &mVkFence );
252 void VulkanWindow::InitializeImageViews()
254 if ( mVkSwapchainKHR == VK_NULL_HANDLE )
256 std::ostringstream stream;
257 stream <<
"Cannot initialize swapchain image views with no swapchain.";
259 throw std::runtime_error ( stream.str().c_str() );
261 if ( VkResult result = vkGetSwapchainImagesKHR ( mVulkanRenderer.GetDevice(), mVkSwapchainKHR, &mSwapchainImageCount,
nullptr ) )
263 std::ostringstream stream;
266 throw std::runtime_error ( stream.str().c_str() );
268 mVkSwapchainImages.resize ( mSwapchainImageCount );
269 mVkSwapchainImageViews.resize ( mSwapchainImageCount );
270 if ( VkResult result = vkGetSwapchainImagesKHR ( mVulkanRenderer.GetDevice(),
272 &mSwapchainImageCount,
273 mVkSwapchainImages.data() ) )
275 std::ostringstream stream;
278 throw std::runtime_error ( stream.str().c_str() );
280 for ( uint32_t i = 0; i < mSwapchainImageCount; ++i )
282 VkImageViewCreateInfo image_view_create_info{};
283 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
284 image_view_create_info.pNext =
nullptr;
285 image_view_create_info.flags = 0;
286 image_view_create_info.image = mVkSwapchainImages[i];
287 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
288 image_view_create_info.format = mVkSurfaceFormatKHR.format;
289 image_view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
290 image_view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
291 image_view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
292 image_view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
293 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
294 image_view_create_info.subresourceRange.baseMipLevel = 0;
295 image_view_create_info.subresourceRange.levelCount = 1;
296 image_view_create_info.subresourceRange.baseArrayLayer = 0;
297 image_view_create_info.subresourceRange.layerCount = 1;
298 vkCreateImageView ( mVulkanRenderer.GetDevice(), &image_view_create_info,
nullptr, &mVkSwapchainImageViews[i] );
302 void VulkanWindow::InitializeDepthStencil()
304 if ( mVkSurfaceCapabilitiesKHR.currentExtent.width == 0 ||
305 mVkSurfaceCapabilitiesKHR.currentExtent.height == 0 )
307 std::cout <<
LogLevel::Debug <<
"Cannot create depth stencil with zero area. (" << mVkSurfaceCapabilitiesKHR.currentExtent.width <<
"x" << mVkSurfaceCapabilitiesKHR.currentExtent.height <<
")" << std::endl;
312 ( mVkDepthStencilFormat == VK_FORMAT_D32_SFLOAT_S8_UINT ||
313 mVkDepthStencilFormat == VK_FORMAT_D24_UNORM_S8_UINT ||
314 mVkDepthStencilFormat == VK_FORMAT_D16_UNORM_S8_UINT );
315 VkImageCreateInfo image_create_info{};
316 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
317 image_create_info.flags = 0;
318 image_create_info.format = mVkDepthStencilFormat;
319 image_create_info.imageType = VK_IMAGE_TYPE_2D;
320 image_create_info.extent.width = mVkSurfaceCapabilitiesKHR.currentExtent.width;
321 image_create_info.extent.height = mVkSurfaceCapabilitiesKHR.currentExtent.height;
322 image_create_info.extent.depth = 1;
323 image_create_info.mipLevels = 1;
324 image_create_info.arrayLayers = 1;
325 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
326 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
327 image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
328 image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
329 image_create_info.queueFamilyIndexCount = 0;
330 image_create_info.pQueueFamilyIndices =
nullptr;
331 image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
332 if ( VkResult result = vkCreateImage ( mVulkanRenderer.GetDevice(), &image_create_info,
nullptr, &mVkDepthStencilImage ) )
334 std::ostringstream stream;
337 throw std::runtime_error ( stream.str().c_str() );
340 VkMemoryRequirements memory_requirements;
341 vkGetImageMemoryRequirements ( mVulkanRenderer.GetDevice(), mVkDepthStencilImage, &memory_requirements );
343 auto required_bits = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
344 uint32_t memory_index = UINT32_MAX;
345 for ( uint32_t i = 0; i < mVulkanRenderer.GetPhysicalDeviceMemoryProperties().memoryTypeCount; ++i )
347 if ( memory_requirements.memoryTypeBits & ( 1 << i ) )
349 if ( ( mVulkanRenderer.GetPhysicalDeviceMemoryProperties().memoryTypes[i].propertyFlags & required_bits ) == required_bits )
357 if ( memory_index == UINT32_MAX )
359 std::ostringstream stream;
360 stream <<
"Could not find a suitable memory index.";
362 throw std::runtime_error ( stream.str().c_str() );
364 VkMemoryAllocateInfo memory_allocate_info{};
365 memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
366 memory_allocate_info.allocationSize = memory_requirements.size;
367 memory_allocate_info.memoryTypeIndex = memory_index;
368 vkAllocateMemory ( mVulkanRenderer.GetDevice(), &memory_allocate_info,
nullptr, &mVkDepthStencilImageMemory );
369 vkBindImageMemory ( mVulkanRenderer.GetDevice(), mVkDepthStencilImage, mVkDepthStencilImageMemory, 0 );
371 VkImageViewCreateInfo image_view_create_info{};
372 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
373 image_view_create_info.image = mVkDepthStencilImage;
374 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
375 image_view_create_info.format = mVkDepthStencilFormat;
376 image_view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
377 image_view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
378 image_view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
379 image_view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
380 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | ( mHasStencil ? VK_IMAGE_ASPECT_STENCIL_BIT : 0 );
381 image_view_create_info.subresourceRange.baseMipLevel = 0;
382 image_view_create_info.subresourceRange.levelCount = 1;
383 image_view_create_info.subresourceRange.baseArrayLayer = 0;
384 image_view_create_info.subresourceRange.layerCount = 1;
385 vkCreateImageView ( mVulkanRenderer.GetDevice(), &image_view_create_info,
nullptr, &mVkDepthStencilImageView );
388 void VulkanWindow::InitializeFrameBuffers()
390 if ( mVkSurfaceCapabilitiesKHR.currentExtent.width == 0 ||
391 mVkSurfaceCapabilitiesKHR.currentExtent.height == 0 )
393 std::cout <<
LogLevel::Debug <<
"Cannot create framebuffers with zero area. (" << mVkSurfaceCapabilitiesKHR.currentExtent.width <<
"x" << mVkSurfaceCapabilitiesKHR.currentExtent.height <<
")" << std::endl;
396 mVkFramebuffers.resize ( mSwapchainImageCount );
397 for ( uint32_t i = 0; i < mSwapchainImageCount; ++i )
399 std::array<VkImageView, 2> attachments
402 mVkSwapchainImageViews[i],
403 mVkDepthStencilImageView
406 VkFramebufferCreateInfo framebuffer_create_info{};
407 framebuffer_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
408 framebuffer_create_info.renderPass = mVkRenderPass;
409 framebuffer_create_info.attachmentCount =
static_cast<uint32_t
> ( attachments.size() );
410 framebuffer_create_info.pAttachments = attachments.data();
411 framebuffer_create_info.width = mVkSurfaceCapabilitiesKHR.currentExtent.width;
412 framebuffer_create_info.height = mVkSurfaceCapabilitiesKHR.currentExtent.height;
413 framebuffer_create_info.layers = 1;
414 vkCreateFramebuffer ( mVulkanRenderer.GetDevice(), &framebuffer_create_info,
nullptr, &mVkFramebuffers[i] );
418 void VulkanWindow::InitializeRenderPass()
420 uint32_t surface_format_count = 0;
421 vkGetPhysicalDeviceSurfaceFormatsKHR ( mVulkanRenderer.GetPhysicalDevice(), mVkSurfaceKHR, &surface_format_count,
nullptr );
422 if ( surface_format_count == 0 )
424 std::ostringstream stream;
425 stream <<
"Physical device reports no surface formats.";
427 throw std::runtime_error ( stream.str().c_str() );
430 std::vector<VkSurfaceFormatKHR> surface_format_list ( surface_format_count );
431 vkGetPhysicalDeviceSurfaceFormatsKHR (
432 mVulkanRenderer.GetPhysicalDevice(),
434 &surface_format_count,
435 surface_format_list.data() );
437 if ( surface_format_list[0].format == VK_FORMAT_UNDEFINED )
439 mVkSurfaceFormatKHR.format = VK_FORMAT_B8G8R8A8_UNORM;
440 mVkSurfaceFormatKHR.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
444 mVkSurfaceFormatKHR = surface_format_list[0];
446 std::array<VkFormat, 5> try_formats
449 VK_FORMAT_D32_SFLOAT_S8_UINT,
450 VK_FORMAT_D24_UNORM_S8_UINT,
451 VK_FORMAT_D16_UNORM_S8_UINT,
452 VK_FORMAT_D32_SFLOAT,
456 for (
auto format : try_formats )
458 VkFormatProperties format_properties{};
459 vkGetPhysicalDeviceFormatProperties ( mVulkanRenderer.GetPhysicalDevice(), format, &format_properties );
460 if ( format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT )
462 mVkDepthStencilFormat = format;
467 if ( std::find ( try_formats.begin(), try_formats.end(), mVkDepthStencilFormat ) == try_formats.end() )
469 std::ostringstream stream;
470 stream <<
"Unable to find a suitable depth stencil format";
472 throw std::runtime_error ( stream.str().c_str() );
475 std::array<VkAttachmentDescription, 2> attachment_descriptions{ {} };
476 attachment_descriptions[0].flags = 0;
477 attachment_descriptions[0].format = mVkSurfaceFormatKHR.format;
478 attachment_descriptions[0].samples = VK_SAMPLE_COUNT_1_BIT;
479 attachment_descriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
480 attachment_descriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
481 attachment_descriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
482 attachment_descriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
483 attachment_descriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
484 attachment_descriptions[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
486 attachment_descriptions[1].flags = 0;
487 attachment_descriptions[1].format = mVkDepthStencilFormat;
488 attachment_descriptions[1].samples = VK_SAMPLE_COUNT_1_BIT;
489 attachment_descriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
490 attachment_descriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
491 attachment_descriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
492 attachment_descriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
493 attachment_descriptions[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
494 attachment_descriptions[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
496 std::array<VkAttachmentReference, 1> color_attachment_references{};
497 color_attachment_references[0].attachment = 0;
498 color_attachment_references[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
500 VkAttachmentReference depth_stencil_attachment_reference{};
501 depth_stencil_attachment_reference.attachment = 1;
502 depth_stencil_attachment_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
504 std::array<VkSubpassDescription, 1> subpass_descriptions{};
505 subpass_descriptions[0].flags = 0;
506 subpass_descriptions[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
507 subpass_descriptions[0].inputAttachmentCount = 0;
508 subpass_descriptions[0].pInputAttachments =
nullptr;
509 subpass_descriptions[0].colorAttachmentCount =
static_cast<uint32_t
> ( color_attachment_references.size() );
510 subpass_descriptions[0].pColorAttachments = color_attachment_references.data();
511 subpass_descriptions[0].pResolveAttachments =
nullptr;
512 subpass_descriptions[0].pDepthStencilAttachment = &depth_stencil_attachment_reference;
513 subpass_descriptions[0].preserveAttachmentCount = 0;
514 subpass_descriptions[0].pPreserveAttachments =
nullptr;
516 VkSubpassDependency subpass_dependency = {};
517 subpass_dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
518 subpass_dependency.dstSubpass = 0;
519 subpass_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
520 subpass_dependency.srcAccessMask = 0;
521 subpass_dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
522 subpass_dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
524 VkRenderPassCreateInfo render_pass_create_info{};
525 render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
526 render_pass_create_info.attachmentCount =
static_cast<uint32_t
> ( attachment_descriptions.size() );
527 render_pass_create_info.pAttachments = attachment_descriptions.data();
528 render_pass_create_info.dependencyCount = 1;
529 render_pass_create_info.pDependencies = &subpass_dependency;
530 render_pass_create_info.subpassCount =
static_cast<uint32_t
> ( subpass_descriptions.size() );
531 render_pass_create_info.pSubpasses = subpass_descriptions.data();
532 vkCreateRenderPass ( mVulkanRenderer.GetDevice(), &render_pass_create_info,
nullptr, &mVkRenderPass );
535 void VulkanWindow::FinalizeRenderPass()
537 if ( mVkRenderPass != VK_NULL_HANDLE )
539 vkDestroyRenderPass ( mVulkanRenderer.GetDevice(), mVkRenderPass,
nullptr );
543 void VulkanWindow::InitializeMatrices()
545 mMatrices.Initialize (
546 sizeof (
float ) * 16 * 2,
547 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
548 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT );
550 VkDescriptorSetLayoutCreateInfo matrices_descriptor_set_layout_create_info{};
551 matrices_descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
552 matrices_descriptor_set_layout_create_info.bindingCount = 1;
553 VkDescriptorSetLayoutBinding matrices_descriptor_set_layout_binding{};
554 matrices_descriptor_set_layout_binding.binding = 0;
555 matrices_descriptor_set_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
556 matrices_descriptor_set_layout_binding.descriptorCount = 1;
559 matrices_descriptor_set_layout_binding.stageFlags = VK_SHADER_STAGE_ALL;
560 matrices_descriptor_set_layout_binding.pImmutableSamplers =
nullptr;
561 matrices_descriptor_set_layout_create_info.pBindings = &matrices_descriptor_set_layout_binding;
563 mMatricesDescriptorPool =
CreateDescriptorPool ( mVulkanRenderer.GetDevice(), {{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1}} );
564 mMatricesDescriptorSet =
CreateDescriptorSet ( mVulkanRenderer.GetDevice(), mMatricesDescriptorPool, mVulkanRenderer.GetDescriptorSetLayout ( matrices_descriptor_set_layout_create_info ) );
565 VkDescriptorBufferInfo descriptor_buffer_info{};
566 descriptor_buffer_info.buffer = mMatrices.GetBuffer();
567 descriptor_buffer_info.offset = 0;
568 descriptor_buffer_info.range = mMatrices.GetSize();
569 VkWriteDescriptorSet write_descriptor_set{};
570 write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
571 write_descriptor_set.pNext =
nullptr;
572 write_descriptor_set.dstSet = mMatricesDescriptorSet;
573 write_descriptor_set.dstBinding = 0;
574 write_descriptor_set.dstArrayElement = 0;
575 write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
576 write_descriptor_set.descriptorCount = 1;
577 write_descriptor_set.pBufferInfo = &descriptor_buffer_info;
578 write_descriptor_set.pImageInfo =
nullptr;
579 write_descriptor_set.pTexelBufferView =
nullptr;
580 vkUpdateDescriptorSets ( mVulkanRenderer.GetDevice(), 1, &write_descriptor_set, 0,
nullptr );
583 void VulkanWindow::FinalizeMatrices()
586 mMatrices.Finalize();
589 void VulkanWindow::Initialize()
591 InitializeMatrices();
593 InitializeRenderPass();
594 InitializeSwapchain();
595 InitializeImageViews();
596 InitializeDepthStencil();
597 InitializeFrameBuffers();
598 InitializeCommandBuffer();
601 void VulkanWindow::Finalize()
603 if ( VkResult result = vkQueueWaitIdle ( mVulkanRenderer.GetQueue() ) )
607 if ( VkResult result = vkDeviceWaitIdle ( mVulkanRenderer.GetDevice() ) )
611 FinalizeCommandBuffer();
612 FinalizeFrameBuffers();
613 FinalizeDepthStencil();
614 FinalizeImageViews();
616 FinalizeRenderPass();
623 VkSurfaceCapabilitiesKHR surface_capabilities{};
624 VkResult result {vkGetPhysicalDeviceSurfaceCapabilitiesKHR ( mVulkanRenderer.GetPhysicalDevice(), mVkSurfaceKHR, &surface_capabilities ) };
625 if ( result == VK_SUCCESS && std::memcmp ( &surface_capabilities, &mVkSurfaceCapabilitiesKHR,
sizeof ( VkSurfaceCapabilitiesKHR ) ) != 0 )
627 if ( VK_SUCCESS != ( result = vkQueueWaitIdle ( mVulkanRenderer.GetQueue() ) ) )
629 std::ostringstream stream;
632 throw std::runtime_error ( stream.str().c_str() );
635 if ( VK_SUCCESS != ( result = vkDeviceWaitIdle ( mVulkanRenderer.GetDevice() ) ) )
637 std::ostringstream stream;
640 throw std::runtime_error ( stream.str().c_str() );
642 FinalizeFrameBuffers();
643 FinalizeDepthStencil();
644 FinalizeImageViews();
646 InitializeSwapchain();
647 InitializeImageViews();
648 InitializeDepthStencil();
649 InitializeFrameBuffers();
651 mVkViewport.x =
static_cast<float> ( aX );
652 mVkViewport.y =
static_cast<float> ( aY );
653 mVkViewport.width =
static_cast<float> ( aWidth );
654 mVkViewport.height =
static_cast<float> ( aHeight );
656 mVkScissor.offset.x = ( aX < 0 ) ? 0 : aX;
657 mVkScissor.offset.y = ( aY < 0 ) ? 0 : aY;
658 mVkScissor.extent.width = ( aX + aWidth > mVkSurfaceCapabilitiesKHR.currentExtent.width ) ? mVkSurfaceCapabilitiesKHR.currentExtent.width : aX + aWidth;
659 mVkScissor.extent.height = ( aY + aHeight > mVkSurfaceCapabilitiesKHR.currentExtent.height ) ? mVkSurfaceCapabilitiesKHR.currentExtent.height : aY + aHeight;
664 mProjectionMatrix = aMatrix;
665 mFrustum = mProjectionMatrix * mViewMatrix;
666 mMatrices.WriteMemory ( 0,
sizeof (
float ) * 16, aMatrix.
GetMatrix4x4() );
671 mViewMatrix = aMatrix;
672 mFrustum = mProjectionMatrix * mViewMatrix;
673 mMatrices.WriteMemory (
sizeof (
float ) * 16,
sizeof (
float ) * 16, aMatrix.
GetMatrix4x4() );
678 return mProjectionMatrix;
691 void VulkanWindow::InitializeCommandBuffer()
693 VkCommandPoolCreateInfo command_pool_create_info{};
694 command_pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
700 command_pool_create_info.flags = 0;
701 command_pool_create_info.queueFamilyIndex = mVulkanRenderer.GetQueueFamilyIndex();
702 vkCreateCommandPool ( mVulkanRenderer.GetDevice(), &command_pool_create_info,
nullptr, &mVkCommandPool );
704 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
705 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
706 command_buffer_allocate_info.commandPool = mVkCommandPool;
707 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
708 command_buffer_allocate_info.commandBufferCount = 1;
709 vkAllocateCommandBuffers ( mVulkanRenderer.GetDevice(), &command_buffer_allocate_info, &mVkCommandBuffer );
712 void VulkanWindow::FinalizeCommandBuffer()
714 if ( mVkCommandPool != VK_NULL_HANDLE )
716 vkDestroyCommandPool ( mVulkanRenderer.GetDevice(), mVkCommandPool,
nullptr );
717 mVkCommandPool = VK_NULL_HANDLE;
723 if ( VkResult result = vkWaitForFences ( mVulkanRenderer.GetDevice(), 1,
725 VK_TRUE, UINT64_MAX ) )
729 if ( VkResult result = vkResetFences ( mVulkanRenderer.GetDevice(), 1,
734 if ( VkResult result = vkAcquireNextImageKHR (
735 mVulkanRenderer.GetDevice(),
740 const_cast<uint32_t *
> ( &mActiveImageIndex ) ) )
744 VkCommandBufferBeginInfo command_buffer_begin_info{};
745 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
746 command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
747 vkResetCommandPool ( mVulkanRenderer.GetDevice(), mVkCommandPool, 0 );
748 if ( VkResult result = vkBeginCommandBuffer ( mVkCommandBuffer, &command_buffer_begin_info ) )
753 vkCmdSetViewport ( mVkCommandBuffer, 0, 1, &mVkViewport );
754 vkCmdSetScissor ( mVkCommandBuffer, 0, 1, &mVkScissor );
758 std::array<VkClearValue, 2> clear_values{ { { {{0}} }, { {{0}} } } };
759 clear_values[0].color.float32[0] = 0.5f;
760 clear_values[0].color.float32[1] = 0.5f;
761 clear_values[0].color.float32[2] = 0.5f;
762 clear_values[0].color.float32[3] = 0.0f;
763 clear_values[1].depthStencil.depth = 1.0f;
764 clear_values[1].depthStencil.stencil = 0;
766 VkRenderPassBeginInfo render_pass_begin_info{};
767 render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
768 render_pass_begin_info.renderPass = mVkRenderPass;
769 render_pass_begin_info.framebuffer = mVkFramebuffers[mActiveImageIndex];
770 render_pass_begin_info.renderArea = mVkScissor;
771 render_pass_begin_info.clearValueCount =
static_cast<uint32_t
> ( clear_values.size() );
772 render_pass_begin_info.pClearValues = clear_values.data();
773 vkCmdBeginRenderPass ( mVkCommandBuffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE );
778 vkCmdEndRenderPass ( mVkCommandBuffer );
779 if ( VkResult result = vkEndCommandBuffer ( mVkCommandBuffer ) )
783 VkSubmitInfo submit_info{};
784 VkPipelineStageFlags wait_stages{ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
785 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
786 submit_info.waitSemaphoreCount = 1;
787 submit_info.pWaitSemaphores = &mVkAcquireSemaphore;
788 submit_info.pWaitDstStageMask = &wait_stages;
789 submit_info.commandBufferCount = 1;
790 submit_info.pCommandBuffers = &mVkCommandBuffer;
791 submit_info.signalSemaphoreCount = 1;
792 submit_info.pSignalSemaphores = &mVkSubmitSemaphores[mActiveImageIndex];
793 if ( VkResult result = vkQueueSubmit ( mVulkanRenderer.GetQueue(), 1, &submit_info, mVkFence ) )
797 std::array<VkResult, 1> result_array{ { VkResult::VK_SUCCESS } };
798 VkPresentInfoKHR present_info{};
799 present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
800 present_info.waitSemaphoreCount = 1;
801 present_info.pWaitSemaphores = &mVkSubmitSemaphores[mActiveImageIndex];
802 present_info.swapchainCount = 1;
803 present_info.pSwapchains = &mVkSwapchainKHR;
804 present_info.pImageIndices = &mActiveImageIndex;
805 present_info.pResults = result_array.data();
806 if ( VkResult result = vkQueuePresentKHR ( mVulkanRenderer.GetQueue(), &present_info ) )
810 mMemoryPoolBuffer.Reset();
813 static const std::unordered_map<Topology, VkPrimitiveTopology> TopologyMap
815 {
POINT_LIST, VK_PRIMITIVE_TOPOLOGY_POINT_LIST},
816 {LINE_STRIP, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP},
817 {
LINE_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST},
825 {
PATCH_LIST, VK_PRIMITIVE_TOPOLOGY_PATCH_LIST}
834 uint32_t aVertexStart,
835 uint32_t aVertexCount,
836 uint32_t aInstanceCount,
837 uint32_t aFirstInstance )
const
839 const VulkanPipeline* pipeline = mVulkanRenderer.GetVulkanPipeline ( aPipeline );
840 vkCmdBindPipeline ( mVkCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->
GetVkPipeline() );
841 vkCmdSetPrimitiveTopology ( mVkCommandBuffer, TopologyMap.at ( aTopology ) );
847 VK_PIPELINE_BIND_POINT_GRAPHICS,
851 &mMatricesDescriptorSet, 0,
nullptr );
854 if (
const VkPushConstantRange& push_constant_model_matrix = pipeline->
GetPushConstantModelMatrix() ; push_constant_model_matrix.size != 0 )
856 vkCmdPushConstants ( mVkCommandBuffer,
858 push_constant_model_matrix.stageFlags,
859 push_constant_model_matrix.offset, push_constant_model_matrix.size,
862 if ( aMaterial !=
nullptr )
864 mVulkanRenderer.GetVulkanMaterial ( *aMaterial )->Bind ( mVkCommandBuffer, *pipeline );
866 if ( aSkeleton !=
nullptr )
870 uint32_t offset =
static_cast<uint32_t
> ( aSkeleton->
GetOffset() );
874 VK_PIPELINE_BIND_POINT_GRAPHICS,
881 mVulkanRenderer.GetVulkanMesh ( aMesh )->Bind ( mVkCommandBuffer );
886 ( aVertexCount != 0xffffffff ) ? aVertexCount : aMesh.
GetIndexCount(),
896 ( aVertexCount != 0xffffffff ) ? aVertexCount : aMesh.
GetVertexCount(),
903 void VulkanWindow::FinalizeSurface()
905 if ( mVkSurfaceKHR != VK_NULL_HANDLE )
907 vkDestroySurfaceKHR ( mVulkanRenderer.GetInstance(), mVkSurfaceKHR,
nullptr );
908 mVkSurfaceKHR = VK_NULL_HANDLE;
912 void VulkanWindow::FinalizeSwapchain()
914 if ( mVkSwapchainKHR != VK_NULL_HANDLE )
916 vkDestroySwapchainKHR ( mVulkanRenderer.GetDevice(), mVkSwapchainKHR,
nullptr );
917 mVkSwapchainKHR = VK_NULL_HANDLE;
919 if ( mVkAcquireSemaphore != VK_NULL_HANDLE )
921 vkDestroySemaphore ( mVulkanRenderer.GetDevice(), mVkAcquireSemaphore,
nullptr );
922 std::cout << LogLevel::Debug <<
"Destroyed Acquire Semaphore " << std::hex << mVkAcquireSemaphore << std::endl;
923 mVkAcquireSemaphore = VK_NULL_HANDLE;
925 for (
auto& i : mVkSubmitSemaphores )
927 if ( i != VK_NULL_HANDLE )
929 vkDestroySemaphore ( mVulkanRenderer.GetDevice(), i,
nullptr );
930 std::cout << LogLevel::Debug <<
"Destroyed Submit Semaphore " << std::hex << i << std::endl;
933 mVkSubmitSemaphores.clear();
934 if ( mVkFence != VK_NULL_HANDLE )
936 vkDestroyFence ( mVulkanRenderer.GetDevice(), mVkFence,
nullptr );
937 mVkFence = VK_NULL_HANDLE;
941 void VulkanWindow::FinalizeImageViews()
943 for (
auto& i : mVkSwapchainImageViews )
945 if ( i != VK_NULL_HANDLE )
947 vkDestroyImageView ( mVulkanRenderer.GetDevice(), i,
nullptr );
953 void VulkanWindow::FinalizeDepthStencil()
955 if ( mVkDepthStencilImageView != VK_NULL_HANDLE )
957 vkDestroyImageView ( mVulkanRenderer.GetDevice(), mVkDepthStencilImageView,
nullptr );
958 mVkDepthStencilImageView = VK_NULL_HANDLE;
960 if ( mVkDepthStencilImage != VK_NULL_HANDLE )
962 vkDestroyImage ( mVulkanRenderer.GetDevice(), mVkDepthStencilImage,
nullptr );
963 mVkDepthStencilImage = VK_NULL_HANDLE;
965 if ( mVkDepthStencilImageMemory != VK_NULL_HANDLE )
967 vkFreeMemory ( mVulkanRenderer.GetDevice(), mVkDepthStencilImageMemory,
nullptr );
968 mVkDepthStencilImageMemory = VK_NULL_HANDLE;
972 void VulkanWindow::FinalizeFrameBuffers()
974 for (
auto& i : mVkFramebuffers )
976 if ( i != VK_NULL_HANDLE )
978 vkDestroyFramebuffer ( mVulkanRenderer.GetDevice(), i,
nullptr );
986 return mMemoryPoolBuffer.Allocate ( aSize );
991 return mVkRenderPass;
996 return mVkCommandBuffer;
Header for the axis aligned bounding box class.
Header for the frustum class.
Defines log severity levels and stream output for the AeonGames engine.
Header for the Scene class.
Provides access to a region within a memory pool buffer.
DLL const MemoryPoolBuffer * GetMemoryPoolBuffer() const
Get the underlying memory pool buffer.
DLL size_t GetOffset() const
Get the byte offset of this accessor within the memory pool buffer.
View frustum defined by six clipping planes, extracted from a projection (or view-projection) matrix.
Represents a surface material with uniform properties and texture samplers.
4 by 4 matrix in colum mayor order.
DLL const float *const GetMatrix4x4() const
Get a pointer to the internal matrix data.
Represents a polygon mesh with vertex attributes and index data.
@ MATRICES
Matrices binding.
@ SKELETON
Skeleton binding.
DLL uint32_t GetIndexCount() const
Get the total number of indices.
DLL uint32_t GetVertexCount() const
Get the total number of vertices.
Rendering pipeline resource.
Vulkan memory pool buffer for transient per-frame uniform allocations.
const VkDescriptorSet & GetDescriptorSet() const
Get the Vulkan descriptor set for this pool buffer.
Vulkan graphics pipeline with descriptor set and push constant reflection.
uint32_t GetDescriptorSetIndex(uint32_t hash) const
Get the descriptor set index for a given hash.
const VkPipeline GetVkPipeline() const
Get the Vulkan pipeline handle.
const VkPushConstantRange & GetPushConstantModelMatrix() const
Get the push constant range used for the model matrix.
const VkPipelineLayout GetPipelineLayout() const
Get the Vulkan pipeline layout handle.
Vulkan rendering backend implementing the Renderer interface.
VkRenderPass GetRenderPass() const
Get the Vulkan render pass for this window.
void SetViewMatrix(const Matrix4x4 &aMatrix)
Set the view matrix for this window.
VulkanWindow(VulkanRenderer &aVulkanRenderer, void *aWindowId)
Construct from a renderer and native window handle.
BufferAccessor AllocateSingleFrameUniformMemory(size_t aSize)
Allocate transient uniform memory for the current frame.
void EndRender()
End the current frame, submit commands, and present.
const Matrix4x4 & GetProjectionMatrix() const
Get the current projection matrix.
VkCommandBuffer GetCommandBuffer() const
Get the current command buffer being recorded.
void ResizeViewport(int32_t aX, int32_t aY, uint32_t aWidth, uint32_t aHeight)
Resize the rendering viewport.
void Render(const Matrix4x4 &aModelMatrix, const Mesh &aMesh, const Pipeline &aPipeline, const Material *aMaterial=nullptr, const BufferAccessor *aSkeleton=nullptr, Topology aTopology=Topology::TRIANGLE_LIST, uint32_t aVertexStart=0, uint32_t aVertexCount=0xffffffff, uint32_t aInstanceCount=1, uint32_t aFirstInstance=0) const
Render a mesh with the given pipeline, material, and transform.
const Frustum & GetFrustum() const
Get the view frustum derived from the current matrices.
const Matrix4x4 & GetViewMatrix() const
Get the current view matrix.
void SetProjectionMatrix(const Matrix4x4 &aMatrix)
Set the projection matrix for this window.
<- This is here just for the literals
VkDescriptorPool CreateDescriptorPool(const VkDevice &aVkDevice, const std::vector< VkDescriptorPoolSize > &aVkDescriptorPoolSizes)
Create a Vulkan descriptor pool from the given pool sizes.
void DestroyDescriptorPool(const VkDevice &aVkDevice, VkDescriptorPool aVkDescriptorPool)
Destroy a Vulkan descriptor pool.
const char * GetVulkanResultString(VkResult aResult)
Convert a VkResult code to a human-readable string.
Topology
Primitive topology types for rendering.
@ TRIANGLE_STRIP
Connected triangle strip.
@ PATCH_LIST
Patch list for tessellation.
@ LINE_LIST_WITH_ADJACENCY
Line list with adjacency information.
@ TRIANGLE_LIST_WITH_ADJACENCY
Triangle list with adjacency information.
@ POINT_LIST
List of individual points.
@ LINE_LIST
Pairs of vertices forming individual lines.
@ TRIANGLE_LIST
Independent triangles.
@ TRIANGLE_STRIP_WITH_ADJACENCY
Triangle strip with adjacency information.
@ TRIANGLE_FAN
Triangles sharing a common vertex.
@ LINE_STRIP_WITH_ADJACENCY
Line strip with adjacency information.
@ Info
General informational messages.
@ Debug
Detailed diagnostic information.
VkDescriptorSet CreateDescriptorSet(const VkDevice &aVkDevice, const VkDescriptorPool &aVkDescriptorPool, const VkDescriptorSetLayout &aVkDescriptorSetLayout, uint32_t aDescriptorSetCount)
Allocate a Vulkan descriptor set from the given pool and layout.