Choose depth buffer format; Log GPU memory usage

This commit is contained in:
Bailey Harrison 2023-03-21 14:18:59 +00:00
parent c462e873bc
commit b21dad41cd
8 changed files with 67 additions and 12 deletions

View File

@ -62,6 +62,8 @@ namespace engine {
uint64_t getFrameCount(); uint64_t getFrameCount();
void logPerformanceInfo();
// wait until all the active GPU queues have finished working // wait until all the active GPU queues have finished working
void waitIdle(); void waitIdle();

View File

@ -166,6 +166,7 @@ namespace engine {
if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] { if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] {
lastTick = now; lastTick = now;
LOG_INFO("fps: {}", m_window->getAvgFPS()); LOG_INFO("fps: {}", m_window->getAvgFPS());
gfx()->logPerformanceInfo();
m_window->resetAvgFPS(); m_window->resetAvgFPS();
} }

View File

@ -3,9 +3,13 @@
/* IMPORTANT INFORMATION /* IMPORTANT INFORMATION
* *
* When allocating memory with VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, always set a memory priority. * When allocating memory with VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, always set a memory priority.
* This feature uses the device extension VK_EXT_memory_priority. Depth buffers have a priority of 0.9f. * This feature uses the device extension VK_EXT_memory_priority. Depth buffers have a priority of 1.0f.
* Other, non-essential allocations will have a priority of 0.5f. * Other, non-essential allocations will have a priority of 0.5f.
* *
* Call vkResetCommandPool before reusing it in another frame.
* Otherwise, the pool will keep on growing until you run out of memory.
* - NVIDIA Vulkan Dos and Don'ts
*
*/ */
#include <assert.h> #include <assert.h>
@ -333,7 +337,7 @@ namespace engine {
}; };
DeviceRequirements deviceRequirements{}; DeviceRequirements deviceRequirements{};
deviceRequirements.requiredExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; deviceRequirements.requiredExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_EXT_MEMORY_BUDGET_EXTENSION_NAME };
deviceRequirements.optionalExtensions = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME }; deviceRequirements.optionalExtensions = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME };
deviceRequirements.requiredFeatures.samplerAnisotropy = VK_TRUE; deviceRequirements.requiredFeatures.samplerAnisotropy = VK_TRUE;
deviceRequirements.requiredFeatures.fillModeNonSolid = VK_TRUE; deviceRequirements.requiredFeatures.fillModeNonSolid = VK_TRUE;
@ -390,7 +394,7 @@ namespace engine {
pimpl->device = createDevice(pimpl->instance.instance, deviceRequirements, pimpl->surface); pimpl->device = createDevice(pimpl->instance.instance, deviceRequirements, pimpl->surface);
pimpl->allocator = createAllocator(pimpl->instance.instance, pimpl->device.device, pimpl->device.physicalDevice); pimpl->allocator = createAllocator(pimpl->instance.instance, pimpl->device);
pimpl->swapchainInfo.device = pimpl->device.device; pimpl->swapchainInfo.device = pimpl->device.device;
pimpl->swapchainInfo.allocator = pimpl->allocator; pimpl->swapchainInfo.allocator = pimpl->allocator;
@ -512,6 +516,8 @@ namespace engine {
const uint32_t currentFrameIndex = pimpl->FRAMECOUNT % FRAMES_IN_FLIGHT; const uint32_t currentFrameIndex = pimpl->FRAMECOUNT % FRAMES_IN_FLIGHT;
const FrameData frameData = pimpl->frameData[currentFrameIndex]; const FrameData frameData = pimpl->frameData[currentFrameIndex];
vmaSetCurrentFrameIndex(pimpl->allocator, (uint32_t)pimpl->FRAMECOUNT);
/* wait until the previous frame RENDERING has finished */ /* wait until the previous frame RENDERING has finished */
res = vkWaitForFences(pimpl->device.device, 1, &frameData.renderFence, VK_TRUE, 1000000000LL); res = vkWaitForFences(pimpl->device.device, 1, &frameData.renderFence, VK_TRUE, 1000000000LL);
VKCHECK(res); VKCHECK(res);
@ -1252,6 +1258,32 @@ namespace engine {
(void)texture; (void)texture;
} }
void GFXDevice::logPerformanceInfo()
{
VmaTotalStatistics pStats{};
vmaCalculateStatistics(pimpl->allocator, &pStats);
VkPhysicalDeviceMemoryProperties2 memProps{};
memProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
vkGetPhysicalDeviceMemoryProperties2(pimpl->device.physicalDevice, &memProps);
LOG_INFO("GPU Memory Statistics:");
for (uint32_t i = 0; i < memProps.memoryProperties.memoryHeapCount; i++) {
const VmaStatistics& statistics = pStats.memoryType[i].statistics;
VkMemoryHeap heap = memProps.memoryProperties.memoryHeaps[i];
if (statistics.allocationCount > 0) {
LOG_INFO("Memory heap {}", i);
LOG_INFO(" Memory blocks allocated: {} ({} MiB)", statistics.blockCount, statistics.allocationBytes / (1024 * 1024));
LOG_INFO(" Number of allocations: {} ({} MiB)", statistics.allocationCount, statistics.allocationBytes / (1024 * 1024));
LOG_INFO(" Max size: {} MiB", heap.size / (1024 * 1024));
if (heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) {
LOG_INFO(" DEVICE_LOCAL");
}
}
}
}
uint64_t GFXDevice::getFrameCount() uint64_t GFXDevice::getFrameCount()
{ {
return pimpl->FRAMECOUNT; return pimpl->FRAMECOUNT;

View File

@ -12,7 +12,7 @@
namespace engine { namespace engine {
VmaAllocator createAllocator(VkInstance instance, VkDevice device, VkPhysicalDevice physicalDevice) VmaAllocator createAllocator(VkInstance instance, const Device& device)
{ {
VmaVulkanFunctions functions{ VmaVulkanFunctions functions{
.vkGetInstanceProcAddr = nullptr, .vkGetInstanceProcAddr = nullptr,
@ -44,9 +44,9 @@ namespace engine {
}; };
VmaAllocatorCreateInfo createInfo{ VmaAllocatorCreateInfo createInfo{
.flags = VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT, .flags = VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT,
.physicalDevice = physicalDevice, .physicalDevice = device.physicalDevice,
.device = device, .device = device.device,
.preferredLargeHeapBlockSize = 0, .preferredLargeHeapBlockSize = 0,
.pAllocationCallbacks = nullptr, .pAllocationCallbacks = nullptr,
.pDeviceMemoryCallbacks = nullptr, .pDeviceMemoryCallbacks = nullptr,
@ -57,6 +57,11 @@ namespace engine {
.pTypeExternalMemoryHandleTypes = nullptr .pTypeExternalMemoryHandleTypes = nullptr
}; };
if (std::find(device.enabledExtensions.begin(), device.enabledExtensions.end(),
std::string(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME)) != device.enabledExtensions.end()) {
createInfo.flags |= VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT;
}
[[maybe_unused]] VkResult res; [[maybe_unused]] VkResult res;
VmaAllocator allocator; VmaAllocator allocator;
res = vmaCreateAllocator(&createInfo, &allocator); res = vmaCreateAllocator(&createInfo, &allocator);

View File

@ -1,9 +1,11 @@
#pragma once #pragma once
#include <vk_mem_alloc.h> #include <vk_mem_alloc.h>
#include "device.h"
namespace engine { namespace engine {
VmaAllocator createAllocator(VkInstance instance, VkDevice device, VkPhysicalDevice physicalDevice); VmaAllocator createAllocator(VkInstance instance, const Device& device);
void destroyAllocator(VmaAllocator allocator); void destroyAllocator(VmaAllocator allocator);
} }

View File

@ -98,7 +98,20 @@ namespace engine {
sc->extent = oldExtent; sc->extent = oldExtent;
} }
/* TODO: delete old framebuffers and image views */ /* find depth stencil format to use */
VkFormatProperties2 formatProperties{};
formatProperties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
vkGetPhysicalDeviceFormatProperties2(info.physicalDevice, VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties);
if (formatProperties.formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
sc->depthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
} else {
vkGetPhysicalDeviceFormatProperties2(info.physicalDevice, VK_FORMAT_D16_UNORM, &formatProperties);
if (formatProperties.formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
sc->depthStencilFormat = VK_FORMAT_D16_UNORM;
} else {
throw std::runtime_error("Failed to find suitable depth-buffer image format!");
}
}
/* create swapchain */ /* create swapchain */
@ -286,7 +299,7 @@ namespace engine {
VmaAllocationCreateInfo depthAllocInfo{}; VmaAllocationCreateInfo depthAllocInfo{};
depthAllocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; depthAllocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
depthAllocInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; depthAllocInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
depthAllocInfo.priority = 0.9f; depthAllocInfo.priority = 1.0f;
res = vmaCreateImage(sc->allocator, &depthImageInfo, &depthAllocInfo, &depthImage, &depthAllocation, nullptr); res = vmaCreateImage(sc->allocator, &depthImageInfo, &depthAllocInfo, &depthImage, &depthAllocation, nullptr);
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create depth buffer image! Code: " + std::to_string(res)); if (res != VK_SUCCESS) throw std::runtime_error("Failed to create depth buffer image! Code: " + std::to_string(res));

View File

@ -26,7 +26,7 @@ namespace engine {
VkPresentModeKHR presentMode{}; VkPresentModeKHR presentMode{};
VkExtent2D extent{}; VkExtent2D extent{};
VkRenderPass renderpass = VK_NULL_HANDLE; VkRenderPass renderpass = VK_NULL_HANDLE;
const VkFormat depthStencilFormat = VK_FORMAT_D16_UNORM; VkFormat depthStencilFormat;
std::vector<std::pair<VkImage, VkImageView>> swapchainImages{}; std::vector<std::pair<VkImage, VkImageView>> swapchainImages{};
std::vector<DepthStencil> depthImages{}; std::vector<DepthStencil> depthImages{};
std::vector<VkFramebuffer> framebuffers{}; std::vector<VkFramebuffer> framebuffers{};

View File

@ -56,7 +56,7 @@ void playGame(GameSettings settings)
app.setFrameLimiter(settings.enableFrameLimiter); app.setFrameLimiter(settings.enableFrameLimiter);
// configure window // configure window
//app.window()->setRelativeMouseMode(true); app.window()->setRelativeMouseMode(true);
configureInputs(app.inputManager()); configureInputs(app.inputManager());