Revert "moved settings to separate header"
This reverts commit 3adcc72036
.
This commit is contained in:
parent
3adcc72036
commit
c4e491d9b7
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,7 +6,6 @@ old
|
|||||||
shaders
|
shaders
|
||||||
stb_image.h
|
stb_image.h
|
||||||
*.log
|
*.log
|
||||||
vk.xml
|
|
||||||
textures
|
textures
|
||||||
tiny_obj_loader.h
|
tiny_obj_loader.h
|
||||||
vk_enum_string.h
|
vk_enum_string.h
|
||||||
|
16
compile.sh
16
compile.sh
@ -1,16 +1,12 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
WDIR=$HOME/c++/vulkan
|
WDIR=$HOME/c++/vulkan
|
||||||
SHADER_DIR=$WDIR/shaders
|
|
||||||
SOURCE_DIR=$WDIR/src/shaders
|
|
||||||
|
|
||||||
mkdir -p "${SHADER_DIR}"
|
mkdir -p $WDIR/shaders
|
||||||
|
|
||||||
for file in $(ls ${SOURCE_DIR}); do
|
glslc $WDIR/shader.vert -o $WDIR/shaders/vert.spv
|
||||||
ext="${file##*.}"
|
glslc $WDIR/shader.frag -o $WDIR/shaders/frag.spv
|
||||||
if [[ $ext == "vert" ]] || [[ $ext == "frag" ]]; then
|
|
||||||
echo "compiling ${file}"
|
glslc $WDIR/shader2D.vert -o $WDIR/shaders/vert2D.spv
|
||||||
glslc ${SOURCE_DIR}/${file} -o ${SHADER_DIR}/$(basename ${file}).spv
|
glslc $WDIR/shader2D.frag -o $WDIR/shaders/frag2D.spv
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,10 +48,7 @@ $(OBJECT_DIRS):
|
|||||||
# Extras Options
|
# Extras Options
|
||||||
#
|
#
|
||||||
# with debug flags
|
# with debug flags
|
||||||
.PHONY += shader debug run gdb pch clean docs
|
.PHONY += debug run gdb pch clean docs
|
||||||
shader:
|
|
||||||
sh ../compile.sh
|
|
||||||
|
|
||||||
debug: CXXFLAGS += -g # -DDEBUG
|
debug: CXXFLAGS += -g # -DDEBUG
|
||||||
debug: default
|
debug: default
|
||||||
|
|
||||||
|
33
src/main.cpp
33
src/main.cpp
@ -1,31 +1,30 @@
|
|||||||
|
#include "main.hpp"
|
||||||
|
|
||||||
#include "shape.hpp"
|
#include "shape.hpp"
|
||||||
#include "vulkan_instance.hpp"
|
#include "vulkan_instance.hpp"
|
||||||
#include "renderer2D.hpp"
|
#include "renderer2D.hpp"
|
||||||
#include "renderer3D.hpp"
|
#include "renderer3D.hpp"
|
||||||
#include "vulkan_settings.hpp"
|
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <ratio>
|
#include <ratio>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
int mainLoop() {
|
int mainLoop() {
|
||||||
LogCreateInfo logCI {
|
LogCreateInfo logCI{};
|
||||||
.logfile = "main.log",
|
logCI.logfile = "main.log";
|
||||||
.storeLog = false,
|
logCI.storeLog = false;
|
||||||
.prefix = "Main",
|
logCI.prefix = "Main";
|
||||||
.prefixColor = Color::BG_RED,
|
logCI.prefixColor = Color::BG_RED;
|
||||||
.timeColor = settings::VULKAN_MESSAGE_TIME_COLOR,
|
logCI.timeColor = VULKAN_MESSAGE_TIME_COLOR;
|
||||||
};
|
|
||||||
Log log(std::move(logCI));
|
Log log(std::move(logCI));
|
||||||
|
|
||||||
gz::SettingsManagerCreateInfo<VULKAN_SETTINGS_MAN_TYPES> smCI {
|
gz::SettingsManagerCreateInfo<SettingsTypes> smCI{};
|
||||||
.filepath = settings::CONFIG_FILE,
|
smCI.filepath = gz::vk::CONFIG_FILE;
|
||||||
.initialValues = settings::INITIAL_SETTINGS,
|
smCI.readFileOnCreation = true;
|
||||||
.readFileOnCreation = true,
|
smCI.writeFileOnExit = true;
|
||||||
.writeFileOnExit = true,
|
smCI.initialValues = gz::vk::INITIAL_SETTINGS;
|
||||||
.throwExceptionWhenNewValueNotAllowed = true,
|
smCI.throwExceptionWhenNewValueNotAllowed = true;
|
||||||
};
|
|
||||||
|
|
||||||
VulkanInstance vulkanInstance(smCI);
|
VulkanInstance vulkanInstance(smCI);
|
||||||
vulkanInstance.init();
|
vulkanInstance.init();
|
||||||
@ -91,5 +90,5 @@ namespace gz::vlk {
|
|||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
return gz::vlk::mainLoop();
|
return gz::vk::mainLoop();
|
||||||
}
|
}
|
||||||
|
19
src/main.hpp
Normal file
19
src/main.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
namespace gz::vk {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace gz::vk
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "vulkan_instance.hpp"
|
#include "vulkan_instance.hpp"
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
void Renderer::cleanup_(){
|
void Renderer::cleanup_(){
|
||||||
vk.destroyCommandBuffers(commandBuffers);
|
vk.destroyCommandBuffers(commandBuffers);
|
||||||
|
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
|
||||||
#define VULKAN_HPP_NO_EXCEPTIONS
|
|
||||||
#include <vulkan/vulkan.hpp>
|
|
||||||
|
|
||||||
// includes for child classes
|
// includes for child classes
|
||||||
#include "vulkan_util.hpp"
|
|
||||||
#include <gz-util/log.hpp>
|
|
||||||
|
|
||||||
#include "texture_manager.hpp"
|
#include "texture_manager.hpp"
|
||||||
#include "vertex.hpp"
|
#include "vertex.hpp"
|
||||||
#include "vulkan_allocator.hpp"
|
#include "vulkan_allocator.hpp"
|
||||||
|
#include <gz-util/log.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
/// Defined in texture_manager.hpp
|
/// Defined in texture_manager.hpp
|
||||||
class TextureManager;
|
class TextureManager;
|
||||||
/// Defined in vulkan_instance.hpp
|
/// Defined in vulkan_instance.hpp
|
||||||
@ -37,13 +31,13 @@ namespace gz::vlk {
|
|||||||
VulkanInstance& vk;
|
VulkanInstance& vk;
|
||||||
TextureManager& textureManager;
|
TextureManager& textureManager;
|
||||||
|
|
||||||
std::vector<vk::CommandBuffer> commandBuffers;
|
std::vector<VkCommandBuffer> commandBuffers;
|
||||||
/// On device local memory
|
/// On device local memory
|
||||||
vk::Buffer vertexBuffer;
|
VkBuffer vertexBuffer;
|
||||||
MemoryInfo vertexBufferMemory;
|
MemoryInfo vertexBufferMemory;
|
||||||
vk::DeviceSize vertexBufferSize;
|
VkDeviceSize vertexBufferSize;
|
||||||
vk::Buffer indexBuffer;
|
VkBuffer indexBuffer;
|
||||||
MemoryInfo indexBufferMemory;
|
MemoryInfo indexBufferMemory;
|
||||||
vk::DeviceSize indexBufferSize;
|
VkDeviceSize indexBufferSize;
|
||||||
}; // class RendererBase
|
}; // class RendererBase
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
#include "renderer2D.hpp"
|
#include "renderer2D.hpp"
|
||||||
|
|
||||||
#include "exceptions.hpp"
|
#include "exceptions.hpp"
|
||||||
|
#include "vk_enum_string.h"
|
||||||
#include "vulkan_allocator.hpp"
|
#include "vulkan_allocator.hpp"
|
||||||
#include "vulkan_instance.hpp"
|
#include "vulkan_instance.hpp"
|
||||||
#include "texture_manager.hpp"
|
#include "texture_manager.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdexcept>
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
namespace gz::vlk {
|
|
||||||
|
namespace gz::vk {
|
||||||
|
|
||||||
//
|
//
|
||||||
// INIT & CLEANUP
|
// INIT & CLEANUP
|
||||||
@ -18,13 +19,12 @@ namespace gz::vlk {
|
|||||||
Renderer2D::Renderer2D(VulkanInstance& instance, TextureManager& textureManager) :
|
Renderer2D::Renderer2D(VulkanInstance& instance, TextureManager& textureManager) :
|
||||||
Renderer(instance, textureManager)
|
Renderer(instance, textureManager)
|
||||||
{
|
{
|
||||||
LogCreateInfo logCI {
|
LogCreateInfo logCI{};
|
||||||
.logfile = "renderer2D.log",
|
logCI.logfile = "renderer2D.log";
|
||||||
.storeLog = false,
|
logCI.storeLog = false;
|
||||||
.prefix = "2D-Renderer",
|
logCI.prefix = "2D-Renderer";
|
||||||
.prefixColor = Color::LI_MAGENTA,
|
logCI.prefixColor = Color::LI_MAGENTA;
|
||||||
.timeColor = settings::VULKAN_MESSAGE_TIME_COLOR,
|
logCI.timeColor = VULKAN_MESSAGE_TIME_COLOR;
|
||||||
};
|
|
||||||
rLog = Log(std::move(logCI));
|
rLog = Log(std::move(logCI));
|
||||||
|
|
||||||
vk.registerCleanupCallback(std::bind(&Renderer2D::cleanup, this));
|
vk.registerCleanupCallback(std::bind(&Renderer2D::cleanup, this));
|
||||||
@ -59,19 +59,8 @@ namespace gz::vlk {
|
|||||||
createRenderPass();
|
createRenderPass();
|
||||||
createImages();
|
createImages();
|
||||||
vk.createFramebuffers(framebuffers, imageViews, renderPass);
|
vk.createFramebuffers(framebuffers, imageViews, renderPass);
|
||||||
std::vector<vk::DescriptorSetLayout> descriptorSetLayouts = { textureManager.getDescriptorSetLayout() };
|
std::vector<VkDescriptorSetLayout> descriptorSetLayouts = { textureManager.getDescriptorSetLayout() };
|
||||||
|
vk.createGraphicsPipeline<Vertex2D>("shaders/vert2D.spv", "shaders/frag2D.spv", descriptorSetLayouts, false, renderPass, pipelines[PL_2D]);
|
||||||
// specialization constant for sampler2D array length = atlas count
|
|
||||||
vk::SpecializationMapEntry specME {
|
|
||||||
.constantID = 0,
|
|
||||||
.offset = 0,
|
|
||||||
.size = sizeof(uint32_t),
|
|
||||||
};
|
|
||||||
uint32_t atlasCount = textureManager.getAtlasCount();
|
|
||||||
vk::SpecializationInfo specI;
|
|
||||||
specI.setData<uint32_t>(atlasCount);
|
|
||||||
specI.setMapEntries(specME);
|
|
||||||
vk.createGraphicsPipeline<Vertex2D>("shaders/vert2D.spv", "shaders/frag2D.spv", descriptorSetLayouts, false, renderPass, pipelines[PL_2D], &specI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -85,7 +74,7 @@ namespace gz::vlk {
|
|||||||
vk.destroyImageView(imageViews[i]);
|
vk.destroyImageView(imageViews[i]);
|
||||||
vk.destroyImage(images[i], imageMemory[i]);
|
vk.destroyImage(images[i], imageMemory[i]);
|
||||||
}
|
}
|
||||||
vk.getDevice().destroyRenderPass(renderPass, nullptr);
|
vkDestroyRenderPass(vk.getDevice(), renderPass, nullptr);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -104,10 +93,10 @@ namespace gz::vlk {
|
|||||||
images.resize(vk.getScImages().size());
|
images.resize(vk.getScImages().size());
|
||||||
imageMemory.resize(vk.getScImages().size());
|
imageMemory.resize(vk.getScImages().size());
|
||||||
imageViews.resize(vk.getScImages().size());
|
imageViews.resize(vk.getScImages().size());
|
||||||
vk::ImageUsageFlags usage= vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc;
|
VkImageUsageFlags usage= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
for (size_t i = 0; i < images.size(); i++) {
|
for (size_t i = 0; i < images.size(); i++) {
|
||||||
vk.createImage(vk.getScExtent().width, vk.getScExtent().height, vk.getScImageFormat(), vk::ImageTiling::eOptimal, usage, vk::MemoryPropertyFlagBits::eDeviceLocal, images[i], imageMemory[i]);
|
vk.createImage(vk.getScExtent().width, vk.getScExtent().height, vk.getScImageFormat(), VK_IMAGE_TILING_OPTIMAL, usage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, images[i], imageMemory[i]);
|
||||||
vk.createImageView(vk.getScImageFormat(), images[i], imageViews[i], vk::ImageAspectFlagBits::eColor);
|
vk.createImageView(vk.getScImageFormat(), images[i], imageViews[i], VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,80 +104,87 @@ namespace gz::vlk {
|
|||||||
// RENDER PASS
|
// RENDER PASS
|
||||||
//
|
//
|
||||||
void Renderer2D::createRenderPass() {
|
void Renderer2D::createRenderPass() {
|
||||||
vk::AttachmentDescription2 colorBlendAttachment {
|
VkAttachmentDescription2 colorBlendAttachment{};
|
||||||
.format = vk.getScImageFormat(),
|
colorBlendAttachment.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2;
|
||||||
.samples = vk::SampleCountFlagBits::e1,
|
colorBlendAttachment.format = vk.getScImageFormat();
|
||||||
.loadOp = vk::AttachmentLoadOp::eClear,
|
colorBlendAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
.storeOp = vk::AttachmentStoreOp::eStore,
|
colorBlendAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
.stencilLoadOp = vk::AttachmentLoadOp::eDontCare,
|
colorBlendAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
.stencilStoreOp = vk::AttachmentStoreOp::eDontCare,
|
colorBlendAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
.initialLayout = vk::ImageLayout::eUndefined,
|
colorBlendAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
.finalLayout = vk::ImageLayout::eTransferSrcOptimal,
|
colorBlendAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
};
|
colorBlendAttachment.finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||||
|
|
||||||
vk::AttachmentReference2 colorAttachmentRef {
|
VkAttachmentReference2 colorAttachmentRef{};
|
||||||
.attachment = 0,
|
colorAttachmentRef.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2;
|
||||||
.layout = vk::ImageLayout::eColorAttachmentOptimal,
|
colorAttachmentRef.attachment = 0;
|
||||||
};
|
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
/* vk::AttachmentDescription depthAttachment { */
|
/* VkAttachmentDescription depthAttachment{}; */
|
||||||
/* depthAttachment.format = findDepthFormat(); */
|
/* depthAttachment.format = findDepthFormat(); */
|
||||||
/* depthAttachment.samples = vk::SampleCountFlagBits::e1; */
|
/* depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT; */
|
||||||
/* depthAttachment.loadOp = vk::AttachmentLoadOp::eClear; */
|
/* depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; */
|
||||||
/* depthAttachment.storeOp = vk::AttachmentStoreOp::eDontCare; */
|
/* depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; */
|
||||||
/* depthAttachment.stencilLoadOp = vk::AttachmentLoadOp::eDontCare; */
|
/* depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; */
|
||||||
/* depthAttachment.stencilStoreOp = vk::AttachmentStoreOp::eDontCare; */
|
/* depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; */
|
||||||
/* depthAttachment.initialLayout = vk::ImageLayout::eUndefined; */
|
/* depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; */
|
||||||
/* depthAttachment.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal; */
|
/* depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; */
|
||||||
|
|
||||||
/* vk::AttachmentReference depthAttachmentRef { */
|
/* VkAttachmentReference depthAttachmentRef{}; */
|
||||||
/* depthAttachmentRef.attachment = 1; */
|
/* depthAttachmentRef.attachment = 1; */
|
||||||
/* depthAttachmentRef.layout = vk::ImageLayout::eDepthStencilAttachmentOptimal; */
|
/* depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; */
|
||||||
|
|
||||||
vk::SubpassDescription2 subpass {
|
VkSubpassDescription2 subpass{};
|
||||||
.pipelineBindPoint = vk::PipelineBindPoint::eGraphics,
|
subpass.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2;
|
||||||
.colorAttachmentCount = 1,
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
.pColorAttachments = &colorAttachmentRef,
|
subpass.colorAttachmentCount = 1;
|
||||||
/* .pDepthStencilAttachment = &depthAttachmentRef, */
|
subpass.pColorAttachments = &colorAttachmentRef;
|
||||||
};
|
/* subpass.pDepthStencilAttachment = &depthAttachmentRef; */
|
||||||
|
|
||||||
vk::SubpassDependency2 colorAttachmentSD {
|
VkSubpassDependency2 colorAttachmentSD{};
|
||||||
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
colorAttachmentSD.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2;
|
||||||
.dstSubpass = 0,
|
colorAttachmentSD.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
colorAttachmentSD.dstSubpass = 0;
|
||||||
.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
colorAttachmentSD.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
.srcAccessMask = NO_ACC_FLAGS,
|
colorAttachmentSD.srcAccessMask = 0;
|
||||||
.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite,
|
colorAttachmentSD.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
};
|
colorAttachmentSD.dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
|
||||||
// dependecy for the image layout transition to transfer dst
|
// dependecy for the image layout transition to transfer dst
|
||||||
vk::SubpassDependency2 layoutTransitionSD {
|
VkSubpassDependency2 layoutTransitionSD{};
|
||||||
.srcSubpass = 0,
|
layoutTransitionSD.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2;
|
||||||
.dstSubpass = VK_SUBPASS_EXTERNAL,
|
layoutTransitionSD.srcSubpass = 0;
|
||||||
.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
layoutTransitionSD.dstSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
.dstStageMask = vk::PipelineStageFlagBits::eTransfer,
|
layoutTransitionSD.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
.srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite,
|
layoutTransitionSD.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
.dstAccessMask = vk::AccessFlagBits::eTransferRead,
|
layoutTransitionSD.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
|
||||||
.dependencyFlags = vk::DependencyFlagBits::eByRegion,
|
layoutTransitionSD.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT;
|
||||||
};
|
layoutTransitionSD.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||||
/* vk::SubpassDependency dependency { */
|
/* VkSubpassDependency dependency{}; */
|
||||||
/* dependency.srcSubpass = VK_SUBPASS_EXTERNAL; */
|
/* dependency.srcSubpass = VK_SUBPASS_EXTERNAL; */
|
||||||
/* dependency.dstSubpass = 0; */
|
/* dependency.dstSubpass = 0; */
|
||||||
/* dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests; */
|
/* dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; */
|
||||||
/* dependency.srcAccessMask = 0; */
|
/* dependency.srcAccessMask = 0; */
|
||||||
/* dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests; */
|
/* dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; */
|
||||||
/* dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentWrite; */
|
/* dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; */
|
||||||
|
|
||||||
/* std::array<vk::AttachmentDescription, 2> attachments = { colorBlendAttachment, depthAttachment }; */
|
/* std::array<VkAttachmentDescription, 2> attachments = { colorBlendAttachment, depthAttachment }; */
|
||||||
std::vector<vk::AttachmentDescription2> attachments = { colorBlendAttachment };
|
std::vector<VkAttachmentDescription2> attachments = { colorBlendAttachment };
|
||||||
std::vector<vk::SubpassDependency2> dependencies = { colorAttachmentSD, layoutTransitionSD };
|
std::vector<VkSubpassDependency2> dependencies = { colorAttachmentSD, layoutTransitionSD };
|
||||||
vk::RenderPassCreateInfo2 renderPassCI;
|
VkRenderPassCreateInfo2 renderPassCI{};
|
||||||
renderPassCI.setDependencies(dependencies);
|
renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2;
|
||||||
renderPassCI.setAttachments(attachments);
|
renderPassCI.attachmentCount = static_cast<uint32_t>(attachments.size());
|
||||||
renderPassCI.setSubpasses(subpass);
|
renderPassCI.pAttachments = attachments.data();
|
||||||
|
renderPassCI.subpassCount = 1;
|
||||||
vk::Result result = vk.getDevice().createRenderPass2(&renderPassCI, nullptr, &renderPass);
|
renderPassCI.pSubpasses = &subpass;
|
||||||
if (result != vk::Result::eSuccess) {
|
renderPassCI.dependencyCount = dependencies.size();
|
||||||
|
renderPassCI.pDependencies = dependencies.data();
|
||||||
|
/* renderPassCI.dependencyCount = 0; */
|
||||||
|
/* renderPassCI.pDependencies = nullptr; */
|
||||||
|
/* renderPassCI.correlatedViewMaskCount = 0; */
|
||||||
|
/* renderPassCI.pCorrelatedViewMasks = nullptr; */
|
||||||
|
VkResult result = vkCreateRenderPass2(vk.getDevice(), &renderPassCI, nullptr, &renderPass);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
throw getVkException(result, "Could not create render pass", "Renderer2D::createRenderPass");
|
throw getVkException(result, "Could not create render pass", "Renderer2D::createRenderPass");
|
||||||
}
|
}
|
||||||
rLog("createRenderPass: Created render pass.");
|
rLog("createRenderPass: Created render pass.");
|
||||||
@ -200,55 +196,54 @@ namespace gz::vlk {
|
|||||||
// RENDERING
|
// RENDERING
|
||||||
//
|
//
|
||||||
void Renderer2D::recordCommandBuffer(uint32_t imageIndex, uint32_t currentFrame) {
|
void Renderer2D::recordCommandBuffer(uint32_t imageIndex, uint32_t currentFrame) {
|
||||||
vk::CommandBufferBeginInfo commandBufferBI {
|
VkCommandBufferBeginInfo commandBufferBI{};
|
||||||
/* .flags = 0, */
|
commandBufferBI.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
/* .pInheritanceInfo = nullptr, */
|
/* commandBufferBI.flags = 0; */
|
||||||
};
|
/* commandBufferBI.pInheritanceInfo = nullptr; */
|
||||||
vk::Result result = commandBuffers[currentFrame].begin(&commandBufferBI);
|
VkResult result = vkBeginCommandBuffer(commandBuffers[currentFrame], &commandBufferBI);
|
||||||
if (result != vk::Result::eSuccess) {
|
if (result != VK_SUCCESS) {
|
||||||
throw getVkException(result, "Failed to begin 2D command buffer", "Renderer2D::recordCommandBuffer");
|
throw getVkException(result, "Failed to begin 2D command buffer", "Renderer2D::recordCommandBuffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkRenderPassBeginInfo renderPassBI{};
|
||||||
|
renderPassBI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
|
renderPassBI.renderPass = renderPass;
|
||||||
|
renderPassBI.framebuffer = framebuffers[imageIndex];
|
||||||
|
renderPassBI.renderArea.offset = { 0, 0 };
|
||||||
|
renderPassBI.renderArea.extent = vk.getScExtent();
|
||||||
// clear
|
// clear
|
||||||
std::array<vk::ClearValue, 1> clearValues{};
|
std::array<VkClearValue, 1> clearValues{};
|
||||||
vk::ClearColorValue clearColor{};
|
clearValues[0].color = {{1.0f, 0.0f, 0.0f, 1.0f}};
|
||||||
clearColor.setFloat32({ 0.0f, 0.0f, 0.1f, 0.5f });
|
|
||||||
clearValues[0].setColor(std::move(clearColor));
|
|
||||||
/* clearValues[1].depthStencil = {1.0f, 0}; */
|
/* clearValues[1].depthStencil = {1.0f, 0}; */
|
||||||
vk::RenderPassBeginInfo renderPassBI {
|
renderPassBI.clearValueCount = static_cast<uint32_t>(clearValues.size());
|
||||||
.renderPass = renderPass,
|
renderPassBI.pClearValues = clearValues.data();
|
||||||
.framebuffer = framebuffers[imageIndex],
|
|
||||||
.renderArea { .offset = { 0, 0 }, .extent = vk.getScExtent(), }
|
|
||||||
};
|
|
||||||
renderPassBI.setClearValues(clearValues);
|
|
||||||
|
|
||||||
commandBuffers[currentFrame].beginRenderPass(&renderPassBI, vk::SubpassContents::eInline);
|
vkCmdBeginRenderPass(commandBuffers[currentFrame], &renderPassBI, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
commandBuffers[currentFrame].bindPipeline(vk::PipelineBindPoint::eGraphics, pipelines[PL_2D].pipeline);
|
vkCmdBindPipeline(commandBuffers[currentFrame], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines[PL_2D].pipeline);
|
||||||
vk::Buffer vertexBuffers[] = { vertexBuffer };
|
VkBuffer vertexBuffers[] = { vertexBuffer };
|
||||||
vk::DeviceSize offsets[] = {0};
|
VkDeviceSize offsets[] = {0};
|
||||||
uint32_t bindingCount = 1;
|
uint32_t bindingCount = 1;
|
||||||
uint32_t binding = 0;
|
vkCmdBindVertexBuffers(commandBuffers[currentFrame], BINDING, bindingCount, vertexBuffers, offsets);
|
||||||
commandBuffers[currentFrame].bindVertexBuffers(binding, bindingCount, vertexBuffers, offsets);
|
|
||||||
// TODO use correct index type!
|
// TODO use correct index type!
|
||||||
commandBuffers[currentFrame].bindIndexBuffer(indexBuffer, NO_OFFSET, vk::IndexType::eUint32);
|
vkCmdBindIndexBuffer(commandBuffers[currentFrame], indexBuffer, NO_OFFSET, VK_INDEX_TYPE_UINT32);
|
||||||
|
|
||||||
uint32_t descriptorCount = 1;
|
uint32_t descriptorCount = 1;
|
||||||
uint32_t firstSet = 0;
|
uint32_t firstSet = 0;
|
||||||
uint32_t dynamicOffsetCount = 0;
|
uint32_t dynamicOffsetCount = 0;
|
||||||
uint32_t* dynamicOffsets = nullptr;
|
uint32_t* dynamicOffsets = nullptr;
|
||||||
commandBuffers[currentFrame].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelines[PL_2D].layout, firstSet, descriptorCount, &textureManager.getDescriptorSet(), dynamicOffsetCount, dynamicOffsets);
|
vkCmdBindDescriptorSets(commandBuffers[currentFrame], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines[PL_2D].layout, firstSet, descriptorCount, &textureManager.getDescriptorSet(), dynamicOffsetCount, dynamicOffsets);
|
||||||
|
|
||||||
int instanceCount = 1;
|
int instanceCount = 1;
|
||||||
int firstIndex = 0;
|
int firstIndex = 0;
|
||||||
int firstInstance = 0;
|
int firstInstance = 0;
|
||||||
commandBuffers[currentFrame].drawIndexed(static_cast<uint32_t>(shapesIndicesCount), instanceCount, firstIndex, NO_OFFSET, firstInstance);
|
vkCmdDrawIndexed(commandBuffers[currentFrame], static_cast<uint32_t>(shapesIndicesCount), instanceCount, firstIndex, NO_OFFSET, firstInstance);
|
||||||
commandBuffers[currentFrame].endRenderPass();
|
vkCmdEndRenderPass(commandBuffers[currentFrame]);
|
||||||
|
|
||||||
vk.copyImageToImage(commandBuffers[currentFrame], images[imageIndex], vk.getScImages()[imageIndex], vk.getScExtent());
|
vk.copyImageToImage(commandBuffers[currentFrame], images[imageIndex], vk.getScImages()[imageIndex], vk.getScExtent());
|
||||||
result = commandBuffers[currentFrame].end();
|
result = vkEndCommandBuffer(commandBuffers[currentFrame]);
|
||||||
if (result != vk::Result::eSuccess) {
|
if (result != VK_SUCCESS) {
|
||||||
rLog.error("Failed to record 2D - command buffer", "VkResult:", result);
|
rLog.error("Failed to record 2D - command buffer", "VkResult:", STR_VK_RESULT(result));
|
||||||
throw getVkException(result, "Failed to record 2D - command buffer", "Renderer2D::recordCommandBufferWithTexture");
|
throw getVkException(result, "Failed to record 2D - command buffer", "Renderer2D::recordCommandBufferWithTexture");
|
||||||
}
|
}
|
||||||
vk.submitThisFrame(commandBuffers[currentFrame]);
|
vk.submitThisFrame(commandBuffers[currentFrame]);
|
||||||
@ -262,24 +257,21 @@ namespace gz::vlk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create staging buffer
|
// create staging buffer
|
||||||
vk::Buffer stagingBuffer;
|
VkBuffer stagingBuffer;
|
||||||
MemoryInfo stagingBufferMemory;
|
MemoryInfo stagingBufferMemory;
|
||||||
vk.createBuffer(vertexBufferSize, vk::BufferUsageFlagBits::eTransferSrc, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, stagingBuffer, stagingBufferMemory);
|
vk.createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, stagingBuffer, stagingBufferMemory);
|
||||||
|
|
||||||
// fill staging buffer
|
// fill staging buffer
|
||||||
void* data;
|
void* data;
|
||||||
vk::Result result = vk.getDevice().mapMemory(stagingBufferMemory.memory, stagingBufferMemory.offset, vertexBufferSize, NO_MEM_FLAGS, &data);
|
vkMapMemory(vk.getDevice(), stagingBufferMemory.memory, stagingBufferMemory.offset, vertexBufferSize, NO_FLAGS, &data);
|
||||||
if (result != vk::Result::eSuccess) {
|
|
||||||
throw getVkException(result, "Failed to map staging buffer", "Renderer3D::fillVertexBufferWithShapes");
|
|
||||||
}
|
|
||||||
Vertex2D* vdata = reinterpret_cast<Vertex2D*>(data);
|
Vertex2D* vdata = reinterpret_cast<Vertex2D*>(data);
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
for (auto it = shapes.begin(); it != shapes.end(); it++) {
|
for (auto it = shapes.begin(); it != shapes.end(); it++) {
|
||||||
rLog.log0("fillVertexBufferWithShapes: copying vertex buffer nr", it - shapes.begin(), "-", it->getVertices(), "to address:", long(vdata + offset), " offset:", offset);
|
rLog("fillVertexBufferWithShapes: copying vertex buffer nr", it - shapes.begin(), "-", it->getVertices(), "to address:", long(vdata + offset), " offset:", offset);
|
||||||
memcpy(vdata+offset, it->getVertices().data(), it->getVertices().size() * sizeof(Vertex2D));
|
memcpy(vdata+offset, it->getVertices().data(), it->getVertices().size() * sizeof(Vertex2D));
|
||||||
offset += it->getVertices().size();
|
offset += it->getVertices().size();
|
||||||
}
|
}
|
||||||
vk.getDevice().unmapMemory(stagingBufferMemory.memory);
|
vkUnmapMemory(vk.getDevice(), stagingBufferMemory.memory);
|
||||||
// fill vertex buffer
|
// fill vertex buffer
|
||||||
vk.copyBuffer(stagingBuffer, vertexBuffer, vertexBufferSize);
|
vk.copyBuffer(stagingBuffer, vertexBuffer, vertexBufferSize);
|
||||||
vk.destroyBuffer(stagingBuffer, stagingBufferMemory);
|
vk.destroyBuffer(stagingBuffer, stagingBufferMemory);
|
||||||
@ -291,16 +283,13 @@ namespace gz::vlk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create staging buffer
|
// create staging buffer
|
||||||
vk::Buffer stagingBuffer;
|
VkBuffer stagingBuffer;
|
||||||
MemoryInfo stagingBufferMemory;
|
MemoryInfo stagingBufferMemory;
|
||||||
vk.createBuffer(indexBufferSize, vk::BufferUsageFlagBits::eTransferSrc, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, stagingBuffer, stagingBufferMemory);
|
vk.createBuffer(indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, stagingBuffer, stagingBufferMemory);
|
||||||
|
|
||||||
// fill staging buffer
|
// fill staging buffer
|
||||||
void* data;
|
void* data;
|
||||||
vk::Result result = vk.getDevice().mapMemory(stagingBufferMemory.memory, stagingBufferMemory.offset, indexBufferSize, NO_MEM_FLAGS, &data);
|
vkMapMemory(vk.getDevice(), stagingBufferMemory.memory, stagingBufferMemory.offset, indexBufferSize, NO_FLAGS, &data);
|
||||||
if (result != vk::Result::eSuccess) {
|
|
||||||
throw getVkException(result, "Failed to map staging buffer", "Renderer2D::fillIndexBufferWithShapes");
|
|
||||||
}
|
|
||||||
uint32_t* idata = reinterpret_cast<uint32_t*>(data);
|
uint32_t* idata = reinterpret_cast<uint32_t*>(data);
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
for (auto it = shapes.begin(); it != shapes.end(); it++) {
|
for (auto it = shapes.begin(); it != shapes.end(); it++) {
|
||||||
@ -308,8 +297,8 @@ namespace gz::vlk {
|
|||||||
memcpy(idata+offset, it->getIndices().data(), it->getIndices().size() * sizeof(uint32_t));
|
memcpy(idata+offset, it->getIndices().data(), it->getIndices().size() * sizeof(uint32_t));
|
||||||
offset += it->getIndices().size();
|
offset += it->getIndices().size();
|
||||||
}
|
}
|
||||||
rLog.log0("fillIndexBufferWithShapes: indices count:", shapesIndicesCount);
|
rLog("fillIndexBufferWithShapes: indices count:", shapesIndicesCount);
|
||||||
vk.getDevice().unmapMemory(stagingBufferMemory.memory);
|
vkUnmapMemory(vk.getDevice(), stagingBufferMemory.memory);
|
||||||
|
|
||||||
// fill index buffer
|
// fill index buffer
|
||||||
vk.copyBuffer(stagingBuffer, indexBuffer, indexBufferSize);
|
vk.copyBuffer(stagingBuffer, indexBuffer, indexBufferSize);
|
||||||
@ -331,11 +320,11 @@ namespace gz::vlk {
|
|||||||
|
|
||||||
|
|
||||||
void Renderer2D::drawFrame(uint32_t imageIndex) {
|
void Renderer2D::drawFrame(uint32_t imageIndex) {
|
||||||
commandBuffers[vk.getCurrentFrame()].reset();
|
vkResetCommandBuffer(commandBuffers[vk.getCurrentFrame()], NO_FLAGS);
|
||||||
/* recordCommandBuffer(imageIndex, vk.getCurrentFrame()); */
|
/* recordCommandBuffer(imageIndex, vk.getCurrentFrame()); */
|
||||||
recordCommandBuffer(imageIndex, vk.getCurrentFrame());
|
recordCommandBuffer(imageIndex, vk.getCurrentFrame());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "vulkan_allocator.hpp"
|
#include "vulkan_allocator.hpp"
|
||||||
#include "vulkan_util.hpp"
|
#include "vulkan_util.hpp"
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
class Renderer2D : public Renderer {
|
class Renderer2D : public Renderer {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -49,13 +49,13 @@ namespace gz::vlk {
|
|||||||
* @details
|
* @details
|
||||||
* As of now, this does (in the same command buffer from graphicsPool)
|
* As of now, this does (in the same command buffer from graphicsPool)
|
||||||
* -# begin render pass
|
* -# begin render pass
|
||||||
* - image layout: vk::ImageLayout::eColorAttachmentOptimal
|
* - image layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||||
* - clear image
|
* - clear image
|
||||||
* -# bind 2d pipeline, vertex and index buffer
|
* -# bind 2d pipeline, vertex and index buffer
|
||||||
* -# bind texture sampler
|
* -# bind texture sampler
|
||||||
* -# draw indexed: draw the shapes from shapes vector
|
* -# draw indexed: draw the shapes from shapes vector
|
||||||
* -# end render pass
|
* -# end render pass
|
||||||
* - image layout: vk::ImageLayout::eTransferSrcOptimal
|
* - image layout: VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
|
||||||
* -# copy image to swapChain image with same imageIndex
|
* -# copy image to swapChain image with same imageIndex
|
||||||
*/
|
*/
|
||||||
void recordCommandBuffer(uint32_t imageIndex, uint32_t currentFrame);
|
void recordCommandBuffer(uint32_t imageIndex, uint32_t currentFrame);
|
||||||
@ -67,9 +67,9 @@ namespace gz::vlk {
|
|||||||
* The images are used as render targets. After rendering, the current image gets blitted onto the current swap chain image.
|
* The images are used as render targets. After rendering, the current image gets blitted onto the current swap chain image.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
std::vector<vk::Image> images;
|
std::vector<VkImage> images;
|
||||||
std::vector<MemoryInfo> imageMemory;
|
std::vector<MemoryInfo> imageMemory;
|
||||||
std::vector<vk::ImageView> imageViews;
|
std::vector<VkImageView> imageViews;
|
||||||
/**
|
/**
|
||||||
* @brief Creates the images (on imageMemory) and imageViews with the format of the VulkanInstance::swapChain images
|
* @brief Creates the images (on imageMemory) and imageViews with the format of the VulkanInstance::swapChain images
|
||||||
*/
|
*/
|
||||||
@ -81,10 +81,10 @@ namespace gz::vlk {
|
|||||||
* @details
|
* @details
|
||||||
* Attachments:
|
* Attachments:
|
||||||
* - color blend:
|
* - color blend:
|
||||||
* - loadOp = vk::AttachmentLoadOp::eClear
|
* - loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR
|
||||||
* - storeOp = vk::AttachmentStoreOp::eStore
|
* - storeOp = VK_ATTACHMENT_STORE_OP_STORE
|
||||||
* - initialLayout = vk::ImageLayout::eColorAttachmentOptimal
|
* - initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||||
* - finalLayout = vk::ImageLayout::eColorAttachmentOptimal
|
* - finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||||
* - stencil load/store = dont care
|
* - stencil load/store = dont care
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
@ -92,10 +92,10 @@ namespace gz::vlk {
|
|||||||
* @brief Create a render pass
|
* @brief Create a render pass
|
||||||
*/
|
*/
|
||||||
void createRenderPass();
|
void createRenderPass();
|
||||||
vk::RenderPass renderPass;
|
VkRenderPass renderPass;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
std::vector<vk::Framebuffer> framebuffers;
|
std::vector<VkFramebuffer> framebuffers;
|
||||||
// PIPELINE
|
// PIPELINE
|
||||||
PipelineContainer pipelines;
|
PipelineContainer pipelines;
|
||||||
|
|
||||||
@ -130,4 +130,4 @@ namespace gz::vlk {
|
|||||||
|
|
||||||
Log rLog;
|
Log rLog;
|
||||||
};
|
};
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
@ -6,24 +6,23 @@
|
|||||||
#include "texture_manager.hpp"
|
#include "texture_manager.hpp"
|
||||||
#include "exceptions.hpp"
|
#include "exceptions.hpp"
|
||||||
#include "vk_enum_string.h"
|
#include "vk_enum_string.h"
|
||||||
#include "vulkan_settings.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
//
|
//
|
||||||
// INIT & CLEANUP
|
// INIT & CLEANUP
|
||||||
//
|
//
|
||||||
Renderer3D::Renderer3D(VulkanInstance& instance, TextureManager& textureManager) :
|
Renderer3D::Renderer3D(VulkanInstance& instance, TextureManager& textureManager) :
|
||||||
Renderer(instance, textureManager) {
|
Renderer(instance, textureManager) {
|
||||||
LogCreateInfo logCI{
|
LogCreateInfo logCI{};
|
||||||
.logfile = "renderer3D.log",
|
logCI.logfile = "renderer3D.log";
|
||||||
.storeLog = false,
|
logCI.storeLog = false;
|
||||||
.prefix = "3D-Renderer",
|
logCI.prefix = "3D-Renderer";
|
||||||
.prefixColor = Color::LI_CYAN,
|
logCI.prefixColor = Color::LI_CYAN;
|
||||||
.timeColor = settings::VULKAN_MESSAGE_TIME_COLOR,
|
logCI.timeColor = VULKAN_MESSAGE_TIME_COLOR;
|
||||||
};
|
|
||||||
rLog = Log(std::move(logCI));
|
rLog = Log(std::move(logCI));
|
||||||
|
|
||||||
vk.registerCleanupCallback(std::bind(&Renderer3D::cleanup, this));
|
vk.registerCleanupCallback(std::bind(&Renderer3D::cleanup, this));
|
||||||
@ -34,6 +33,7 @@ namespace gz::vlk {
|
|||||||
const size_t indexCount = 10000;
|
const size_t indexCount = 10000;
|
||||||
vk.createVertexBuffer<Vertex3D>(vertexCount, vertexBuffer, vertexBufferMemory, vertexBufferSize);
|
vk.createVertexBuffer<Vertex3D>(vertexCount, vertexBuffer, vertexBufferMemory, vertexBufferSize);
|
||||||
vk.createIndexBuffer<uint32_t>(indexCount, indexBuffer, indexBufferMemory, indexBufferSize);
|
vk.createIndexBuffer<uint32_t>(indexCount, indexBuffer, indexBufferMemory, indexBufferSize);
|
||||||
|
rLog("Created Renderer3D");
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
loadModel();
|
loadModel();
|
||||||
@ -46,7 +46,7 @@ namespace gz::vlk {
|
|||||||
&descriptorSetLayout, &descriptorPool, },
|
&descriptorSetLayout, &descriptorPool, },
|
||||||
{ &framebuffers, &images, &imageMemory, &imageViews, &commandBuffers,
|
{ &framebuffers, &images, &imageMemory, &imageViews, &commandBuffers,
|
||||||
&descriptorSets }));
|
&descriptorSets }));
|
||||||
rLog.log1("Created Renderer3D");
|
rLog("Created Renderer3D");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer3D::cleanup() {
|
void Renderer3D::cleanup() {
|
||||||
@ -55,8 +55,8 @@ namespace gz::vlk {
|
|||||||
for (size_t i = 0; i < vk.getMaxFramesInFlight(); i++) {
|
for (size_t i = 0; i < vk.getMaxFramesInFlight(); i++) {
|
||||||
vk.destroyBuffer(uniformBuffers[i], uniformBuffersMemory[i]);
|
vk.destroyBuffer(uniformBuffers[i], uniformBuffersMemory[i]);
|
||||||
}
|
}
|
||||||
vk.getDevice().destroyDescriptorSetLayout(descriptorSetLayout, NO_ALLOC);
|
vkDestroyDescriptorSetLayout(vk.getDevice(), descriptorSetLayout, NO_ALLOC);
|
||||||
vk.getDevice().destroyDescriptorPool(descriptorPool, NO_ALLOC);
|
vkDestroyDescriptorPool(vk.getDevice(), descriptorPool, NO_ALLOC);
|
||||||
|
|
||||||
cleanupSwapChainDependantResources();
|
cleanupSwapChainDependantResources();
|
||||||
cleanup_();
|
cleanup_();
|
||||||
@ -67,13 +67,11 @@ namespace gz::vlk {
|
|||||||
// SWAPCHAIN DEPENDANT
|
// SWAPCHAIN DEPENDANT
|
||||||
//
|
//
|
||||||
void Renderer3D::initSwapChainDependantResources() {
|
void Renderer3D::initSwapChainDependantResources() {
|
||||||
// UPDATE DOC ON CHANGES!
|
|
||||||
createRenderPass();
|
createRenderPass();
|
||||||
createImages();
|
createImages();
|
||||||
createDepthImage();
|
vk.createFramebuffers(framebuffers, imageViews, renderPass);
|
||||||
vk.createFramebuffers(framebuffers, imageViews, renderPass, depthImageView);
|
std::vector<VkDescriptorSetLayout> descriptorSetLayouts = { descriptorSetLayout };
|
||||||
std::vector<vk::DescriptorSetLayout> descriptorSetLayouts = { descriptorSetLayout };
|
vk.createGraphicsPipeline<Vertex3D>("shaders/vert.spv", "shaders/frag.spv", descriptorSetLayouts, false, renderPass, pipelines[PL_3D]);
|
||||||
vk.createGraphicsPipeline<Vertex3D>("shaders/vert.spv", "shaders/frag.spv", descriptorSetLayouts, true, renderPass, pipelines[PL_3D]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -83,14 +81,13 @@ namespace gz::vlk {
|
|||||||
|
|
||||||
vk.destroyFramebuffers(framebuffers);
|
vk.destroyFramebuffers(framebuffers);
|
||||||
|
|
||||||
vk.destroyImageView(depthImageView);
|
|
||||||
vk.destroyImage(depthImage, depthImageMemory);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < images.size(); i++) {
|
for (size_t i = 0; i < images.size(); i++) {
|
||||||
vk.destroyImageView(imageViews[i]);
|
vk.destroyImageView(imageViews[i]);
|
||||||
vk.destroyImage(images[i], imageMemory[i]);
|
vk.destroyImage(images[i], imageMemory[i]);
|
||||||
}
|
}
|
||||||
vk.getDevice().destroyRenderPass(renderPass, nullptr);
|
vkDestroyRenderPass(vk.getDevice(), renderPass, nullptr);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -107,120 +104,99 @@ namespace gz::vlk {
|
|||||||
images.resize(vk.getScImages().size());
|
images.resize(vk.getScImages().size());
|
||||||
imageMemory.resize(vk.getScImages().size());
|
imageMemory.resize(vk.getScImages().size());
|
||||||
imageViews.resize(vk.getScImages().size());
|
imageViews.resize(vk.getScImages().size());
|
||||||
vk::ImageUsageFlags usage= vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc;
|
VkImageUsageFlags usage= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
for (size_t i = 0; i < images.size(); i++) {
|
for (size_t i = 0; i < images.size(); i++) {
|
||||||
vk.createImage(vk.getScExtent().width, vk.getScExtent().height, vk.getScImageFormat(), vk::ImageTiling::eOptimal, usage, vk::MemoryPropertyFlagBits::eDeviceLocal, images[i], imageMemory[i]);
|
vk.createImage(vk.getScExtent().width, vk.getScExtent().height, vk.getScImageFormat(), VK_IMAGE_TILING_OPTIMAL, usage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, images[i], imageMemory[i]);
|
||||||
vk.createImageView(vk.getScImageFormat(), images[i], imageViews[i], vk::ImageAspectFlagBits::eColor);
|
vk.createImageView(vk.getScImageFormat(), images[i], imageViews[i], VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// DEPTH
|
|
||||||
//
|
|
||||||
void Renderer3D::createDepthImage() {
|
|
||||||
vk::MemoryPropertyFlags memoryProperties = vk::MemoryPropertyFlagBits::eDeviceLocal;
|
|
||||||
vk::ImageUsageFlags imageUsage = vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
|
||||||
vk::ImageTiling tiling = vk::ImageTiling::eOptimal;
|
|
||||||
vk::Format depthFormat = vk.getDepthFormat();
|
|
||||||
|
|
||||||
vk.createImage(vk.getScExtent().width, vk.getScExtent().height, depthFormat, tiling, imageUsage, memoryProperties, depthImage, depthImageMemory);
|
|
||||||
vk.createImageView(depthFormat, depthImage, depthImageView, vk::ImageAspectFlagBits::eDepth);
|
|
||||||
|
|
||||||
vk.transitionImageLayout(depthImage, depthFormat, vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilAttachmentOptimal);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// RENDER PASS
|
// RENDER PASS
|
||||||
//
|
//
|
||||||
void Renderer3D::createRenderPass() {
|
void Renderer3D::createRenderPass() {
|
||||||
vk::AttachmentDescription2 colorBlendAD {
|
VkAttachmentDescription2 colorBlendAttachment{};
|
||||||
.format = vk.getScImageFormat(),
|
colorBlendAttachment.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2;
|
||||||
.samples = vk::SampleCountFlagBits::e1,
|
colorBlendAttachment.format = vk.getScImageFormat();
|
||||||
.loadOp = vk::AttachmentLoadOp::eClear,
|
colorBlendAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
.storeOp = vk::AttachmentStoreOp::eStore,
|
colorBlendAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
.stencilLoadOp = vk::AttachmentLoadOp::eDontCare,
|
colorBlendAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
.stencilStoreOp = vk::AttachmentStoreOp::eDontCare,
|
colorBlendAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
.initialLayout = vk::ImageLayout::eUndefined,
|
colorBlendAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
.finalLayout = vk::ImageLayout::eTransferSrcOptimal,
|
colorBlendAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
};
|
colorBlendAttachment.finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||||
|
|
||||||
vk::AttachmentReference2 colorBlendAR {
|
VkAttachmentReference2 colorAttachmentRef{};
|
||||||
.attachment = 0,
|
colorAttachmentRef.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2;
|
||||||
.layout = vk::ImageLayout::eColorAttachmentOptimal,
|
colorAttachmentRef.attachment = 0;
|
||||||
};
|
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
vk::AttachmentDescription2 depthAD {
|
/* VkAttachmentDescription depthAttachment{}; */
|
||||||
.format = vk.getDepthFormat(),
|
/* depthAttachment.format = findDepthFormat(); */
|
||||||
.samples = vk::SampleCountFlagBits::e1,
|
/* depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT; */
|
||||||
.loadOp = vk::AttachmentLoadOp::eClear,
|
/* depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; */
|
||||||
.storeOp = vk::AttachmentStoreOp::eDontCare,
|
/* depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; */
|
||||||
.stencilLoadOp = vk::AttachmentLoadOp::eDontCare,
|
/* depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; */
|
||||||
.stencilStoreOp = vk::AttachmentStoreOp::eDontCare,
|
/* depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; */
|
||||||
.initialLayout = vk::ImageLayout::eUndefined,
|
/* depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; */
|
||||||
.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal,
|
/* depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; */
|
||||||
};
|
|
||||||
|
|
||||||
vk::AttachmentReference2 depthAR {
|
/* VkAttachmentReference depthAttachmentRef{}; */
|
||||||
.attachment = 1,
|
/* depthAttachmentRef.attachment = 1; */
|
||||||
.layout = vk::ImageLayout::eDepthStencilAttachmentOptimal,
|
/* depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; */
|
||||||
};
|
|
||||||
|
|
||||||
vk::SubpassDescription2 subpass {
|
VkSubpassDescription2 subpass{};
|
||||||
.pipelineBindPoint = vk::PipelineBindPoint::eGraphics,
|
subpass.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2;
|
||||||
.colorAttachmentCount = 1,
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
.pColorAttachments = &colorBlendAR,
|
subpass.colorAttachmentCount = 1;
|
||||||
.pDepthStencilAttachment = &depthAR,
|
subpass.pColorAttachments = &colorAttachmentRef;
|
||||||
};
|
/* subpass.pDepthStencilAttachment = &depthAttachmentRef; */
|
||||||
|
|
||||||
// wait until image is available
|
VkSubpassDependency2 colorAttachmentSD{};
|
||||||
vk::SubpassDependency2 colorAttachmentSD {
|
colorAttachmentSD.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2;
|
||||||
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
colorAttachmentSD.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
.dstSubpass = 0,
|
colorAttachmentSD.dstSubpass = 0;
|
||||||
.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests,
|
colorAttachmentSD.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests,
|
colorAttachmentSD.srcAccessMask = 0;
|
||||||
.srcAccessMask = NO_ACC_FLAGS,
|
colorAttachmentSD.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentWrite,
|
colorAttachmentSD.dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
};
|
|
||||||
|
|
||||||
// image layout transition to transfer dst
|
// dependecy for the image layout transition to transfer dst
|
||||||
vk::SubpassDependency2 layoutTransitionSD {
|
VkSubpassDependency2 layoutTransitionSD{};
|
||||||
.srcSubpass = 0,
|
layoutTransitionSD.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2;
|
||||||
.dstSubpass = VK_SUBPASS_EXTERNAL,
|
layoutTransitionSD.srcSubpass = 0;
|
||||||
.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
layoutTransitionSD.dstSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
.dstStageMask = vk::PipelineStageFlagBits::eTransfer,
|
layoutTransitionSD.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
.srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite,
|
layoutTransitionSD.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
.dstAccessMask = vk::AccessFlagBits::eTransferRead,
|
layoutTransitionSD.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
|
||||||
.dependencyFlags = vk::DependencyFlagBits::eByRegion,
|
layoutTransitionSD.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT;
|
||||||
};
|
layoutTransitionSD.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||||
|
VkSubpassDependency dependency{};
|
||||||
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
dependency.dstSubpass = 0;
|
||||||
|
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||||
|
dependency.srcAccessMask = 0;
|
||||||
|
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||||
|
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
|
|
||||||
/* vk::SubpassDependency2 dependency { */
|
/* std::array<VkAttachmentDescription, 2> attachments = { colorBlendAttachment, depthAttachment }; */
|
||||||
/* dependency.srcSubpass = VK_SUBPASS_EXTERNAL; */
|
std::vector<VkAttachmentDescription2> attachments = { colorBlendAttachment };
|
||||||
/* dependency.dstSubpass = 0; */
|
std::vector<VkSubpassDependency2> dependencies = { colorAttachmentSD, layoutTransitionSD };
|
||||||
/* dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests; */
|
VkRenderPassCreateInfo2 renderPassCI{};
|
||||||
/* dependency.srcAccessMask = 0; */
|
renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2;
|
||||||
/* dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests; */
|
renderPassCI.attachmentCount = static_cast<uint32_t>(attachments.size());
|
||||||
/* dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentWrite; */
|
renderPassCI.pAttachments = attachments.data();
|
||||||
|
renderPassCI.subpassCount = 1;
|
||||||
std::vector<vk::AttachmentDescription2> attachments = { colorBlendAD, depthAD, };
|
renderPassCI.pSubpasses = &subpass;
|
||||||
std::vector<vk::SubpassDependency2> dependencies = { colorAttachmentSD, layoutTransitionSD };
|
renderPassCI.dependencyCount = dependencies.size();
|
||||||
vk::RenderPassCreateInfo2 renderPassCI {
|
renderPassCI.pDependencies = dependencies.data();
|
||||||
/* .attachmentCount = static_cast<uint32_t>(attachments.size()), */
|
/* renderPassCI.dependencyCount = 0; */
|
||||||
/* .pAttachments = attachments.data(), */
|
/* renderPassCI.pDependencies = nullptr; */
|
||||||
/* .subpassCount = 1, */
|
/* renderPassCI.correlatedViewMaskCount = 0; */
|
||||||
/* .pSubpasses = &subpass, */
|
/* renderPassCI.pCorrelatedViewMasks = nullptr; */
|
||||||
/* .dependencyCount = static_cast<uint32_t>(dependencies.size()), */
|
VkResult result = vkCreateRenderPass2(vk.getDevice(), &renderPassCI, nullptr, &renderPass);
|
||||||
/* .pDependencies = dependencies.data(), */
|
if (result != VK_SUCCESS) {
|
||||||
/* .dependencyCount = 0, */
|
|
||||||
/* .pDependencies = nullptr, */
|
|
||||||
/* .correlatedViewMaskCount = 0, */
|
|
||||||
/* .pCorrelatedViewMasks = nullptr, */
|
|
||||||
};
|
|
||||||
renderPassCI.setAttachments(attachments);
|
|
||||||
renderPassCI.setDependencies(dependencies);
|
|
||||||
renderPassCI.setSubpasses(subpass);
|
|
||||||
vk::Result result = vk.getDevice().createRenderPass2(&renderPassCI, nullptr, &renderPass);
|
|
||||||
if (result != vk::Result::eSuccess) {
|
|
||||||
throw getVkException(result, "Could not create render pass", "Renderer3D::createRenderPass");
|
throw getVkException(result, "Could not create render pass", "Renderer3D::createRenderPass");
|
||||||
}
|
}
|
||||||
rLog.log0("createRenderPass: Created render pass.");
|
rLog.log0("createRenderPass: Created render pass.");
|
||||||
@ -234,90 +210,91 @@ namespace gz::vlk {
|
|||||||
void Renderer3D::createDescriptorResources() {
|
void Renderer3D::createDescriptorResources() {
|
||||||
// LAYOUT
|
// LAYOUT
|
||||||
// 1) uniform buffer object
|
// 1) uniform buffer object
|
||||||
vk::DescriptorSetLayoutBinding uboLayoutBinding {
|
VkDescriptorSetLayoutBinding uboLayoutBinding{};
|
||||||
.binding = 0,
|
uboLayoutBinding.binding = 0;
|
||||||
.descriptorType = vk::DescriptorType::eUniformBuffer,
|
uboLayoutBinding.descriptorCount = 1;
|
||||||
.descriptorCount = 1,
|
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
.stageFlags = vk::ShaderStageFlagBits::eVertex,
|
uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
/* .pImmutableSamplers = nullptr, */
|
/* uboLayoutBinding.pImmutableSamplers = nullptr; */
|
||||||
};
|
|
||||||
|
|
||||||
// 2) combined image sampler
|
// 2) combined image sampler
|
||||||
vk::DescriptorSetLayoutBinding samplerLayoutBinding {
|
VkDescriptorSetLayoutBinding samplerLayoutBinding{};
|
||||||
.binding = 1,
|
samplerLayoutBinding.binding = 1;
|
||||||
.descriptorType = vk::DescriptorType::eCombinedImageSampler,
|
samplerLayoutBinding.descriptorCount = 1;
|
||||||
.descriptorCount = 1,
|
samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
.stageFlags = vk::ShaderStageFlagBits::eFragment,
|
samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
/* .pImmutableSamplers = nullptr, */
|
/* samplerLayoutBinding.pImmutableSamplers = nullptr; */
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<vk::DescriptorSetLayoutBinding> bindings = { uboLayoutBinding, samplerLayoutBinding };
|
std::vector<VkDescriptorSetLayoutBinding> bindings = { uboLayoutBinding, samplerLayoutBinding };
|
||||||
vk.createDescriptorSetLayout(bindings, descriptorSetLayout);
|
vk.createDescriptorSetLayout(bindings, descriptorSetLayout);
|
||||||
|
|
||||||
// POOL
|
// POOL
|
||||||
std::array<vk::DescriptorPoolSize, 2> poolSizes;
|
std::array<VkDescriptorPoolSize, 2> poolSizes;
|
||||||
poolSizes[0].type = vk::DescriptorType::eUniformBuffer;
|
poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
poolSizes[0].descriptorCount = static_cast<uint32_t>(vk.getMaxFramesInFlight());
|
poolSizes[0].descriptorCount = static_cast<uint32_t>(vk.getMaxFramesInFlight());
|
||||||
poolSizes[1].type = vk::DescriptorType::eCombinedImageSampler;
|
poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
poolSizes[1].descriptorCount = static_cast<uint32_t>(vk.getMaxFramesInFlight());
|
poolSizes[1].descriptorCount = static_cast<uint32_t>(vk.getMaxFramesInFlight());
|
||||||
|
|
||||||
vk::DescriptorPoolCreateInfo poolCI {
|
VkDescriptorPoolCreateInfo poolCI{};
|
||||||
.maxSets = static_cast<uint32_t>(vk.getMaxFramesInFlight()),
|
poolCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
};
|
poolCI.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
|
||||||
poolCI.setPoolSizes(poolSizes);
|
poolCI.pPoolSizes = poolSizes.data();
|
||||||
|
poolCI.maxSets = static_cast<uint32_t>(vk.getMaxFramesInFlight());
|
||||||
vk::Result result;
|
VkResult result = vkCreateDescriptorPool(vk.getDevice(), &poolCI, nullptr, &descriptorPool);
|
||||||
std::tie(result, descriptorPool) = vk.getDevice().createDescriptorPool(poolCI);
|
if (result != VK_SUCCESS) {
|
||||||
if (result != vk::Result::eSuccess) {
|
throw getVkException(result, "Failed to create descriptor pool", "Renderer3D::createDescriptorResources");
|
||||||
throw getVkException(result, "Failed to create descriptor pool", "Renderer3D::createDescriptorResources");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// SETS
|
// SETS
|
||||||
std::vector<vk::DescriptorSetLayout> layouts(vk.getMaxFramesInFlight(), descriptorSetLayout);
|
std::vector<VkDescriptorSetLayout> layouts(vk.getMaxFramesInFlight(), descriptorSetLayout);
|
||||||
vk::DescriptorSetAllocateInfo setAI {
|
VkDescriptorSetAllocateInfo setAI{};
|
||||||
.descriptorPool = descriptorPool,
|
setAI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||||
};
|
setAI.descriptorPool = descriptorPool;
|
||||||
setAI.setSetLayouts(layouts);
|
setAI.descriptorSetCount = static_cast<uint32_t>(layouts.size());
|
||||||
|
setAI.pSetLayouts = layouts.data();
|
||||||
|
|
||||||
// TODO is resize needed?
|
descriptorSets.resize(vk.getMaxFramesInFlight());
|
||||||
/* descriptorSets.resize(vk.getMaxFramesInFlight()); */
|
result = vkAllocateDescriptorSets(vk.getDevice(), &setAI, descriptorSets.data());
|
||||||
std::tie(result, descriptorSets) = vk.getDevice().allocateDescriptorSets(setAI);
|
if (result != VK_SUCCESS) {
|
||||||
if (result != vk::Result::eSuccess) {
|
|
||||||
throw getVkException(result, "Failed to create descriptor sets", "Renderer3D::createDescriptorResources");
|
throw getVkException(result, "Failed to create descriptor sets", "Renderer3D::createDescriptorResources");
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure sets
|
// configure sets
|
||||||
for (size_t i = 0; i < vk.getMaxFramesInFlight(); i++) {
|
for (size_t i = 0; i < vk.getMaxFramesInFlight(); i++) {
|
||||||
vk::DescriptorBufferInfo bufferI {
|
VkDescriptorBufferInfo bufferI{};
|
||||||
.buffer = uniformBuffers[i],
|
bufferI.buffer = uniformBuffers[i];
|
||||||
.offset = 0,
|
bufferI.offset = 0;
|
||||||
.range = VK_WHOLE_SIZE, // sizeof(UniformBufferObject),
|
bufferI.range = VK_WHOLE_SIZE; // sizeof(UniformBufferObject);
|
||||||
};
|
|
||||||
|
|
||||||
vk::DescriptorImageInfo imageI {
|
VkDescriptorImageInfo imageI{};
|
||||||
.sampler = textureManager.getTextureAtlas().getTextureSampler(),
|
imageI.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
.imageView = textureManager.getTextureAtlas().getTextureImageView(),
|
imageI.imageView = textureManager.getTextureAtlas().getTextureImageView();
|
||||||
.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal,
|
imageI.sampler = textureManager.getTextureAtlas().getTextureSampler();
|
||||||
};
|
|
||||||
|
|
||||||
std::array<vk::WriteDescriptorSet, 2> descriptorW{};
|
std::array<VkWriteDescriptorSet, 2> descriptorW{};
|
||||||
|
descriptorW[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
descriptorW[0].dstSet = descriptorSets[i];
|
descriptorW[0].dstSet = descriptorSets[i];
|
||||||
descriptorW[0].dstBinding = bindingUniformBuffer;
|
descriptorW[0].dstBinding = bindingUniformBuffer;
|
||||||
descriptorW[0].dstArrayElement = 0;
|
descriptorW[0].dstArrayElement = 0;
|
||||||
descriptorW[0].descriptorType = vk::DescriptorType::eUniformBuffer;
|
descriptorW[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
descriptorW[0].setBufferInfo(bufferI);
|
descriptorW[0].descriptorCount = 1;
|
||||||
|
descriptorW[0].pBufferInfo = &bufferI;
|
||||||
/* descriptorW[0].pImageInfo = nullptr; */
|
/* descriptorW[0].pImageInfo = nullptr; */
|
||||||
/* descriptorW[0].pTexelBufferView = nullptr; */
|
/* descriptorW[0].pTexelBufferView = nullptr; */
|
||||||
|
|
||||||
|
descriptorW[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
descriptorW[1].dstSet = descriptorSets[i];
|
descriptorW[1].dstSet = descriptorSets[i];
|
||||||
descriptorW[1].dstBinding = bindingCombinedImageSampler;
|
descriptorW[1].dstBinding = bindingCombinedImageSampler;
|
||||||
descriptorW[1].dstArrayElement = 0;
|
descriptorW[1].dstArrayElement = 0;
|
||||||
descriptorW[1].descriptorType = vk::DescriptorType::eCombinedImageSampler;
|
descriptorW[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
descriptorW[1].setImageInfo(imageI);
|
descriptorW[1].descriptorCount = 1;
|
||||||
|
/* descriptorW[1].pBufferInfo = &bufferI; */
|
||||||
|
descriptorW[1].pImageInfo = &imageI;
|
||||||
/* descriptorW[1].pTexelBufferView = nullptr; */
|
/* descriptorW[1].pTexelBufferView = nullptr; */
|
||||||
|
|
||||||
// write 1, copy 0
|
uint32_t descriptorWriteCount = static_cast<uint32_t>(descriptorW.size());
|
||||||
vk.getDevice().updateDescriptorSets(descriptorW, nullptr);
|
uint32_t descriptorCopyCount = 0;
|
||||||
|
vkUpdateDescriptorSets(vk.getDevice(), descriptorWriteCount, descriptorW.data(), descriptorCopyCount, nullptr);
|
||||||
}
|
}
|
||||||
rLog.log0("createDescriptorResources: Created descriptor layouts, pool and sets.");
|
rLog.log0("createDescriptorResources: Created descriptor layouts, pool and sets.");
|
||||||
}
|
}
|
||||||
@ -328,10 +305,10 @@ namespace gz::vlk {
|
|||||||
void Renderer3D::loadModel() {
|
void Renderer3D::loadModel() {
|
||||||
// load model into VerticesAndIndices struct
|
// load model into VerticesAndIndices struct
|
||||||
rLog.log1("Renderer3D: loadModel: loading model");
|
rLog.log1("Renderer3D: loadModel: loading model");
|
||||||
vk.loadModel(settings::MODEL_PATH, model);
|
vk.loadModel(model);
|
||||||
// TODO use correct type
|
// TODO use correct type
|
||||||
vk::DeviceSize requiredVertexBufferSize = model.vertices.size() * sizeof(Vertex3D);
|
VkDeviceSize requiredVertexBufferSize = model.vertices.size() * sizeof(Vertex3D);
|
||||||
vk::DeviceSize requiredIndexBufferSize = model.indices.size() * sizeof(uint32_t);
|
VkDeviceSize requiredIndexBufferSize = model.indices.size() * sizeof(uint32_t);
|
||||||
|
|
||||||
if (requiredVertexBufferSize > vertexBufferSize) { throw VkException("Renderer3D::loadModel: vertex buffer too small"); }
|
if (requiredVertexBufferSize > vertexBufferSize) { throw VkException("Renderer3D::loadModel: vertex buffer too small"); }
|
||||||
if (requiredIndexBufferSize > indexBufferSize) { throw VkException("Renderer3D::loadModel: index buffer too small"); }
|
if (requiredIndexBufferSize > indexBufferSize) { throw VkException("Renderer3D::loadModel: index buffer too small"); }
|
||||||
@ -339,18 +316,14 @@ namespace gz::vlk {
|
|||||||
rLog.log0("Renderer3D: loadModel: filling vertex buffer");
|
rLog.log0("Renderer3D: loadModel: filling vertex buffer");
|
||||||
// copy to vertexBuffer
|
// copy to vertexBuffer
|
||||||
// create staging buffer
|
// create staging buffer
|
||||||
vk::Buffer stagingBuffer;
|
VkBuffer stagingBuffer;
|
||||||
MemoryInfo stagingBufferMemory;
|
MemoryInfo stagingBufferMemory;
|
||||||
vk.createBuffer(requiredVertexBufferSize, vk::BufferUsageFlagBits::eTransferSrc, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, stagingBuffer, stagingBufferMemory);
|
vk.createBuffer(requiredVertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, stagingBuffer, stagingBufferMemory);
|
||||||
// fill staging buffer
|
// fill staging buffer
|
||||||
void* data;
|
void* data;
|
||||||
vk::Result result = vk.getDevice().mapMemory(stagingBufferMemory.memory, stagingBufferMemory.offset, requiredVertexBufferSize, NO_MEM_FLAGS, &data);
|
vkMapMemory(vk.getDevice(), stagingBufferMemory.memory, stagingBufferMemory.offset, requiredVertexBufferSize, NO_FLAGS, &data);
|
||||||
if (result != vk::Result::eSuccess) {
|
|
||||||
throw getVkException(result, "Failed to map staging buffer for vertices", "Renderer3D::loadModel");
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(data, model.vertices.data(), requiredVertexBufferSize);
|
memcpy(data, model.vertices.data(), requiredVertexBufferSize);
|
||||||
vk.getDevice().unmapMemory(stagingBufferMemory.memory);
|
vkUnmapMemory(vk.getDevice(), stagingBufferMemory.memory);
|
||||||
// fill vertex buffer
|
// fill vertex buffer
|
||||||
vk.copyBuffer(stagingBuffer, vertexBuffer, requiredVertexBufferSize);
|
vk.copyBuffer(stagingBuffer, vertexBuffer, requiredVertexBufferSize);
|
||||||
vk.destroyBuffer(stagingBuffer, stagingBufferMemory);
|
vk.destroyBuffer(stagingBuffer, stagingBufferMemory);
|
||||||
@ -358,14 +331,11 @@ namespace gz::vlk {
|
|||||||
rLog.log0("Renderer3D: loadModel: filling index buffer");
|
rLog.log0("Renderer3D: loadModel: filling index buffer");
|
||||||
data = nullptr;
|
data = nullptr;
|
||||||
// copy to index buffer
|
// copy to index buffer
|
||||||
vk.createBuffer(requiredIndexBufferSize, vk::BufferUsageFlagBits::eTransferSrc, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, stagingBuffer, stagingBufferMemory);
|
vk.createBuffer(requiredIndexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, stagingBuffer, stagingBufferMemory);
|
||||||
// fill staging buffer
|
// fill staging buffer
|
||||||
result = vk.getDevice().mapMemory(stagingBufferMemory.memory, stagingBufferMemory.offset, requiredIndexBufferSize, NO_MEM_FLAGS, &data);
|
vkMapMemory(vk.getDevice(), stagingBufferMemory.memory, stagingBufferMemory.offset, requiredIndexBufferSize, NO_FLAGS, &data);
|
||||||
if (result != vk::Result::eSuccess) {
|
|
||||||
throw getVkException(result, "Failed to map staging buffer for indices", "Renderer3D::loadModel");
|
|
||||||
}
|
|
||||||
memcpy(data, model.indices.data(), requiredIndexBufferSize);
|
memcpy(data, model.indices.data(), requiredIndexBufferSize);
|
||||||
vk.getDevice().unmapMemory(stagingBufferMemory.memory);
|
vkUnmapMemory(vk.getDevice(), stagingBufferMemory.memory);
|
||||||
// fill index buffer
|
// fill index buffer
|
||||||
vk.copyBuffer(stagingBuffer, indexBuffer, requiredIndexBufferSize);
|
vk.copyBuffer(stagingBuffer, indexBuffer, requiredIndexBufferSize);
|
||||||
vk.destroyBuffer(stagingBuffer, stagingBufferMemory);
|
vk.destroyBuffer(stagingBuffer, stagingBufferMemory);
|
||||||
@ -375,50 +345,54 @@ namespace gz::vlk {
|
|||||||
// RENDERING
|
// RENDERING
|
||||||
//
|
//
|
||||||
void Renderer3D::recordCommandBuffer(uint32_t imageIndex, uint32_t currentFrame) {
|
void Renderer3D::recordCommandBuffer(uint32_t imageIndex, uint32_t currentFrame) {
|
||||||
vk::CommandBufferBeginInfo commandBufferBI;
|
VkCommandBufferBeginInfo commandBufferBI{};
|
||||||
vk::Result result = commandBuffers[currentFrame].begin(commandBufferBI);
|
commandBufferBI.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
if (result != vk::Result::eSuccess) {
|
commandBufferBI.flags = 0;
|
||||||
|
commandBufferBI.pInheritanceInfo = nullptr;
|
||||||
|
VkResult result = vkBeginCommandBuffer(commandBuffers[currentFrame], &commandBufferBI);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
throw getVkException(result, "Failed to begin 3D command buffer", "Renderer3D::recordCommandBuffer");
|
throw getVkException(result, "Failed to begin 3D command buffer", "Renderer3D::recordCommandBuffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkRenderPassBeginInfo renderPassBI{};
|
||||||
|
renderPassBI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
|
renderPassBI.renderPass = renderPass;
|
||||||
|
renderPassBI.framebuffer = framebuffers[imageIndex];
|
||||||
|
renderPassBI.renderArea.offset = { 0, 0 };
|
||||||
|
renderPassBI.renderArea.extent = vk.getScExtent();
|
||||||
// clear
|
// clear
|
||||||
std::array<vk::ClearValue, 2> clearValues{};
|
std::array<VkClearValue, 1> clearValues{};
|
||||||
vk::ClearColorValue clearColor{};
|
clearValues[0].color = {{1.0f, 0.0f, 0.0f, 1.0f}};
|
||||||
clearColor.setFloat32({0.1f, 0.0f, 0.0f, 0.5f});
|
/* clearValues[1].depthStencil = {1.0f, 0}; */
|
||||||
clearValues[0].setColor(std::move(clearColor));
|
renderPassBI.clearValueCount = static_cast<uint32_t>(clearValues.size());
|
||||||
clearValues[1].setDepthStencil({1.0f, 0});
|
renderPassBI.pClearValues = clearValues.data();
|
||||||
|
|
||||||
vk::RenderPassBeginInfo renderPassBI {
|
vkCmdBeginRenderPass(commandBuffers[currentFrame], &renderPassBI, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
.renderPass = renderPass,
|
|
||||||
.framebuffer = framebuffers[imageIndex],
|
|
||||||
.renderArea { .offset = { 0, 0 }, .extent = vk.getScExtent() }
|
|
||||||
};
|
|
||||||
renderPassBI.setClearValues(clearValues);
|
|
||||||
|
|
||||||
commandBuffers[currentFrame].beginRenderPass(renderPassBI, vk::SubpassContents::eInline);
|
vkCmdBindPipeline(commandBuffers[currentFrame], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines[PL_3D].pipeline);
|
||||||
|
VkBuffer vertexBuffers[] = { vertexBuffer };
|
||||||
commandBuffers[currentFrame].bindPipeline(vk::PipelineBindPoint::eGraphics, pipelines[PL_3D].pipeline);
|
VkDeviceSize offsets[] = {0};
|
||||||
vk::Buffer vertexBuffers[] = { vertexBuffer };
|
|
||||||
vk::DeviceSize offsets[] = {0};
|
|
||||||
uint32_t bindingCount = 1;
|
uint32_t bindingCount = 1;
|
||||||
uint32_t firstBinding = 0;
|
vkCmdBindVertexBuffers(commandBuffers[currentFrame], BINDING, bindingCount, vertexBuffers, offsets);
|
||||||
commandBuffers[currentFrame].bindVertexBuffers(firstBinding, bindingCount, vertexBuffers, offsets);
|
|
||||||
// TODO use correct index type!
|
// TODO use correct index type!
|
||||||
commandBuffers[currentFrame].bindIndexBuffer(indexBuffer, NO_OFFSET, vk::IndexType::eUint32);
|
vkCmdBindIndexBuffer(commandBuffers[currentFrame], indexBuffer, NO_OFFSET, VK_INDEX_TYPE_UINT32);
|
||||||
|
|
||||||
|
uint32_t descriptorCount = 1;
|
||||||
uint32_t firstSet = 0;
|
uint32_t firstSet = 0;
|
||||||
commandBuffers[currentFrame].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelines[PL_3D].layout, firstSet, descriptorSets[currentFrame], {});
|
uint32_t dynamicOffsetCount = 0;
|
||||||
|
uint32_t* dynamicOffsets = nullptr;
|
||||||
|
vkCmdBindDescriptorSets(commandBuffers[currentFrame], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines[PL_3D].layout, firstSet, descriptorCount, &descriptorSets[currentFrame], dynamicOffsetCount, dynamicOffsets);
|
||||||
|
|
||||||
int instanceCount = 1;
|
int instanceCount = 1;
|
||||||
int firstIndex = 0;
|
int firstIndex = 0;
|
||||||
int firstInstance = 0;
|
int firstInstance = 0;
|
||||||
commandBuffers[currentFrame].drawIndexed(static_cast<uint32_t>(model.indices.size()), instanceCount, firstIndex, NO_OFFSET, firstInstance);
|
vkCmdDrawIndexed(commandBuffers[currentFrame], static_cast<uint32_t>(model.indices.size()), instanceCount, firstIndex, NO_OFFSET, firstInstance);
|
||||||
commandBuffers[currentFrame].endRenderPass();
|
vkCmdEndRenderPass(commandBuffers[currentFrame]);
|
||||||
|
|
||||||
vk.copyImageToImage(commandBuffers[currentFrame], images[imageIndex], vk.getScImages()[imageIndex], vk.getScExtent());
|
vk.copyImageToImage(commandBuffers[currentFrame], images[imageIndex], vk.getScImages()[imageIndex], vk.getScExtent());
|
||||||
result = commandBuffers[currentFrame].end();
|
result = vkEndCommandBuffer(commandBuffers[currentFrame]);
|
||||||
if (result != vk::Result::eSuccess) {
|
if (result != VK_SUCCESS) {
|
||||||
rLog.error("Failed to record 3D - command buffer", "VkResult:", result);
|
rLog.error("Failed to record 3D - command buffer", "VkResult:", STR_VK_RESULT(result));
|
||||||
throw getVkException(result, "Failed to record 3D - command buffer", "Renderer3D::recordCommandBuffer");
|
throw getVkException(result, "Failed to record 3D - command buffer", "Renderer3D::recordCommandBuffer");
|
||||||
}
|
}
|
||||||
vk.submitThisFrame(commandBuffers[currentFrame]);
|
vk.submitThisFrame(commandBuffers[currentFrame]);
|
||||||
@ -427,7 +401,7 @@ namespace gz::vlk {
|
|||||||
// RENDERING
|
// RENDERING
|
||||||
//
|
//
|
||||||
void Renderer3D::drawFrame(uint32_t imageIndex) {
|
void Renderer3D::drawFrame(uint32_t imageIndex) {
|
||||||
commandBuffers[vk.getCurrentFrame()].reset(NO_CMD_RESET_FLAGS);
|
vkResetCommandBuffer(commandBuffers[vk.getCurrentFrame()], NO_FLAGS);
|
||||||
/* recordCommandBuffer(imageIndex, vk.getCurrentFrame()); */
|
/* recordCommandBuffer(imageIndex, vk.getCurrentFrame()); */
|
||||||
updateUniformBuffer();
|
updateUniformBuffer();
|
||||||
recordCommandBuffer(imageIndex, vk.getCurrentFrame());
|
recordCommandBuffer(imageIndex, vk.getCurrentFrame());
|
||||||
@ -435,13 +409,13 @@ namespace gz::vlk {
|
|||||||
|
|
||||||
|
|
||||||
void Renderer3D::createUniformBuffers() {
|
void Renderer3D::createUniformBuffers() {
|
||||||
vk::DeviceSize bufferSize = sizeof(UniformBufferObject);
|
VkDeviceSize bufferSize = sizeof(UniformBufferObject);
|
||||||
|
|
||||||
uniformBuffers.resize(vk.getMaxFramesInFlight());
|
uniformBuffers.resize(vk.getMaxFramesInFlight());
|
||||||
uniformBuffersMemory.resize(vk.getMaxFramesInFlight());
|
uniformBuffersMemory.resize(vk.getMaxFramesInFlight());
|
||||||
|
|
||||||
for (size_t i = 0; i < vk.getMaxFramesInFlight(); i++) {
|
for (size_t i = 0; i < vk.getMaxFramesInFlight(); i++) {
|
||||||
vk.createBuffer(bufferSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, uniformBuffers[i], uniformBuffersMemory[i]);
|
vk.createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, uniformBuffers[i], uniformBuffersMemory[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,12 +436,9 @@ namespace gz::vlk {
|
|||||||
/* ubo.projection[1][1] *= -1; // y coordinate inverted in opengl */
|
/* ubo.projection[1][1] *= -1; // y coordinate inverted in opengl */
|
||||||
MemoryInfo& uniformBufferMI = uniformBuffersMemory[vk.getCurrentFrame()];
|
MemoryInfo& uniformBufferMI = uniformBuffersMemory[vk.getCurrentFrame()];
|
||||||
void* data;
|
void* data;
|
||||||
vk::Result result = vk.getDevice().mapMemory(uniformBufferMI.memory, uniformBufferMI.offset, sizeof(ubo), NO_MEM_FLAGS, &data);
|
vkMapMemory(vk.getDevice(), uniformBufferMI.memory, uniformBufferMI.offset, sizeof(ubo), NO_FLAGS, &data);
|
||||||
if (result != vk::Result::eSuccess) {
|
|
||||||
throw getVkException(result, "Failed to map staging buffer", "Renderer3D::updateUniformBuffer");
|
|
||||||
}
|
|
||||||
memcpy(data, &ubo, sizeof(ubo));
|
memcpy(data, &ubo, sizeof(ubo));
|
||||||
vk.getDevice().unmapMemory(uniformBufferMI.memory);
|
vkUnmapMemory(vk.getDevice(), uniformBufferMI.memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -475,4 +446,4 @@ namespace gz::vlk {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "vulkan_allocator.hpp"
|
#include "vulkan_allocator.hpp"
|
||||||
#include "vulkan_util.hpp"
|
#include "vulkan_util.hpp"
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
struct UniformBufferObject {
|
struct UniformBufferObject {
|
||||||
alignas(16) glm::mat4 model;
|
alignas(16) glm::mat4 model;
|
||||||
alignas(16) glm::mat4 view;
|
alignas(16) glm::mat4 view;
|
||||||
@ -34,7 +34,7 @@ namespace gz::vlk {
|
|||||||
/// @}
|
/// @}
|
||||||
private:
|
private:
|
||||||
void recordCommandBuffer(uint32_t imageIndex, uint32_t currentFrame);
|
void recordCommandBuffer(uint32_t imageIndex, uint32_t currentFrame);
|
||||||
std::vector<vk::Buffer> uniformBuffers;
|
std::vector<VkBuffer> uniformBuffers;
|
||||||
std::vector<MemoryInfo> uniformBuffersMemory;
|
std::vector<MemoryInfo> uniformBuffersMemory;
|
||||||
void createUniformBuffers();
|
void createUniformBuffers();
|
||||||
void updateUniformBuffer();
|
void updateUniformBuffer();
|
||||||
@ -45,36 +45,24 @@ namespace gz::vlk {
|
|||||||
* The images are used as render targets. After rendering, the current image gets blitted onto the current swap chain image.
|
* The images are used as render targets. After rendering, the current image gets blitted onto the current swap chain image.
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
std::vector<vk::Image> images;
|
std::vector<VkImage> images;
|
||||||
std::vector<MemoryInfo> imageMemory;
|
std::vector<MemoryInfo> imageMemory;
|
||||||
std::vector<vk::ImageView> imageViews;
|
std::vector<VkImageView> imageViews;
|
||||||
/**
|
/**
|
||||||
* @brief Creates the images (on imageMemory) and imageViews with the format of the VulkanInstance::swapChain images
|
* @brief Creates the images (on imageMemory) and imageViews with the format of the VulkanInstance::swapChain images
|
||||||
*/
|
*/
|
||||||
void createImages();
|
void createImages();
|
||||||
/// @}
|
/// @}
|
||||||
/**
|
|
||||||
* @name Depth
|
|
||||||
*/
|
|
||||||
/// @{
|
|
||||||
vk::Image depthImage;
|
|
||||||
MemoryInfo depthImageMemory;
|
|
||||||
vk::ImageView depthImageView;
|
|
||||||
/**
|
|
||||||
* @brief Create depth image and view with a @ref VulkanInstance::getDepthFormat() "depth format"
|
|
||||||
*/
|
|
||||||
void createDepthImage();
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name Render pass
|
* @name Render pass
|
||||||
* @details
|
* @details
|
||||||
* Attachments:
|
* Attachments:
|
||||||
* - color blend:
|
* - color blend:
|
||||||
* - loadOp = vk::AttachmentLoadOp::eClear
|
* - loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR
|
||||||
* - storeOp = vk::AttachmentStoreOp::eStore
|
* - storeOp = VK_ATTACHMENT_STORE_OP_STORE
|
||||||
* - initialLayout = vk::ImageLayout::eColorAttachmentOptimal
|
* - initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||||
* - finalLayout = vk::ImageLayout::eColorAttachmentOptimal
|
* - finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||||
* - stencil load/store = dont care
|
* - stencil load/store = dont care
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
@ -82,10 +70,10 @@ namespace gz::vlk {
|
|||||||
* @brief Create a render pass
|
* @brief Create a render pass
|
||||||
*/
|
*/
|
||||||
void createRenderPass();
|
void createRenderPass();
|
||||||
vk::RenderPass renderPass;
|
VkRenderPass renderPass;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
std::vector<vk::Framebuffer> framebuffers;
|
std::vector<VkFramebuffer> framebuffers;
|
||||||
// PIPELINE
|
// PIPELINE
|
||||||
PipelineContainer pipelines;
|
PipelineContainer pipelines;
|
||||||
|
|
||||||
@ -96,9 +84,9 @@ namespace gz::vlk {
|
|||||||
* -# Combined Image Sampler (DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
|
* -# Combined Image Sampler (DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
vk::DescriptorPool descriptorPool;
|
VkDescriptorPool descriptorPool;
|
||||||
vk::DescriptorSetLayout descriptorSetLayout;
|
VkDescriptorSetLayout descriptorSetLayout;
|
||||||
std::vector<vk::DescriptorSet> descriptorSets;
|
std::vector<VkDescriptorSet> descriptorSets;
|
||||||
/**
|
/**
|
||||||
* @brief Create a descriptor layout binding for the MVP uniform buffer object
|
* @brief Create a descriptor layout binding for the MVP uniform buffer object
|
||||||
* @details Create a desciptor set layout with bindings for
|
* @details Create a desciptor set layout with bindings for
|
||||||
@ -128,11 +116,10 @@ namespace gz::vlk {
|
|||||||
/**
|
/**
|
||||||
* @brief Sets up resources that depend on the swap chain or its attributes
|
* @brief Sets up resources that depend on the swap chain or its attributes
|
||||||
* @details
|
* @details
|
||||||
* Initializes:
|
* Initializes up:
|
||||||
* - @ref createRenderPass() "render pass"
|
* - images, imageMemory, imageViews
|
||||||
* - @ref createImages() "images and imageViews"
|
* - framebuffers
|
||||||
* - @ref createDepthImage() "depth image and view"
|
* - render pass
|
||||||
* - @ref VulkanInstance::createFramebuffers() "framebuffers"
|
|
||||||
* - pipeline
|
* - pipeline
|
||||||
*/
|
*/
|
||||||
void initSwapChainDependantResources();
|
void initSwapChainDependantResources();
|
||||||
|
16
src/shader/shader.frag
Normal file
16
src/shader/shader.frag
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_EXT_debug_printf : enable
|
||||||
|
|
||||||
|
layout(binding = 1) uniform sampler2D textureSampler;
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 fragColor;
|
||||||
|
layout(location = 1) in vec2 fragTextureCoordinate;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
/* outColor = vec4(fragColor, 1.0); */
|
||||||
|
/* debugPrintfEXT("outColor %v3f", fragColor); */
|
||||||
|
outColor = vec4(fragTextureCoordinate, 0.0, 1.0);
|
||||||
|
/* outColor = vec4(fragColor * texture(textureSampler, fragTextureCoordinate).rgb, 1.0); */
|
||||||
|
}
|
25
src/shader/shader.vert
Normal file
25
src/shader/shader.vert
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_EXT_debug_printf : enable
|
||||||
|
|
||||||
|
layout(binding = 0) uniform UniformBufferObject {
|
||||||
|
mat4 model;
|
||||||
|
mat4 view;
|
||||||
|
mat4 proj;
|
||||||
|
} ubo;
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 inPosition;
|
||||||
|
layout(location = 1) in vec3 inColor;
|
||||||
|
layout(location = 2) in vec2 inTextureCoordinate;
|
||||||
|
|
||||||
|
layout(location = 0) out vec3 fragColor;
|
||||||
|
layout(location = 1) out vec2 fragTextureCoordinate;
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
|
||||||
|
/* gl_Position = vec4(inPosition, 1.0); */
|
||||||
|
|
||||||
|
/* debugPrintfEXT("inPosition %v3f, inColor %v3f", inPosition, inColor); */
|
||||||
|
fragColor = inColor;
|
||||||
|
fragTextureCoordinate = inTextureCoordinate;
|
||||||
|
}
|
17
src/shader/shader2D.frag
Normal file
17
src/shader/shader2D.frag
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_EXT_debug_printf : enable
|
||||||
|
|
||||||
|
layout(binding = 0) uniform sampler2D textureSampler;
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 fragColor;
|
||||||
|
layout(location = 1) in vec2 fragTextureCoordinate;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
/* outColor = vec4(fragColor, 1.0); */
|
||||||
|
/* outColor = vec4(fragTextureCoordinate, 0.0, 1.0); */
|
||||||
|
/* outColor = vec4(fragColor * texture(textureSampler, fragTextureCoordinate).rgb, 1.0); */
|
||||||
|
outColor = texture(textureSampler, fragTextureCoordinate);
|
||||||
|
/* debugPrintfEXT("outColor %v3f", outColor); */
|
||||||
|
}
|
25
src/shader/shader2D.vert
Normal file
25
src/shader/shader2D.vert
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_EXT_debug_printf : enable
|
||||||
|
|
||||||
|
/* layout(binding = 0) uniform UniformBufferObject { */
|
||||||
|
/* mat4 model; */
|
||||||
|
/* mat4 view; */
|
||||||
|
/* mat4 proj; */
|
||||||
|
/* } ubo; */
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 inPosition;
|
||||||
|
layout(location = 1) in vec3 inColor;
|
||||||
|
layout(location = 2) in vec2 inTextureCoordinate;
|
||||||
|
|
||||||
|
layout(location = 0) out vec3 fragColor;
|
||||||
|
layout(location = 1) out vec2 fragTextureCoordinate;
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
/* gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0); */
|
||||||
|
gl_Position = vec4(inPosition, 0.0, 1.0);
|
||||||
|
|
||||||
|
/* debugPrintfEXT("inPosition %v2f, inColor %v3f", inPosition, inColor); */
|
||||||
|
fragColor = inColor;
|
||||||
|
fragTextureCoordinate = inTextureCoordinate;
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "texture_manager.hpp"
|
#include "texture_manager.hpp"
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
Rectangle::Rectangle(float top, float left, uint32_t width, uint32_t height, glm::vec3 color, std::string&& texture)
|
Rectangle::Rectangle(float top, float left, uint32_t width, uint32_t height, glm::vec3 color, std::string&& texture)
|
||||||
: top(top), left(left), width(width), height(height), color(color)
|
: top(top), left(left), width(width), height(height), color(color)
|
||||||
{
|
{
|
||||||
@ -55,4 +55,4 @@ namespace gz::vlk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "vertex.hpp"
|
#include "vertex.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
// defined in texture_manager.hpp
|
// defined in texture_manager.hpp
|
||||||
class TextureManager;
|
class TextureManager;
|
||||||
class Shape {
|
class Shape {
|
||||||
@ -46,4 +46,4 @@ namespace gz::vlk {
|
|||||||
glm::vec3 color;
|
glm::vec3 color;
|
||||||
void generateVertices();
|
void generateVertices();
|
||||||
};
|
};
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#include "exceptions.hpp"
|
#include "exceptions.hpp"
|
||||||
|
|
||||||
#include "vulkan_util.hpp"
|
#include "vk_enum_string.h"
|
||||||
|
|
||||||
namespace gz {
|
namespace gz {
|
||||||
VkException getVkException(vk::Result result, std::string&& what, std::string&& functionName) {
|
VkException getVkException(VkResult result, std::string&& what, std::string&& functionName) {
|
||||||
std::string whatStr;
|
std::string whatStr;
|
||||||
if (!functionName.empty()) {
|
if (!functionName.empty()) {
|
||||||
whatStr += "Error in function: " + functionName + ": ";
|
whatStr += "Error in function: " + functionName + ": ";
|
||||||
@ -15,7 +15,7 @@ namespace gz {
|
|||||||
whatStr += what + ": ";
|
whatStr += what + ": ";
|
||||||
}
|
}
|
||||||
whatStr += "VkResult=";
|
whatStr += "VkResult=";
|
||||||
whatStr += ::toString(result);
|
whatStr += STR_VK_RESULT(result);
|
||||||
return VkException(whatStr);
|
return VkException(whatStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
#include <gz-util/exceptions.hpp>
|
#include <gz-util/exceptions.hpp>
|
||||||
|
|
||||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
#include <vulkan/vulkan_core.h>
|
||||||
#include <vulkan/vulkan.hpp>
|
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -32,8 +31,7 @@ namespace gz {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return a VkException with a formatted string
|
* @brief Return a VkException with a formatted string
|
||||||
* @todo Return different Exceptions depending in result or make this a constructor of VkException
|
|
||||||
*/
|
*/
|
||||||
VkException getVkException(vk::Result result, std::string&& what="", std::string&& functionName="");
|
VkException getVkException(VkResult result, std::string&& what="", std::string&& functionName="");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
#include <gz-util/util/string_concepts.hpp>
|
#include <gz-util/util/string_concepts.hpp>
|
||||||
#include <gz-util/util/string_conversion.hpp>
|
#include <gz-util/util/string_conversion.hpp>
|
||||||
#include <ratio>
|
#include <ratio>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
std::string TextureImageArea::toString() const {
|
std::string TextureImageArea::toString() const {
|
||||||
return "<(" + gz::toString(x) + "," + gz::toString(y) + "), (" + gz::toString(width) + "x" + gz::toString(height) + ")>";
|
return "<(" + gz::toString(x) + "," + gz::toString(y) + "), (" + gz::toString(width) + "x" + gz::toString(height) + ")>";
|
||||||
}
|
}
|
||||||
@ -29,13 +29,12 @@ TextureAtlas::TextureAtlas(VulkanInstance& instance, uint16_t slotWidth, uint16_
|
|||||||
slotCountX(slotCountX), slotCountY(slotCountY)
|
slotCountX(slotCountX), slotCountY(slotCountY)
|
||||||
{
|
{
|
||||||
#ifdef LOG_LEVEL_0
|
#ifdef LOG_LEVEL_0
|
||||||
LogCreateInfo logCI{
|
LogCreateInfo logCI{};
|
||||||
.logfile = "textureAtlas.log",
|
logCI.logfile = "textureAtlas.log";
|
||||||
.storeLog = false,
|
logCI.storeLog = false;
|
||||||
.prefix = "TextureAtlas (" + gz::toString(slotCountX) + "x" + gz::toString(slotCountY) + ")X(" + gz::toString(slotWidth) + "x" + gz::toString(slotHeight) + ")",
|
logCI.prefix = "TextureAtlas (" + gz::toString(slotCountX) + "x" + gz::toString(slotCountY) + ")X(" + gz::toString(slotWidth) + "x" + gz::toString(slotHeight) + ")";
|
||||||
.prefixColor = Color::GREEN,
|
logCI.prefixColor = Color::GREEN;
|
||||||
.timeColor = settings::VULKAN_MESSAGE_TIME_COLOR,
|
logCI.timeColor = VULKAN_MESSAGE_TIME_COLOR;
|
||||||
};
|
|
||||||
tLog = Log(std::move(logCI));
|
tLog = Log(std::move(logCI));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -60,24 +59,23 @@ void TextureAtlas::cleanup() {
|
|||||||
|
|
||||||
|
|
||||||
void TextureAtlas::createImageResources() {
|
void TextureAtlas::createImageResources() {
|
||||||
vk.createImage(slotWidth * slotCountX, slotHeight * slotCountY, vk::Format::eR8G8B8A8Srgb, vk::ImageTiling::eLinear,
|
vk.createImage(slotWidth * slotCountX, slotHeight * slotCountY, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_LINEAR,
|
||||||
vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled,
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
vk::MemoryPropertyFlagBits::eDeviceLocal,
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||||
textureImage, textureImageMemory);
|
textureImage, textureImageMemory);
|
||||||
vk::CommandBuffer cmdBuffer = vk.beginSingleTimeCommands(POOL_GRAPHICS);
|
VkCommandBuffer cmdBuffer = vk.beginSingleTimeCommands(POOL_GRAPHICS);
|
||||||
vk.transitionImageLayout(textureImage, vk::Format::eR8G8B8A8Srgb, vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, &cmdBuffer);
|
vk.transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cmdBuffer);
|
||||||
vk::ImageSubresourceRange subresourceRange {
|
VkImageSubresourceRange subresourceRange{};
|
||||||
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
.baseMipLevel = 0,
|
subresourceRange.baseMipLevel = 0;
|
||||||
.levelCount = 1,
|
subresourceRange.levelCount = 1;
|
||||||
.baseArrayLayer = 0,
|
subresourceRange.baseArrayLayer = 0;
|
||||||
.layerCount = 1,
|
subresourceRange.layerCount = 1;
|
||||||
};
|
vkCmdClearColorImage(cmdBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &missingTextureColor, 1, &subresourceRange);
|
||||||
cmdBuffer.clearColorImage(textureImage, vk::ImageLayout::eTransferDstOptimal, &settings::missingTextureColor, 1, &subresourceRange);
|
vk.transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, &cmdBuffer);
|
||||||
vk.transitionImageLayout(textureImage, vk::Format::eR8G8B8A8Srgb, vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, &cmdBuffer);
|
|
||||||
vk.endSingleTimeCommands(cmdBuffer, POOL_GRAPHICS);
|
vk.endSingleTimeCommands(cmdBuffer, POOL_GRAPHICS);
|
||||||
|
|
||||||
vk.createImageView(vk::Format::eR8G8B8A8Srgb, textureImage, textureImageView, vk::ImageAspectFlagBits::eColor);
|
vk.createImageView(VK_FORMAT_R8G8B8A8_SRGB, textureImage, textureImageView, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
vk.createTextureSampler(textureSampler);
|
vk.createTextureSampler(textureSampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,26 +161,22 @@ std::pair<glm::vec2, glm::vec2> TextureAtlas::addTexture(uint8_t* pixels, uint16
|
|||||||
|
|
||||||
void TextureAtlas::blitTextureOnImage(uint8_t* pixels, uint16_t slotX, uint16_t slotY, uint16_t textureWidth, uint16_t textureHeight) {
|
void TextureAtlas::blitTextureOnImage(uint8_t* pixels, uint16_t slotX, uint16_t slotY, uint16_t textureWidth, uint16_t textureHeight) {
|
||||||
constexpr size_t BYTES_PER_PIXEL = 4;
|
constexpr size_t BYTES_PER_PIXEL = 4;
|
||||||
vk::DeviceSize imageSize = textureWidth * textureHeight * BYTES_PER_PIXEL;
|
VkDeviceSize imageSize = textureWidth * textureHeight * BYTES_PER_PIXEL;
|
||||||
vk::Buffer stagingBuffer;
|
VkBuffer stagingBuffer;
|
||||||
MemoryInfo stagingBufferMemory;
|
MemoryInfo stagingBufferMemory;
|
||||||
vk.createBuffer(imageSize, vk::BufferUsageFlagBits::eTransferSrc,
|
vk.createBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||||
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent,
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||||
stagingBuffer, stagingBufferMemory);
|
stagingBuffer, stagingBufferMemory);
|
||||||
void* data;
|
void* data;
|
||||||
vk::Result result = vk.getDevice().mapMemory(stagingBufferMemory.memory, stagingBufferMemory.offset, imageSize, vk::MemoryMapFlags(), &data);
|
vkMapMemory(vk.getDevice(), stagingBufferMemory.memory, stagingBufferMemory.offset, imageSize, NO_FLAGS, &data);
|
||||||
if (result != vk::Result::eSuccess) {
|
|
||||||
throw getVkException(result, "Failed to map staging buffer", "TextureAtlas::blitTextureOnImage");
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(data, pixels, static_cast<size_t>(imageSize));
|
memcpy(data, pixels, static_cast<size_t>(imageSize));
|
||||||
vk.getDevice().unmapMemory(stagingBufferMemory.memory);
|
vkUnmapMemory(vk.getDevice(), stagingBufferMemory.memory);
|
||||||
|
|
||||||
vk.transitionImageLayout(textureImage, vk::Format::eR8G8B8A8Srgb, vk::ImageLayout::eShaderReadOnlyOptimal, vk::ImageLayout::eTransferDstOptimal);
|
vk.transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
vk.copyBufferToImage(stagingBuffer, textureImage,
|
vk.copyBufferToImage(stagingBuffer, textureImage,
|
||||||
static_cast<int32_t>(slotWidth * slotX), static_cast<int32_t>(slotHeight * slotY), // offset
|
static_cast<int32_t>(slotWidth * slotX), static_cast<int32_t>(slotHeight * slotY), // offset
|
||||||
static_cast<uint32_t>(textureWidth), static_cast<uint32_t>(textureHeight)); // dimensions
|
static_cast<uint32_t>(textureWidth), static_cast<uint32_t>(textureHeight)); // dimensions
|
||||||
vk.transitionImageLayout(textureImage, vk::Format::eR8G8B8A8Srgb, vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal);
|
vk.transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
|
||||||
vk.destroyBuffer(stagingBuffer, stagingBufferMemory);
|
vk.destroyBuffer(stagingBuffer, stagingBufferMemory);
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
#include "vulkan_allocator.hpp"
|
#include "vulkan_allocator.hpp"
|
||||||
#include <gz-util/log.hpp>
|
#include <gz-util/log.hpp>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
#include <vulkan/vulkan_core.h>
|
||||||
#include <vulkan/vulkan.hpp>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -15,7 +14,7 @@
|
|||||||
#include <gz-util/log.hpp>
|
#include <gz-util/log.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
/**
|
/**
|
||||||
* @brief Describes an area in the textureImage that is not in use
|
* @brief Describes an area in the textureImage that is not in use
|
||||||
*/
|
*/
|
||||||
@ -62,8 +61,8 @@ namespace gz::vlk {
|
|||||||
* @throws Exception when there is no space in the atlas to add the texture
|
* @throws Exception when there is no space in the atlas to add the texture
|
||||||
*/
|
*/
|
||||||
std::pair<glm::vec2, glm::vec2> addTexture(uint8_t* pixels, uint16_t textureWidth, uint16_t textureHeight);
|
std::pair<glm::vec2, glm::vec2> addTexture(uint8_t* pixels, uint16_t textureWidth, uint16_t textureHeight);
|
||||||
const vk::ImageView& getTextureImageView() const { return textureImageView; }
|
const VkImageView& getTextureImageView() const { return textureImageView; }
|
||||||
const vk::Sampler& getTextureSampler() const { return textureSampler; }
|
const VkSampler& getTextureSampler() const { return textureSampler; }
|
||||||
|
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
|
||||||
@ -82,10 +81,10 @@ namespace gz::vlk {
|
|||||||
* the textureImage is created with missingTextureColor and then transitioned to SHADER_READ_ONLY_OPTIMAL layout.
|
* the textureImage is created with missingTextureColor and then transitioned to SHADER_READ_ONLY_OPTIMAL layout.
|
||||||
*/
|
*/
|
||||||
void createImageResources();
|
void createImageResources();
|
||||||
vk::Image textureImage;
|
VkImage textureImage;
|
||||||
MemoryInfo textureImageMemory;
|
MemoryInfo textureImageMemory;
|
||||||
vk::ImageView textureImageView;
|
VkImageView textureImageView;
|
||||||
vk::Sampler textureSampler;
|
VkSampler textureSampler;
|
||||||
|
|
||||||
std::set<TextureImageArea, decltype(freeAreaCmp)> freeAreas;
|
std::set<TextureImageArea, decltype(freeAreaCmp)> freeAreas;
|
||||||
/**
|
/**
|
||||||
@ -104,4 +103,4 @@ namespace gz::vlk {
|
|||||||
Log tLog;
|
Log tLog;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
@ -3,22 +3,22 @@
|
|||||||
#include "vulkan_instance.hpp"
|
#include "vulkan_instance.hpp"
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
TextureManager::TextureManager(VulkanInstance& instance)
|
TextureManager::TextureManager(VulkanInstance& instance)
|
||||||
: vk(instance)
|
: vk(instance)
|
||||||
{
|
{
|
||||||
LogCreateInfo logCI{
|
LogCreateInfo logCI{};
|
||||||
.logfile = "textureManager.log",
|
logCI.logfile = "textureManager.log";
|
||||||
.storeLog = false,
|
logCI.storeLog = false;
|
||||||
.prefix = "Texture",
|
logCI.prefix = "Texture";
|
||||||
.prefixColor = Color::GREEN,
|
logCI.prefixColor = Color::GREEN;
|
||||||
.timeColor = settings::VULKAN_MESSAGE_TIME_COLOR,
|
logCI.timeColor = VULKAN_MESSAGE_TIME_COLOR;
|
||||||
};
|
|
||||||
tLog = Log(std::move(logCI));
|
tLog = Log(std::move(logCI));
|
||||||
|
|
||||||
vk.registerCleanupCallback(std::bind(&TextureManager::cleanup, this));
|
vk.registerCleanupCallback(std::bind(&TextureManager::cleanup, this));
|
||||||
atlases.emplace_back(TextureAtlas(vk, 24, 24, 24, 24));
|
atlases.insert({ 0, TextureAtlas(vk, 24, 24, 24, 24) });
|
||||||
createDescriptorSetLayout();
|
createDescriptorSetLayout();
|
||||||
createDescriptorPool();
|
createDescriptorPool();
|
||||||
createDescriptorSet();
|
createDescriptorSet();
|
||||||
@ -30,10 +30,12 @@ namespace gz::vlk {
|
|||||||
|
|
||||||
void TextureManager::cleanup() {
|
void TextureManager::cleanup() {
|
||||||
tLog.log0("cleanup: cleaning up");
|
tLog.log0("cleanup: cleaning up");
|
||||||
vk.getDevice().destroyDescriptorSetLayout(descriptorSetLayout, NO_ALLOC);
|
/* vkFreeDescriptorSets(vk.getDevice(), descriptorPool, 1, &descriptorSet); */
|
||||||
vk.getDevice().destroyDescriptorPool(descriptorPool, NO_ALLOC);
|
vkDestroyDescriptorSetLayout(vk.getDevice(), descriptorSetLayout, NO_ALLOC);
|
||||||
for (auto& atlas : atlases) {
|
vkDestroyDescriptorPool(vk.getDevice(), descriptorPool, NO_ALLOC);
|
||||||
|
for (auto& [i, atlas] : atlases) {
|
||||||
atlas.cleanup();
|
atlas.cleanup();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +46,8 @@ namespace gz::vlk {
|
|||||||
}
|
}
|
||||||
TextureInfo& texI = textureInfos[textureName];
|
TextureInfo& texI = textureInfos[textureName];
|
||||||
tLog.log0("getTexCoords", texCoords, "textureInfo: topleft", texI.texCoordTopLeft, "botright", texI.texCoordBottomRight);
|
tLog.log0("getTexCoords", texCoords, "textureInfo: topleft", texI.texCoordTopLeft, "botright", texI.texCoordBottomRight);
|
||||||
|
/* texCoords.x = texI.texCoordTopLeft.x + texCoords.x * (texI.texCoordBottomRight.x - texI.texCoordTopLeft.x); */
|
||||||
|
/* texCoords.y = texI.texCoordTopLeft.y + texCoords.y * (texI.texCoordBottomRight.y - texI.texCoordTopLeft.y); */
|
||||||
texCoords = texI.texCoordTopLeft + texCoords * (texI.texCoordBottomRight - texI.texCoordTopLeft);
|
texCoords = texI.texCoordTopLeft + texCoords * (texI.texCoordBottomRight - texI.texCoordTopLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,12 +60,11 @@ namespace gz::vlk {
|
|||||||
}
|
}
|
||||||
TextureInfo& texI = textureInfos[textureName];
|
TextureInfo& texI = textureInfos[textureName];
|
||||||
texI.atlas = 0;
|
texI.atlas = 0;
|
||||||
// TODO
|
|
||||||
auto texCoords = atlases.at(0).addTexture(pixels, textureWidth, textureHeight);
|
auto texCoords = atlases.at(0).addTexture(pixels, textureWidth, textureHeight);
|
||||||
stbi_image_free(pixels);
|
stbi_image_free(pixels);
|
||||||
tLog.log0("TextureManager::loadTextureFromFile: TexCoords of new image:", texCoords.first, texCoords.second);
|
tLog.log0("TextureManager::loadTextureFromFile: TexCoords of new image:", texCoords.first, texCoords.second);
|
||||||
texI.texCoordTopLeft = std::move(texCoords.first),
|
texI.texCoordTopLeft = std::move(texCoords.first);
|
||||||
texI.texCoordBottomRight = std::move(texCoords.second),
|
texI.texCoordBottomRight = std::move(texCoords.second);
|
||||||
tLog.log0("TextureManager::loadTextureFromFile: After loading:", atlases.at(0));
|
tLog.log0("TextureManager::loadTextureFromFile: After loading:", atlases.at(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,20 +74,20 @@ namespace gz::vlk {
|
|||||||
//
|
//
|
||||||
void TextureManager::createDescriptorSetLayout() {
|
void TextureManager::createDescriptorSetLayout() {
|
||||||
// combined image sampler
|
// combined image sampler
|
||||||
std::vector<vk::DescriptorSetLayoutBinding> samplerLayoutBindings(atlases.size(), {
|
VkDescriptorSetLayoutBinding samplerLayoutBinding{};
|
||||||
.binding = 0,
|
samplerLayoutBinding.binding = 0;
|
||||||
.descriptorType = vk::DescriptorType::eCombinedImageSampler,
|
samplerLayoutBinding.descriptorCount = 1;
|
||||||
.descriptorCount = 1,
|
samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
.stageFlags = vk::ShaderStageFlagBits::eFragment,
|
samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
/* .pImmutableSamplers = nullptr, */
|
/* samplerLayoutBinding.pImmutableSamplers = nullptr; */
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
vk::DescriptorSetLayoutCreateInfo descriptorSetLayoutCI;
|
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCI{};
|
||||||
descriptorSetLayoutCI.setBindings(samplerLayoutBindings);
|
descriptorSetLayoutCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
|
descriptorSetLayoutCI.bindingCount = 1;
|
||||||
|
descriptorSetLayoutCI.pBindings = &samplerLayoutBinding;
|
||||||
|
|
||||||
vk::Result result = vk.getDevice().createDescriptorSetLayout(&descriptorSetLayoutCI, nullptr, &descriptorSetLayout);
|
VkResult result = vkCreateDescriptorSetLayout(vk.getDevice(), &descriptorSetLayoutCI, nullptr, &descriptorSetLayout);
|
||||||
if (result != vk::Result::eSuccess) {
|
if (result != VK_SUCCESS) {
|
||||||
throw getVkException(result, "Could not create descriptorSetLayout", "TextureManager::createDescriptorSetLayout");
|
throw getVkException(result, "Could not create descriptorSetLayout", "TextureManager::createDescriptorSetLayout");
|
||||||
}
|
}
|
||||||
/* vLog("createDescriptorSetLayout: Created descriptor set layout."); */
|
/* vLog("createDescriptorSetLayout: Created descriptor set layout."); */
|
||||||
@ -92,56 +95,64 @@ void TextureManager::createDescriptorSetLayout() {
|
|||||||
|
|
||||||
|
|
||||||
void TextureManager::createDescriptorPool() {
|
void TextureManager::createDescriptorPool() {
|
||||||
std::vector<vk::DescriptorPoolSize> poolSizes {
|
std::array<VkDescriptorPoolSize, 1> poolSizes;
|
||||||
vk::DescriptorPoolSize {
|
/* poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; */
|
||||||
.type = vk::DescriptorType::eCombinedImageSampler,
|
/* poolSizes[0].descriptorCount = static_cast<uint32_t>(vk.getMaxFramesInFlight()); */
|
||||||
.descriptorCount = static_cast<uint32_t>(vk.getMaxFramesInFlight())
|
poolSizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
}
|
poolSizes[0].descriptorCount = static_cast<uint32_t>(vk.getMaxFramesInFlight());
|
||||||
};
|
|
||||||
|
|
||||||
vk::DescriptorPoolCreateInfo poolCI { .maxSets = 1 };
|
VkDescriptorPoolCreateInfo poolCI{};
|
||||||
poolCI.setPoolSizes(poolSizes);
|
poolCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
|
poolCI.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
|
||||||
vk::Result result;
|
poolCI.pPoolSizes = poolSizes.data();
|
||||||
std::tie(result, descriptorPool) = vk.getDevice().createDescriptorPool(poolCI);
|
poolCI.maxSets = 1;
|
||||||
if (result != vk::Result::eSuccess) {
|
VkResult result = vkCreateDescriptorPool(vk.getDevice(), &poolCI, nullptr, &descriptorPool);
|
||||||
throw getVkException(result, "Failed to create descriptor pool", "TextureManager::createDescriptorPool");
|
if (result != VK_SUCCESS) {
|
||||||
}
|
throw getVkException(result, "Failed to create descriptor pool", "TextureManager::createDescriptorPool");
|
||||||
|
}
|
||||||
/* vLog("createDescriptorPool: Created descriptor pool."); */
|
/* vLog("createDescriptorPool: Created descriptor pool."); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TextureManager::createDescriptorSet() {
|
void TextureManager::createDescriptorSet() {
|
||||||
vk::DescriptorSetAllocateInfo setAI {
|
/* std::vector<VkDescriptorSetLayout> layouts(vk.getMaxFramesInFlight(), descriptorSetLayout); */
|
||||||
.descriptorPool = descriptorPool,
|
VkDescriptorSetAllocateInfo setAI{};
|
||||||
};
|
setAI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||||
setAI.setSetLayouts(descriptorSetLayout);
|
setAI.descriptorPool = descriptorPool;
|
||||||
|
/* setAI.descriptorSetCount = static_cast<uint32_t>(vk.getMaxFramesInFlight()); */
|
||||||
|
/* setAI.pSetLayouts = layouts.data(); */
|
||||||
|
setAI.descriptorSetCount = 1;
|
||||||
|
setAI.pSetLayouts = &descriptorSetLayout;
|
||||||
|
|
||||||
auto [result, descriptorSetV] = vk.getDevice().allocateDescriptorSets(setAI);
|
/* descriptorSets.resize(vk.getMaxFramesInFlight()); */
|
||||||
descriptorSet = descriptorSetV.front();
|
/* VkResult result = vkAllocateDescriptorSets(vk.getDevice(), &setAI, descriptorSets.data()); */
|
||||||
if (result != vk::Result::eSuccess) {
|
VkResult result = vkAllocateDescriptorSets(vk.getDevice(), &setAI, &descriptorSet);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
throw getVkException(result, "Failed to create descriptor set", "TextureManager::createDescriptorPool");
|
throw getVkException(result, "Failed to create descriptor set", "TextureManager::createDescriptorPool");
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure sets
|
// configure sets
|
||||||
std::vector<vk::DescriptorImageInfo> imageInfos;
|
std::vector<VkDescriptorImageInfo> imageInfos;
|
||||||
for (auto it = atlases.cbegin(); it != atlases.cend(); it++) {
|
for (auto it = atlases.cbegin(); it != atlases.cend(); it++) {
|
||||||
imageInfos.emplace_back();
|
imageInfos.emplace_back();
|
||||||
imageInfos.back().imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
|
imageInfos.back().imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
imageInfos.back().imageView = it->getTextureImageView();
|
imageInfos.back().imageView = it->second.getTextureImageView();
|
||||||
imageInfos.back().sampler = it->getTextureSampler();
|
imageInfos.back().sampler = it->second.getTextureSampler();
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::WriteDescriptorSet descriptorW {
|
std::array<VkWriteDescriptorSet, 1> descriptorW{};
|
||||||
.dstSet = descriptorSet,
|
descriptorW[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
.dstBinding = 0,
|
descriptorW[0].dstSet = descriptorSet;
|
||||||
.dstArrayElement = 0,
|
descriptorW[0].dstBinding = 0;
|
||||||
.descriptorType = vk::DescriptorType::eCombinedImageSampler,
|
descriptorW[0].dstArrayElement = 0;
|
||||||
};
|
descriptorW[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
descriptorW.setImageInfo(imageInfos);
|
descriptorW[0].descriptorCount = static_cast<uint32_t>(imageInfos.size());
|
||||||
|
descriptorW[0].pImageInfo = imageInfos.data();
|
||||||
|
|
||||||
// 1 write, no copies
|
uint32_t descriptorWriteCount = static_cast<uint32_t>(descriptorW.size());
|
||||||
vk.getDevice().updateDescriptorSets(descriptorW, nullptr);
|
uint32_t descriptorCopyCount = 0;
|
||||||
tLog.log0("createDescriptorSets: Created descriptor sets.");
|
vkUpdateDescriptorSets(vk.getDevice(), descriptorWriteCount, descriptorW.data(), descriptorCopyCount, nullptr);
|
||||||
|
/* } */
|
||||||
|
/* vLog("createDescriptorSets: Created descriptor sets."); */
|
||||||
}
|
}
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
struct TextureInfo {
|
struct TextureInfo {
|
||||||
uint32_t atlas;
|
uint32_t atlas;
|
||||||
glm::vec2 texCoordTopLeft;
|
glm::vec2 texCoordTopLeft;
|
||||||
@ -28,35 +28,30 @@ namespace gz::vlk {
|
|||||||
*/
|
*/
|
||||||
TextureManager(VulkanInstance& instance);
|
TextureManager(VulkanInstance& instance);
|
||||||
void getTexCoords(const std::string& textureName, glm::vec2& texCoords);
|
void getTexCoords(const std::string& textureName, glm::vec2& texCoords);
|
||||||
const vk::DescriptorSet& getDescriptorSet() const { return descriptorSet; }
|
const VkDescriptorSet& getDescriptorSet() const { return descriptorSet; }
|
||||||
const vk::DescriptorSetLayout& getDescriptorSetLayout() const { return descriptorSetLayout; }
|
const VkDescriptorSetLayout& getDescriptorSetLayout() const { return descriptorSetLayout; }
|
||||||
// TODO
|
// TODO
|
||||||
/// @todo take texture as argument
|
/// @todo take texture as argument
|
||||||
const TextureAtlas& getTextureAtlas() const { return atlases.at(0); }
|
const TextureAtlas& getTextureAtlas() const { return atlases.at(0); };
|
||||||
uint32_t getAtlasCount() const { return static_cast<uint32_t>(atlases.size()); }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void loadTextureFromFile(const std::string& textureName);
|
void loadTextureFromFile(const std::string& textureName);
|
||||||
// TODO index currently has no meaning
|
std::unordered_map<uint32_t, TextureAtlas> atlases;
|
||||||
std::vector<TextureAtlas> atlases;
|
|
||||||
/**
|
|
||||||
* @brief Contains textureName : TextureInfo pairs
|
|
||||||
*/
|
|
||||||
util::unordered_string_map<TextureInfo> textureInfos;
|
util::unordered_string_map<TextureInfo> textureInfos;
|
||||||
VulkanInstance& vk;
|
VulkanInstance& vk;
|
||||||
Log tLog;
|
Log tLog;
|
||||||
/**
|
/**
|
||||||
* @name Create desciptors
|
* @name Create desciptors
|
||||||
* @details These functions create a desciptor with bindings for
|
* @details These functions create a desciptor with bindings for
|
||||||
* -# Array of combined image samplers (DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) at binding 0. Array length is atlas count
|
* -# Combined Image Sampler (DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) at binding 0
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
vk::DescriptorSetLayout descriptorSetLayout;
|
VkDescriptorSetLayout descriptorSetLayout;
|
||||||
vk::DescriptorPool descriptorPool;
|
VkDescriptorPool descriptorPool;
|
||||||
vk::DescriptorSet descriptorSet;
|
VkDescriptorSet descriptorSet;
|
||||||
/* std::vector<vk::DescriptorSet> descriptorSets; */
|
/* std::vector<VkDescriptorSet> descriptorSets; */
|
||||||
/**
|
/**
|
||||||
* @brief Create a descriptor set layout
|
* @brief Create a descriptor set layout
|
||||||
* @details
|
* @details
|
||||||
@ -74,4 +69,4 @@ namespace gz::vlk {
|
|||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
#include "vulkan_util.hpp"
|
#include "vulkan_util.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
#include <vulkan/vulkan_enums.hpp>
|
|
||||||
#include <vulkan/vulkan_structs.hpp>
|
|
||||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
|
||||||
#include <vulkan/vulkan.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
//
|
//
|
||||||
// CONVENIENCE
|
// CONVENIENCE
|
||||||
//
|
//
|
||||||
@ -20,9 +16,6 @@ namespace gz::vlk {
|
|||||||
f11.pNext = &f12;
|
f11.pNext = &f12;
|
||||||
f12.pNext = &f13;
|
f12.pNext = &f13;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static_assert(sizeof(VkStructureType) != sizeof(vk::StructureType), "Objects do not have same size"); */
|
|
||||||
/* static_assert(sizeof(VkPhysicalDeviceFeatures) != sizeof(vk::PhysicalDeviceFeatures), "Objects do not have same size"); */
|
|
||||||
bool PhysicalDeviceFeatures::requiredFeaturesAvailable(const PhysicalDeviceFeatures& requiredFeatures) const {
|
bool PhysicalDeviceFeatures::requiredFeaturesAvailable(const PhysicalDeviceFeatures& requiredFeatures) const {
|
||||||
// iterate over all the features in the structs
|
// iterate over all the features in the structs
|
||||||
// VkPhysicalDeviceFeatures2
|
// VkPhysicalDeviceFeatures2
|
||||||
@ -75,47 +68,53 @@ namespace gz::vlk {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineContainer::erase(const PipelineT& key, const vk::Device& device, const vk::AllocationCallbacks* pAllocator) {
|
void PipelineContainer::erase(const PipelineT& key, const VkDevice& device, const VkAllocationCallbacks* pAllocator) {
|
||||||
device.destroyPipeline(pipelines[key].pipeline, pAllocator);
|
vkDestroyPipeline(device, pipelines[key].pipeline, pAllocator);
|
||||||
device.destroyPipelineLayout(pipelines[key].layout, pAllocator);
|
vkDestroyPipelineLayout(device, pipelines[key].layout, pAllocator);
|
||||||
pipelines.erase(pipelines.find(key));
|
pipelines.erase(pipelines.find(key));
|
||||||
}
|
}
|
||||||
PipelineContainer::iterator PipelineContainer::erase(const PipelineContainer::iterator& it, const vk::Device& device, const vk::AllocationCallbacks* pAllocator) {
|
PipelineContainer::iterator PipelineContainer::erase(const PipelineContainer::iterator& it, const VkDevice& device, const VkAllocationCallbacks* pAllocator) {
|
||||||
device.destroyPipeline(it->second.pipeline, pAllocator);
|
vkDestroyPipeline(device, it->second.pipeline, pAllocator);
|
||||||
device.destroyPipelineLayout(it->second.layout, pAllocator);
|
vkDestroyPipelineLayout(device, it->second.layout, pAllocator);
|
||||||
return pipelines.erase(it);
|
return pipelines.erase(it);
|
||||||
|
|
||||||
}
|
}
|
||||||
void PipelineContainer::destroy(const vk::Device& device, const vk::AllocationCallbacks* pAllocator) {
|
void PipelineContainer::destroy(const VkDevice& device, const VkAllocationCallbacks* pAllocator) {
|
||||||
auto it = pipelines.begin(); while (it != pipelines.end()) {
|
auto it = pipelines.begin(); while (it != pipelines.end()) {
|
||||||
it = erase(it, device);
|
it = erase(it, device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vk::DependencyInfo getDepInfo(const vk::ImageMemoryBarrier2& barrier) {
|
VkDependencyInfo getDepInfo(const VkImageMemoryBarrier2& barrier) {
|
||||||
vk::DependencyInfo depI {
|
VkDependencyInfo depI{};
|
||||||
.imageMemoryBarrierCount = 1,
|
depI.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
|
||||||
.pImageMemoryBarriers = &barrier,
|
depI.imageMemoryBarrierCount = 1;
|
||||||
};
|
depI.pImageMemoryBarriers = &barrier;
|
||||||
return depI;
|
return depI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* void getBufferMemoryRequirements(const vk::Device& device, const vk::Buffer& buffer, vk::BufferMemoryRequirementsInfo2& bufMemReq, vk::MemoryRequirements2& memReq) { */
|
void getBufferMemoryRequirements(const VkDevice& device, const VkBuffer& buffer, VkBufferMemoryRequirementsInfo2& bufMemReq, VkMemoryRequirements2& memReq) {
|
||||||
/* bufMemReq.pNext = nullptr; */
|
bufMemReq.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
|
||||||
/* bufMemReq.buffer = buffer; */
|
bufMemReq.pNext = nullptr;
|
||||||
|
bufMemReq.buffer = buffer;
|
||||||
|
|
||||||
/* memReq.pNext = nullptr; */
|
memReq.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||||
/* vk::getBufferMemoryRequirements2(device, &bufMemReq, &memReq); */
|
memReq.pNext = nullptr;
|
||||||
/* } */
|
vkGetBufferMemoryRequirements2(device, &bufMemReq, &memReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* void getImageMemoryRequirements(const vk::Device& device, const vk::Image& image, vk::ImageMemoryRequirementsInfo2& imMemReq, vk::MemoryRequirements2& memReq) { */
|
void getImageMemoryRequirements(const VkDevice& device, const VkImage& image, VkImageMemoryRequirementsInfo2& imMemReq, VkMemoryRequirements2& memReq) {
|
||||||
/* imMemReq.image = image; */
|
imMemReq.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
|
||||||
|
imMemReq.pNext = nullptr;
|
||||||
|
imMemReq.image = image;
|
||||||
|
|
||||||
/* memReq = device.getImageMemoryRequirements2(imMemReq); */
|
memReq.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||||
/* } */
|
memReq.pNext = nullptr;
|
||||||
|
vkGetImageMemoryRequirements2(device, &imMemReq, &memReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -143,7 +142,7 @@ namespace gz::vlk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,25 +5,9 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
#include <vulkan/vulkan_core.h>
|
||||||
#define VULKAN_HPP_NO_EXCEPTIONS
|
|
||||||
#include <vulkan/vulkan.hpp>
|
|
||||||
|
|
||||||
#ifdef GZ_UTIL_STRING_CONCEPTS
|
namespace gz::vk {
|
||||||
static_assert(false, "gz-util/util/string_conversion.hpp is included before vulkan_util.hpp!");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
concept VkToString = requires(const T& t) {
|
|
||||||
{ vk::to_string(t) };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<VkToString T>
|
|
||||||
inline std::string toString(const T& t) {
|
|
||||||
return vk::to_string(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace gz::vlk {
|
|
||||||
/**
|
/**
|
||||||
* @name Convenience structs
|
* @name Convenience structs
|
||||||
* @details
|
* @details
|
||||||
@ -34,14 +18,13 @@ namespace gz::vlk {
|
|||||||
* @brief Struct containing all physical device features structs
|
* @brief Struct containing all physical device features structs
|
||||||
* @details
|
* @details
|
||||||
* Make sure to call vkGetPhysicalDeviceFeatures2 with the f member, not this struct itself
|
* Make sure to call vkGetPhysicalDeviceFeatures2 with the f member, not this struct itself
|
||||||
* @todo Redo with vulkan.hpp and vk::StructureChain
|
|
||||||
*/
|
*/
|
||||||
struct PhysicalDeviceFeatures {
|
struct PhysicalDeviceFeatures {
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the structs with sType and pNext chain f -> f11 -> f12 -> f13
|
* @brief Initialize the structs with sType and pNext chain f -> f11 -> f12 -> f13
|
||||||
*/
|
*/
|
||||||
PhysicalDeviceFeatures();
|
PhysicalDeviceFeatures();
|
||||||
VkPhysicalDeviceFeatures2 f {};
|
VkPhysicalDeviceFeatures2 f{};
|
||||||
VkPhysicalDeviceVulkan11Features f11{};
|
VkPhysicalDeviceVulkan11Features f11{};
|
||||||
VkPhysicalDeviceVulkan12Features f12{};
|
VkPhysicalDeviceVulkan12Features f12{};
|
||||||
VkPhysicalDeviceVulkan13Features f13{};
|
VkPhysicalDeviceVulkan13Features f13{};
|
||||||
@ -55,8 +38,8 @@ namespace gz::vlk {
|
|||||||
PL_3D, PL_2D
|
PL_3D, PL_2D
|
||||||
};
|
};
|
||||||
struct Pipeline {
|
struct Pipeline {
|
||||||
vk::Pipeline pipeline;
|
VkPipeline pipeline;
|
||||||
vk::PipelineLayout layout;
|
VkPipelineLayout layout;
|
||||||
void operator=(const Pipeline& other) = delete;
|
void operator=(const Pipeline& other) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,15 +53,15 @@ namespace gz::vlk {
|
|||||||
/**
|
/**
|
||||||
* @brief Destroy the pipeline+layout and then remove the handles from the underlying map
|
* @brief Destroy the pipeline+layout and then remove the handles from the underlying map
|
||||||
*/
|
*/
|
||||||
void erase(const PipelineT& key, const vk::Device& device, const vk::AllocationCallbacks* pAllocator=nullptr);
|
void erase(const PipelineT& key, const VkDevice& device, const VkAllocationCallbacks* pAllocator=nullptr);
|
||||||
/**
|
/**
|
||||||
* @brief Destroy the pipeline+layout and then remove the handles from the underlying map
|
* @brief Destroy the pipeline+layout and then remove the handles from the underlying map
|
||||||
*/
|
*/
|
||||||
iterator erase(const iterator& it, const vk::Device& device, const vk::AllocationCallbacks* pAllocator=nullptr);
|
iterator erase(const iterator& it, const VkDevice& device, const VkAllocationCallbacks* pAllocator=nullptr);
|
||||||
/**
|
/**
|
||||||
* @brief Destroy all pipelines#layouts and then remove the handles from the underlying map
|
* @brief Destroy all pipelines#layouts and then remove the handles from the underlying map
|
||||||
*/
|
*/
|
||||||
void destroy(const vk::Device& device, const vk::AllocationCallbacks* pAllocator=nullptr);
|
void destroy(const VkDevice& device, const VkAllocationCallbacks* pAllocator=nullptr);
|
||||||
iterator begin() { return pipelines.begin(); }
|
iterator begin() { return pipelines.begin(); }
|
||||||
iterator end() { return pipelines.end(); }
|
iterator end() { return pipelines.end(); }
|
||||||
size_t size() const { return pipelines.size(); }
|
size_t size() const { return pipelines.size(); }
|
||||||
@ -88,9 +71,9 @@ namespace gz::vlk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SwapChainSupport {
|
struct SwapChainSupport {
|
||||||
vk::SurfaceCapabilities2KHR capabilities;
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
std::vector<vk::SurfaceFormat2KHR> formats;
|
std::vector<VkSurfaceFormatKHR> formats;
|
||||||
std::vector<vk::PresentModeKHR> presentModes;
|
std::vector<VkPresentModeKHR> presentModes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -101,12 +84,12 @@ namespace gz::vlk {
|
|||||||
struct VerticesAndIndices {
|
struct VerticesAndIndices {
|
||||||
std::vector<Vertex3D> vertices;
|
std::vector<Vertex3D> vertices;
|
||||||
std::vector<T> indices;
|
std::vector<T> indices;
|
||||||
constexpr vk::IndexType getIndexType() const {
|
constexpr VkIndexType getIndexType() const {
|
||||||
if (std::same_as<T, uint16_t>) {
|
if (std::same_as<T, uint16_t>) {
|
||||||
return vk::IndexType::eUint16;
|
return VK_INDEX_TYPE_UINT16;
|
||||||
}
|
}
|
||||||
else if (std::same_as<T, uint32_t>) {
|
else if (std::same_as<T, uint32_t>) {
|
||||||
return vk::IndexType::eUint32;
|
return VK_INDEX_TYPE_UINT32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -141,30 +124,30 @@ namespace gz::vlk {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a vk::DependencyInfo struct for a single image memory barrier
|
* @brief Get a VkDependencyInfo struct for a single image memory barrier
|
||||||
*/
|
*/
|
||||||
vk::DependencyInfo getDepInfo(const vk::ImageMemoryBarrier2& barrier);
|
VkDependencyInfo getDepInfo(const VkImageMemoryBarrier2& barrier);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Fill bufMeqReq and memReq
|
* @brief Fill bufMeqReq and memReq
|
||||||
* @details
|
* @details
|
||||||
* Fill the structs and call vkGetBufferMemoryRequirements2()
|
* Fill the structs and call vkGetBufferMemoryRequirements2()
|
||||||
*/
|
*/
|
||||||
/* void getBufferMemoryRequirements(const vk::Device& device, const vk::Buffer& buffer, vk::BufferMemoryRequirementsInfo2& bufMemReq, vk::MemoryRequirements2& memReq); */
|
void getBufferMemoryRequirements(const VkDevice& device, const VkBuffer& buffer, VkBufferMemoryRequirementsInfo2& bufMemReq, VkMemoryRequirements2& memReq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Fill imMemReq and memReq
|
* @brief Fill imMemReq and memReq
|
||||||
* @details
|
* @details
|
||||||
* Fill the structs and call vkGetImageMemoryRequirements2()
|
* Fill the structs and call vkGetImageMemoryRequirements2()
|
||||||
*/
|
*/
|
||||||
/* void getImageMemoryRequirements(const vk::Device& device, const vk::Image& image, vk::ImageMemoryRequirementsInfo2& imMemReq, vk::MemoryRequirements2& memReq); */
|
void getImageMemoryRequirements(const VkDevice& device, const VkImage& image, VkImageMemoryRequirementsInfo2& imMemReq, VkMemoryRequirements2& memReq);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Used for debugging
|
* @brief Used for debugging
|
||||||
* @see VulkanInstance::debugLog
|
* @see VulkanInstance::debugLog
|
||||||
* @details
|
* @details
|
||||||
* Handles like vk::Device are pointers to the actual handle.
|
* Handles like VkDevice are pointers to the actual handle.
|
||||||
* Register the handle to a vulkan object with this struct and call updateHandles().
|
* Register the handle to a vulkan object with this struct and call updateHandles().
|
||||||
* The handles set will then contain the actual address of the handle, as printed by the validation layers.
|
* The handles set will then contain the actual address of the handle, as printed by the validation layers.
|
||||||
* That means you can check a handle returned by a validation layer
|
* That means you can check a handle returned by a validation layer
|
||||||
@ -186,33 +169,4 @@ namespace gz::vlk {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace gz::vk
|
||||||
/**
|
|
||||||
* @brief Check if all required extensions are available
|
|
||||||
*/
|
|
||||||
template<std::ranges::forward_range RE, std::ranges::forward_range AE>
|
|
||||||
bool areExtensionsAvailable(const RE& requiredExtensions, const AE& availableExtensions)
|
|
||||||
requires std::same_as<std::ranges::range_reference_t<RE>, const char*&> and std::same_as<std::ranges::range_reference_t<AE>, vk::ExtensionProperties&>
|
|
||||||
{
|
|
||||||
bool extensionAvailable;
|
|
||||||
for (const auto& requiredExtension : requiredExtensions) {
|
|
||||||
extensionAvailable = false;
|
|
||||||
for (const auto& extension : availableExtensions) {
|
|
||||||
if (strcmp(requiredExtension, extension.extensionName) == 0) {
|
|
||||||
extensionAvailable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!extensionAvailable) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief Various utility structs and functions, as well as toString() overload for vk objects
|
|
||||||
*/
|
|
||||||
|
|
||||||
} // namespace gz::vlk
|
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
#include "vertex.hpp"
|
#include "vertex.hpp"
|
||||||
|
|
||||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
#include <vulkan/vulkan_core.h>
|
||||||
#include <vulkan/vulkan.hpp>
|
|
||||||
#include <gz-util/util/string_conversion.hpp>
|
#include <gz-util/util/string_conversion.hpp>
|
||||||
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
const uint32_t BINDING = 0;
|
const uint32_t BINDING = 0;
|
||||||
|
|
||||||
template<GLM_vec2_or_3 PosVec>
|
template<GLM_vec2_or_3 PosVec>
|
||||||
vk::Format getVkFormat() {
|
VkFormat getVkFormat() {
|
||||||
if (std::same_as<PosVec, glm::vec3>) {
|
if (std::same_as<PosVec, glm::vec3>) {
|
||||||
return vk::Format::eR32G32B32Sfloat;
|
return VK_FORMAT_R32G32B32_SFLOAT;
|
||||||
}
|
}
|
||||||
else if (std::same_as<PosVec, glm::vec2>) {
|
else if (std::same_as<PosVec, glm::vec2>) {
|
||||||
return vk::Format::eR32G32Sfloat;
|
return VK_FORMAT_R32G32_SFLOAT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,29 +29,28 @@ vk::Format getVkFormat() {
|
|||||||
|
|
||||||
|
|
||||||
template<GLM_vec2_or_3 PosVec>
|
template<GLM_vec2_or_3 PosVec>
|
||||||
vk::VertexInputBindingDescription Vertex<PosVec>::getBindingDescription() {
|
VkVertexInputBindingDescription Vertex<PosVec>::getBindingDescription() {
|
||||||
vk::VertexInputBindingDescription bindingD {
|
VkVertexInputBindingDescription bindingD{};
|
||||||
.binding = BINDING,
|
bindingD.binding = BINDING;
|
||||||
.stride = sizeof(Vertex<PosVec>),
|
bindingD.stride = sizeof(Vertex<PosVec>);
|
||||||
.inputRate = vk::VertexInputRate::eVertex,
|
bindingD.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||||
};
|
|
||||||
return bindingD;
|
return bindingD;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<GLM_vec2_or_3 PosVec>
|
template<GLM_vec2_or_3 PosVec>
|
||||||
std::array<vk::VertexInputAttributeDescription, 3> Vertex<PosVec>::getAttributeDescriptions() {
|
std::array<VkVertexInputAttributeDescription, 3> Vertex<PosVec>::getAttributeDescriptions() {
|
||||||
std::array<vk::VertexInputAttributeDescription, 3> inputAttributeD{};
|
std::array<VkVertexInputAttributeDescription, 3> inputAttributeD{};
|
||||||
inputAttributeD[0].binding = BINDING;
|
inputAttributeD[0].binding = BINDING;
|
||||||
inputAttributeD[0].location = 0;
|
inputAttributeD[0].location = 0;
|
||||||
inputAttributeD[0].format = getVkFormat<PosVec>();
|
inputAttributeD[0].format = getVkFormat<PosVec>();
|
||||||
inputAttributeD[0].offset = offsetof(Vertex, pos);
|
inputAttributeD[0].offset = offsetof(Vertex, pos);
|
||||||
inputAttributeD[1].binding = BINDING;
|
inputAttributeD[1].binding = BINDING;
|
||||||
inputAttributeD[1].location = 1;
|
inputAttributeD[1].location = 1;
|
||||||
inputAttributeD[1].format = vk::Format::eR32G32B32Sfloat;
|
inputAttributeD[1].format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||||
inputAttributeD[1].offset = offsetof(Vertex, color);
|
inputAttributeD[1].offset = offsetof(Vertex, color);
|
||||||
inputAttributeD[2].binding = BINDING;
|
inputAttributeD[2].binding = BINDING;
|
||||||
inputAttributeD[2].location = 2;
|
inputAttributeD[2].location = 2;
|
||||||
inputAttributeD[2].format = vk::Format::eR32G32Sfloat;
|
inputAttributeD[2].format = VK_FORMAT_R32G32_SFLOAT;
|
||||||
inputAttributeD[2].offset = offsetof(Vertex, texCoord);
|
inputAttributeD[2].offset = offsetof(Vertex, texCoord);
|
||||||
|
|
||||||
return inputAttributeD;
|
return inputAttributeD;
|
||||||
@ -65,11 +63,11 @@ vk::Format getVkFormat() {
|
|||||||
|
|
||||||
template std::string Vertex<glm::vec2>::toString() const;
|
template std::string Vertex<glm::vec2>::toString() const;
|
||||||
template std::string Vertex<glm::vec3>::toString() const;
|
template std::string Vertex<glm::vec3>::toString() const;
|
||||||
template vk::VertexInputBindingDescription Vertex<glm::vec2>::getBindingDescription();
|
template VkVertexInputBindingDescription Vertex<glm::vec2>::getBindingDescription();
|
||||||
template vk::VertexInputBindingDescription Vertex<glm::vec3>::getBindingDescription();
|
template VkVertexInputBindingDescription Vertex<glm::vec3>::getBindingDescription();
|
||||||
template std::array<vk::VertexInputAttributeDescription, 3> Vertex<glm::vec2>::getAttributeDescriptions();
|
template std::array<VkVertexInputAttributeDescription, 3> Vertex<glm::vec2>::getAttributeDescriptions();
|
||||||
template std::array<vk::VertexInputAttributeDescription, 3> Vertex<glm::vec3>::getAttributeDescriptions();
|
template std::array<VkVertexInputAttributeDescription, 3> Vertex<glm::vec3>::getAttributeDescriptions();
|
||||||
template bool Vertex<glm::vec2>::operator==(const Vertex<glm::vec2>& other) const;
|
template bool Vertex<glm::vec2>::operator==(const Vertex<glm::vec2>& other) const;
|
||||||
template bool Vertex<glm::vec3>::operator==(const Vertex<glm::vec3>& other) const;
|
template bool Vertex<glm::vec3>::operator==(const Vertex<glm::vec3>& other) const;
|
||||||
|
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
@ -6,19 +6,17 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
/* #include <vulkan/vulkan_core.h> */
|
||||||
|
|
||||||
// defined in vulkan/vulkan.hpp
|
struct VkVertexInputBindingDescription;
|
||||||
namespace vk {
|
struct VkVertexInputAttributeDescription;
|
||||||
struct VertexInputBindingDescription;
|
|
||||||
struct VertexInputAttributeDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept VertexType = requires {
|
concept VertexType = requires {
|
||||||
requires std::same_as<decltype(T::getBindingDescription()), vk::VertexInputBindingDescription>;
|
requires std::same_as<decltype(T::getBindingDescription()), VkVertexInputBindingDescription>;
|
||||||
requires std::ranges::forward_range<decltype(T::getAttributeDescriptions())>;
|
requires std::ranges::forward_range<decltype(T::getAttributeDescriptions())>;
|
||||||
requires std::same_as<std::ranges::range_value_t<decltype(T::getAttributeDescriptions())>, vk::VertexInputAttributeDescription>;
|
requires std::same_as<std::ranges::range_value_t<decltype(T::getAttributeDescriptions())>, VkVertexInputAttributeDescription>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -37,12 +35,12 @@ namespace gz::vlk {
|
|||||||
glm::vec2 texCoord = { 0, 0 };
|
glm::vec2 texCoord = { 0, 0 };
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
bool operator==(const Vertex& other) const;
|
bool operator==(const Vertex& other) const;
|
||||||
static vk::VertexInputBindingDescription getBindingDescription();
|
static VkVertexInputBindingDescription getBindingDescription();
|
||||||
static std::array<vk::VertexInputAttributeDescription, 3> getAttributeDescriptions();
|
static std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions();
|
||||||
}; // struct Vertex
|
}; // struct Vertex
|
||||||
using Vertex3D = Vertex<glm::vec3>;
|
using Vertex3D = Vertex<glm::vec3>;
|
||||||
using Vertex2D = Vertex<glm::vec2>;
|
using Vertex2D = Vertex<glm::vec2>;
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -50,9 +48,9 @@ namespace gz::vlk {
|
|||||||
// HASHES
|
// HASHES
|
||||||
//
|
//
|
||||||
namespace std {
|
namespace std {
|
||||||
template<gz::vlk::GLM_vec2_or_3 PosVec>
|
template<gz::vk::GLM_vec2_or_3 PosVec>
|
||||||
struct hash<gz::vlk::Vertex<PosVec>> {
|
struct hash<gz::vk::Vertex<PosVec>> {
|
||||||
size_t operator()(gz::vlk::Vertex<PosVec> const& vertex) const {
|
size_t operator()(gz::vk::Vertex<PosVec> const& vertex) const {
|
||||||
return ((hash<PosVec>()(vertex.pos)) ^
|
return ((hash<PosVec>()(vertex.pos)) ^
|
||||||
(hash<glm::vec3>()(vertex.color) << 1) >> 1 ) ^
|
(hash<glm::vec3>()(vertex.color) << 1) >> 1 ) ^
|
||||||
(hash<glm::vec2>()(vertex.texCoord) << 1);
|
(hash<glm::vec2>()(vertex.texCoord) << 1);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "vk_convert.hpp"
|
#include "vk_convert.hpp"
|
||||||
|
|
||||||
bool vkBool2Bool(const vk::Bool32& b) {
|
bool vkBool2Bool(const VkBool32& b) {
|
||||||
if (b == VK_TRUE) {
|
if (b == VK_TRUE) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -9,7 +9,7 @@ bool vkBool2Bool(const vk::Bool32& b) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::Bool32 bool2VkBool(const bool& b) {
|
VkBool32 bool2VkBool(const bool& b) {
|
||||||
if (b) {
|
if (b) {
|
||||||
return VK_TRUE;
|
return VK_TRUE;
|
||||||
}
|
}
|
||||||
@ -18,7 +18,7 @@ vk::Bool32 bool2VkBool(const bool& b) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string vkBool2String(const vk::Bool32& b) {
|
std::string vkBool2String(const VkBool32& b) {
|
||||||
if (b == VK_TRUE) {
|
if (b == VK_TRUE) {
|
||||||
return "true";
|
return "true";
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ std::string vkBool2String(const vk::Bool32& b) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::Bool32 string2VkBool(const std::string& s) {
|
VkBool32 string2VkBool(const std::string& s) {
|
||||||
if (s == "true") {
|
if (s == "true") {
|
||||||
return VK_TRUE;
|
return VK_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
#include <vulkan/vulkan_core.h>
|
||||||
#include <vulkan/vulkan.hpp>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
vk::Bool32 bool2VkBool(const bool& b);
|
VkBool32 bool2VkBool(const bool& b);
|
||||||
bool vkBool2Bool(const vk::Bool32& b);
|
bool vkBool2Bool(const VkBool32& b);
|
||||||
|
|
||||||
vk::Bool32 string2VkBool(const std::string& s);
|
VkBool32 string2VkBool(const std::string& s);
|
||||||
std::string vkBool2String(const vk::Bool32& b);
|
std::string vkBool2String(const VkBool32& b);
|
||||||
|
|
||||||
|
@ -5,14 +5,15 @@
|
|||||||
|
|
||||||
#include <glm/vector_relational.hpp>
|
#include <glm/vector_relational.hpp>
|
||||||
#include <gz-util/util/string_conversion.hpp>
|
#include <gz-util/util/string_conversion.hpp>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
std::string MemoryBlock::toString() const {
|
std::string MemoryBlock::toString() const {
|
||||||
return std::string("<offset: " + gz::toHexString(offset, 0) + ", size: " + gz::toHexString(size, 0) + ", free: " + gz::toString(free) + ">");
|
return std::string("<offset: " + gz::toHexString(offset, 0) + ", size: " + gz::toHexString(size, 0) + ", free: " + gz::toString(free) + ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DeviceMemory::DeviceMemory(vk::DeviceSize size_) {
|
DeviceMemory::DeviceMemory(VkDeviceSize size_) {
|
||||||
size = size_;
|
size = size_;
|
||||||
memory = VK_NULL_HANDLE;
|
memory = VK_NULL_HANDLE;
|
||||||
blocks.emplace_back(MemoryBlock{size, 0, true});
|
blocks.emplace_back(MemoryBlock{size, 0, true});
|
||||||
@ -22,18 +23,17 @@ namespace gz::vlk {
|
|||||||
VulkanAllocator::VulkanAllocator(VulkanInstance& instance)
|
VulkanAllocator::VulkanAllocator(VulkanInstance& instance)
|
||||||
: vk(instance)
|
: vk(instance)
|
||||||
{
|
{
|
||||||
LogCreateInfo logCI {
|
LogCreateInfo logCI{};
|
||||||
.logfile = "vulkan_allocator.log",
|
logCI.logfile = "vulkan_allocator.log";
|
||||||
.storeLog = false,
|
logCI.storeLog = false;
|
||||||
.prefix = "Allocator",
|
logCI.prefix = "Allocator";
|
||||||
.prefixColor = Color::BLACK,
|
logCI.prefixColor = Color::BLACK;
|
||||||
.timeColor = settings::VULKAN_MESSAGE_TIME_COLOR,
|
logCI.timeColor = VULKAN_MESSAGE_TIME_COLOR;
|
||||||
};
|
|
||||||
aLog = Log(std::move(logCI));
|
aLog = Log(std::move(logCI));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanAllocator::allocate(const vk::MemoryAllocateInfo& allocI, const vk::MemoryRequirements2& memReq, MemoryInfo& memoryInfo) {
|
void VulkanAllocator::allocate(const VkMemoryAllocateInfo& allocI, const VkMemoryRequirements2& memReq, MemoryInfo& memoryInfo) {
|
||||||
aLog.log0("allocate: Requesting memory with ( size", toHexString(allocI.allocationSize),
|
aLog.log0("allocate: Requesting memory with ( size", toHexString(allocI.allocationSize),
|
||||||
"), ( memoryTypeIndex", allocI.memoryTypeIndex,
|
"), ( memoryTypeIndex", allocI.memoryTypeIndex,
|
||||||
"), ( alignment", toHexString(memReq.memoryRequirements.alignment), ")");
|
"), ( alignment", toHexString(memReq.memoryRequirements.alignment), ")");
|
||||||
@ -72,7 +72,7 @@ namespace gz::vlk {
|
|||||||
memoryInfo.offset = block->offset;
|
memoryInfo.offset = block->offset;
|
||||||
memoryInfo.memoryTypeIndex = allocI.memoryTypeIndex;
|
memoryInfo.memoryTypeIndex = allocI.memoryTypeIndex;
|
||||||
|
|
||||||
/* aLog.log0("allocate: (memory", memoryInfo.memoryTypeIndex, "-", gz::toString(deviceMemory - memory[memoryInfo.memoryTypeIndex].begin()) + ") Blocks:", deviceMemory->blocks); */
|
aLog.log0("allocate: (memory", memoryInfo.memoryTypeIndex, "-", gz::toString(deviceMemory - memory[memoryInfo.memoryTypeIndex].begin()) + ") Blocks:", deviceMemory->blocks);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,12 +80,13 @@ namespace gz::vlk {
|
|||||||
|
|
||||||
// if nothing is found, allocate new memory
|
// if nothing is found, allocate new memory
|
||||||
memory[allocI.memoryTypeIndex].emplace_back(DeviceMemory(allocI.allocationSize * TODO_ALLOCATION_SIZE_MULTIPLIIER));
|
memory[allocI.memoryTypeIndex].emplace_back(DeviceMemory(allocI.allocationSize * TODO_ALLOCATION_SIZE_MULTIPLIIER));
|
||||||
vk::MemoryAllocateInfo allocI_{};
|
VkMemoryAllocateInfo allocI_{};
|
||||||
|
allocI_.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
allocI_.memoryTypeIndex = allocI.memoryTypeIndex;
|
allocI_.memoryTypeIndex = allocI.memoryTypeIndex;
|
||||||
allocI_.allocationSize = memory[allocI.memoryTypeIndex].back().size;
|
allocI_.allocationSize = memory[allocI.memoryTypeIndex].back().size;
|
||||||
aLog.log0("allocate: Allocating new memory of size:", gz::toHexString(allocI_.allocationSize, 0), "(memory", memoryInfo.memoryTypeIndex, "-", gz::toString(memory[memoryInfo.memoryTypeIndex].size()) + ")");
|
aLog.log0("allocate: Allocating new memory of size:", gz::toHexString(allocI_.allocationSize, 0), "(memory", memoryInfo.memoryTypeIndex, "-", gz::toString(memory[memoryInfo.memoryTypeIndex].size()) + ")");
|
||||||
vk::Result result = vk.getDevice().allocateMemory(&allocI_, NO_ALLOC, &memory[allocI.memoryTypeIndex].back().memory);
|
VkResult result = vkAllocateMemory(vk.getDevice(), &allocI_, NO_ALLOC, &memory[allocI.memoryTypeIndex].back().memory);
|
||||||
if (result != vk::Result::eSuccess) {
|
if (result != VK_SUCCESS) {
|
||||||
throw getVkException(result, "Failed to allocate memory", "VulkanAllocator::allocate");
|
throw getVkException(result, "Failed to allocate memory", "VulkanAllocator::allocate");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,11 +96,11 @@ namespace gz::vlk {
|
|||||||
deviceMemory.blocks.front().size -= allocI.allocationSize;
|
deviceMemory.blocks.front().size -= allocI.allocationSize;
|
||||||
deviceMemory.blocks.emplace_front(MemoryBlock{ allocI.allocationSize, 0, false });
|
deviceMemory.blocks.emplace_front(MemoryBlock{ allocI.allocationSize, 0, false });
|
||||||
|
|
||||||
// alignment always satisfied with vk::allocateMemory() and offset 0
|
// alignment always satisfied with vkAllocateMemory() and offset 0
|
||||||
memoryInfo.memory = deviceMemory.memory;
|
memoryInfo.memory = deviceMemory.memory;
|
||||||
memoryInfo.offset = 0;
|
memoryInfo.offset = 0;
|
||||||
memoryInfo.memoryTypeIndex = allocI.memoryTypeIndex;
|
memoryInfo.memoryTypeIndex = allocI.memoryTypeIndex;
|
||||||
/* aLog.log0("allocate: (memory", memoryInfo.memoryTypeIndex, "-", gz::toString(memory[memoryInfo.memoryTypeIndex].size()) + ") Blocks:", deviceMemory.blocks); */
|
aLog.log0("allocate: (memory", memoryInfo.memoryTypeIndex, "-", gz::toString(memory[memoryInfo.memoryTypeIndex].size()) + ") Blocks:", deviceMemory.blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -135,11 +136,11 @@ namespace gz::vlk {
|
|||||||
memoryInfo.memory = VK_NULL_HANDLE;
|
memoryInfo.memory = VK_NULL_HANDLE;
|
||||||
memoryInfo.offset = 0;
|
memoryInfo.offset = 0;
|
||||||
|
|
||||||
/* aLog.log0("free: (memory", memoryInfo.memoryTypeIndex, "-", gz::toString(deviceMemory - memory[memoryInfo.memoryTypeIndex].begin()) + ") Blocks:", deviceMemory->blocks); */
|
aLog.log0("free: (memory", memoryInfo.memoryTypeIndex, "-", gz::toString(deviceMemory - memory[memoryInfo.memoryTypeIndex].begin()) + ") Blocks:", deviceMemory->blocks);
|
||||||
// if now there is only one free block, everything is free -> deallocate memory
|
// if now there is only one free block, everything is free -> deallocate memory
|
||||||
if (deviceMemory->blocks.size() == 1) {
|
if (deviceMemory->blocks.size() == 1) {
|
||||||
aLog.log0("free: Deallocating (memory", memoryInfo.memoryTypeIndex, "-", gz::toString(deviceMemory - memory[memoryInfo.memoryTypeIndex].begin()) + ") of size:", gz::toHexString(deviceMemory->size, 0));
|
aLog.log0("free: Deallocating (memory", memoryInfo.memoryTypeIndex, "-", gz::toString(deviceMemory - memory[memoryInfo.memoryTypeIndex].begin()) + ") of size:", gz::toHexString(deviceMemory->size, 0));
|
||||||
vk.getDevice().freeMemory(deviceMemory->memory, NO_ALLOC);
|
vkFreeMemory(vk.getDevice(), deviceMemory->memory, NO_ALLOC);
|
||||||
memory[memoryInfo.memoryTypeIndex].erase(deviceMemory);
|
memory[memoryInfo.memoryTypeIndex].erase(deviceMemory);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -159,11 +160,11 @@ namespace gz::vlk {
|
|||||||
aLog.warning("cleanup: (memory", memType->first, "-", gz::toString(deviceMemory - memType->second.begin()) + ") Block not freed: ", *block);
|
aLog.warning("cleanup: (memory", memType->first, "-", gz::toString(deviceMemory - memType->second.begin()) + ") Block not freed: ", *block);
|
||||||
}
|
}
|
||||||
aLog.log0("free: Deallocating (memory", memType->first, "-", gz::toString(deviceMemory - memType->second.begin()) + ") of size:", gz::toHexString(deviceMemory->size, 0));
|
aLog.log0("free: Deallocating (memory", memType->first, "-", gz::toString(deviceMemory - memType->second.begin()) + ") of size:", gz::toHexString(deviceMemory->size, 0));
|
||||||
vk.getDevice().freeMemory(deviceMemory->memory, NO_ALLOC);
|
vkFreeMemory(vk.getDevice(), deviceMemory->memory, NO_ALLOC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memory.clear();
|
memory.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
@ -4,28 +4,27 @@
|
|||||||
#include <gz-util/log.hpp>
|
#include <gz-util/log.hpp>
|
||||||
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
#define VULKAN_HPP_NO_EXCEPTIONS
|
|
||||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
/* #include <vulkan/vulkan_core.h> */
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
/**
|
/**
|
||||||
* @brief Contains information about a subsection (block) of a vk::DeviceMemory
|
* @brief Contains information about a subsection (block) of a VkDeviceMemory
|
||||||
*/
|
*/
|
||||||
struct MemoryInfo {
|
struct MemoryInfo {
|
||||||
/**
|
/**
|
||||||
* @brief Handle of the memory
|
* @brief Handle of the memory
|
||||||
*/
|
*/
|
||||||
vk::DeviceMemory memory = VK_NULL_HANDLE;
|
VkDeviceMemory memory = VK_NULL_HANDLE;
|
||||||
/**
|
/**
|
||||||
* @brief Offset into memory
|
* @brief Offset into memory
|
||||||
*/
|
*/
|
||||||
vk::DeviceSize offset = 0;
|
VkDeviceSize offset = 0;
|
||||||
/**
|
/**
|
||||||
* @brief The memoryTypeIndex memory was allocated from. Needed for VulkanAllocator::free()
|
* @brief The memoryTypeIndex memory was allocated from. Needed for VulkanAllocator::free()
|
||||||
*/
|
*/
|
||||||
@ -43,20 +42,20 @@ namespace gz::vlk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Manage a single vk::DeviceMemory chunk
|
* @brief Manage a single VkDeviceMemory chunk
|
||||||
*/
|
*/
|
||||||
struct DeviceMemory {
|
struct DeviceMemory {
|
||||||
DeviceMemory() = delete;
|
DeviceMemory() = delete;
|
||||||
DeviceMemory(vk::DeviceSize size_);
|
DeviceMemory(VkDeviceSize size_);
|
||||||
|
|
||||||
vk::DeviceSize size;
|
VkDeviceSize size;
|
||||||
vk::DeviceMemory memory;
|
VkDeviceMemory memory;
|
||||||
std::list<MemoryBlock> blocks;
|
std::list<MemoryBlock> blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// if no memory is available, allocate a chunk of multiplier * requested size
|
// if no memory is available, allocate a chunk of multiplier * requested size
|
||||||
constexpr vk::DeviceSize TODO_ALLOCATION_SIZE_MULTIPLIIER = 10;
|
constexpr VkDeviceSize TODO_ALLOCATION_SIZE_MULTIPLIIER = 10;
|
||||||
|
|
||||||
|
|
||||||
// defined in vulkan_instance.hpp
|
// defined in vulkan_instance.hpp
|
||||||
@ -65,7 +64,7 @@ namespace gz::vlk {
|
|||||||
/**
|
/**
|
||||||
* @brief Allocator for device local memory
|
* @brief Allocator for device local memory
|
||||||
* @details
|
* @details
|
||||||
* Allocates larger chunks of vk::DeviceMemory from which blocks can be @ref allocate() "allocated".
|
* Allocates larger chunks of VkDeviceMemory from which blocks can be @ref allocate() "allocated".
|
||||||
*
|
*
|
||||||
* This class is for device local memory only, not for host memory.
|
* This class is for device local memory only, not for host memory.
|
||||||
* You can not use it for vulkan memory allocation callbacks (pAllocator).
|
* You can not use it for vulkan memory allocation callbacks (pAllocator).
|
||||||
@ -74,34 +73,34 @@ namespace gz::vlk {
|
|||||||
* The usage is explained with the example of creating and destroying a single buffer.
|
* The usage is explained with the example of creating and destroying a single buffer.
|
||||||
* @code
|
* @code
|
||||||
* // Create buffer handle
|
* // Create buffer handle
|
||||||
* vk::Buffer buffer;
|
* VkBuffer buffer;
|
||||||
* // Create empty memory info struct
|
* // Create empty memory info struct
|
||||||
* MemoryInfo bufferMI;
|
* MemoryInfo bufferMI;
|
||||||
*
|
*
|
||||||
* vk::BufferCreateInfo bufferCI{}
|
* VkBufferCreateInfo bufferCI{}
|
||||||
* ...
|
* ...
|
||||||
* vk::createBuffer(...);
|
* vkCreateBuffer(...);
|
||||||
*
|
*
|
||||||
* // get memory requirements
|
* // get memory requirements
|
||||||
* vk::MemoryRequirements2 memReq;
|
* VkMemoryRequirements2 memReq;
|
||||||
* vk::BufferMemoryRequirementsInfo2 bufMemReq;
|
* VkBufferMemoryRequirementsInfo2 bufMemReq;
|
||||||
* // from vulkan_util.hpp, same exists for imageMemoryRequirements
|
* // from vulkan_util.hpp, same exists for imageMemoryRequirements
|
||||||
* getBufferMemoryRequirements(device, buffer, bufMemReq, memReq);
|
* getBufferMemoryRequirements(device, buffer, bufMemReq, memReq);
|
||||||
*
|
*
|
||||||
* // set allocation info
|
* // set allocation info
|
||||||
* vk::MemoryAllocateInfo memAI {
|
* VkMemoryAllocateInfo memAI{};
|
||||||
* ...
|
* ...
|
||||||
* .memoryTypeIndex = VulkanInstance::findMemoryType(memReq.memoryRequirements.memoryTypeBits, wantedProperties),
|
* memAI.memoryTypeIndex = VulkanInstance::findMemoryType(memReq.memoryRequirements.memoryTypeBits, wantedProperties);
|
||||||
*
|
*
|
||||||
* // allocate memory for the buffer
|
* // allocate memory for the buffer
|
||||||
* VulkanAllocator::allocate(memAI, memReq, bufferMI);
|
* VulkanAllocator::allocate(memAI, memReq, bufferMI);
|
||||||
*
|
*
|
||||||
* // bind the buffer to the memory
|
* // bind the buffer to the memory
|
||||||
* device.bindBufferMemory(buffer, bufferMI.memory, bufferMI.offset);
|
* vkBindBufferMemory(device, buffer, bufferMI.memory, bufferMI.offset);
|
||||||
*
|
*
|
||||||
* ...
|
* ...
|
||||||
*
|
*
|
||||||
* device.destroyBuffer(buffer);
|
* vkDestroyBuffer(device, buffer);
|
||||||
* VulkanAllocator::free(bufferMemoryInfo);
|
* VulkanAllocator::free(bufferMemoryInfo);
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
@ -111,23 +110,23 @@ namespace gz::vlk {
|
|||||||
public:
|
public:
|
||||||
VulkanAllocator(VulkanInstance& instance);
|
VulkanAllocator(VulkanInstance& instance);
|
||||||
/**
|
/**
|
||||||
* @brief Get a block from a vk::DeviceMemory
|
* @brief Get a block from a VkDeviceMemory
|
||||||
* @details
|
* @details
|
||||||
* Get a block of allocI.allocationSize of a vk::DeviceMemory that was allocated with allocI.memoryTypeIndex.
|
* Get a block of allocI.allocationSize of a VkDeviceMemory that was allocated with allocI.memoryTypeIndex.
|
||||||
*
|
*
|
||||||
* When this function returns, memoryInfo will contain the information about the available block.
|
* When this function returns, memoryInfo will contain the information about the available block.
|
||||||
* You can then bind something of size allocI.allocationSize to memoryInfo.memory at offset memoryInfo.offset.
|
* You can then bind something of size allocI.allocationSize to memoryInfo.memory at offset memoryInfo.offset.
|
||||||
* @throws vk::Exception when a call to vkAllocateMemory is needed and fails
|
* @throws VkException when a call to vkAllocateMemory is needed and fails
|
||||||
* @todo Determine the size of new allocations
|
* @todo Determine the size of new allocations
|
||||||
* @todo alignment, maybe use vk::MemoryRequirements instead of vk::MemoryAllocateInfo?
|
* @todo alignment, maybe use VkMemoryRequirements instead of VkMemoryAllocateInfo?
|
||||||
* @todo maybe increase the block size of the allocated block so that the following blocks is already 16-aligned?
|
* @todo maybe increase the block size of the allocated block so that the following blocks is already 16-aligned?
|
||||||
*/
|
*/
|
||||||
void allocate(const vk::MemoryAllocateInfo& allocI, const vk::MemoryRequirements2& memReq, MemoryInfo& memoryInfo);
|
void allocate(const VkMemoryAllocateInfo& allocI, const VkMemoryRequirements2& memReq, MemoryInfo& memoryInfo);
|
||||||
/**
|
/**
|
||||||
* @brief Free a block allocated with allocate()
|
* @brief Free a block allocated with allocate()
|
||||||
*
|
*
|
||||||
* When this function returns, memoryInfo will be reset to default values
|
* When this function returns, memoryInfo will be reset to default values
|
||||||
* @throws vk::UserError if memoryInfo was not allocated from this allocator
|
* @throws VkUserError if memoryInfo was not allocated from this allocator
|
||||||
*/
|
*/
|
||||||
void free(MemoryInfo& memoryInfo);
|
void free(MemoryInfo& memoryInfo);
|
||||||
|
|
||||||
@ -148,4 +147,4 @@ namespace gz::vlk {
|
|||||||
VulkanInstance& vk;
|
VulkanInstance& vk;
|
||||||
|
|
||||||
}; // class VulkanAllocator
|
}; // class VulkanAllocator
|
||||||
} // namespace gz::vlk
|
} // namespace gz::vk
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,45 +1,57 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||||
/* #include <glm/glm.hpp> */
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#define VULKAN_HPP_NO_EXCEPTIONS
|
|
||||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
|
||||||
#include <vulkan/vulkan.hpp>
|
|
||||||
|
|
||||||
#include "vk_convert.hpp"
|
#include "vk_convert.hpp"
|
||||||
|
|
||||||
#include "vertex.hpp"
|
#include "vertex.hpp"
|
||||||
|
#include "shape.hpp"
|
||||||
#include "vulkan_util.hpp"
|
#include "vulkan_util.hpp"
|
||||||
#include "vulkan_allocator.hpp"
|
#include "vulkan_allocator.hpp"
|
||||||
|
|
||||||
#include "vulkan_settings.hpp"
|
|
||||||
|
|
||||||
#include <gz-util/log.hpp>
|
#include <gz-util/log.hpp>
|
||||||
#include <gz-util/settings_manager.hpp>
|
#include <gz-util/settings_manager.hpp>
|
||||||
#include <gz-util/util/string.hpp>
|
#include <gz-util/util/string.hpp>
|
||||||
|
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace gz::vlk {
|
namespace gz::vk {
|
||||||
constexpr vk::MemoryMapFlags NO_MEM_FLAGS;
|
constexpr bool throwExceptionOnValidationError = true;
|
||||||
constexpr vk::AccessFlags NO_ACC_FLAGS;
|
constexpr gz::Color VULKAN_MESSAGE_PREFIX_COLOR = gz::Color::BO_BLUE;
|
||||||
constexpr vk::AccessFlags2 NO_ACC_2_FLAGS;
|
constexpr gz::Color VULKAN_MESSAGE_TIME_COLOR = gz::Color::BLUE;
|
||||||
constexpr vk::CommandBufferResetFlags NO_CMD_RESET_FLAGS;
|
const std::string CONFIG_FILE = "vulkan.conf";
|
||||||
const uint32_t NO_OFFSET = 0;
|
#define SettingsTypes uint32_t, bool, float
|
||||||
constexpr vk::AllocationCallbacks* NO_ALLOC = nullptr;
|
|
||||||
/* const vk::ImageSubresourceRange DEFAULT_SUBRESOURCE_RANGE { */
|
|
||||||
/* .aspectMask = vk::ImageAspectFlagBits::eColor, */
|
|
||||||
/* .baseMipLevel = 0, */
|
|
||||||
/* .levelCount = 1, */
|
|
||||||
/* .baseArrayLayer = 0, */
|
|
||||||
/* .layerCount = 1, */
|
|
||||||
/* }; */
|
|
||||||
|
|
||||||
|
/* const std::string MODEL_PATH = "models/gazebo-3d-model/gazebo.obj"; */
|
||||||
|
/* const std::string TEXTURE_PATH = "models/gazebo-3d-model/gazebo_diffuse.png"; */
|
||||||
|
|
||||||
|
const std::string MODEL_PATH = "models/armoire-3d-model/Armoire.obj";
|
||||||
|
const std::string TEXTURE_PATH = "models/armoire-3d-model/Armoire_diffuse.png";
|
||||||
|
|
||||||
|
const gz::util::unordered_string_map<std::string> INITIAL_SETTINGS = {
|
||||||
|
{ "framerate", "60" },
|
||||||
|
{ "anisotropy_enable", "false" },
|
||||||
|
{ "max_anisotropy", "1" },
|
||||||
|
{ "max_frames_in_flight", "3" },
|
||||||
|
/* { "", "" } */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
constexpr VkClearColorValue missingTextureColor = { { 0.4f, 0.0f, 0.4f, 1.0f } };
|
||||||
|
const int BINDING = 0;
|
||||||
|
const uint32_t NO_FLAGS = 0;
|
||||||
|
const uint32_t NO_OFFSET = 0;
|
||||||
|
constexpr VkAllocationCallbacks* NO_ALLOC = nullptr;
|
||||||
|
const size_t VERTEX_BUFFER_SIZE = 512;
|
||||||
|
const size_t INDEX_BUFFER_SIZE = 512;
|
||||||
enum InstanceCommandPool {
|
enum InstanceCommandPool {
|
||||||
POOL_GRAPHICS, POOL_TRANSFER
|
POOL_GRAPHICS, POOL_TRANSFER
|
||||||
};
|
};
|
||||||
@ -55,7 +67,7 @@ namespace gz::vlk {
|
|||||||
* These functions will probably called from your `main` function and loop.
|
* These functions will probably called from your `main` function and loop.
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
VulkanInstance(gz::SettingsManagerCreateInfo<VULKAN_SETTINGS_MAN_TYPES>smCI) : settings(smCI), allocator(*this) {};
|
VulkanInstance(gz::SettingsManagerCreateInfo<SettingsTypes>smCI) : settings(smCI), allocator(*this) {};
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the vulkan instance
|
* @brief Initializes the vulkan instance
|
||||||
* @details
|
* @details
|
||||||
@ -146,13 +158,12 @@ namespace gz::vlk {
|
|||||||
*/
|
*/
|
||||||
public:
|
public:
|
||||||
/// @{
|
/// @{
|
||||||
const vk::Device& getDevice() const { return device; }
|
const VkDevice& getDevice() const { return device; }
|
||||||
const vk::Extent2D& getScExtent() const { return scExtent; }
|
const VkExtent2D& getScExtent() const { return scExtent; }
|
||||||
const std::vector<vk::Image>& getScImages() const { return scImages; }
|
const std::vector<VkImage>& getScImages() const { return scImages; }
|
||||||
const vk::Format& getScImageFormat() const { return scImageFormat; }
|
const VkFormat& getScImageFormat() const { return scImageFormat; }
|
||||||
const vk::Format& getDepthFormat() const { return depthFormat; }
|
|
||||||
|
|
||||||
SettingsManager<VULKAN_SETTINGS_MAN_TYPES>& getSettings() { return settings; }
|
SettingsManager<SettingsTypes>& getSettings() { return settings; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the maximum number of frames in flight
|
* @brief Get the maximum number of frames in flight
|
||||||
@ -165,30 +176,28 @@ namespace gz::vlk {
|
|||||||
*/
|
*/
|
||||||
uint32_t getCurrentFrame() const { return currentFrame; }
|
uint32_t getCurrentFrame() const { return currentFrame; }
|
||||||
|
|
||||||
void submitThisFrame(vk::CommandBuffer& cmdBuffer);
|
void submitThisFrame(VkCommandBuffer& cmdBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copy from srcBuffer to dstBuffer
|
* @brief Copy from srcBuffer to dstBuffer
|
||||||
* @details
|
* @details
|
||||||
* Uses @ref beginSingleTimeCommands() "a single time command buffer" from commandPoolTransfer.
|
* Uses @ref beginSingleTimeCommands() "a single time command buffer" from commandPoolTransfer.
|
||||||
*/
|
*/
|
||||||
void copyBuffer(vk::Buffer srcBuffer, vk::Buffer dstBuffer, vk::DeviceSize size);
|
void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Begin a command buffer that is going to be used once
|
* @brief Begin a command buffer that is going to be used once
|
||||||
* @param commandPool: The command pool from which the buffer should be allocated
|
* @param commandPool: The command pool from which the buffer should be allocated
|
||||||
*/
|
*/
|
||||||
vk::CommandBuffer beginSingleTimeCommands(InstanceCommandPool commandPool);
|
VkCommandBuffer beginSingleTimeCommands(InstanceCommandPool commandPool);
|
||||||
/**
|
/**
|
||||||
* @brief Submit cmdBuffer on the queue and free it afterwards
|
* @brief Submit cmdBuffer on the queue and free it afterwards
|
||||||
* @param cmdBuffer: Command buffer returned by beginSingleTimeCommands()
|
* @param cmdBuffer: Command buffer returned by beginSingleTimeCommands()
|
||||||
* @param commandPool: The same pool as passed to beginSingleTimeCommands()
|
* @param commandPool: The same pool as passed to beginSingleTimeCommands()
|
||||||
* @details
|
|
||||||
* After command buffer is submitted on the specified queue, the function waits for the queue to idle
|
|
||||||
*/
|
*/
|
||||||
void endSingleTimeCommands(vk::CommandBuffer cmdBuffer, InstanceCommandPool commandPool);
|
void endSingleTimeCommands(VkCommandBuffer cmdBuffer, InstanceCommandPool commandPool);
|
||||||
|
|
||||||
void loadModel(const std::string& path, VerticesAndIndices<uint32_t>& model);
|
void loadModel(VerticesAndIndices<uint32_t>& model);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -203,16 +212,16 @@ namespace gz::vlk {
|
|||||||
/**
|
/**
|
||||||
* @brief Create MAX_FRAMES_IN_FLIGHT command buffers from the commandPoolGraphics
|
* @brief Create MAX_FRAMES_IN_FLIGHT command buffers from the commandPoolGraphics
|
||||||
*/
|
*/
|
||||||
void createCommandBuffers(std::vector<vk::CommandBuffer>& commandBuffers);
|
void createCommandBuffers(std::vector<VkCommandBuffer>& commandBuffers);
|
||||||
/**
|
/**
|
||||||
* @brief Destroy all command buffers (must be from commandPoolGraphics)
|
* @brief Destroy all command buffers (must be from commandPoolGraphics)
|
||||||
*/
|
*/
|
||||||
void destroyCommandBuffers(std::vector<vk::CommandBuffer>& commandBuffers);
|
void destroyCommandBuffers(std::vector<VkCommandBuffer>& commandBuffers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a descriptor layout with bindings
|
* @brief Create a descriptor layout with bindings
|
||||||
*/
|
*/
|
||||||
void createDescriptorSetLayout(std::vector<vk::DescriptorSetLayoutBinding> bindings, vk::DescriptorSetLayout& layout);
|
void createDescriptorSetLayout(std::vector<VkDescriptorSetLayoutBinding> bindings, VkDescriptorSetLayout& layout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a new graphics pipeline
|
* @brief Create a new graphics pipeline
|
||||||
@ -227,19 +236,17 @@ namespace gz::vlk {
|
|||||||
* @details
|
* @details
|
||||||
* Create a pipeline with:
|
* Create a pipeline with:
|
||||||
* - 2 shader stages: vertex and fragment shader
|
* - 2 shader stages: vertex and fragment shader
|
||||||
* - vk::PrimitiveTopology::eTriangleList, vertices are triangles
|
* - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices are triangles
|
||||||
* - viewport viewing the whole image as described by scExtent
|
* - viewport viewing the whole image as described by scExtent
|
||||||
* - scissor with offset (0, 0)
|
* - scissor with offset (0, 0)
|
||||||
* - rasterizer:
|
* - rasterizer:
|
||||||
* - triangles are filled with the colors from the vertex (VK_POLYGON_FILL)
|
* - triangles are filled with the colors from the vertex (VK_POLYGON_FILL)
|
||||||
* - counter clockwise front face (vk::FrontFace::eCounterClockwise)
|
* - counter clockwise front face (VK_FRONT_FACE_COUNTER_CLOCKWISE)
|
||||||
*
|
|
||||||
* @todo Move shader module creation and maybe pipelineshaderstagecreateinfo outside
|
|
||||||
*/
|
*/
|
||||||
template<VertexType T>
|
template<VertexType T>
|
||||||
void createGraphicsPipeline(const std::string& vertexShader, const std::string& fragmentShader, std::vector<vk::DescriptorSetLayout>& descriptorSetLayouts, bool useDepthStencil, vk::RenderPass& renderPass, Pipeline& pipeline, vk::SpecializationInfo* fragSI=nullptr, vk::SpecializationInfo* vertSI=nullptr);
|
void createGraphicsPipeline(const std::string& vertexShader, const std::string& fragmentShader, std::vector<VkDescriptorSetLayout>& descriptorSetLayouts, bool useDepthStencil, VkRenderPass& renderPass, Pipeline& pipeline);
|
||||||
|
|
||||||
vk::ShaderModule createShaderModule(const std::vector<char>& code);
|
VkShaderModule createShaderModule(const std::vector<char>& code);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate memory, create a buffer and bind buffer to memory
|
* @brief Allocate memory, create a buffer and bind buffer to memory
|
||||||
@ -247,16 +254,15 @@ namespace gz::vlk {
|
|||||||
* @param buffer The (null) handle to the buffer
|
* @param buffer The (null) handle to the buffer
|
||||||
* @param bufferMemory Reference to an (uninitialized) MemoryInfo struct. It will be valid when the function returns
|
* @param bufferMemory Reference to an (uninitialized) MemoryInfo struct. It will be valid when the function returns
|
||||||
* @param properties Properties that the buffers memory needs to satisfy
|
* @param properties Properties that the buffers memory needs to satisfy
|
||||||
* @param qFamiliesWithAccess [Optional] vector of queue families that have access to the buffer. Only needed with SHARING_MODE_CONCURRENT
|
|
||||||
* @details
|
* @details
|
||||||
* The memory the buffer will be bound to is HOST_VISIBLE and HOST_COHERENT
|
* The memory the buffer will be bound to is HOST_VISIBLE and HOST_COHERENT
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags properties, vk::Buffer& buffer, MemoryInfo& bufferMemory, vk::SharingMode sharingMode=vk::SharingMode::eExclusive, std::vector<uint32_t>* qFamiliesWithAccess=nullptr);
|
void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, MemoryInfo& bufferMemory, VkSharingMode sharingMode=VK_SHARING_MODE_EXCLUSIVE, std::vector<uint32_t>* qFamiliesWithAccess=nullptr);
|
||||||
/**
|
/**
|
||||||
* @brief Destroy buffer and free memory
|
* @brief Destroy buffer and free memory
|
||||||
*/
|
*/
|
||||||
void destroyBuffer(vk::Buffer& buffer, MemoryInfo& bufferMemory);
|
void destroyBuffer(VkBuffer& buffer, MemoryInfo& bufferMemory);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a vertex buffer
|
* @brief Create a vertex buffer
|
||||||
@ -267,7 +273,7 @@ namespace gz::vlk {
|
|||||||
* The function is instantiated for Vertex2D and Vertex3D
|
* The function is instantiated for Vertex2D and Vertex3D
|
||||||
*/
|
*/
|
||||||
template<VertexType VertexT>
|
template<VertexType VertexT>
|
||||||
void createVertexBuffer(size_t vertexCount, vk::Buffer& vertexBuffer, MemoryInfo& vertexBufferMemory, vk::DeviceSize& vertexBufferSize);
|
void createVertexBuffer(size_t vertexCount, VkBuffer& vertexBuffer, MemoryInfo& vertexBufferMemory, VkDeviceSize& vertexBufferSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create an index buffer
|
* @brief Create an index buffer
|
||||||
@ -278,30 +284,30 @@ namespace gz::vlk {
|
|||||||
* The function is instantiated for uint16_t and uint32_t
|
* The function is instantiated for uint16_t and uint32_t
|
||||||
*/
|
*/
|
||||||
template<SupportedIndexType T>
|
template<SupportedIndexType T>
|
||||||
void createIndexBuffer(size_t indexCount, vk::Buffer& indexBuffer, MemoryInfo& indexBufferMemory, vk::DeviceSize& indexBufferSize);
|
void createIndexBuffer(size_t indexCount, VkBuffer& indexBuffer, MemoryInfo& indexBufferMemory, VkDeviceSize& indexBufferSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create MAX_FRAMES_IN_FLIGHT uniform buffers
|
* @brief Create MAX_FRAMES_IN_FLIGHT uniform buffers
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void createUniformBuffers(std::vector<vk::Buffer>& uniformBuffers, std::vector<MemoryInfo>& uniformBuffersMemory);
|
void createUniformBuffers(std::vector<VkBuffer>& uniformBuffers, std::vector<MemoryInfo>& uniformBuffersMemory);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create as many framebuffers as the swap chain has images, with the extent of the swap chain
|
* @brief Create as many framebuffers as the swap chain has images, with the extent of the swap chain
|
||||||
*/
|
*/
|
||||||
void createFramebuffers(std::vector<vk::Framebuffer>& framebuffers, std::vector<vk::ImageView>& imageViews, vk::RenderPass& renderPass, vk::ImageView depthImageView=VK_NULL_HANDLE);
|
void createFramebuffers(std::vector<VkFramebuffer>& framebuffers, std::vector<VkImageView>& imageViews, VkRenderPass& renderPass);
|
||||||
/**
|
/**
|
||||||
* @brief Destroy the framebuffers
|
* @brief Destroy the framebuffers
|
||||||
*/
|
*/
|
||||||
void destroyFramebuffers(std::vector<vk::Framebuffer>& framebuffers);
|
void destroyFramebuffers(std::vector<VkFramebuffer>& framebuffers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a texture sampler
|
* @brief Create a texture sampler
|
||||||
* @todo add options and documentation
|
* @todo add options and documentation
|
||||||
*/
|
*/
|
||||||
void createTextureSampler(vk::Sampler& sampler);
|
void createTextureSampler(VkSampler& sampler);
|
||||||
|
|
||||||
void destroyTextureSampler(vk::Sampler& sampler);
|
void destroyTextureSampler(VkSampler& sampler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name Public Interface: Image utility
|
* @name Public Interface: Image utility
|
||||||
@ -313,15 +319,15 @@ namespace gz::vlk {
|
|||||||
/**
|
/**
|
||||||
* @brief Create a 2D image, allocate the imageMemory and bind the image to it
|
* @brief Create a 2D image, allocate the imageMemory and bind the image to it
|
||||||
*/
|
*/
|
||||||
void createImage(uint32_t width, uint32_t height, vk::Format format, vk::ImageTiling tiling, vk::ImageUsageFlags usage, vk::MemoryPropertyFlags memoryProperties, vk::Image& image, MemoryInfo& imageMI);
|
void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags memoryProperties, VkImage& image, MemoryInfo& imageMI);
|
||||||
void destroyImage(vk::Image& image, MemoryInfo& imageMemory);
|
void destroyImage(VkImage& image, MemoryInfo& imageMemory);
|
||||||
/**
|
/**
|
||||||
* @brief Create a 2D imageView with format for image.
|
* @brief Create a 2D imageView with format for image.
|
||||||
*/
|
*/
|
||||||
void createImageView(vk::Format format, vk::Image& image, vk::ImageView& imageView, vk::ImageAspectFlags aspectFlags);
|
void createImageView(VkFormat format, VkImage& image, VkImageView& imageView, VkImageAspectFlags aspectFlags);
|
||||||
void destroyImageView(vk::ImageView& imageView);
|
void destroyImageView(VkImageView& imageView);
|
||||||
|
|
||||||
void copyBufferToImage(vk::Buffer buffer, vk::Image image, int32_t offsetX, int32_t offsetY, uint32_t width, uint32_t height);
|
void copyBufferToImage(VkBuffer buffer, VkImage image, int32_t offsetX, int32_t offsetY, uint32_t width, uint32_t height);
|
||||||
/**
|
/**
|
||||||
* @todo make a version using vkCmdResolveImage for multisampled images
|
* @todo make a version using vkCmdResolveImage for multisampled images
|
||||||
* @brief Copy srcImage to dstImage
|
* @brief Copy srcImage to dstImage
|
||||||
@ -336,7 +342,7 @@ namespace gz::vlk {
|
|||||||
* @param srcImage Image with layout TRANSFER_SRC_OPTIMAL
|
* @param srcImage Image with layout TRANSFER_SRC_OPTIMAL
|
||||||
* @param dstImage Image with layout TRANSFER_DST_OPTIMAL
|
* @param dstImage Image with layout TRANSFER_DST_OPTIMAL
|
||||||
*/
|
*/
|
||||||
void copyImageToImage(vk::CommandBuffer& cmdBuffer, vk::Image srcImage, vk::Image dstImage, vk::Extent2D extent); //, vk::CommandPool& commandPool=commandPoolTransfer);
|
void copyImageToImage(VkCommandBuffer& cmdBuffer, VkImage srcImage, VkImage dstImage, VkExtent2D extent); //, VkCommandPool& commandPool=commandPoolTransfer);
|
||||||
/**
|
/**
|
||||||
* @brief Transition the layout of image from oldLayout to newLayout
|
* @brief Transition the layout of image from oldLayout to newLayout
|
||||||
* @details
|
* @details
|
||||||
@ -350,12 +356,12 @@ namespace gz::vlk {
|
|||||||
* If you do not provide a command buffer, a command buffer from the indicated queue will be created and submitted.
|
* If you do not provide a command buffer, a command buffer from the indicated queue will be created and submitted.
|
||||||
* If you do provide a command buffer, the command is recorded but NOT submitted.
|
* If you do provide a command buffer, the command is recorded but NOT submitted.
|
||||||
*
|
*
|
||||||
* The transition is done by submitting a vk::ImageMemoryBarrier2
|
* The transition is done by submitting a VkImageMemoryBarrier2
|
||||||
*
|
*
|
||||||
* @param cmdBuffer [Optional] The command buffer where the command will be recorded to
|
* @param cmdBuffer [Optional] The command buffer where the command will be recorded to
|
||||||
* @throws vk::UserError if the transition is not supported.
|
* @throws VkUserError if the transition is not supported.
|
||||||
*/
|
*/
|
||||||
void transitionImageLayout(vk::Image image, vk::Format format, vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::CommandBuffer* cmdBuffer=nullptr);
|
void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, VkCommandBuffer* cmdBuffer=nullptr);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
@ -387,7 +393,7 @@ namespace gz::vlk {
|
|||||||
* @name Settings
|
* @name Settings
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
gz::SettingsManager<VULKAN_SETTINGS_MAN_TYPES> settings;
|
gz::SettingsManager<SettingsTypes> settings;
|
||||||
/**
|
/**
|
||||||
* @brief Set valid values for the SettingsManager according to phDevFeatures and phDevProperties
|
* @brief Set valid values for the SettingsManager according to phDevFeatures and phDevProperties
|
||||||
* @details
|
* @details
|
||||||
@ -451,48 +457,37 @@ namespace gz::vlk {
|
|||||||
* @name Instance
|
* @name Instance
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
vk::Instance instance;
|
VkInstance instance;
|
||||||
/**
|
/**
|
||||||
* @brief Create the vulkan instance
|
* @brief Create the vulkan instance
|
||||||
* @details
|
* @details
|
||||||
* -# check if validationLayers are available (if enabled)
|
* -# check if validationLayers are available (if enabled)
|
||||||
* -# create instance with info
|
* -# create instance with info
|
||||||
* -# check if all extensions required by glfw are available
|
* -# check if all extensions required by glfw are available
|
||||||
* @throws VkException if:
|
|
||||||
* - validation layers are enabled but not supported
|
|
||||||
* - instance creation fails
|
|
||||||
* - not all required instance extensions are available
|
|
||||||
*/
|
*/
|
||||||
void createInstance();
|
void createInstance();
|
||||||
/**
|
|
||||||
* @brief Get all the required instance extensions
|
|
||||||
* @details
|
|
||||||
* The required extensions are:
|
|
||||||
* - all extensions required by glfw (glfwGetRequiredInstanceExtensions())
|
|
||||||
* - if validation layers are enabled: "VK_EXT_debug_utils"
|
|
||||||
*/
|
|
||||||
std::vector<const char*> getRequiredInstanceExtensions() const;
|
|
||||||
/**
|
|
||||||
* @brief Check if @ref settings::validationLayers "all requrested validation layers" are supported
|
|
||||||
*/
|
|
||||||
bool validationLayersSupported();
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name Physical device (selection process)
|
* @name Physical device
|
||||||
* @brief Member variables and functions that are used to select a physical device
|
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
|
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||||
|
/// all the properties of the selected physcial device
|
||||||
|
VkPhysicalDeviceProperties phDevProperties;
|
||||||
|
/// all the features that the selected physical device supports
|
||||||
|
PhysicalDeviceFeatures phDevFeatures;
|
||||||
|
/**
|
||||||
|
* @brief Get the required physical device features
|
||||||
|
* @details
|
||||||
|
* The required features are:
|
||||||
|
* - synchronization2
|
||||||
|
*/
|
||||||
|
PhysicalDeviceFeatures getRequiredFeatures() const;
|
||||||
/**
|
/**
|
||||||
* @brief Assign the physicalDevice handle to the @ref rateDevice "best rated" GPU
|
* @brief Assign the physicalDevice handle to the @ref rateDevice "best rated" GPU
|
||||||
* @details
|
* @details
|
||||||
* After this method, the following members will be initalized:
|
* After this method, physicalDevice, phDevProperties and phDevFeatures will be initialized
|
||||||
* - physicalDevice
|
|
||||||
* - phDevProperties
|
|
||||||
* - phDevFeatures
|
|
||||||
* - phDevMemProperties
|
|
||||||
* - qFamilyIndices
|
|
||||||
* - depthFormat
|
|
||||||
*/
|
*/
|
||||||
void selectPhysicalDevice();
|
void selectPhysicalDevice();
|
||||||
/**
|
/**
|
||||||
@ -504,44 +499,20 @@ namespace gz::vlk {
|
|||||||
* - support all necessary extensions
|
* - support all necessary extensions
|
||||||
* - have swap chain support
|
* - have swap chain support
|
||||||
*/
|
*/
|
||||||
unsigned int rateDevice(vk::PhysicalDevice device);
|
unsigned int rateDevice(VkPhysicalDevice device);
|
||||||
/**
|
|
||||||
* @brief Get the required physical device features
|
|
||||||
* @details
|
|
||||||
* The required features are:
|
|
||||||
* - synchronization2
|
|
||||||
*/
|
|
||||||
PhysicalDeviceFeatures getRequiredDeviceFeatures() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name Physical device (selected)
|
|
||||||
* @brief Member variables and functions that are usable/initalized after selectPhysicalDevice
|
|
||||||
*/
|
|
||||||
/// @{
|
|
||||||
vk::PhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
|
||||||
/// all the properties of the selected physcial device
|
|
||||||
vk::PhysicalDeviceProperties2 phDevProperties;
|
|
||||||
/// memory properties of the selected physical device
|
|
||||||
vk::PhysicalDeviceMemoryProperties2 phDevMemProperties;
|
|
||||||
/// all the features that the selected physical device supports
|
|
||||||
PhysicalDeviceFeatures phDevFeatures;
|
|
||||||
/// preferred depth format
|
|
||||||
vk::Format depthFormat;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Find the best of the supported formats
|
* @brief Find the best of the supported formats
|
||||||
* @param candidates Candidate format, from best to worst
|
* @param candidates Candidate format, from best to worst
|
||||||
* @returns The first format from candidates that is supported
|
* @returns The first format from candidates that is supported
|
||||||
* @throws VkException if no suitable format is found
|
|
||||||
*/
|
*/
|
||||||
vk::Format findSupportedFormat(const std::vector<vk::Format>& candidates, vk::ImageTiling tiling, vk::FormatFeatureFlags features);
|
VkFormat findSupportedFormat(const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name Memory management
|
* @name Memory management
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
uint32_t findMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags properties);
|
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
|
||||||
VulkanAllocator allocator;
|
VulkanAllocator allocator;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@ -549,19 +520,19 @@ namespace gz::vlk {
|
|||||||
* @name Queue
|
* @name Queue
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
QueueFamilyIndices findQueueFamilies(vk::PhysicalDevice device);
|
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
|
||||||
QueueFamilyIndices qFamilyIndices;
|
QueueFamilyIndices qFamilyIndices;
|
||||||
vk::Queue graphicsQ;
|
VkQueue graphicsQ;
|
||||||
vk::Queue presentQ;
|
VkQueue presentQ;
|
||||||
// if possible, use dedicated transferQ. if not available, transferQ = graphicsQ
|
// if possible, use dedicated transferQ. if not available, transferQ = graphicsQ
|
||||||
vk::Queue transferQ;
|
VkQueue transferQ;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name Logical device
|
* @name Logical device
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
vk::Device device;
|
VkDevice device;
|
||||||
/**
|
/**
|
||||||
* @details
|
* @details
|
||||||
* request anisotropic sampling feature
|
* request anisotropic sampling feature
|
||||||
@ -573,7 +544,7 @@ namespace gz::vlk {
|
|||||||
* @name Surface
|
* @name Surface
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
vk::SurfaceKHR surface;
|
VkSurfaceKHR surface;
|
||||||
void createSurface();
|
void createSurface();
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@ -581,23 +552,22 @@ namespace gz::vlk {
|
|||||||
* @name Swap chain
|
* @name Swap chain
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
vk::SwapchainKHR swapChain;
|
VkSwapchainKHR swapChain;
|
||||||
std::vector<vk::Image> scImages;
|
std::vector<VkImage> scImages;
|
||||||
std::vector<vk::ImageView> scImageViews;
|
std::vector<VkImageView> scImageViews;
|
||||||
vk::Format scImageFormat;
|
VkFormat scImageFormat;
|
||||||
vk::Extent2D scExtent;
|
VkExtent2D scExtent;
|
||||||
|
|
||||||
SwapChainSupport querySwapChainSupport(vk::PhysicalDevice device);
|
SwapChainSupport querySwapChainSupport(VkPhysicalDevice device);
|
||||||
/**
|
/**
|
||||||
* @todo Rate formats if preferred is not available
|
* @todo Rate formats if preferred is not available
|
||||||
* @todo Move back to SurfaceFormatKHR? 2 is an (for now) unnecessary extension
|
|
||||||
*/
|
*/
|
||||||
vk::SurfaceFormat2KHR selectSwapChainSurfaceFormat(const std::vector<vk::SurfaceFormat2KHR>& availableFormats);
|
VkSurfaceFormatKHR selectSwapChainSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
||||||
/**
|
/**
|
||||||
* @todo Check settings for preferred mode
|
* @todo Check settings for preferred mode
|
||||||
*/
|
*/
|
||||||
vk::PresentModeKHR selectSwapChainPresentMode(const std::vector<vk::PresentModeKHR>& availableModes);
|
VkPresentModeKHR selectSwapChainPresentMode(const std::vector<VkPresentModeKHR>& availableModes);
|
||||||
vk::Extent2D selectSwapExtent(const vk::SurfaceCapabilities2KHR& capabilities);
|
VkExtent2D selectSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
|
||||||
void createSwapChain();
|
void createSwapChain();
|
||||||
void createSwapChainImageViews();
|
void createSwapChainImageViews();
|
||||||
void cleanupSwapChain();
|
void cleanupSwapChain();
|
||||||
@ -619,31 +589,31 @@ namespace gz::vlk {
|
|||||||
* @name Command pools
|
* @name Command pools
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
vk::CommandPool commandPoolGraphics;
|
VkCommandPool commandPoolGraphics;
|
||||||
vk::CommandPool commandPoolTransfer;
|
VkCommandPool commandPoolTransfer;
|
||||||
void createCommandPools();
|
void createCommandPools();
|
||||||
/// @}
|
/// @}
|
||||||
/**
|
/**
|
||||||
* @name Command buffers
|
* @name Command buffers
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
std::vector<vk::CommandBuffer> commandBuffersBegin;
|
std::vector<VkCommandBuffer> commandBuffersBegin;
|
||||||
std::vector<vk::CommandBuffer> commandBuffersEnd;
|
std::vector<VkCommandBuffer> commandBuffersEnd;
|
||||||
/**
|
/**
|
||||||
* @brief All command buffers to submit on graphics queue for the current frame
|
* @brief All command buffers to submit on graphics queue for the current frame
|
||||||
* @details
|
* @details
|
||||||
* Use submitThisFrame() to submit a command buffer
|
* Use submitThisFrame() to submit a command buffer
|
||||||
*/
|
*/
|
||||||
std::vector<vk::CommandBuffer> commandBuffersToSubmitThisFrame;
|
std::vector<VkCommandBuffer> commandBuffersToSubmitThisFrame;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name Synchronization
|
* @name Synchronization
|
||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
std::vector<vk::Semaphore> imageAvailableSemaphores;
|
std::vector<VkSemaphore> imageAvailableSemaphores;
|
||||||
std::vector<vk::Semaphore> renderFinishedSemaphores;
|
std::vector<VkSemaphore> renderFinishedSemaphores;
|
||||||
std::vector<vk::Fence> inFlightFences;
|
std::vector<VkFence> inFlightFences;
|
||||||
void createSyncObjects();
|
void createSyncObjects();
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@ -664,7 +634,7 @@ namespace gz::vlk {
|
|||||||
*/
|
*/
|
||||||
/// @{
|
/// @{
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
vk::Result runVkResultFunction(const char* name, Args&&... args);
|
VkResult runVkResultFunction(const char* name, Args&&... args);
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
void runVkVoidFunction(const char* name, Args&&... args);
|
void runVkVoidFunction(const char* name, Args&&... args);
|
||||||
|
|
||||||
@ -706,14 +676,14 @@ namespace gz::vlk {
|
|||||||
// UNIFORM BUFFERS
|
// UNIFORM BUFFERS
|
||||||
//
|
//
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void VulkanInstance::createUniformBuffers(std::vector<vk::Buffer>& uniformBuffers, std::vector<MemoryInfo>& uniformBuffersMemory) {
|
void VulkanInstance::createUniformBuffers(std::vector<VkBuffer>& uniformBuffers, std::vector<MemoryInfo>& uniformBuffersMemory) {
|
||||||
vk::DeviceSize bufferSize = sizeof(T);
|
VkDeviceSize bufferSize = sizeof(T);
|
||||||
|
|
||||||
uniformBuffers.resize(MAX_FRAMES_IN_FLIGHT);
|
uniformBuffers.resize(MAX_FRAMES_IN_FLIGHT);
|
||||||
uniformBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT);
|
uniformBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT);
|
||||||
|
|
||||||
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
||||||
createBuffer(bufferSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, uniformBuffers[i], uniformBuffersMemory[i]);
|
createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, uniformBuffers[i], uniformBuffersMemory[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,14 +691,14 @@ namespace gz::vlk {
|
|||||||
// UTILITY
|
// UTILITY
|
||||||
//
|
//
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
vk::Result VulkanInstance::runVkResultFunction(const char* name, Args&&... args) {
|
VkResult VulkanInstance::runVkResultFunction(const char* name, Args&&... args) {
|
||||||
auto f = reinterpret_cast<T>(vkGetInstanceProcAddr(instance, name));
|
auto f = reinterpret_cast<T>(vkGetInstanceProcAddr(instance, name));
|
||||||
if (f == nullptr) {
|
if (f == nullptr) {
|
||||||
vLog.error("getVkFunction: Could not get function:", name);
|
vLog.error("getVkFunction: Could not get function:", name);
|
||||||
throw std::runtime_error("getVkFunction: Could not get function.");
|
throw std::runtime_error("getVkFunction: Could not get function.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return vk::Result(f(std::forward<Args>(args)...));
|
return f(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <gz-util/settings_manager.hpp>
|
|
||||||
#include <gz-util/log.hpp>
|
|
||||||
|
|
||||||
#define VULKAN_HPP_NO_EXCEPTIONS
|
|
||||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
|
||||||
#include <vulkan/vulkan.hpp>
|
|
||||||
|
|
||||||
namespace gz::vlk::settings {
|
|
||||||
constexpr bool throwExceptionOnValidationError = true;
|
|
||||||
constexpr gz::Color VULKAN_MESSAGE_PREFIX_COLOR = gz::Color::BO_BLUE;
|
|
||||||
constexpr gz::Color VULKAN_MESSAGE_TIME_COLOR = gz::Color::BLUE;
|
|
||||||
const std::string CONFIG_FILE = "vulkan.conf";
|
|
||||||
|
|
||||||
/* const std::string MODEL_PATH = "models/gazebo-3d-model/gazebo.obj"; */
|
|
||||||
/* const std::string TEXTURE_PATH = "models/gazebo-3d-model/gazebo_diffuse.png"; */
|
|
||||||
|
|
||||||
const std::string MODEL_PATH = "models/armoire-3d-model/Armoire.obj";
|
|
||||||
const std::string TEXTURE_PATH = "models/armoire-3d-model/Armoire_diffuse.png";
|
|
||||||
|
|
||||||
#define VULKAN_SETTINGS_MAN_TYPES uint32_t, bool, float
|
|
||||||
const gz::util::unordered_string_map<std::string> INITIAL_SETTINGS = {
|
|
||||||
{ "framerate", "60" },
|
|
||||||
{ "anisotropy_enable", "false" },
|
|
||||||
{ "max_anisotropy", "1" },
|
|
||||||
{ "max_frames_in_flight", "3" },
|
|
||||||
/* { "", "" } */
|
|
||||||
};
|
|
||||||
constexpr vk::ClearColorValue missingTextureColor = { std::array<float, 4>{ 0.4f, 0.0f, 0.4f, 1.0f } };
|
|
||||||
|
|
||||||
constexpr size_t VERTEX_BUFFER_SIZE = 512;
|
|
||||||
constexpr size_t INDEX_BUFFER_SIZE = 512;
|
|
||||||
|
|
||||||
|
|
||||||
constexpr std::array<const char*, 1> deviceExtensions = {
|
|
||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
|
||||||
/* VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME */
|
|
||||||
};
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
/**
|
|
||||||
* @brief Which message severities to log in VulkanInstance::debugLog()
|
|
||||||
*/
|
|
||||||
constexpr vk::DebugUtilsMessageSeverityFlagsEXT debugMessageSevereties =
|
|
||||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
|
|
||||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo |
|
|
||||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
|
|
||||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Which message types to log in VulkanInstance::debugLog()
|
|
||||||
*/
|
|
||||||
constexpr vk::DebugUtilsMessageTypeFlagsEXT debugMessageTypes =
|
|
||||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
|
|
||||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
|
|
||||||
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance;
|
|
||||||
|
|
||||||
// VALIDATION LAYERS
|
|
||||||
constexpr std::array<const char*, 1> validationLayers {
|
|
||||||
"VK_LAYER_KHRONOS_validation",
|
|
||||||
};
|
|
||||||
constexpr std::array<vk::ValidationFeatureEnableEXT, 3> validationFeaturesEnable {
|
|
||||||
vk::ValidationFeatureEnableEXT::eDebugPrintf,
|
|
||||||
vk::ValidationFeatureEnableEXT::eSynchronizationValidation,
|
|
||||||
vk::ValidationFeatureEnableEXT::eBestPractices
|
|
||||||
};
|
|
||||||
constexpr vk::ValidationFeaturesEXT validationFeatures {
|
|
||||||
.enabledValidationFeatureCount = static_cast<uint32_t>(validationFeaturesEnable.size()),
|
|
||||||
.pEnabledValidationFeatures = validationFeaturesEnable.data(),
|
|
||||||
};
|
|
||||||
} // namespace gz::vlk::setting
|
|
Loading…
Reference in New Issue
Block a user