Compare commits
6 commits
master
...
refactor_c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d36517b4f | ||
|
|
b5c6774412 | ||
|
|
61931083c6 | ||
|
|
35198bce6b | ||
|
|
4f7ab6db68 | ||
|
|
d1d57ab682 |
13 changed files with 547 additions and 583 deletions
|
|
@ -1,34 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include <nlohmann/json_fwd.hpp>
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#define ENROLL_COMPONENT(COMPONENT, ...) \
|
|
||||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(COMPONENT, __VA_ARGS__); \
|
|
||||||
template <> struct NameOf<COMPONENT> { \
|
|
||||||
static constexpr const char *name = #COMPONENT; \
|
|
||||||
};
|
|
||||||
|
|
||||||
// partial specialization (full specialization works too)
|
|
||||||
namespace nlohmann {
|
|
||||||
template <typename T>
|
|
||||||
struct adl_serializer<std::optional<T>> {
|
|
||||||
static void to_json(json& j, const std::optional<T>& opt) {
|
|
||||||
if (opt == std::nullopt) {
|
|
||||||
j = nullptr;
|
|
||||||
} else {
|
|
||||||
j = *opt; // this will call adl_serializer<T>::to_json which will
|
|
||||||
// find the free function to_json in T's namespace!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void from_json(const json& j, std::optional<T>& opt) {
|
|
||||||
if (j.is_null() || j == false) {
|
|
||||||
opt = std::nullopt;
|
|
||||||
} else {
|
|
||||||
opt = std::make_optional<T>(j.template get<T>());
|
|
||||||
// same as above, but with adl_serializer<T>::from_json
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -104,7 +104,6 @@ else
|
||||||
})
|
})
|
||||||
endif
|
endif
|
||||||
|
|
||||||
json = subproject('nlohmann_json').get_variable('nlohmann_json_dep')
|
|
||||||
vkbootstrap_proj = cmake.subproject('vk-bootstrap', options: vk_opts)
|
vkbootstrap_proj = cmake.subproject('vk-bootstrap', options: vk_opts)
|
||||||
vkbootstrap = vkbootstrap_proj.get_variable('vk_bootstrap_dep')
|
vkbootstrap = vkbootstrap_proj.get_variable('vk_bootstrap_dep')
|
||||||
|
|
||||||
|
|
@ -114,7 +113,6 @@ dependencies += [
|
||||||
glm,
|
glm,
|
||||||
imgui,
|
imgui,
|
||||||
sdl2,
|
sdl2,
|
||||||
json,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
|
|
@ -123,6 +121,7 @@ sources = [
|
||||||
'vk_images.cpp',
|
'vk_images.cpp',
|
||||||
'vk_descriptors.cpp',
|
'vk_descriptors.cpp',
|
||||||
'vk_pipelines.cpp',
|
'vk_pipelines.cpp',
|
||||||
|
'vk_gui.cpp',
|
||||||
'main.cpp',
|
'main.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#include "vk_types.h"
|
|
||||||
#include "json_mods.hpp"
|
|
||||||
|
|
||||||
template <typename T> struct NameOf;
|
|
||||||
|
|
||||||
ENROLL_COMPONENT(VkSemaphoreCreateInfo, sType);
|
|
||||||
ENROLL_COMPONENT(VkFenceCreateInfo, sType);
|
|
||||||
ENROLL_COMPONENT(VkImageViewCreateInfo, sType, viewType, subresourceRange.baseMipLevel, subresourceRange.levelCount, subresourceRange.baseArrayLayer, subresourceRange.layerCount);
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
void DescriptorLayoutBuilder::add_binding(uint32_t binding, VkDescriptorType type)
|
void DescriptorLayoutBuilder::add_binding(uint32_t binding, VkDescriptorType type)
|
||||||
{
|
{
|
||||||
|
VkDescriptorSetLayoutBinding newbind{
|
||||||
VkDescriptorSetLayoutBinding newbind {};
|
.binding = binding,
|
||||||
newbind.binding = binding;
|
.descriptorType = type,
|
||||||
newbind.descriptorCount = 1;
|
.descriptorCount = 1,
|
||||||
newbind.descriptorType = type;
|
};
|
||||||
|
|
||||||
bindings.push_back(newbind);
|
bindings.push_back(newbind);
|
||||||
}
|
}
|
||||||
|
|
@ -25,18 +25,16 @@ VkDescriptorSetLayout DescriptorLayoutBuilder::build(VkDevice device,
|
||||||
b.stageFlags |= shaderStages;
|
b.stageFlags |= shaderStages;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo info = {
|
VkDescriptorSetLayoutCreateInfo info{
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||||
|
.pNext = pNext,
|
||||||
|
.flags = flags,
|
||||||
|
.bindingCount = (uint32_t)bindings.size(),
|
||||||
|
.pBindings = bindings.data(),
|
||||||
};
|
};
|
||||||
info.pNext = pNext;
|
|
||||||
|
|
||||||
info.pBindings = bindings.data();
|
|
||||||
info.bindingCount = (uint32_t)bindings.size();
|
|
||||||
info.flags = flags;
|
|
||||||
|
|
||||||
VkDescriptorSetLayout set;
|
VkDescriptorSetLayout set;
|
||||||
VK_CHECK(vkCreateDescriptorSetLayout(device,
|
VK_CHECK(vkCreateDescriptorSetLayout(device, &info, nullptr, &set));
|
||||||
&info, nullptr, &set));
|
|
||||||
|
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
@ -46,19 +44,19 @@ void DescriptorAllocator::init_pool(VkDevice device, uint32_t maxSets,
|
||||||
{
|
{
|
||||||
std::vector<VkDescriptorPoolSize> poolSizes;
|
std::vector<VkDescriptorPoolSize> poolSizes;
|
||||||
for(PoolSizeRatio ratio : poolRatios) {
|
for(PoolSizeRatio ratio : poolRatios) {
|
||||||
poolSizes.push_back(VkDescriptorPoolSize{
|
poolSizes.push_back({
|
||||||
.type = ratio.type,
|
.type = ratio.type,
|
||||||
.descriptorCount = uint32_t(ratio.ratio * maxSets)
|
.descriptorCount = uint32_t(ratio.ratio * maxSets)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorPoolCreateInfo pool_info = {
|
VkDescriptorPoolCreateInfo pool_info{
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||||
|
.flags = 0,
|
||||||
|
.maxSets = maxSets,
|
||||||
|
.poolSizeCount = (uint32_t)poolSizes.size(),
|
||||||
|
.pPoolSizes = poolSizes.data(),
|
||||||
};
|
};
|
||||||
pool_info.flags = 0;
|
|
||||||
pool_info.maxSets = maxSets;
|
|
||||||
pool_info.poolSizeCount = (uint32_t)poolSizes.size();
|
|
||||||
pool_info.pPoolSizes = poolSizes.data();
|
|
||||||
|
|
||||||
vkCreateDescriptorPool(device, &pool_info, nullptr, &pool);
|
vkCreateDescriptorPool(device, &pool_info, nullptr, &pool);
|
||||||
}
|
}
|
||||||
|
|
@ -75,15 +73,13 @@ void DescriptorAllocator::destroy_pool(VkDevice device)
|
||||||
|
|
||||||
VkDescriptorSet DescriptorAllocator::allocate(VkDevice device, VkDescriptorSetLayout layout)
|
VkDescriptorSet DescriptorAllocator::allocate(VkDevice device, VkDescriptorSetLayout layout)
|
||||||
{
|
{
|
||||||
VkDescriptorSetAllocateInfo allocInfo = {
|
VkDescriptorSetAllocateInfo allocInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||||
|
.descriptorPool = pool,
|
||||||
|
.descriptorSetCount = 1,
|
||||||
|
.pSetLayouts = &layout,
|
||||||
};
|
};
|
||||||
|
|
||||||
allocInfo.pNext = nullptr;
|
|
||||||
allocInfo.descriptorPool = pool;
|
|
||||||
allocInfo.descriptorSetCount = 1;
|
|
||||||
allocInfo.pSetLayouts = &layout;
|
|
||||||
|
|
||||||
VkDescriptorSet ds;
|
VkDescriptorSet ds;
|
||||||
VK_CHECK(vkAllocateDescriptorSets(device, &allocInfo, &ds));
|
VK_CHECK(vkAllocateDescriptorSets(device, &allocInfo, &ds));
|
||||||
|
|
||||||
|
|
|
||||||
460
vk_engine.cpp
460
vk_engine.cpp
|
|
@ -3,23 +3,18 @@
|
||||||
#include "vk_pipelines.h"
|
#include "vk_pipelines.h"
|
||||||
#include <print>
|
#include <print>
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
#include <SDL_vulkan.h>
|
|
||||||
|
|
||||||
#include <vk_types.h>
|
#include <vk_types.h>
|
||||||
#include <vk_initializers.h>
|
#include <vk_initializers.h>
|
||||||
#include "VkBootstrap.h"
|
#include "VkBootstrap.h"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "imgui.h"
|
#include <SDL_vulkan.h>
|
||||||
#include "imgui_impl_sdl2.h"
|
|
||||||
#include "imgui_impl_vulkan.h"
|
|
||||||
|
|
||||||
#define VMA_IMPLEMENTATION
|
#define VMA_IMPLEMENTATION
|
||||||
#include "vk_mem_alloc.h"
|
#include "vk_mem_alloc.h"
|
||||||
|
|
||||||
constexpr bool bUseValidationLayers = false;
|
constexpr bool bUseValidationLayers = true;
|
||||||
|
|
||||||
VulkanEngine* loadedEngine = nullptr;
|
VulkanEngine* loadedEngine = nullptr;
|
||||||
|
|
||||||
|
|
@ -32,18 +27,7 @@ void VulkanEngine::init()
|
||||||
assert(loadedEngine == nullptr);
|
assert(loadedEngine == nullptr);
|
||||||
loadedEngine = this;
|
loadedEngine = this;
|
||||||
|
|
||||||
// We initialize SDL and create a window with it.
|
_window = _gui.init_window(_windowExtent);
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
|
||||||
|
|
||||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN);
|
|
||||||
|
|
||||||
_window = SDL_CreateWindow(
|
|
||||||
"Vulkan Engine",
|
|
||||||
SDL_WINDOWPOS_UNDEFINED,
|
|
||||||
SDL_WINDOWPOS_UNDEFINED,
|
|
||||||
int(_windowExtent.width),
|
|
||||||
int(_windowExtent.height),
|
|
||||||
window_flags);
|
|
||||||
|
|
||||||
init_vulkan();
|
init_vulkan();
|
||||||
init_swapchain();
|
init_swapchain();
|
||||||
|
|
@ -51,7 +35,7 @@ void VulkanEngine::init()
|
||||||
init_sync_structures();
|
init_sync_structures();
|
||||||
init_descriptors();
|
init_descriptors();
|
||||||
init_pipelines();
|
init_pipelines();
|
||||||
init_imgui();
|
_gui.init_imgui(VulkanEngine::Get());
|
||||||
|
|
||||||
//everything went fine
|
//everything went fine
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
|
|
@ -81,14 +65,14 @@ void VulkanEngine::cleanup()
|
||||||
vkDestroyDevice(_device, nullptr);
|
vkDestroyDevice(_device, nullptr);
|
||||||
vkb::destroy_debug_utils_messenger(_instance, _debug_messenger);
|
vkb::destroy_debug_utils_messenger(_instance, _debug_messenger);
|
||||||
vkDestroyInstance(_instance, nullptr);
|
vkDestroyInstance(_instance, nullptr);
|
||||||
SDL_DestroyWindow(_window);
|
_gui.destroy(_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadedEngine = nullptr;
|
loadedEngine = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanEngine::draw()
|
Transaction VulkanEngine::begin_transaction() {
|
||||||
{
|
// ZED: begin command transaction
|
||||||
// wait until the gpu has finished rendering the last frame. Timeout of 1 second
|
// wait until the gpu has finished rendering the last frame. Timeout of 1 second
|
||||||
VK_CHECK(vkWaitForFences(_device, 1, &get_current_frame()._renderFence, true, 1000000000));
|
VK_CHECK(vkWaitForFences(_device, 1, &get_current_frame()._renderFence, true, 1000000000));
|
||||||
get_current_frame()._deletionQueue.flush();
|
get_current_frame()._deletionQueue.flush();
|
||||||
|
|
@ -103,44 +87,24 @@ void VulkanEngine::draw()
|
||||||
|
|
||||||
VkCommandBufferBeginInfo cmdBeginInfo = vkinit::command_buffer_begin_info(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
VkCommandBufferBeginInfo cmdBeginInfo = vkinit::command_buffer_begin_info(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||||
|
|
||||||
_drawExtent.width = _drawImage.imageExtent.width;
|
|
||||||
_drawExtent.height = _drawImage.imageExtent.height;
|
|
||||||
|
|
||||||
VK_CHECK(vkBeginCommandBuffer(cmd, &cmdBeginInfo));
|
VK_CHECK(vkBeginCommandBuffer(cmd, &cmdBeginInfo));
|
||||||
|
|
||||||
// transition our main draw image into general layout so we can write into it
|
return {cmd, swapchainImageIndex};
|
||||||
// we will overwrite it all so we dont care about what was the older layout
|
}
|
||||||
|
|
||||||
vkutil::transition_image(cmd, _drawImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
void VulkanEngine::commit_transaction(Transaction& t) {
|
||||||
|
VK_CHECK(vkEndCommandBuffer(t.cmd));
|
||||||
draw_background(cmd);
|
|
||||||
|
|
||||||
vkutil::transition_image(cmd, _drawImage.image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
|
||||||
|
|
||||||
vkutil::transition_image(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
|
||||||
|
|
||||||
vkutil::copy_image_to_image(cmd, _drawImage.image,
|
|
||||||
_swapchainImages[swapchainImageIndex],
|
|
||||||
_drawExtent, _swapchainExtent);
|
|
||||||
|
|
||||||
vkutil::transition_image(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
|
||||||
|
|
||||||
draw_imgui(cmd, _swapchainImageViews[swapchainImageIndex]);
|
|
||||||
|
|
||||||
vkutil::transition_image(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
|
||||||
|
|
||||||
VK_CHECK(vkEndCommandBuffer(cmd));
|
|
||||||
|
|
||||||
|
// ZED: submit command to queue
|
||||||
//prepare the submission to the queue.
|
//prepare the submission to the queue.
|
||||||
//we want to wait on the _presentSemaphore, as that semaphore is signaled when the swapchain is ready
|
//we want to wait on the _presentSemaphore, as that semaphore is signaled when the swapchain is ready
|
||||||
//we will signal the _renderSemaphore, to signal that rendering has finished
|
//we will signal the _renderSemaphore, to signal that rendering has finished
|
||||||
|
VkCommandBufferSubmitInfo cmdinfo = vkinit::command_buffer_submit_info(t.cmd);
|
||||||
VkCommandBufferSubmitInfo cmdinfo = vkinit::command_buffer_submit_info(cmd);
|
|
||||||
|
|
||||||
VkSemaphoreSubmitInfo waitInfo = vkinit::semaphore_submit_info(VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,get_current_frame()._swapchainSemaphore);
|
VkSemaphoreSubmitInfo waitInfo = vkinit::semaphore_submit_info(VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,get_current_frame()._swapchainSemaphore);
|
||||||
VkSemaphoreSubmitInfo signalInfo = vkinit::semaphore_submit_info(VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, get_current_frame()._renderSemaphore);
|
VkSemaphoreSubmitInfo signalInfo = vkinit::semaphore_submit_info(VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, get_current_frame()._renderSemaphore);
|
||||||
|
|
||||||
VkSubmitInfo2 submit = vkinit::submit_info(&cmdinfo,&signalInfo,&waitInfo);
|
VkSubmitInfo2 submit = vkinit::submit_info(&cmdinfo, &signalInfo, &waitInfo);
|
||||||
|
|
||||||
//submit command buffer to the queue and execute it.
|
//submit command buffer to the queue and execute it.
|
||||||
// _renderFence will now block until the graphic commands finish execution
|
// _renderFence will now block until the graphic commands finish execution
|
||||||
|
|
@ -150,16 +114,15 @@ void VulkanEngine::draw()
|
||||||
// this will put the image we just rendered to into the visible window.
|
// this will put the image we just rendered to into the visible window.
|
||||||
// we want to wait on the _renderSemaphore for that,
|
// we want to wait on the _renderSemaphore for that,
|
||||||
// as its necessary that drawing commands have finished before the image is displayed to the user
|
// as its necessary that drawing commands have finished before the image is displayed to the user
|
||||||
VkPresentInfoKHR presentInfo{};
|
VkPresentInfoKHR presentInfo{
|
||||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||||
presentInfo.pNext = nullptr;
|
.pNext = nullptr,
|
||||||
presentInfo.pSwapchains = &_swapchain;
|
.waitSemaphoreCount = 1,
|
||||||
presentInfo.swapchainCount = 1;
|
.pWaitSemaphores = &get_current_frame()._renderSemaphore,
|
||||||
|
.swapchainCount = 1,
|
||||||
presentInfo.pWaitSemaphores = &get_current_frame()._renderSemaphore;
|
.pSwapchains = &_swapchain,
|
||||||
presentInfo.waitSemaphoreCount = 1;
|
.pImageIndices = &t.swapchainImageIndex,
|
||||||
|
};
|
||||||
presentInfo.pImageIndices = &swapchainImageIndex;
|
|
||||||
|
|
||||||
VK_CHECK(vkQueuePresentKHR(_graphicsQueue, &presentInfo));
|
VK_CHECK(vkQueuePresentKHR(_graphicsQueue, &presentInfo));
|
||||||
|
|
||||||
|
|
@ -167,70 +130,61 @@ void VulkanEngine::draw()
|
||||||
_frameNumber++;
|
_frameNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanEngine::draw()
|
||||||
|
{
|
||||||
|
auto t = begin_transaction();
|
||||||
|
|
||||||
|
// ZED: draw the things
|
||||||
|
_drawExtent.width = _drawImage.imageExtent.width;
|
||||||
|
_drawExtent.height = _drawImage.imageExtent.height;
|
||||||
|
|
||||||
|
// transition our main draw image into general layout so we can write into it
|
||||||
|
// we will overwrite it all so we dont care about what was the older layout
|
||||||
|
vkutil::transition_image(t.cmd, _drawImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
|
|
||||||
|
draw_background(t.cmd);
|
||||||
|
|
||||||
|
// ZED: ?
|
||||||
|
vkutil::transition_image(t.cmd, _drawImage.image, VK_IMAGE_LAYOUT_GENERAL,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||||
|
|
||||||
|
// ZED: ?
|
||||||
|
vkutil::transition_image(t.cmd, _swapchainImages[t.swapchainImageIndex],
|
||||||
|
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
|
vkutil::copy_image_to_image(t.cmd, _drawImage.image,
|
||||||
|
_swapchainImages[t.swapchainImageIndex],
|
||||||
|
_drawExtent, _swapchainExtent);
|
||||||
|
|
||||||
|
// ZED: ?
|
||||||
|
vkutil::transition_image(t.cmd, _swapchainImages[t.swapchainImageIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
|
||||||
|
_gui.draw_imgui(_swapchainExtent, t.cmd, _swapchainImageViews[t.swapchainImageIndex]);
|
||||||
|
// ZED: end drawing the things
|
||||||
|
|
||||||
|
// ZED: finalize image and commit command buffer
|
||||||
|
vkutil::transition_image(t.cmd, _swapchainImages[t.swapchainImageIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||||
|
|
||||||
|
commit_transaction(t);
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanEngine::run()
|
void VulkanEngine::run()
|
||||||
{
|
{
|
||||||
SDL_Event e;
|
|
||||||
bool bQuit = false;
|
|
||||||
bool stop_rendering = false;
|
|
||||||
|
|
||||||
//main loop
|
//main loop
|
||||||
while(!bQuit)
|
while(!_gui.should_quit)
|
||||||
{
|
{
|
||||||
//Handle events on queue
|
_gui.poll_event();
|
||||||
while(SDL_PollEvent(&e) != 0)
|
|
||||||
{
|
|
||||||
//close the window when user alt-f4s or clicks the X button
|
|
||||||
if(e.type == SDL_QUIT) {
|
|
||||||
bQuit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(e.type == SDL_WINDOWEVENT) {
|
if(_gui.stop_rendering) {
|
||||||
if(e.window.event == SDL_WINDOWEVENT_MINIMIZED) {
|
|
||||||
stop_rendering = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(e.window.event == SDL_WINDOWEVENT_RESTORED) {
|
|
||||||
stop_rendering = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui_ImplSDL2_ProcessEvent(&e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stop_rendering) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
render_imgui();
|
_gui.render_imgui(backgroundEffects, ¤tBackgroundEffect);
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanEngine::render_imgui() {
|
|
||||||
ImGui_ImplVulkan_NewFrame();
|
|
||||||
ImGui_ImplSDL2_NewFrame();
|
|
||||||
|
|
||||||
ImGui::NewFrame();
|
|
||||||
|
|
||||||
if (ImGui::Begin("background")) {
|
|
||||||
|
|
||||||
ComputeEffect& selected = backgroundEffects[currentBackgroundEffect];
|
|
||||||
|
|
||||||
ImGui::Text("Selected effect: %s", selected.name);
|
|
||||||
|
|
||||||
ImGui::SliderInt("Effect Index", ¤tBackgroundEffect,0, backgroundEffects.size() - 1);
|
|
||||||
|
|
||||||
ImGui::InputFloat4("data1",(float*)& selected.data.data1);
|
|
||||||
ImGui::InputFloat4("data2",(float*)& selected.data.data2);
|
|
||||||
ImGui::InputFloat4("data3",(float*)& selected.data.data3);
|
|
||||||
ImGui::InputFloat4("data4",(float*)& selected.data.data4);
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
|
|
||||||
ImGui::Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
void VulkanEngine::init_vulkan() {
|
void VulkanEngine::init_vulkan() {
|
||||||
vkb::InstanceBuilder builder;
|
vkb::InstanceBuilder builder;
|
||||||
|
|
||||||
|
|
@ -251,18 +205,19 @@ void VulkanEngine::init_vulkan() {
|
||||||
SDL_Vulkan_CreateSurface(_window, _instance, &_surface);
|
SDL_Vulkan_CreateSurface(_window, _instance, &_surface);
|
||||||
|
|
||||||
//vulkan 1.3 features
|
//vulkan 1.3 features
|
||||||
VkPhysicalDeviceVulkan13Features features13{};
|
VkPhysicalDeviceVulkan13Features features13{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
|
||||||
features13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
|
.synchronization2 = true,
|
||||||
features13.dynamicRendering = true;
|
.dynamicRendering = true,
|
||||||
features13.synchronization2 = true;
|
};
|
||||||
|
|
||||||
//vulkan 1.2 features
|
//vulkan 1.2 features
|
||||||
VkPhysicalDeviceVulkan12Features features12{};
|
VkPhysicalDeviceVulkan12Features features12{
|
||||||
features12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
|
||||||
features12.bufferDeviceAddress = true;
|
.descriptorIndexing = true,
|
||||||
features12.descriptorIndexing = true;
|
.bufferDeviceAddress = true,
|
||||||
|
};
|
||||||
|
|
||||||
// use vkbootstrap to select a gpu
|
// use vkbootstrap to select a gpu
|
||||||
// We want a gpu that can write to the SDL surface
|
// We want a gpu that can write to the SDL surface
|
||||||
vkb::PhysicalDeviceSelector selector{ vkb_inst };
|
vkb::PhysicalDeviceSelector selector{ vkb_inst };
|
||||||
|
|
@ -284,11 +239,13 @@ void VulkanEngine::init_vulkan() {
|
||||||
_graphicsQueueFamily = vkbDevice.get_queue_index(vkb::QueueType::graphics).value();
|
_graphicsQueueFamily = vkbDevice.get_queue_index(vkb::QueueType::graphics).value();
|
||||||
|
|
||||||
// initialize the memory allocator
|
// initialize the memory allocator
|
||||||
VmaAllocatorCreateInfo allocatorInfo{};
|
VmaAllocatorCreateInfo allocatorInfo{
|
||||||
allocatorInfo.physicalDevice = _chosenGPU;
|
.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT,
|
||||||
allocatorInfo.device = _device;
|
.physicalDevice = _chosenGPU,
|
||||||
allocatorInfo.instance = _instance;
|
.device = _device,
|
||||||
allocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
|
.instance = _instance,
|
||||||
|
};
|
||||||
|
|
||||||
vmaCreateAllocator(&allocatorInfo, &_allocator);
|
vmaCreateAllocator(&allocatorInfo, &_allocator);
|
||||||
|
|
||||||
_mainDeletionQueue.push_function([&]() {
|
_mainDeletionQueue.push_function([&]() {
|
||||||
|
|
@ -339,18 +296,19 @@ void VulkanEngine::init_swapchain() {
|
||||||
_drawImage.imageFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
|
_drawImage.imageFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||||
_drawImage.imageExtent = drawImageExtent;
|
_drawImage.imageExtent = drawImageExtent;
|
||||||
|
|
||||||
VkImageUsageFlags drawImageUsages{};
|
VkImageUsageFlags drawImageUsages =
|
||||||
drawImageUsages |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
VK_IMAGE_USAGE_TRANSFER_SRC_BIT
|
||||||
drawImageUsages |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
||||||
drawImageUsages |= VK_IMAGE_USAGE_STORAGE_BIT;
|
| VK_IMAGE_USAGE_STORAGE_BIT
|
||||||
drawImageUsages |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
|
||||||
VkImageCreateInfo rimg_info = vkinit::image_create_info(_drawImage.imageFormat, drawImageUsages, drawImageExtent);
|
VkImageCreateInfo rimg_info = vkinit::image_create_info(_drawImage.imageFormat, drawImageUsages, drawImageExtent);
|
||||||
|
|
||||||
VmaAllocationCreateInfo rimg_allocinfo{};
|
VmaAllocationCreateInfo rimg_allocinfo{
|
||||||
rimg_allocinfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
|
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
|
||||||
rimg_allocinfo.requiredFlags = VkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
.requiredFlags = VkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT),
|
||||||
|
};
|
||||||
|
|
||||||
//allocate and create the image
|
//allocate and create the image
|
||||||
vmaCreateImage(_allocator, &rimg_info, &rimg_allocinfo, &_drawImage.image, &_drawImage.allocation, nullptr);
|
vmaCreateImage(_allocator, &rimg_info, &rimg_allocinfo, &_drawImage.image, &_drawImage.allocation, nullptr);
|
||||||
|
|
||||||
|
|
@ -430,7 +388,7 @@ void VulkanEngine::init_descriptors() {
|
||||||
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1 }
|
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
globalDescriptorAllocator.init_pool(_device, 10, sizes);
|
_globalDescriptorAllocator.init_pool(_device, 10, sizes);
|
||||||
|
|
||||||
// make the descriptor set layout for our compute draw
|
// make the descriptor set layout for our compute draw
|
||||||
{
|
{
|
||||||
|
|
@ -441,27 +399,27 @@ void VulkanEngine::init_descriptors() {
|
||||||
|
|
||||||
// other code
|
// other code
|
||||||
//allocate a descriptor set for our draw image
|
//allocate a descriptor set for our draw image
|
||||||
_drawImageDescriptors = globalDescriptorAllocator.allocate(_device,_drawImageDescriptorLayout);
|
_drawImageDescriptors = _globalDescriptorAllocator.allocate(_device,_drawImageDescriptorLayout);
|
||||||
|
|
||||||
VkDescriptorImageInfo imgInfo{};
|
VkDescriptorImageInfo imgInfo{
|
||||||
imgInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
.imageView = _drawImage.imageView,
|
||||||
imgInfo.imageView = _drawImage.imageView;
|
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||||
|
};
|
||||||
VkWriteDescriptorSet drawImageWrite = {};
|
|
||||||
drawImageWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
VkWriteDescriptorSet drawImageWrite{
|
||||||
drawImageWrite.pNext = nullptr;
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.dstSet = _drawImageDescriptors,
|
||||||
drawImageWrite.dstBinding = 0;
|
.dstBinding = 0,
|
||||||
drawImageWrite.dstSet = _drawImageDescriptors;
|
.descriptorCount = 1,
|
||||||
drawImageWrite.descriptorCount = 1;
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||||
drawImageWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
.pImageInfo = &imgInfo,
|
||||||
drawImageWrite.pImageInfo = &imgInfo;
|
};
|
||||||
|
|
||||||
vkUpdateDescriptorSets(_device, 1, &drawImageWrite, 0, nullptr),
|
vkUpdateDescriptorSets(_device, 1, &drawImageWrite, 0, nullptr),
|
||||||
|
|
||||||
//make sure both the descriptor allocator and the new layout get cleaned up properly
|
//make sure both the descriptor allocator and the new layout get cleaned up properly
|
||||||
_mainDeletionQueue.push_function([&]() {
|
_mainDeletionQueue.push_function([&]() {
|
||||||
globalDescriptorAllocator.destroy_pool(_device);
|
_globalDescriptorAllocator.destroy_pool(_device);
|
||||||
|
|
||||||
vkDestroyDescriptorSetLayout(_device, _drawImageDescriptorLayout, nullptr);
|
vkDestroyDescriptorSetLayout(_device, _drawImageDescriptorLayout, nullptr);
|
||||||
});
|
});
|
||||||
|
|
@ -470,77 +428,81 @@ void VulkanEngine::init_descriptors() {
|
||||||
void VulkanEngine::init_pipelines()
|
void VulkanEngine::init_pipelines()
|
||||||
{
|
{
|
||||||
init_background_pipelines();
|
init_background_pipelines();
|
||||||
|
init_shaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanEngine::load_shader(const char *file_name, const char *entry_point, ComputeEffect effect) {
|
||||||
|
VkShaderModule shader;
|
||||||
|
bool good = vkutil::load_shader_module(file_name, _device, &shader);
|
||||||
|
assert(good && "failed to load shader");
|
||||||
|
|
||||||
|
VkPipelineShaderStageCreateInfo stageinfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||||
|
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||||
|
.module = shader,
|
||||||
|
.pName = entry_point,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkComputePipelineCreateInfo computePipelineCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
||||||
|
.stage = stageinfo,
|
||||||
|
.layout = _gradientPipelineLayout,
|
||||||
|
};
|
||||||
|
|
||||||
|
effect.layout = _gradientPipelineLayout;
|
||||||
|
|
||||||
|
VK_CHECK(vkCreateComputePipelines(_device, VK_NULL_HANDLE, 1, &computePipelineCreateInfo, nullptr, &effect.pipeline));
|
||||||
|
|
||||||
|
backgroundEffects.push_back(effect);
|
||||||
|
|
||||||
|
vkDestroyShaderModule(_device, shader, nullptr);
|
||||||
|
|
||||||
|
_mainDeletionQueue.push_function([=,this]() {
|
||||||
|
vkDestroyPipeline(_device, effect.pipeline, nullptr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanEngine::init_background_pipelines()
|
void VulkanEngine::init_background_pipelines()
|
||||||
{
|
{
|
||||||
VkPipelineLayoutCreateInfo computeLayout{};
|
VkPushConstantRange pushConstant{
|
||||||
computeLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||||
computeLayout.pNext = nullptr;
|
.offset = 0,
|
||||||
computeLayout.pSetLayouts = &_drawImageDescriptorLayout;
|
.size = sizeof(ComputePushConstants),
|
||||||
computeLayout.setLayoutCount = 1;
|
};
|
||||||
|
|
||||||
VkPushConstantRange pushConstant{};
|
VkPipelineLayoutCreateInfo computeLayout{
|
||||||
pushConstant.offset = 0;
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
pushConstant.size = sizeof(ComputePushConstants) ;
|
.setLayoutCount = 1,
|
||||||
pushConstant.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
.pSetLayouts = &_drawImageDescriptorLayout,
|
||||||
|
.pushConstantRangeCount = 1,
|
||||||
computeLayout.pPushConstantRanges = &pushConstant;
|
.pPushConstantRanges = &pushConstant,
|
||||||
computeLayout.pushConstantRangeCount = 1;
|
};
|
||||||
|
|
||||||
VK_CHECK(vkCreatePipelineLayout(_device, &computeLayout, nullptr, &_gradientPipelineLayout));
|
VK_CHECK(vkCreatePipelineLayout(_device, &computeLayout, nullptr, &_gradientPipelineLayout));
|
||||||
|
|
||||||
VkShaderModule gradientShader;
|
// final cleanup
|
||||||
bool good = vkutil::load_shader_module("gradient_color.comp.spv", _device, &gradientShader);
|
|
||||||
assert(good && "failed to load gradient_color.comp.spv");
|
|
||||||
|
|
||||||
VkShaderModule skyShader;
|
|
||||||
good = vkutil::load_shader_module("sky.comp.spv", _device, &skyShader);
|
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo stageinfo{};
|
|
||||||
stageinfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
||||||
stageinfo.pNext = nullptr;
|
|
||||||
stageinfo.stage = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
||||||
stageinfo.module = gradientShader;
|
|
||||||
stageinfo.pName = "main";
|
|
||||||
|
|
||||||
VkComputePipelineCreateInfo computePipelineCreateInfo{};
|
|
||||||
computePipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
|
||||||
computePipelineCreateInfo.pNext = nullptr;
|
|
||||||
computePipelineCreateInfo.layout = _gradientPipelineLayout;
|
|
||||||
computePipelineCreateInfo.stage = stageinfo;
|
|
||||||
|
|
||||||
ComputeEffect gradient;
|
|
||||||
gradient.layout = _gradientPipelineLayout;
|
|
||||||
gradient.name = "gradient";
|
|
||||||
gradient.data = {};
|
|
||||||
gradient.data.data1 = glm::vec4(1, 0, 0, 1);
|
|
||||||
gradient.data.data2 = glm::vec4(0, 0, 1, 1);
|
|
||||||
|
|
||||||
VK_CHECK(vkCreateComputePipelines(_device, VK_NULL_HANDLE, 1, &computePipelineCreateInfo, nullptr, &gradient.pipeline));
|
|
||||||
|
|
||||||
// change the shader module only to create the sky
|
|
||||||
computePipelineCreateInfo.stage.module = skyShader;
|
|
||||||
ComputeEffect sky;
|
|
||||||
sky.layout = _gradientPipelineLayout;
|
|
||||||
sky.name = "sky";
|
|
||||||
sky.data = {};
|
|
||||||
// default sky
|
|
||||||
sky.data.data1 = glm::vec4(0.1, 0.2, 0.4, 0.97);
|
|
||||||
|
|
||||||
VK_CHECK(vkCreateComputePipelines(_device, VK_NULL_HANDLE, 1, &computePipelineCreateInfo, nullptr, &sky.pipeline));
|
|
||||||
|
|
||||||
|
|
||||||
backgroundEffects.push_back(gradient);
|
|
||||||
backgroundEffects.push_back(sky);
|
|
||||||
|
|
||||||
vkDestroyShaderModule(_device, gradientShader, nullptr);
|
|
||||||
vkDestroyShaderModule(_device, skyShader, nullptr);
|
|
||||||
|
|
||||||
_mainDeletionQueue.push_function([=,this]() {
|
_mainDeletionQueue.push_function([=,this]() {
|
||||||
vkDestroyPipelineLayout(_device, _gradientPipelineLayout, nullptr);
|
vkDestroyPipelineLayout(_device, _gradientPipelineLayout, nullptr);
|
||||||
vkDestroyPipeline(_device, sky.pipeline, nullptr);
|
});
|
||||||
vkDestroyPipeline(_device, sky.pipeline, nullptr);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VulkanEngine::init_shaders() {
|
||||||
|
/// gradient shader
|
||||||
|
load_shader("gradient_color.comp.spv", "main", {
|
||||||
|
.name="gradient",
|
||||||
|
.data={
|
||||||
|
.data1 = glm::vec4(1, 0, 0, 1),
|
||||||
|
.data2 = glm::vec4(0, 0, 1, 1),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
load_shader("sky.comp.spv", "main", {
|
||||||
|
.name="sky",
|
||||||
|
.data = {
|
||||||
|
.data1 = glm::vec4(0.1, 0.2, 0.4, 0.97)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -565,75 +527,7 @@ void VulkanEngine::immediate_submit(std::function<void(VkCommandBuffer cmd)>&& f
|
||||||
|
|
||||||
VK_CHECK(vkQueueSubmit2(_graphicsQueue, 1, &submit, _immFence));
|
VK_CHECK(vkQueueSubmit2(_graphicsQueue, 1, &submit, _immFence));
|
||||||
VK_CHECK(vkWaitForFences(_device, 1, &_immFence, true,9999999999));
|
VK_CHECK(vkWaitForFences(_device, 1, &_immFence, true,9999999999));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanEngine::init_imgui()
|
|
||||||
{
|
|
||||||
// 1: create descriptor pool for IMGUI
|
|
||||||
// the size of the pool is very oversize, but it's copied from imgui demo
|
|
||||||
// itself.
|
|
||||||
VkDescriptorPoolSize pool_sizes[] = { { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } };
|
|
||||||
|
|
||||||
VkDescriptorPoolCreateInfo pool_info{};
|
|
||||||
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
|
||||||
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
|
||||||
pool_info.maxSets = 1000;
|
|
||||||
pool_info.poolSizeCount = (uint32_t)std::size(pool_sizes);
|
|
||||||
pool_info.pPoolSizes = pool_sizes;
|
|
||||||
|
|
||||||
VkDescriptorPool imguiPool;
|
|
||||||
VK_CHECK(vkCreateDescriptorPool(_device, &pool_info, nullptr, &imguiPool));
|
|
||||||
|
|
||||||
// 2: initialize the imgui library
|
|
||||||
ImGui::CreateContext();
|
|
||||||
|
|
||||||
ImGui_ImplSDL2_InitForVulkan(_window);
|
|
||||||
ImGui_ImplVulkan_InitInfo init_info{};
|
|
||||||
init_info.Instance = _instance;
|
|
||||||
init_info.PhysicalDevice = _chosenGPU;
|
|
||||||
init_info.Device = _device;
|
|
||||||
init_info.Queue = _graphicsQueue;
|
|
||||||
init_info.DescriptorPool = imguiPool;
|
|
||||||
init_info.MinImageCount = 3;
|
|
||||||
init_info.ImageCount = 3;
|
|
||||||
init_info.UseDynamicRendering = true;
|
|
||||||
|
|
||||||
init_info.PipelineRenderingCreateInfo = {.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO};
|
|
||||||
init_info.PipelineRenderingCreateInfo.colorAttachmentCount = 1;
|
|
||||||
init_info.PipelineRenderingCreateInfo.pColorAttachmentFormats = &_swapchainImageFormat;
|
|
||||||
|
|
||||||
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
ImGui_ImplVulkan_Init(&init_info);
|
|
||||||
ImGui_ImplVulkan_CreateFontsTexture();
|
|
||||||
|
|
||||||
_mainDeletionQueue.push_function([=,this]() {
|
|
||||||
ImGui_ImplVulkan_Shutdown();
|
|
||||||
vkDestroyDescriptorPool(_device, imguiPool, nullptr);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void VulkanEngine::draw_imgui(VkCommandBuffer cmd, VkImageView targetImageView)
|
|
||||||
{
|
|
||||||
VkRenderingAttachmentInfo colorAttachment = vkinit::attachment_info(targetImageView, nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
|
||||||
|
|
||||||
VkRenderingInfo renderInfo = vkinit::rendering_info(_swapchainExtent, &colorAttachment, nullptr);
|
|
||||||
|
|
||||||
vkCmdBeginRendering(cmd, &renderInfo);
|
|
||||||
|
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);
|
|
||||||
|
|
||||||
vkCmdEndRendering(cmd);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
32
vk_engine.h
32
vk_engine.h
|
|
@ -5,23 +5,13 @@
|
||||||
|
|
||||||
#include <vk_types.h>
|
#include <vk_types.h>
|
||||||
#include <vk_descriptors.h>
|
#include <vk_descriptors.h>
|
||||||
|
#include "vk_gui.h"
|
||||||
|
|
||||||
struct ComputePushConstants {
|
struct Transaction {
|
||||||
glm::vec4 data1;
|
VkCommandBuffer cmd;
|
||||||
glm::vec4 data2;
|
uint32_t swapchainImageIndex = 0;
|
||||||
glm::vec4 data3;
|
|
||||||
glm::vec4 data4;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ComputeEffect {
|
|
||||||
const char *name;
|
|
||||||
VkPipeline pipeline;
|
|
||||||
VkPipelineLayout layout;
|
|
||||||
|
|
||||||
ComputePushConstants data;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct DeletionQueue {
|
struct DeletionQueue {
|
||||||
std::deque<std::function<void()>> deletors;
|
std::deque<std::function<void()>> deletors;
|
||||||
|
|
||||||
|
|
@ -48,7 +38,6 @@ struct FrameData {
|
||||||
DeletionQueue _deletionQueue;
|
DeletionQueue _deletionQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr unsigned int FRAME_OVERLAP=2;
|
|
||||||
|
|
||||||
class VulkanEngine {
|
class VulkanEngine {
|
||||||
public:
|
public:
|
||||||
|
|
@ -58,7 +47,7 @@ public:
|
||||||
VkPipeline _gradientPipeline;
|
VkPipeline _gradientPipeline;
|
||||||
VkPipelineLayout _gradientPipelineLayout;
|
VkPipelineLayout _gradientPipelineLayout;
|
||||||
|
|
||||||
DescriptorAllocator globalDescriptorAllocator;
|
DescriptorAllocator _globalDescriptorAllocator;
|
||||||
VkDescriptorSet _drawImageDescriptors;
|
VkDescriptorSet _drawImageDescriptors;
|
||||||
VkDescriptorSetLayout _drawImageDescriptorLayout;
|
VkDescriptorSetLayout _drawImageDescriptorLayout;
|
||||||
|
|
||||||
|
|
@ -104,6 +93,9 @@ public:
|
||||||
// imgui shader stuff
|
// imgui shader stuff
|
||||||
std::vector<ComputeEffect> backgroundEffects;
|
std::vector<ComputeEffect> backgroundEffects;
|
||||||
int currentBackgroundEffect{0};
|
int currentBackgroundEffect{0};
|
||||||
|
|
||||||
|
// ZED's REFACTOR
|
||||||
|
VkGUI _gui;
|
||||||
|
|
||||||
static VulkanEngine& Get();
|
static VulkanEngine& Get();
|
||||||
|
|
||||||
|
|
@ -121,6 +113,9 @@ public:
|
||||||
|
|
||||||
void immediate_submit(std::function<void(VkCommandBuffer cmd)>&& function);
|
void immediate_submit(std::function<void(VkCommandBuffer cmd)>&& function);
|
||||||
|
|
||||||
|
Transaction begin_transaction();
|
||||||
|
void commit_transaction(Transaction& cmd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init_vulkan();
|
void init_vulkan();
|
||||||
void init_swapchain();
|
void init_swapchain();
|
||||||
|
|
@ -129,11 +124,10 @@ private:
|
||||||
void init_descriptors();
|
void init_descriptors();
|
||||||
void init_pipelines();
|
void init_pipelines();
|
||||||
void init_background_pipelines();
|
void init_background_pipelines();
|
||||||
void init_imgui();
|
void init_shaders();
|
||||||
|
void load_shader(const char *file_name, const char *entry_point, ComputeEffect data);
|
||||||
|
|
||||||
void create_swapchain(uint32_t width, uint32_t height);
|
void create_swapchain(uint32_t width, uint32_t height);
|
||||||
void destroy_swapchain();
|
void destroy_swapchain();
|
||||||
void draw_background(VkCommandBuffer cmd);
|
void draw_background(VkCommandBuffer cmd);
|
||||||
void draw_imgui(VkCommandBuffer cmd, VkImageView targetImageView);
|
|
||||||
void render_imgui();
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
151
vk_gui.cpp
Normal file
151
vk_gui.cpp
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
#include "vk_gui.h"
|
||||||
|
#include "vk_initializers.h"
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <SDL_vulkan.h>
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <imgui_impl_sdl2.h>
|
||||||
|
#include <imgui_impl_vulkan.h>
|
||||||
|
#include "vk_engine.h"
|
||||||
|
|
||||||
|
struct SDL_Window* VkGUI::init_window(VkExtent2D windowExtent)
|
||||||
|
{
|
||||||
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
|
||||||
|
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN);
|
||||||
|
|
||||||
|
return SDL_CreateWindow(
|
||||||
|
"Vulkan Engine",
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
int(windowExtent.width),
|
||||||
|
int(windowExtent.height),
|
||||||
|
window_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VkGUI::init_imgui(VulkanEngine& engine)
|
||||||
|
{
|
||||||
|
// 1. create descriptor pool for IMGUI
|
||||||
|
// the size of the pool is very oversize, but it's copied from imgui demo
|
||||||
|
// itself.
|
||||||
|
VkDescriptorPoolSize pool_sizes[] = {
|
||||||
|
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 }
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorPoolCreateInfo pool_info{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||||
|
.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||||
|
.maxSets = 1000,
|
||||||
|
.poolSizeCount = (uint32_t)std::size(pool_sizes),
|
||||||
|
.pPoolSizes = pool_sizes,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorPool imguiPool;
|
||||||
|
VK_CHECK(vkCreateDescriptorPool(engine._device, &pool_info, nullptr, &imguiPool));
|
||||||
|
|
||||||
|
// 2: initialize the imgui library
|
||||||
|
ImGui::CreateContext();
|
||||||
|
|
||||||
|
ImGui_ImplSDL2_InitForVulkan(engine._window);
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_InitInfo init_info{
|
||||||
|
.Instance = engine._instance,
|
||||||
|
.PhysicalDevice = engine._chosenGPU,
|
||||||
|
.Device = engine._device,
|
||||||
|
.Queue = engine._graphicsQueue,
|
||||||
|
.DescriptorPool = imguiPool,
|
||||||
|
.MinImageCount = 3,
|
||||||
|
.ImageCount = 3,
|
||||||
|
.MSAASamples = VK_SAMPLE_COUNT_1_BIT,
|
||||||
|
.UseDynamicRendering = true,
|
||||||
|
.PipelineRenderingCreateInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
||||||
|
.colorAttachmentCount = 1,
|
||||||
|
.pColorAttachmentFormats = &engine._swapchainImageFormat,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_Init(&init_info);
|
||||||
|
ImGui_ImplVulkan_CreateFontsTexture();
|
||||||
|
|
||||||
|
engine._mainDeletionQueue.push_function([=,this]() {
|
||||||
|
ImGui_ImplVulkan_Shutdown();
|
||||||
|
vkDestroyDescriptorPool(engine._device, imguiPool, nullptr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void VkGUI::draw_imgui(VkExtent2D& swapchainExtent, VkCommandBuffer cmd, VkImageView targetImageView)
|
||||||
|
{
|
||||||
|
VkRenderingAttachmentInfo colorAttachment = vkinit::attachment_info(targetImageView, nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
|
||||||
|
VkRenderingInfo renderInfo = vkinit::rendering_info(swapchainExtent, &colorAttachment, nullptr);
|
||||||
|
|
||||||
|
vkCmdBeginRendering(cmd, &renderInfo);
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);
|
||||||
|
|
||||||
|
vkCmdEndRendering(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VkGUI::render_imgui(std::vector<ComputeEffect>& backgroundEffects, int* currentBackgroundEffect)
|
||||||
|
{
|
||||||
|
ImGui_ImplVulkan_NewFrame();
|
||||||
|
ImGui_ImplSDL2_NewFrame();
|
||||||
|
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
if (ImGui::Begin("background")) {
|
||||||
|
|
||||||
|
ComputeEffect& selected = backgroundEffects[*currentBackgroundEffect];
|
||||||
|
|
||||||
|
ImGui::Text("Selected effect: %s", selected.name);
|
||||||
|
|
||||||
|
ImGui::SliderInt("Effect Index", currentBackgroundEffect,0, backgroundEffects.size() - 1);
|
||||||
|
|
||||||
|
ImGui::InputFloat4("data1",(float*)& selected.data.data1);
|
||||||
|
ImGui::InputFloat4("data2",(float*)& selected.data.data2);
|
||||||
|
ImGui::InputFloat4("data3",(float*)& selected.data.data3);
|
||||||
|
ImGui::InputFloat4("data4",(float*)& selected.data.data4);
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
ImGui::Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VkGUI::destroy(struct SDL_Window* _window)
|
||||||
|
{
|
||||||
|
SDL_DestroyWindow(_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VkGUI::poll_event() {
|
||||||
|
SDL_Event event;
|
||||||
|
|
||||||
|
while(SDL_PollEvent(&event) != 0) {
|
||||||
|
//close the window when user alt-f4s or clicks the X button
|
||||||
|
if(event.type == SDL_QUIT) {
|
||||||
|
should_quit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event.type == SDL_WINDOWEVENT) {
|
||||||
|
if(event.window.event == SDL_WINDOWEVENT_MINIMIZED) {
|
||||||
|
stop_rendering = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event.window.event == SDL_WINDOWEVENT_RESTORED) {
|
||||||
|
stop_rendering = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
vk_gui.h
Normal file
18
vk_gui.h
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
#include "vk_types.h"
|
||||||
|
|
||||||
|
class VulkanEngine;
|
||||||
|
|
||||||
|
class VkGUI {
|
||||||
|
public:
|
||||||
|
bool should_quit = false;
|
||||||
|
bool stop_rendering = false;
|
||||||
|
|
||||||
|
struct SDL_Window* init_window(VkExtent2D windowExtent);
|
||||||
|
void init_imgui(VulkanEngine& engine);
|
||||||
|
void draw_imgui(VkExtent2D& swapchainExtent, VkCommandBuffer cmd, VkImageView targetImageView);
|
||||||
|
void render_imgui(std::vector<ComputeEffect>& backgroundEffects, int* currentBackgroundEffect);
|
||||||
|
void destroy(struct SDL_Window* _window);
|
||||||
|
|
||||||
|
void poll_event();
|
||||||
|
};
|
||||||
|
|
@ -3,28 +3,25 @@
|
||||||
|
|
||||||
void vkutil::transition_image(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout newLayout)
|
void vkutil::transition_image(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout newLayout)
|
||||||
{
|
{
|
||||||
VkImageMemoryBarrier2 imageBarrier{};
|
|
||||||
imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
|
|
||||||
imageBarrier.pNext = nullptr;
|
|
||||||
|
|
||||||
imageBarrier.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
|
|
||||||
imageBarrier.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT;
|
|
||||||
imageBarrier.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
|
|
||||||
imageBarrier.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT;
|
|
||||||
|
|
||||||
|
|
||||||
imageBarrier.oldLayout = currentLayout;
|
|
||||||
imageBarrier.newLayout = newLayout;
|
|
||||||
|
|
||||||
VkImageAspectFlags aspectMask = (newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
VkImageAspectFlags aspectMask = (newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
imageBarrier.subresourceRange = vkinit::image_subresource_range(aspectMask);
|
|
||||||
imageBarrier.image = image;
|
|
||||||
|
|
||||||
VkDependencyInfo depInfo{};
|
VkImageMemoryBarrier2 imageBarrier{
|
||||||
depInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||||
depInfo.pNext = nullptr;
|
.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
|
||||||
depInfo.imageMemoryBarrierCount = 1;
|
.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT,
|
||||||
depInfo.pImageMemoryBarriers = &imageBarrier;
|
.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
|
||||||
|
.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT,
|
||||||
|
.oldLayout = currentLayout,
|
||||||
|
.newLayout = newLayout,
|
||||||
|
.image = image,
|
||||||
|
.subresourceRange = vkinit::image_subresource_range(aspectMask),
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDependencyInfo depInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||||
|
.imageMemoryBarrierCount = 1,
|
||||||
|
.pImageMemoryBarriers = &imageBarrier,
|
||||||
|
};
|
||||||
|
|
||||||
vkCmdPipelineBarrier2(cmd, &depInfo);
|
vkCmdPipelineBarrier2(cmd, &depInfo);
|
||||||
}
|
}
|
||||||
|
|
@ -33,39 +30,45 @@ void vkutil::copy_image_to_image(VkCommandBuffer cmd, VkImage source, VkImage de
|
||||||
{
|
{
|
||||||
VkImageBlit2 blitRegion{
|
VkImageBlit2 blitRegion{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_BLIT_2,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_BLIT_2,
|
||||||
.pNext = nullptr
|
|
||||||
};
|
};
|
||||||
|
|
||||||
blitRegion.srcOffsets[1].x = srcSize.width;
|
blitRegion.srcSubresource = {
|
||||||
blitRegion.srcOffsets[1].y = srcSize.height;
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
blitRegion.srcOffsets[1].z = 1;
|
.mipLevel = 0,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
};
|
||||||
|
|
||||||
blitRegion.dstOffsets[1].x = dstSize.width;
|
blitRegion.dstSubresource = {
|
||||||
blitRegion.dstOffsets[1].y = dstSize.height;
|
.aspectMask=VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
blitRegion.dstOffsets[1].z = 1;
|
.mipLevel=0,
|
||||||
|
.baseArrayLayer=0,
|
||||||
|
.layerCount=1,
|
||||||
|
};
|
||||||
|
|
||||||
blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
blitRegion.srcOffsets[1] = {
|
||||||
blitRegion.srcSubresource.baseArrayLayer = 0;
|
.x = int32_t(srcSize.width),
|
||||||
blitRegion.srcSubresource.layerCount = 1;
|
.y = int32_t(srcSize.height),
|
||||||
blitRegion.srcSubresource.mipLevel = 0;
|
.z = 1,
|
||||||
|
};
|
||||||
|
|
||||||
blitRegion.dstSubresource.aspectMask=VK_IMAGE_ASPECT_COLOR_BIT;
|
blitRegion.dstOffsets[1] = {
|
||||||
blitRegion.dstSubresource.baseArrayLayer=0;
|
.x = int32_t(dstSize.width),
|
||||||
blitRegion.dstSubresource.layerCount=1;
|
.y = int32_t(dstSize.height),
|
||||||
blitRegion.dstSubresource.mipLevel=0;
|
.z = 1,
|
||||||
|
};
|
||||||
|
|
||||||
VkBlitImageInfo2 blitInfo{
|
VkBlitImageInfo2 blitInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2, .pNext = nullptr
|
.sType = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2,
|
||||||
|
.srcImage = source,
|
||||||
|
.srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||||
|
.dstImage = destination,
|
||||||
|
.dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
.regionCount = 1,
|
||||||
|
.pRegions = &blitRegion,
|
||||||
|
.filter = VK_FILTER_LINEAR,
|
||||||
};
|
};
|
||||||
|
|
||||||
blitInfo.dstImage = destination;
|
|
||||||
blitInfo.dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
||||||
blitInfo.srcImage = source;
|
|
||||||
blitInfo.srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
|
||||||
blitInfo.filter = VK_FILTER_LINEAR;
|
|
||||||
blitInfo.regionCount = 1;
|
|
||||||
blitInfo.pRegions = &blitRegion;
|
|
||||||
|
|
||||||
vkCmdBlitImage2(cmd, &blitInfo);
|
vkCmdBlitImage2(cmd, &blitInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,191 +1,139 @@
|
||||||
#include <vk_initializers.h>
|
#include <vk_initializers.h>
|
||||||
#include <vulkan/vk_enum_string_helper.h>
|
|
||||||
#include "trash_test.hpp"
|
|
||||||
|
|
||||||
nlohmann::json DATA = nlohmann::json::parse(R"(
|
|
||||||
{
|
|
||||||
"VkSemaphoreCreateInfo": {
|
|
||||||
"draw": {
|
|
||||||
"sType": 9
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"VkFenceCreateInfo": {
|
|
||||||
"draw": {
|
|
||||||
"sType": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"VkImageViewCreateInfo": {
|
|
||||||
"draw": {
|
|
||||||
"sType": 15,
|
|
||||||
"viewType": 1,
|
|
||||||
"subresourceRange.baseMipLevel": 0,
|
|
||||||
"subresourceRange.levelCount": 1,
|
|
||||||
"subresourceRange.baseArrayLayer": 0,
|
|
||||||
"subresourceRange.layerCount": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)");
|
|
||||||
|
|
||||||
template<typename COMPONENT> COMPONENT load(nlohmann::json &data, const std::string& profile) {
|
|
||||||
COMPONENT result{};
|
|
||||||
auto& type_stuff = data[NameOf<COMPONENT>::name];
|
|
||||||
auto& profile_data = type_stuff[profile];
|
|
||||||
nlohmann::from_json(profile_data, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkCommandPoolCreateInfo vkinit::command_pool_create_info(uint32_t queueFamilyIndex,
|
VkCommandPoolCreateInfo vkinit::command_pool_create_info(uint32_t queueFamilyIndex,
|
||||||
VkCommandPoolCreateFlags flags /*= 0*/)
|
VkCommandPoolCreateFlags flags /*= 0*/)
|
||||||
{
|
{
|
||||||
VkCommandPoolCreateInfo info = {};
|
return {
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||||
info.pNext = nullptr;
|
.flags = flags,
|
||||||
info.queueFamilyIndex = queueFamilyIndex;
|
.queueFamilyIndex = queueFamilyIndex,
|
||||||
info.flags = flags;
|
};
|
||||||
return info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo vkinit::command_buffer_allocate_info(
|
VkCommandBufferAllocateInfo vkinit::command_buffer_allocate_info(
|
||||||
VkCommandPool pool, uint32_t count /*= 1*/)
|
VkCommandPool pool, uint32_t count /*= 1*/)
|
||||||
{
|
{
|
||||||
VkCommandBufferAllocateInfo info = {};
|
return {
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||||
info.pNext = nullptr;
|
.commandPool = pool,
|
||||||
|
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||||
info.commandPool = pool;
|
.commandBufferCount = count,
|
||||||
info.commandBufferCount = count;
|
};
|
||||||
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
||||||
return info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkFenceCreateInfo vkinit::fence_create_info(VkFenceCreateFlags flags /*=0*/)
|
VkFenceCreateInfo vkinit::fence_create_info(VkFenceCreateFlags flags /*=0*/)
|
||||||
{
|
{
|
||||||
auto info = load<VkFenceCreateInfo>(DATA, "draw");
|
return {
|
||||||
info.flags = flags;
|
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
||||||
return info;
|
.flags = flags
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSemaphoreCreateInfo vkinit::semaphore_create_info(VkSemaphoreCreateFlags flags/*=0*/)
|
VkSemaphoreCreateInfo vkinit::semaphore_create_info(VkSemaphoreCreateFlags flags/*=0*/)
|
||||||
{
|
{
|
||||||
auto info = load<VkSemaphoreCreateInfo>(DATA, "draw");
|
return {
|
||||||
info.flags = flags;
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||||
|
.flags = flags,
|
||||||
return info;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
VkCommandBufferBeginInfo vkinit::command_buffer_begin_info(VkCommandBufferUsageFlags flags /*= 0*/)
|
VkCommandBufferBeginInfo vkinit::command_buffer_begin_info(VkCommandBufferUsageFlags flags /*= 0*/)
|
||||||
{
|
{
|
||||||
VkCommandBufferBeginInfo info = {};
|
return {
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||||
info.pNext = nullptr;
|
.flags = flags,
|
||||||
|
.pInheritanceInfo = nullptr,
|
||||||
info.pInheritanceInfo = nullptr;
|
};
|
||||||
info.flags = flags;
|
|
||||||
return info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageSubresourceRange vkinit::image_subresource_range(VkImageAspectFlags aspectMask)
|
VkImageSubresourceRange vkinit::image_subresource_range(VkImageAspectFlags aspectMask)
|
||||||
{
|
{
|
||||||
VkImageSubresourceRange subImage {};
|
return {
|
||||||
subImage.aspectMask = aspectMask;
|
.aspectMask = aspectMask,
|
||||||
subImage.baseMipLevel = 0;
|
.baseMipLevel = 0,
|
||||||
subImage.levelCount = VK_REMAINING_MIP_LEVELS;
|
.levelCount = VK_REMAINING_MIP_LEVELS,
|
||||||
subImage.baseArrayLayer = 0;
|
.baseArrayLayer = 0,
|
||||||
subImage.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||||
|
};
|
||||||
return subImage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSemaphoreSubmitInfo vkinit::semaphore_submit_info(VkPipelineStageFlags2 stageMask, VkSemaphore semaphore)
|
VkSemaphoreSubmitInfo vkinit::semaphore_submit_info(VkPipelineStageFlags2 stageMask, VkSemaphore semaphore)
|
||||||
{
|
{
|
||||||
VkSemaphoreSubmitInfo submitInfo{};
|
return {
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO;
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
|
||||||
submitInfo.pNext = nullptr;
|
.semaphore = semaphore,
|
||||||
submitInfo.semaphore = semaphore;
|
.value = 1,
|
||||||
submitInfo.stageMask = stageMask;
|
.stageMask = stageMask,
|
||||||
submitInfo.deviceIndex = 0;
|
.deviceIndex = 0,
|
||||||
submitInfo.value = 1;
|
};
|
||||||
|
|
||||||
return submitInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkCommandBufferSubmitInfo vkinit::command_buffer_submit_info(VkCommandBuffer cmd)
|
VkCommandBufferSubmitInfo vkinit::command_buffer_submit_info(VkCommandBuffer cmd)
|
||||||
{
|
{
|
||||||
VkCommandBufferSubmitInfo info{};
|
return {
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO;
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
|
||||||
info.pNext = nullptr;
|
.commandBuffer = cmd,
|
||||||
info.commandBuffer = cmd;
|
.deviceMask = 0,
|
||||||
info.deviceMask = 0;
|
};
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSubmitInfo2 vkinit::submit_info(VkCommandBufferSubmitInfo* cmd, VkSemaphoreSubmitInfo* signalSemaphoreInfo,
|
VkSubmitInfo2 vkinit::submit_info(VkCommandBufferSubmitInfo* cmd, VkSemaphoreSubmitInfo* signalSemaphoreInfo,
|
||||||
VkSemaphoreSubmitInfo* waitSemaphoreInfo)
|
VkSemaphoreSubmitInfo* waitSemaphoreInfo)
|
||||||
{
|
{
|
||||||
VkSubmitInfo2 info = {};
|
return {
|
||||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2;
|
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
|
||||||
info.pNext = nullptr;
|
.waitSemaphoreInfoCount = (waitSemaphoreInfo == nullptr ? 0u : 1u),
|
||||||
|
.pWaitSemaphoreInfos = waitSemaphoreInfo,
|
||||||
info.waitSemaphoreInfoCount = waitSemaphoreInfo == nullptr ? 0 : 1;
|
.commandBufferInfoCount = 1,
|
||||||
info.pWaitSemaphoreInfos = waitSemaphoreInfo;
|
.pCommandBufferInfos = cmd,
|
||||||
|
.signalSemaphoreInfoCount = (signalSemaphoreInfo == nullptr ? 0u : 1u),
|
||||||
info.signalSemaphoreInfoCount = signalSemaphoreInfo == nullptr ? 0 : 1;
|
.pSignalSemaphoreInfos = signalSemaphoreInfo,
|
||||||
info.pSignalSemaphoreInfos = signalSemaphoreInfo;
|
};
|
||||||
|
|
||||||
info.commandBufferInfoCount = 1;
|
|
||||||
info.pCommandBufferInfos = cmd;
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageCreateInfo vkinit::image_create_info(VkFormat format, VkImageUsageFlags usageFlags, VkExtent3D extent)
|
VkImageCreateInfo vkinit::image_create_info(VkFormat format, VkImageUsageFlags usageFlags, VkExtent3D extent)
|
||||||
{
|
{
|
||||||
VkImageCreateInfo info{};
|
return {
|
||||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||||
info.pNext = nullptr;
|
.imageType = VK_IMAGE_TYPE_2D,
|
||||||
|
.format = format,
|
||||||
info.imageType = VK_IMAGE_TYPE_2D;
|
.extent = extent,
|
||||||
|
.mipLevels = 1,
|
||||||
info.format = format;
|
.arrayLayers = 1,
|
||||||
info.extent = extent;
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||||
|
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
||||||
info.mipLevels = 1;
|
.usage = usageFlags,
|
||||||
info.arrayLayers = 1;
|
};
|
||||||
|
|
||||||
info.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
|
|
||||||
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
|
||||||
info.usage = usageFlags;
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageViewCreateInfo vkinit::imageview_create_info(VkFormat format, VkImage image, VkImageAspectFlags aspectFlags)
|
VkImageViewCreateInfo vkinit::imageview_create_info(VkFormat format, VkImage image, VkImageAspectFlags aspectFlags)
|
||||||
{
|
{
|
||||||
auto info = load<VkImageViewCreateInfo>(DATA, "draw");
|
return {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||||
info.image = image;
|
.image = image,
|
||||||
info.format = format;
|
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
||||||
info.subresourceRange.aspectMask = aspectFlags;
|
.format = format,
|
||||||
|
.subresourceRange = {
|
||||||
return info;
|
.aspectMask = aspectFlags,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = 1,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
VkRenderingAttachmentInfo vkinit::attachment_info(
|
VkRenderingAttachmentInfo vkinit::attachment_info(
|
||||||
VkImageView view, VkClearValue* clear ,VkImageLayout layout /*= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL*/)
|
VkImageView view, VkClearValue* clear ,VkImageLayout layout /*= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL*/)
|
||||||
{
|
{
|
||||||
VkRenderingAttachmentInfo colorAttachment {};
|
VkRenderingAttachmentInfo colorAttachment{
|
||||||
colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
colorAttachment.pNext = nullptr;
|
.imageView = view,
|
||||||
|
.imageLayout = layout,
|
||||||
colorAttachment.imageView = view;
|
.loadOp = clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||||
colorAttachment.imageLayout = layout;
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
colorAttachment.loadOp = clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
|
};
|
||||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
||||||
|
|
||||||
if (clear) {
|
if (clear) {
|
||||||
colorAttachment.clearValue = *clear;
|
colorAttachment.clearValue = *clear;
|
||||||
|
|
@ -198,16 +146,13 @@ VkRenderingAttachmentInfo vkinit::attachment_info(
|
||||||
VkRenderingInfo vkinit::rendering_info(VkExtent2D renderExtent, VkRenderingAttachmentInfo* colorAttachment,
|
VkRenderingInfo vkinit::rendering_info(VkExtent2D renderExtent, VkRenderingAttachmentInfo* colorAttachment,
|
||||||
VkRenderingAttachmentInfo* depthAttachment)
|
VkRenderingAttachmentInfo* depthAttachment)
|
||||||
{
|
{
|
||||||
VkRenderingInfo renderInfo {};
|
return {
|
||||||
renderInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
|
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||||
renderInfo.pNext = nullptr;
|
.renderArea = VkRect2D { VkOffset2D { 0, 0 }, renderExtent },
|
||||||
|
.layerCount = 1,
|
||||||
renderInfo.renderArea = VkRect2D { VkOffset2D { 0, 0 }, renderExtent };
|
.colorAttachmentCount = 1,
|
||||||
renderInfo.layerCount = 1;
|
.pColorAttachments = colorAttachment,
|
||||||
renderInfo.colorAttachmentCount = 1;
|
.pDepthAttachment = depthAttachment,
|
||||||
renderInfo.pColorAttachments = colorAttachment;
|
.pStencilAttachment = nullptr,
|
||||||
renderInfo.pDepthAttachment = depthAttachment;
|
};
|
||||||
renderInfo.pStencilAttachment = nullptr;
|
|
||||||
|
|
||||||
return renderInfo;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,13 @@ bool vkutil::load_shader_module(const char* filePath,
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
VkShaderModuleCreateInfo createInfo = {};
|
VkShaderModuleCreateInfo createInfo = {
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||||
createInfo.pNext = nullptr;
|
.pNext = nullptr,
|
||||||
|
// codeSize has to be in bytes
|
||||||
// codeSize has to be in bytes
|
.codeSize = buffer.size() * sizeof(uint32_t),
|
||||||
createInfo.codeSize = buffer.size() * sizeof(uint32_t);
|
.pCode = buffer.data(),
|
||||||
createInfo.pCode = buffer.data();
|
};
|
||||||
|
|
||||||
VkShaderModule shaderModule;
|
VkShaderModule shaderModule;
|
||||||
if(vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
|
if(vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
|
||||||
|
|
|
||||||
17
vk_types.h
17
vk_types.h
|
|
@ -37,3 +37,20 @@ struct AllocatedImage {
|
||||||
VkExtent3D imageExtent;
|
VkExtent3D imageExtent;
|
||||||
VkFormat imageFormat;
|
VkFormat imageFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ComputePushConstants {
|
||||||
|
glm::vec4 data1;
|
||||||
|
glm::vec4 data2;
|
||||||
|
glm::vec4 data3;
|
||||||
|
glm::vec4 data4;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ComputeEffect {
|
||||||
|
const char *name;
|
||||||
|
VkPipeline pipeline;
|
||||||
|
VkPipelineLayout layout;
|
||||||
|
|
||||||
|
ComputePushConstants data;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr unsigned int FRAME_OVERLAP=2;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
[wrap-file]
|
|
||||||
directory = nlohmann_json-3.11.3
|
|
||||||
lead_directory_missing = true
|
|
||||||
source_url = https://github.com/nlohmann/json/releases/download/v3.11.3/include.zip
|
|
||||||
source_filename = nlohmann_json-3.11.3.zip
|
|
||||||
source_hash = a22461d13119ac5c78f205d3df1db13403e58ce1bb1794edc9313677313f4a9d
|
|
||||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/nlohmann_json_3.11.3-1/nlohmann_json-3.11.3.zip
|
|
||||||
wrapdb_version = 3.11.3-1
|
|
||||||
|
|
||||||
[provide]
|
|
||||||
nlohmann_json = nlohmann_json_dep
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue