Skip to content

Commit

Permalink
various hacks to make rendering work again
Browse files Browse the repository at this point in the history
  • Loading branch information
tannergooding committed Oct 22, 2021
1 parent 2801f7b commit ba95f05
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 53 deletions.
14 changes: 14 additions & 0 deletions .vs/tasks.vs.json
Expand Up @@ -9,6 +9,20 @@
"args": [
"cd build & conan install .. --build=missing --profile windows-vs2019-amd64"
]
},
{
"taskLabel": "conan install windows-vs2022-amd64",
"appliesTo": "conanfile.py",
"type": "launch",
"command": "${env.COMSPEC}",
"args": [
"cd build & conan install .. --build=missing --profile windows-vs2022-amd64"
]
},
{
"taskLabel": "task-conanfile",
"appliesTo": "conanfile.py",
"type": "launch"
}
]
}
25 changes: 12 additions & 13 deletions include/NovelRT/Experimental/Graphics/Vulkan/VulkanGraphicsDevice.h
Expand Up @@ -21,17 +21,17 @@ namespace NovelRT::Experimental::Graphics::Vulkan

VkSurfaceKHR _surface;

VkDevice _device;
NovelRT::Utilities::Lazy<VkDevice> _device;

VkQueue _graphicsQueue;
VkQueue _presentQueue;

VkSwapchainKHR _vulkanSwapchain;
std::vector<VkImage> _swapChainImages;
size_t _contextIndex;
VkFormat _vulkanSwapChainFormat;
VkExtent2D _swapChainExtent;

NovelRT::Utilities::Lazy<VkSwapchainKHR> _vulkanSwapchain;
NovelRT::Utilities::Lazy<std::vector<VkImage>> _swapChainImages;
NovelRT::Utilities::Lazy<VkRenderPass> _renderPass;
NovelRT::Utilities::Lazy<std::shared_ptr<VulkanGraphicsMemoryAllocator>> _memoryAllocator;

Expand All @@ -43,11 +43,9 @@ namespace NovelRT::Experimental::Graphics::Vulkan
[[nodiscard]] std::shared_ptr<VulkanGraphicsMemoryAllocator> CreateMemoryAllocator();
void OnGraphicsSurfaceSizeChanged(Maths::GeoVector2F newSize);

void Initialise();

[[nodiscard]] std::vector<std::string> GetFinalPhysicalDeviceExtensionSet() const;

void CreateLogicalDevice();
VkDevice CreateLogicalDevice();

[[nodiscard]] VkSurfaceFormatKHR ChooseSwapSurfaceFormat(
const std::vector<VkSurfaceFormatKHR>& availableFormats) const noexcept;
Expand All @@ -56,7 +54,8 @@ namespace NovelRT::Experimental::Graphics::Vulkan
const std::vector<VkPresentModeKHR>& availablePresentModes) const noexcept;
[[nodiscard]] VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) const noexcept;

void CreateSwapChain();
VkSwapchainKHR CreateSwapChain();
std::vector<VkImage> GetSwapChainImages();

VkRenderPass CreateRenderPass();

Expand Down Expand Up @@ -128,9 +127,9 @@ namespace NovelRT::Experimental::Graphics::Vulkan
gsl::span<GraphicsPipelineInput> inputs = gsl::span<GraphicsPipelineInput>{},
gsl::span<GraphicsPipelineResource> resources = gsl::span<GraphicsPipelineResource>{}) final;

[[nodiscard]] inline VkSwapchainKHR GetVulkanSwapchain() const noexcept
[[nodiscard]] inline VkSwapchainKHR GetVulkanSwapchain()
{
return _vulkanSwapchain;
return _vulkanSwapchain.getActual();
}

[[nodiscard]] inline VkQueue GetVulkanPresentQueue() const noexcept
Expand All @@ -143,9 +142,9 @@ namespace NovelRT::Experimental::Graphics::Vulkan
return _graphicsQueue;
}

[[nodiscard]] inline VkDevice GetVulkanDevice() const noexcept
[[nodiscard]] inline VkDevice GetVulkanDevice()
{
return _device;
return _device.getActual();
}

[[nodiscard]] inline VkRenderPass GetVulkanRenderPass()
Expand All @@ -163,9 +162,9 @@ namespace NovelRT::Experimental::Graphics::Vulkan
return _indicesData;
}

[[nodiscard]] inline const std::vector<VkImage>& GetVulkanSwapChainImages() const noexcept
[[nodiscard]] inline const std::vector<VkImage>& GetVulkanSwapChainImages()
{
return _swapChainImages;
return _swapChainImages.getActual();
}

[[nodiscard]] inline VkFormat GetVulkanSwapChainFormat() const noexcept
Expand Down
2 changes: 1 addition & 1 deletion include/NovelRT/Utilities/Misc.h
Expand Up @@ -11,7 +11,7 @@
#if defined(NDEBUG)
#define unused(x) (void)(x)
#else
#define unused(x) (void)(0)
#define unused(x) (void)(x)
#endif

namespace NovelRT::Utilities
Expand Down
4 changes: 2 additions & 2 deletions samples/Experimental/VulkanRender/main.cpp
Expand Up @@ -38,7 +38,7 @@ struct TexturedVertex
int main()
{
NovelRT::EngineConfig::EnableDebugOutputFromEngineInternals() = true;
NovelRT::EngineConfig::MinimumInternalLoggingLevel() = NovelRT::LogLevel::Warn;
NovelRT::EngineConfig::MinimumInternalLoggingLevel() = NovelRT::LogLevel::Debug;

auto device = std::shared_ptr<IWindowingDevice>(new GlfwWindowingDevice());

Expand All @@ -52,7 +52,7 @@ int main()

std::shared_ptr<GraphicsAdapter> adapter = selector.GetDefaultRecommendedAdapter(vulkanProvider, surfaceContext);

auto gfxDevice = adapter->CreateDevice(surfaceContext, 1);
auto gfxDevice = adapter->CreateDevice(surfaceContext, 2);
auto gfxContext = gfxDevice->GetCurrentContext();

auto vertShaderData = LoadSpv("vert.spv");
Expand Down
Expand Up @@ -213,7 +213,6 @@ namespace NovelRT::Experimental::Graphics::Vulkan
_vulkanSwapChainImageView([&]() { return CreateVulkanSwapChainImageView(); })
{
static_cast<void>(_state.Transition(Threading::VolatileState::Initialised));
_waitForExecuteCompletionFence->Reset();
}

void VulkanGraphicsContext::BeginDrawing(NovelRT::Graphics::RGBAColour backgroundColour)
Expand Down
103 changes: 72 additions & 31 deletions src/NovelRT/Experimental/Graphics/Vulkan/VulkanGraphicsDevice.cpp
Expand Up @@ -29,11 +29,11 @@ namespace NovelRT::Experimental::Graphics::Vulkan
}),
_logger(LoggingService(NovelRT::Utilities::Misc::CONSOLE_LOG_GFX)),
_surface(GetSurfaceContext()->GetVulkanSurfaceContextHandle()),
_device(VK_NULL_HANDLE),
_device([&]() { return CreateLogicalDevice(); }),
_graphicsQueue(VK_NULL_HANDLE),
_presentQueue(VK_NULL_HANDLE),
_vulkanSwapchain(VK_NULL_HANDLE),
_swapChainImages(std::vector<VkImage>{}),
_vulkanSwapchain([&]() { return CreateSwapChain(); }),
_swapChainImages([&]() { return GetSwapChainImages(); }),
_contextIndex(0),
_vulkanSwapChainFormat(VkFormat{}),
_swapChainExtent(VkExtent2D{}),
Expand All @@ -43,7 +43,6 @@ namespace NovelRT::Experimental::Graphics::Vulkan
_state()
{
_logger.logInfoLine("Provided GPU device: " + GetAdapter()->GetName());
Initialise();
static_cast<void>(_state.Transition(Threading::VolatileState::Initialised));
// TODO: This gonna be an issue...?
GetSurface()->SizeChanged += [&](auto args) { OnGraphicsSurfaceSizeChanged(args); };
Expand Down Expand Up @@ -123,8 +122,10 @@ namespace NovelRT::Experimental::Graphics::Vulkan
return allExtensions;
}

void VulkanGraphicsDevice::CreateLogicalDevice()
VkDevice VulkanGraphicsDevice::CreateLogicalDevice()
{
VkDevice device;

_indicesData = Utilities::FindQueueFamilies(GetAdapter()->GetVulkanPhysicalDevice(), _surface);

std::vector<VkDeviceQueueCreateInfo> queueCreateInfos{};
Expand Down Expand Up @@ -168,17 +169,18 @@ namespace NovelRT::Experimental::Graphics::Vulkan
createInfo.enabledLayerCount = 0;
}

VkResult deviceResult = vkCreateDevice(GetAdapter()->GetVulkanPhysicalDevice(), &createInfo, nullptr, &_device);
VkResult deviceResult = vkCreateDevice(GetAdapter()->GetVulkanPhysicalDevice(), &createInfo, nullptr, &device);

if (deviceResult != VK_SUCCESS)
{
throw Exceptions::InitialisationFailureException("Failed to initialise the VkDevice.", deviceResult);
}

vkGetDeviceQueue(_device, _indicesData.graphicsFamily.value(), 0, &_graphicsQueue);
vkGetDeviceQueue(_device, _indicesData.presentFamily.value(), 0, &_presentQueue);
vkGetDeviceQueue(device, _indicesData.graphicsFamily.value(), 0, &_graphicsQueue);
vkGetDeviceQueue(device, _indicesData.presentFamily.value(), 0, &_presentQueue);

_logger.logInfoLine("VkDevice successfully created.");
return device;
}

VkSurfaceFormatKHR VulkanGraphicsDevice::ChooseSwapSurfaceFormat(
Expand Down Expand Up @@ -241,8 +243,10 @@ namespace NovelRT::Experimental::Graphics::Vulkan
return actualExtent;
}

void VulkanGraphicsDevice::CreateSwapChain()
VkSwapchainKHR VulkanGraphicsDevice::CreateSwapChain()
{
VkSwapchainKHR vulkanSwapchain;

SwapChainSupportDetails swapChainSupport = Utilities::QuerySwapChainSupport(
GetAdapter()->GetVulkanPhysicalDevice(), GetSurfaceContext()->GetVulkanSurfaceContextHandle());

Expand Down Expand Up @@ -289,49 +293,74 @@ namespace NovelRT::Experimental::Graphics::Vulkan
createInfo.clipped = VK_TRUE;
createInfo.oldSwapchain = VK_NULL_HANDLE;

VkResult swapChainResult = vkCreateSwapchainKHR(_device, &createInfo, nullptr, &_vulkanSwapchain);
VkResult swapChainResult = vkCreateSwapchainKHR(GetVulkanDevice(), &createInfo, nullptr, &vulkanSwapchain);
if (swapChainResult != VK_SUCCESS)
{
throw Exceptions::InitialisationFailureException("Failed to create the VkSwapchainKHR.", swapChainResult);
}

_logger.logInfoLine("VkSwapchainKHR successfully created. Retrieving VkImages...");
_vulkanSwapChainFormat = surfaceFormat.format;
_swapChainExtent = extent;

_logger.logInfoLine("VkSwapchainKHR successfully created.");
return vulkanSwapchain;
}

VkResult imagesKHRQuery = vkGetSwapchainImagesKHR(_device, _vulkanSwapchain, &imageCount, nullptr);
std::vector<VkImage> VulkanGraphicsDevice::GetSwapChainImages()
{
VkDevice device = GetVulkanDevice();
VkSwapchainKHR vulkanSwapchain = GetVulkanSwapchain();

uint32_t imageCount;
VkResult imagesKHRQuery = vkGetSwapchainImagesKHR(device, vulkanSwapchain, &imageCount, nullptr);

if (imagesKHRQuery != VK_SUCCESS)
{
throw Exceptions::InitialisationFailureException("Failed to retrieve the VkImages from the VkSwapchainKHR.",
imagesKHRQuery);
}

_swapChainImages.resize(imageCount);
imagesKHRQuery = vkGetSwapchainImagesKHR(_device, _vulkanSwapchain, &imageCount, _swapChainImages.data());
std::vector<VkImage> swapChainImages = std::vector<VkImage>(imageCount);
imagesKHRQuery = vkGetSwapchainImagesKHR(device, vulkanSwapchain, &imageCount, swapChainImages.data());

if (imagesKHRQuery != VK_SUCCESS)
{
throw Exceptions::InitialisationFailureException("Failed to retrieve the VkImages from the VkSwapchainKHR.",
imagesKHRQuery);
}

_vulkanSwapChainFormat = surfaceFormat.format;
_swapChainExtent = extent;
auto presentCompletionGraphicsFence = GetPresentCompletionFence();

_logger.logInfoLine("VkImages successfully retrieved.");
}
uint32_t contextIndex;
VkResult acquireNextImageResult =
vkAcquireNextImageKHR(GetVulkanDevice(), vulkanSwapchain, std::numeric_limits<uint64_t>::max(),
VK_NULL_HANDLE, presentCompletionGraphicsFence->GetVulkanFence(), &contextIndex);

void VulkanGraphicsDevice::Initialise()
{
CreateLogicalDevice();
CreateSwapChain();
if (acquireNextImageResult != VK_SUCCESS)
{
throw std::runtime_error("Failed to acquire next VkImage! Reason: " +
std::to_string(acquireNextImageResult));
}
_contextIndex = contextIndex;

presentCompletionGraphicsFence->Wait();
presentCompletionGraphicsFence->Reset();

_logger.logInfoLine("Vulkan logical device version 1.2 has been successfully initialised.");
_logger.logInfoLine("VkImages successfully retrieved.");
return swapChainImages;
}

void VulkanGraphicsDevice::TearDown()
{
vkDestroySwapchainKHR(_device, _vulkanSwapchain, nullptr);
vkDestroyDevice(_device, nullptr);
if (_vulkanSwapchain.isCreated())
{
vkDestroySwapchainKHR(GetVulkanDevice(), GetVulkanSwapchain(), nullptr);
}

if (_device.isCreated())
{
vkDestroyDevice(GetVulkanDevice(), nullptr);
}

_logger.logInfoLine("Vulkan logical device version 1.2 successfully torn down.");
}
Expand Down Expand Up @@ -374,6 +403,10 @@ namespace NovelRT::Experimental::Graphics::Vulkan
{
VkRenderPass returnRenderPass;

// The swap chain needs to be created first to ensure we know the format
auto vulkanSwapchain = GetVulkanSwapchain();
unused(vulkanSwapchain);

VkAttachmentDescription attachmentDescription{};
attachmentDescription.format = _vulkanSwapChainFormat;
attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT;
Expand All @@ -397,7 +430,8 @@ namespace NovelRT::Experimental::Graphics::Vulkan
renderPassCreateInfo.subpassCount = 1;
renderPassCreateInfo.pSubpasses = &subpass;

VkResult renderPassResult = vkCreateRenderPass(_device, &renderPassCreateInfo, nullptr, &returnRenderPass);
VkResult renderPassResult =
vkCreateRenderPass(GetVulkanDevice(), &renderPassCreateInfo, nullptr, &returnRenderPass);

if (renderPassResult != VK_SUCCESS)
{
Expand Down Expand Up @@ -483,7 +517,7 @@ namespace NovelRT::Experimental::Graphics::Vulkan

void VulkanGraphicsDevice::WaitForIdle()
{
VkResult waitForIdleResult = vkDeviceWaitIdle(_device);
VkResult waitForIdleResult = vkDeviceWaitIdle(GetVulkanDevice());

if (waitForIdleResult != VK_SUCCESS)
{
Expand All @@ -501,10 +535,17 @@ namespace NovelRT::Experimental::Graphics::Vulkan
{
WaitForIdle();

_swapChainImages = GetVulkanSwapChainImages();
vkDestroySwapchainKHR(GetVulkanDevice(), _vulkanSwapchain, nullptr);
CreateSwapChain();
_contextIndex = 0;
if (_swapChainImages.isCreated())
{
_swapChainImages.reset();
}

if (_vulkanSwapchain.isCreated())
{
vkDestroySwapchainKHR(GetVulkanDevice(), GetVulkanSwapchain(), nullptr);
_vulkanSwapchain.reset();
_contextIndex = 0;
}

for (auto&& context : _contexts.getActual())
{
Expand Down
Expand Up @@ -68,6 +68,12 @@ namespace NovelRT::Experimental::Graphics::Vulkan
continue;
}

if (memoryProperties.memoryHeaps[memoryProperties.memoryTypes[i].heapIndex].flags &
VK_MEMORY_HEAP_MULTI_INSTANCE_BIT)
{
continue;
}

int32_t cost =
Maths::Utilities::PopCount(static_cast<uint32_t>(preferredMemoryPropertyFlags) & ~memoryPropertyFlags) +
Maths::Utilities::PopCount(static_cast<uint32_t>(unpreferredMemoryPropertyFlags) &
Expand Down

0 comments on commit ba95f05

Please sign in to comment.