Now have a blue screen.
This commit is contained in:
parent
7298568818
commit
8a7ef61c78
11 changed files with 527 additions and 55 deletions
2
Makefile
2
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
all: build test
|
||||
all: build
|
||||
|
||||
reset:
|
||||
ifeq '$(OS)' 'Windows_NT'
|
||||
|
|
|
|||
2
main.cpp
2
main.cpp
|
|
@ -1,6 +1,6 @@
|
|||
#include <vk_engine.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
int main()
|
||||
{
|
||||
VulkanEngine engine;
|
||||
|
||||
|
|
|
|||
15
meson.build
15
meson.build
|
|
@ -7,6 +7,8 @@ project('hellovulk', 'cpp',
|
|||
'cpp_args=-D_GLIBCXX_DEBUG=1 -D_GLIBCXX_DEBUG_PEDANTIC=1',
|
||||
])
|
||||
|
||||
cmake = import('cmake')
|
||||
|
||||
# use this for common options only for our executables
|
||||
cpp_args=[]
|
||||
link_args=[]
|
||||
|
|
@ -54,16 +56,20 @@ elif build_machine.system() == 'darwin'
|
|||
endif
|
||||
|
||||
vma = subproject('vulkan-memory-allocator').get_variable('vma_allocator_dep')
|
||||
vulkanheaders = subproject('vulkan-headers').get_variable('vulkan_headers_dep')
|
||||
|
||||
vkbootstrap = subproject('vk-bootstrap').get_variable('vk_bootstrap_dep')
|
||||
glm = subproject('glm').get_variable('glm_dep')
|
||||
imgui = subproject('imgui').get_variable('imgui_dep')
|
||||
sdl2 = subproject('sdl2').get_variable('sdl2_dep')
|
||||
|
||||
opts = cmake.subproject_options()
|
||||
opts.add_cmake_defines({
|
||||
'VK_BOOTSTRAP_TEST': false,
|
||||
'VK_BOOTSTRAP_INSTALL': false,
|
||||
})
|
||||
vkbootstrap_proj = cmake.subproject('vk-bootstrap', options: opts)
|
||||
vkbootstrap = vkbootstrap_proj.get_variable('vk_bootstrap_dep')
|
||||
|
||||
dependencies += [
|
||||
vma,
|
||||
vulkanheaders,
|
||||
vkbootstrap,
|
||||
glm,
|
||||
imgui,
|
||||
|
|
@ -73,6 +79,7 @@ dependencies += [
|
|||
sources = [
|
||||
'vk_initializers.cpp',
|
||||
'vk_engine.cpp',
|
||||
'vk_images.cpp',
|
||||
'main.cpp',
|
||||
]
|
||||
|
||||
|
|
|
|||
0
scripts/reset_build.sh
Normal file → Executable file
0
scripts/reset_build.sh
Normal file → Executable file
298
vk_engine.cpp
298
vk_engine.cpp
|
|
@ -1,5 +1,9 @@
|
|||
|
||||
/*
|
||||
* Stopped at https://vkguide.dev/docs/new_chapter_1/vulkan_mainloop_code/
|
||||
*/
|
||||
|
||||
#include "vk_engine.h"
|
||||
#include "vk_images.h"
|
||||
#include <print>
|
||||
|
||||
#include <SDL.h>
|
||||
|
|
@ -7,54 +11,282 @@
|
|||
|
||||
#include <vk_types.h>
|
||||
#include <vk_initializers.h>
|
||||
#include "VkBootstrap.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
constexpr bool bUseValidationLayers = false;
|
||||
|
||||
VulkanEngine* loadedEngine = nullptr;
|
||||
|
||||
VulkanEngine& VulkanEngine::Get() {
|
||||
return *loadedEngine;
|
||||
}
|
||||
|
||||
void VulkanEngine::init()
|
||||
{
|
||||
// We initialize SDL and create a window with it.
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
assert(loadedEngine == nullptr);
|
||||
loadedEngine = this;
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
//everything went fine
|
||||
_isInitialized = true;
|
||||
// We initialize SDL and create a window with it.
|
||||
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_swapchain();
|
||||
init_commands();
|
||||
init_sync_structures();
|
||||
|
||||
//everything went fine
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
void VulkanEngine::cleanup()
|
||||
{
|
||||
if (_isInitialized) {
|
||||
SDL_DestroyWindow(_window);
|
||||
}
|
||||
{
|
||||
if (_isInitialized) {
|
||||
vkDeviceWaitIdle(_device);
|
||||
|
||||
for(int i = 0; i < FRAME_OVERLAP; i++) {
|
||||
vkDestroyCommandPool(_device, _frames[i]._commandPool, nullptr);
|
||||
|
||||
//destroy sync objects
|
||||
vkDestroyFence(_device, _frames[i]._renderFence, nullptr);
|
||||
vkDestroySemaphore(_device, _frames[i]._renderSemaphore, nullptr);
|
||||
vkDestroySemaphore(_device ,_frames[i]._swapchainSemaphore, nullptr);
|
||||
}
|
||||
|
||||
destroy_swapchain();
|
||||
|
||||
vkDestroySurfaceKHR(_instance, _surface, nullptr);
|
||||
vkDestroyDevice(_device, nullptr);
|
||||
vkb::destroy_debug_utils_messenger(_instance, _debug_messenger);
|
||||
vkDestroyInstance(_instance, nullptr);
|
||||
SDL_DestroyWindow(_window);
|
||||
}
|
||||
|
||||
loadedEngine = nullptr;
|
||||
}
|
||||
|
||||
void VulkanEngine::draw()
|
||||
{
|
||||
//nothing yet
|
||||
// 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(vkResetFences(_device, 1, &get_current_frame()._renderFence));
|
||||
|
||||
uint32_t swapchainImageIndex = 0;
|
||||
VK_CHECK(vkAcquireNextImageKHR(_device, _swapchain, 1000000000, get_current_frame()._swapchainSemaphore, nullptr, &swapchainImageIndex));
|
||||
|
||||
VkCommandBuffer cmd = get_current_frame()._mainCommandBuffer;
|
||||
VK_CHECK(vkResetCommandBuffer(cmd, 0));
|
||||
|
||||
VkCommandBufferBeginInfo cmdBeginInfo = vkinit::command_buffer_begin_info(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
|
||||
VK_CHECK(vkBeginCommandBuffer(cmd, &cmdBeginInfo));
|
||||
|
||||
vkutil::transition_image(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
VkClearColorValue clearValue;
|
||||
float flash = std::abs(std::sin(_frameNumber / 120.0f));
|
||||
clearValue = { { 0.0f, 0.0f, flash, 1.0f} };
|
||||
|
||||
VkImageSubresourceRange clearRange = vkinit::image_subresource_range(VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
vkCmdClearColorImage(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_GENERAL, &clearValue, 1, &clearRange);
|
||||
|
||||
vkutil::transition_image(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
VK_CHECK(vkEndCommandBuffer(cmd));
|
||||
|
||||
//prepare the submission to the queue.
|
||||
//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
|
||||
|
||||
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 signalInfo = vkinit::semaphore_submit_info(VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, get_current_frame()._renderSemaphore);
|
||||
|
||||
VkSubmitInfo2 submit = vkinit::submit_info(&cmdinfo,&signalInfo,&waitInfo);
|
||||
|
||||
//submit command buffer to the queue and execute it.
|
||||
// _renderFence will now block until the graphic commands finish execution
|
||||
VK_CHECK(vkQueueSubmit2(_graphicsQueue, 1, &submit, get_current_frame()._renderFence));
|
||||
|
||||
//prepare present
|
||||
// this will put the image we just rendered to into the visible window.
|
||||
// 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
|
||||
VkPresentInfoKHR presentInfo = {};
|
||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
presentInfo.pNext = nullptr;
|
||||
presentInfo.pSwapchains = &_swapchain;
|
||||
presentInfo.swapchainCount = 1;
|
||||
|
||||
presentInfo.pWaitSemaphores = &get_current_frame()._renderSemaphore;
|
||||
presentInfo.waitSemaphoreCount = 1;
|
||||
|
||||
presentInfo.pImageIndices = &swapchainImageIndex;
|
||||
|
||||
VK_CHECK(vkQueuePresentKHR(_graphicsQueue, &presentInfo));
|
||||
|
||||
//increase the number of frames drawn
|
||||
_frameNumber++;
|
||||
}
|
||||
|
||||
void VulkanEngine::run()
|
||||
{
|
||||
SDL_Event e;
|
||||
bool bQuit = false;
|
||||
SDL_Event e;
|
||||
bool bQuit = false;
|
||||
bool stop_rendering = false;
|
||||
|
||||
//main loop
|
||||
while (!bQuit)
|
||||
{
|
||||
//Handle events on queue
|
||||
while (SDL_PollEvent(&e) != 0)
|
||||
{
|
||||
//close the window when user alt-f4s or clicks the X button
|
||||
if (e.type == SDL_QUIT) bQuit = true;
|
||||
}
|
||||
//main loop
|
||||
while(!bQuit)
|
||||
{
|
||||
//Handle events on queue
|
||||
while(SDL_PollEvent(&e) != 0)
|
||||
{
|
||||
//close the window when user alt-f4s or clicks the X button
|
||||
if(e.type == SDL_QUIT) {
|
||||
bQuit = true;
|
||||
}
|
||||
|
||||
draw();
|
||||
if(e.type == SDL_WINDOWEVENT) {
|
||||
if(e.window.event == SDL_WINDOWEVENT_MINIMIZED) {
|
||||
stop_rendering = true;
|
||||
}
|
||||
|
||||
if(e.window.event == SDL_WINDOWEVENT_RESTORED) {
|
||||
stop_rendering = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(stop_rendering) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
continue;
|
||||
}
|
||||
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanEngine::init_vulkan() {
|
||||
vkb::InstanceBuilder builder;
|
||||
|
||||
// make the vulkan instance, with basic debug features
|
||||
|
||||
auto inst_ret = builder.set_app_name("Example Vulkan Application")
|
||||
.request_validation_layers(bUseValidationLayers)
|
||||
.use_default_debug_messenger()
|
||||
.require_api_version(1, 3, 0)
|
||||
.build();
|
||||
|
||||
vkb::Instance vkb_inst = inst_ret.value();
|
||||
|
||||
// grab the instance
|
||||
_instance = vkb_inst.instance;
|
||||
_debug_messenger = vkb_inst.debug_messenger;
|
||||
|
||||
SDL_Vulkan_CreateSurface(_window, _instance, &_surface);
|
||||
|
||||
//vulkan 1.3 features
|
||||
VkPhysicalDeviceVulkan13Features features{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES };
|
||||
features.dynamicRendering = true;
|
||||
features.synchronization2 = true;
|
||||
|
||||
//vulkan 1.2 features
|
||||
VkPhysicalDeviceVulkan12Features features12{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES };
|
||||
features12.bufferDeviceAddress = true;
|
||||
features12.descriptorIndexing = true;
|
||||
|
||||
// use vkbootstrap to select a gpu
|
||||
// We want a gpu that can write to the SDL surface
|
||||
vkb::PhysicalDeviceSelector selector{ vkb_inst };
|
||||
vkb::PhysicalDevice physicalDevice = selector
|
||||
.set_minimum_version(1, 4)
|
||||
.set_required_features_13(features)
|
||||
.set_required_features_12(features12)
|
||||
.set_surface(_surface)
|
||||
.select()
|
||||
.value();
|
||||
|
||||
vkb::DeviceBuilder deviceBuilder{physicalDevice};
|
||||
vkb::Device vkbDevice = deviceBuilder.build().value();
|
||||
|
||||
_device = vkbDevice.device;
|
||||
_chosenGPU = physicalDevice.physical_device;
|
||||
|
||||
_graphicsQueue = vkbDevice.get_queue(vkb::QueueType::graphics).value();
|
||||
_graphicsQueueFamily = vkbDevice.get_queue_index(vkb::QueueType::graphics).value();
|
||||
}
|
||||
|
||||
void VulkanEngine::create_swapchain(uint32_t width, uint32_t height) {
|
||||
vkb::SwapchainBuilder swapchainBuilder{ _chosenGPU, _device, _surface};
|
||||
|
||||
_swapchainImageFormat = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
|
||||
vkb::Swapchain vkbSwapchain = swapchainBuilder
|
||||
//.use_default_format_selection()
|
||||
.set_desired_format(VkSurfaceFormatKHR{.format=_swapchainImageFormat})
|
||||
// use vsync present mode
|
||||
.set_desired_present_mode(VK_PRESENT_MODE_FIFO_KHR)
|
||||
.set_desired_extent(width, height)
|
||||
.add_image_usage_flags(VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
||||
.build()
|
||||
.value();
|
||||
|
||||
_swapchainExtent = vkbSwapchain.extent;
|
||||
_swapchain = vkbSwapchain.swapchain;
|
||||
_swapchainImages = vkbSwapchain.get_images().value();
|
||||
_swapchainImageViews = vkbSwapchain.get_image_views().value();
|
||||
}
|
||||
|
||||
void VulkanEngine::destroy_swapchain() {
|
||||
vkDestroySwapchainKHR(_device, _swapchain, nullptr);
|
||||
|
||||
for(auto& view : _swapchainImageViews) {
|
||||
vkDestroyImageView(_device, view, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanEngine::init_swapchain() {
|
||||
create_swapchain(_windowExtent.width, _windowExtent.height);
|
||||
}
|
||||
|
||||
void VulkanEngine::init_commands() {
|
||||
//create a command pool for commands submitted to the graphics queue.
|
||||
//we also want the pool to allow for resetting of individual command buffers
|
||||
VkCommandPoolCreateInfo commandPoolInfo = vkinit::command_pool_create_info(_graphicsQueueFamily, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
|
||||
|
||||
for (int i = 0; i < FRAME_OVERLAP; i++) {
|
||||
|
||||
VK_CHECK(vkCreateCommandPool(_device, &commandPoolInfo, nullptr, &_frames[i]._commandPool));
|
||||
|
||||
// allocate the default command buffer that we will use for rendering
|
||||
VkCommandBufferAllocateInfo cmdAllocInfo = vkinit::command_buffer_allocate_info(_frames[i]._commandPool, 1);
|
||||
|
||||
VK_CHECK(vkAllocateCommandBuffers(_device, &cmdAllocInfo, &_frames[i]._mainCommandBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanEngine::init_sync_structures() {
|
||||
VkFenceCreateInfo fenceCreateInfo = vkinit::fence_create_info(VK_FENCE_CREATE_SIGNALED_BIT);
|
||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vkinit::semaphore_create_info();
|
||||
|
||||
for (int i = 0; i < FRAME_OVERLAP; i++) {
|
||||
VK_CHECK(vkCreateFence(_device, &fenceCreateInfo, nullptr, &_frames[i]._renderFence));
|
||||
|
||||
VK_CHECK(vkCreateSemaphore(_device, &semaphoreCreateInfo, nullptr, &_frames[i]._swapchainSemaphore));
|
||||
VK_CHECK(vkCreateSemaphore(_device, &semaphoreCreateInfo, nullptr, &_frames[i]._renderSemaphore));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
70
vk_engine.h
70
vk_engine.h
|
|
@ -5,25 +5,71 @@
|
|||
|
||||
#include <vk_types.h>
|
||||
|
||||
struct FrameData {
|
||||
VkCommandPool _commandPool;
|
||||
VkCommandBuffer _mainCommandBuffer;
|
||||
VkSemaphore _swapchainSemaphore;
|
||||
VkSemaphore _renderSemaphore;
|
||||
VkFence _renderFence;
|
||||
};
|
||||
|
||||
constexpr unsigned int FRAME_OVERLAP=2;
|
||||
|
||||
class VulkanEngine {
|
||||
public:
|
||||
// device selection
|
||||
VkInstance _instance;
|
||||
VkDebugUtilsMessengerEXT _debug_messenger;
|
||||
VkPhysicalDevice _chosenGPU;
|
||||
VkDevice _device;
|
||||
VkSurfaceKHR _surface;
|
||||
|
||||
bool _isInitialized{ false };
|
||||
int _frameNumber {0};
|
||||
// swapchain
|
||||
VkSwapchainKHR _swapchain;
|
||||
VkFormat _swapchainImageFormat;
|
||||
|
||||
VkExtent2D _windowExtent{ 1700 , 900 };
|
||||
std::vector<VkImage> _swapchainImages;
|
||||
std::vector<VkImageView> _swapchainImageViews;
|
||||
VkExtent2D _swapchainExtent;
|
||||
|
||||
struct SDL_Window* _window{ nullptr };
|
||||
// frames/command buffer
|
||||
int _frameNumber {0};
|
||||
FrameData _frames[FRAME_OVERLAP];
|
||||
|
||||
//initializes everything in the engine
|
||||
void init();
|
||||
FrameData& get_current_frame() {
|
||||
return _frames[_frameNumber % FRAME_OVERLAP];
|
||||
}
|
||||
|
||||
//shuts down the engine
|
||||
void cleanup();
|
||||
VkQueue _graphicsQueue;
|
||||
uint32_t _graphicsQueueFamily;
|
||||
|
||||
//draw loop
|
||||
void draw();
|
||||
// internal data
|
||||
bool _isInitialized{ false };
|
||||
|
||||
//run main loop
|
||||
void run();
|
||||
VkExtent2D _windowExtent{ 1700 , 900 };
|
||||
|
||||
struct SDL_Window* _window{ nullptr };
|
||||
|
||||
static VulkanEngine& Get();
|
||||
|
||||
//initializes everything in the engine
|
||||
void init();
|
||||
|
||||
//shuts down the engine
|
||||
void cleanup();
|
||||
|
||||
//draw loop
|
||||
void draw();
|
||||
|
||||
//run main loop
|
||||
void run();
|
||||
|
||||
private:
|
||||
void init_vulkan();
|
||||
void init_swapchain();
|
||||
void init_commands();
|
||||
void init_sync_structures();
|
||||
|
||||
void create_swapchain(uint32_t width, uint32_t height);
|
||||
void destroy_swapchain();
|
||||
};
|
||||
|
|
|
|||
30
vk_images.cpp
Normal file
30
vk_images.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include "vk_images.h"
|
||||
#include "vk_initializers.h"
|
||||
|
||||
void vkutil::transition_image(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout newLayout)
|
||||
{
|
||||
VkImageMemoryBarrier2 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;
|
||||
imageBarrier.subresourceRange = vkinit::image_subresource_range(aspectMask);
|
||||
imageBarrier.image = image;
|
||||
|
||||
VkDependencyInfo depInfo{};
|
||||
depInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
|
||||
depInfo.pNext = nullptr;
|
||||
|
||||
depInfo.imageMemoryBarrierCount = 1;
|
||||
depInfo.pImageMemoryBarriers = &imageBarrier;
|
||||
|
||||
vkCmdPipelineBarrier2(cmd, &depInfo);
|
||||
}
|
||||
7
vk_images.h
Normal file
7
vk_images.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
namespace vkutil {
|
||||
void transition_image(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout newLayout);
|
||||
}
|
||||
|
|
@ -1 +1,110 @@
|
|||
#include <vk_initializers.h>
|
||||
|
||||
VkCommandPoolCreateInfo vkinit::command_pool_create_info(uint32_t queueFamilyIndex,
|
||||
VkCommandPoolCreateFlags flags /*= 0*/)
|
||||
{
|
||||
VkCommandPoolCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
info.pNext = nullptr;
|
||||
info.queueFamilyIndex = queueFamilyIndex;
|
||||
info.flags = flags;
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
VkCommandBufferAllocateInfo vkinit::command_buffer_allocate_info(
|
||||
VkCommandPool pool, uint32_t count /*= 1*/)
|
||||
{
|
||||
VkCommandBufferAllocateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
info.pNext = nullptr;
|
||||
|
||||
info.commandPool = pool;
|
||||
info.commandBufferCount = count;
|
||||
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
return info;
|
||||
}
|
||||
|
||||
VkFenceCreateInfo vkinit::fence_create_info(VkFenceCreateFlags flags /*=0*/)
|
||||
{
|
||||
VkFenceCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
info.pNext = nullptr;
|
||||
info.flags = flags;
|
||||
return info;
|
||||
}
|
||||
|
||||
VkSemaphoreCreateInfo vkinit::semaphore_create_info(VkSemaphoreCreateFlags flags/*=0*/)
|
||||
{
|
||||
VkSemaphoreCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
info.pNext = nullptr;
|
||||
info.flags = flags;
|
||||
return info;
|
||||
}
|
||||
|
||||
VkCommandBufferBeginInfo vkinit::command_buffer_begin_info(VkCommandBufferUsageFlags flags /*= 0*/)
|
||||
{
|
||||
VkCommandBufferBeginInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
info.pNext = nullptr;
|
||||
|
||||
info.pInheritanceInfo = nullptr;
|
||||
info.flags = flags;
|
||||
return info;
|
||||
}
|
||||
|
||||
VkImageSubresourceRange vkinit::image_subresource_range(VkImageAspectFlags aspectMask)
|
||||
{
|
||||
VkImageSubresourceRange subImage {};
|
||||
subImage.aspectMask = aspectMask;
|
||||
subImage.baseMipLevel = 0;
|
||||
subImage.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
subImage.baseArrayLayer = 0;
|
||||
subImage.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||
|
||||
return subImage;
|
||||
}
|
||||
|
||||
VkSemaphoreSubmitInfo vkinit::semaphore_submit_info(VkPipelineStageFlags2 stageMask, VkSemaphore semaphore)
|
||||
{
|
||||
VkSemaphoreSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO;
|
||||
submitInfo.pNext = nullptr;
|
||||
submitInfo.semaphore = semaphore;
|
||||
submitInfo.stageMask = stageMask;
|
||||
submitInfo.deviceIndex = 0;
|
||||
submitInfo.value = 1;
|
||||
|
||||
return submitInfo;
|
||||
}
|
||||
|
||||
VkCommandBufferSubmitInfo vkinit::command_buffer_submit_info(VkCommandBuffer cmd)
|
||||
{
|
||||
VkCommandBufferSubmitInfo info{};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO;
|
||||
info.pNext = nullptr;
|
||||
info.commandBuffer = cmd;
|
||||
info.deviceMask = 0;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
VkSubmitInfo2 vkinit::submit_info(VkCommandBufferSubmitInfo* cmd, VkSemaphoreSubmitInfo* signalSemaphoreInfo,
|
||||
VkSemaphoreSubmitInfo* waitSemaphoreInfo)
|
||||
{
|
||||
VkSubmitInfo2 info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2;
|
||||
info.pNext = nullptr;
|
||||
|
||||
info.waitSemaphoreInfoCount = waitSemaphoreInfo == nullptr ? 0 : 1;
|
||||
info.pWaitSemaphoreInfos = waitSemaphoreInfo;
|
||||
|
||||
info.signalSemaphoreInfoCount = signalSemaphoreInfo == nullptr ? 0 : 1;
|
||||
info.pSignalSemaphoreInfos = signalSemaphoreInfo;
|
||||
|
||||
info.commandBufferInfoCount = 1;
|
||||
info.pCommandBufferInfos = cmd;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,24 @@
|
|||
|
||||
namespace vkinit {
|
||||
|
||||
//vulkan init code goes here
|
||||
VkCommandPoolCreateInfo command_pool_create_info(uint32_t queueFamilyIndex,
|
||||
VkCommandPoolCreateFlags flags=0);
|
||||
|
||||
VkCommandBufferAllocateInfo command_buffer_allocate_info(
|
||||
VkCommandPool pool, uint32_t count=1);
|
||||
|
||||
VkFenceCreateInfo fence_create_info(VkFenceCreateFlags flags=0);
|
||||
|
||||
VkSemaphoreCreateInfo semaphore_create_info(VkSemaphoreCreateFlags flags=0);
|
||||
|
||||
VkCommandBufferBeginInfo command_buffer_begin_info(VkCommandBufferUsageFlags flags=0);
|
||||
|
||||
VkImageSubresourceRange image_subresource_range(VkImageAspectFlags aspectMask);
|
||||
|
||||
VkSemaphoreSubmitInfo semaphore_submit_info(VkPipelineStageFlags2 stageMask, VkSemaphore semaphore);
|
||||
|
||||
VkCommandBufferSubmitInfo command_buffer_submit_info(VkCommandBuffer cmd);
|
||||
|
||||
VkSubmitInfo2 submit_info(VkCommandBufferSubmitInfo* cmd, VkSemaphoreSubmitInfo* signalSemaphoreInfo, VkSemaphoreSubmitInfo* waitSemaphoreInfo);
|
||||
}
|
||||
|
||||
|
|
|
|||
29
vk_types.h
29
vk_types.h
|
|
@ -1,8 +1,31 @@
|
|||
// vulkan_guide.h : Include file for standard system include files,
|
||||
// or project specific include files.
|
||||
// or project specific include files.
|
||||
//we will add our main reusable types here
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <deque>
|
||||
|
||||
//we will add our main reusable types here
|
||||
#include <vulkan/vulkan.h>
|
||||
// #include <vulkan/vk_enum_string_helper.h>
|
||||
#include <vk_mem_alloc.h>
|
||||
|
||||
#include <print>
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#define VK_CHECK(x)\
|
||||
do {\
|
||||
VkResult err = x;\
|
||||
if (err) {\
|
||||
std::println("Detected Vulkan error: {}", int(err));\
|
||||
}\
|
||||
} while (0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue