Added class to handle allocation and creation of Buffers and Image, as well as Timers.
No memory leaks detected yet. (Fingers crossed).
This commit is contained in:
parent
952176f4c9
commit
e077eeaf5d
30
Memory/Buffer.cpp
Normal file
30
Memory/Buffer.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include <Memory/Buffer.hpp>
|
||||||
|
#include <Memory/Memory.hpp>
|
||||||
|
|
||||||
|
Buffer::Buffer(vk::PhysicalDevice phys_dev, vk::Device dev, vk::DeviceSize sz, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags mem_flags, vk::SharingMode sharing) : dev(dev), size(sz) {
|
||||||
|
auto info = vk::BufferCreateInfo {
|
||||||
|
.size = sz,
|
||||||
|
.usage = usage,
|
||||||
|
.sharingMode = sharing,
|
||||||
|
};
|
||||||
|
buffer = dev.createBuffer(info);
|
||||||
|
|
||||||
|
auto reqs = dev.getBufferMemoryRequirements(buffer);
|
||||||
|
auto alloc_info = vk::MemoryAllocateInfo{
|
||||||
|
.allocationSize = reqs.size,
|
||||||
|
.memoryTypeIndex = mem::choose_heap(phys_dev, reqs, mem_flags),
|
||||||
|
};
|
||||||
|
memory = dev.allocateMemory(alloc_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::map(const uint8_t* data, vk::DeviceSize size) {
|
||||||
|
auto p = dev.mapMemory(memory, 0, size);
|
||||||
|
std::memcpy(p, data, size);
|
||||||
|
dev.unmapMemory(memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::~Buffer() {
|
||||||
|
dev.freeMemory(memory);
|
||||||
|
dev.destroyBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
27
Memory/Buffer.hpp
Normal file
27
Memory/Buffer.hpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
||||||
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
|
struct Buffer {
|
||||||
|
Buffer(vk::PhysicalDevice phys_dev, vk::Device dev, vk::DeviceSize sz, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags mem_flags, vk::SharingMode sharing = vk::SharingMode::eExclusive);
|
||||||
|
|
||||||
|
vk::DeviceSize size;
|
||||||
|
vk::Device dev;
|
||||||
|
vk::DeviceMemory memory;
|
||||||
|
vk::Buffer buffer;
|
||||||
|
|
||||||
|
void map(const uint8_t* data, vk::DeviceSize size);
|
||||||
|
inline void map(const uint8_t* data) {
|
||||||
|
map(data, size);
|
||||||
|
}
|
||||||
|
inline void map(const std::vector<uint8_t>& data) {
|
||||||
|
map(data.data(), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator vk::Buffer& () {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Buffer();
|
||||||
|
};
|
||||||
44
Memory/Image.cpp
Normal file
44
Memory/Image.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include <Memory/Image.hpp>
|
||||||
|
#include <Memory/Memory.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
Image::Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Image _image, vk::MemoryPropertyFlags memory_flags) : dev(dev), image(_image) {
|
||||||
|
|
||||||
|
auto reqs = dev.getImageMemoryRequirements(image);
|
||||||
|
|
||||||
|
auto alloc = vk::MemoryAllocateInfo{
|
||||||
|
.allocationSize = reqs.size,
|
||||||
|
.memoryTypeIndex = mem::choose_heap(phys_dev, reqs, memory_flags),
|
||||||
|
};
|
||||||
|
memory = dev.allocateMemory(alloc);
|
||||||
|
dev.bindImageMemory(image, memory, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Image::Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::ImageCreateInfo info, vk::MemoryPropertyFlags memory_flags) : dev(dev) {
|
||||||
|
image = dev.createImage(info);
|
||||||
|
|
||||||
|
*this = Image(phys_dev, dev, image, memory_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
Image::Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Extent3D extent, vk::Format format, vk::ImageTiling tiling, vk::ImageUsageFlags usage, vk::MemoryPropertyFlags memory_flags) : dev(dev) {
|
||||||
|
auto info = vk::ImageCreateInfo{
|
||||||
|
.imageType = vk::ImageType::e2D,
|
||||||
|
.format = format,
|
||||||
|
.extent = extent,
|
||||||
|
.mipLevels = 1,
|
||||||
|
.arrayLayers = 1,
|
||||||
|
.samples = vk::SampleCountFlagBits::e1,
|
||||||
|
.tiling = tiling,
|
||||||
|
.usage = usage,
|
||||||
|
.sharingMode = vk::SharingMode::eExclusive,
|
||||||
|
.initialLayout = vk::ImageLayout::eUndefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
*this = Image(phys_dev, dev, info, memory_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::cleanup() {
|
||||||
|
dev.destroyImage(image);
|
||||||
|
dev.freeMemory(memory);
|
||||||
|
}
|
||||||
20
Memory/Image.hpp
Normal file
20
Memory/Image.hpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
||||||
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
|
#include <util/log.hpp>
|
||||||
|
|
||||||
|
struct Image {
|
||||||
|
vk::Device dev;
|
||||||
|
vk::Extent3D extent;
|
||||||
|
vk::Format format;
|
||||||
|
vk::Image image;
|
||||||
|
vk::DeviceMemory memory;
|
||||||
|
|
||||||
|
Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Image image, vk::MemoryPropertyFlags memory_flags);
|
||||||
|
Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::ImageCreateInfo info, vk::MemoryPropertyFlags memory_flags);
|
||||||
|
Image(vk::PhysicalDevice phys_dev, vk::Device dev, vk::Extent3D extent, vk::Format format, vk::ImageTiling, vk::ImageUsageFlags usage, vk::MemoryPropertyFlags memory_flags);
|
||||||
|
|
||||||
|
void cleanup();
|
||||||
|
};
|
||||||
@ -1,6 +1,8 @@
|
|||||||
#include <Renderer/CommandBuffer.hpp>
|
#include <Renderer/CommandBuffer.hpp>
|
||||||
#include <Renderer/Pipeline.hpp>
|
#include <Renderer/Pipeline.hpp>
|
||||||
|
|
||||||
|
#include <Memory/Buffer.hpp>
|
||||||
|
#include <Memory/Image.hpp>
|
||||||
|
|
||||||
#include <util/log.hpp>
|
#include <util/log.hpp>
|
||||||
|
|
||||||
@ -32,8 +34,27 @@ void CommandBuffer::begin() {
|
|||||||
command_buffer.begin(begin_info);
|
command_buffer.begin(begin_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBuffer::copy(vk::Buffer in, vk::Buffer out, vk::ArrayProxy<const vk::BufferCopy> regions) {
|
void CommandBuffer::copy(vk::Buffer src, vk::Buffer dst, vk::ArrayProxy<const vk::BufferCopy> regions) {
|
||||||
command_buffer.copyBuffer(in, out, regions);
|
command_buffer.copyBuffer(src, dst, regions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandBuffer::copy(Buffer& src, Image& dst, vk::ImageLayout layout) {
|
||||||
|
auto region = vk::BufferImageCopy{
|
||||||
|
.bufferOffset = 0,
|
||||||
|
/* RowLength and ImageHeight are automatically set to imageExtent dimensions if set to 0 */
|
||||||
|
.bufferRowLength = 0,
|
||||||
|
.bufferImageHeight = 0,
|
||||||
|
.imageSubresource = {
|
||||||
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.mipLevel = 0,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 0,
|
||||||
|
},
|
||||||
|
.imageOffset = { 0, 0, 0 },
|
||||||
|
.imageExtent = dst.extent,
|
||||||
|
};
|
||||||
|
|
||||||
|
command_buffer.copyBufferToImage(src, dst.image, layout, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBuffer::bind(const GraphicsPipeline& pipeline) {
|
void CommandBuffer::bind(const GraphicsPipeline& pipeline) {
|
||||||
|
|||||||
@ -5,6 +5,9 @@
|
|||||||
|
|
||||||
#include <util/int.hpp>
|
#include <util/int.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
struct Buffer;
|
||||||
|
struct Image;
|
||||||
struct GraphicsPipeline;
|
struct GraphicsPipeline;
|
||||||
struct ComputePipeline;
|
struct ComputePipeline;
|
||||||
|
|
||||||
@ -18,6 +21,8 @@ struct CommandBuffer {
|
|||||||
|
|
||||||
/* copy between buffer */
|
/* copy between buffer */
|
||||||
void copy(vk::Buffer in, vk::Buffer out, vk::ArrayProxy<const vk::BufferCopy> regions);
|
void copy(vk::Buffer in, vk::Buffer out, vk::ArrayProxy<const vk::BufferCopy> regions);
|
||||||
|
/* copy buffer to image */
|
||||||
|
void copy(Buffer& in, Image& out, vk::ImageLayout layout = vk::ImageLayout::eTransferDstOptimal);
|
||||||
|
|
||||||
void bind(const GraphicsPipeline& pipeline);
|
void bind(const GraphicsPipeline& pipeline);
|
||||||
void bind(const ComputePipeline& pipeline);
|
void bind(const ComputePipeline& pipeline);
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
#include <Renderer/Pipeline.hpp>
|
|
||||||
|
|
||||||
#include <Renderer/Shader.hpp>
|
|
||||||
|
|
||||||
ComputePipeline::ComputePipeline(vk::Device dev, const Shader& shader) {
|
|
||||||
auto shader_info = vk::PipelineShaderStageCreateInfo {
|
|
||||||
.stage = vk::ShaderStageFlagBits::eCompute,
|
|
||||||
.module = shader,
|
|
||||||
.pName = "main",
|
|
||||||
};
|
|
||||||
|
|
||||||
auto layout = vk::PipelineLayoutCreateInfo {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
auto create_info = vk::ComputePipelineCreateInfo {
|
|
||||||
.stage = shader_info,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -5,15 +5,16 @@
|
|||||||
|
|
||||||
#include <Memory/Memory.hpp>
|
#include <Memory/Memory.hpp>
|
||||||
|
|
||||||
|
#include <util/Timer.hpp>
|
||||||
|
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
Renderer::Renderer(Window& win) : win(win) {
|
Renderer::Renderer(Window& win) : win(win) {
|
||||||
/* Create Instance object */
|
/* Create Instance object */
|
||||||
auto app_info = vk::ApplicationInfo {
|
auto app_info = vk::ApplicationInfo {
|
||||||
.pApplicationName = "Pl<EFBFBD>ascach Demo",
|
.pApplicationName = "Pléascach Demo",
|
||||||
.applicationVersion = VK_MAKE_API_VERSION(0, 0, 1, 0),
|
.applicationVersion = VK_MAKE_API_VERSION(0, 0, 1, 0),
|
||||||
.pEngineName = "Pl<EFBFBD>ascach",
|
.pEngineName = "Pléascach",
|
||||||
.engineVersion = VK_MAKE_API_VERSION(0, 0, 1, 0),
|
.engineVersion = VK_MAKE_API_VERSION(0, 0, 1, 0),
|
||||||
.apiVersion = VK_API_VERSION_1_1,
|
.apiVersion = VK_API_VERSION_1_1,
|
||||||
};
|
};
|
||||||
@ -162,7 +163,6 @@ Renderer::Renderer(Window& win) : win(win) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::draw() {
|
void Renderer::draw() {
|
||||||
Log::debug("draw() called \n");
|
|
||||||
|
|
||||||
if(dev.waitForFences(render_fence, true, UINT64_MAX) != vk::Result::eSuccess) {
|
if(dev.waitForFences(render_fence, true, UINT64_MAX) != vk::Result::eSuccess) {
|
||||||
Log::error("Failed to wait for fences in draw()\n");
|
Log::error("Failed to wait for fences in draw()\n");
|
||||||
@ -240,7 +240,6 @@ void Renderer::draw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::present() {
|
void Renderer::present() {
|
||||||
Log::debug("present() called \n");
|
|
||||||
auto present_info = vk::PresentInfoKHR{
|
auto present_info = vk::PresentInfoKHR{
|
||||||
.waitSemaphoreCount = 1,
|
.waitSemaphoreCount = 1,
|
||||||
.pWaitSemaphores = &render_wait_semaphore,
|
.pWaitSemaphores = &render_wait_semaphore,
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include <Window/Window.hpp>
|
#include <Window/Window.hpp>
|
||||||
|
|
||||||
#include <Memory/Memory.hpp>
|
#include <Memory/Memory.hpp>
|
||||||
|
#include <Memory/Image.hpp>
|
||||||
|
|
||||||
#include <util/log.hpp>
|
#include <util/log.hpp>
|
||||||
|
|
||||||
@ -66,38 +67,11 @@ void Swapchain::create(vk::SwapchainKHR old_swapchain) {
|
|||||||
|
|
||||||
images = dev.getSwapchainImagesKHR(swapchain);
|
images = dev.getSwapchainImagesKHR(swapchain);
|
||||||
|
|
||||||
auto depth_image_info = vk::ImageCreateInfo{
|
depth_image = std::make_unique<Image>(phys_dev, dev, vk::Extent3D { extent.width, extent.height, 1 }, vk::Format::eD16Unorm,
|
||||||
.imageType = vk::ImageType::e2D,
|
vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eDepthStencilAttachment, vk::MemoryPropertyFlagBits::eDeviceLocal);
|
||||||
.format = vk::Format::eD16Unorm,
|
|
||||||
.extent = {
|
|
||||||
.width = extent.width,
|
|
||||||
.height = extent.height,
|
|
||||||
.depth = 1,
|
|
||||||
},
|
|
||||||
.mipLevels = 1,
|
|
||||||
.arrayLayers = 1,
|
|
||||||
.samples = vk::SampleCountFlagBits::e1,
|
|
||||||
.usage = vk::ImageUsageFlagBits::eDepthStencilAttachment,
|
|
||||||
.sharingMode = vk::SharingMode::eExclusive,
|
|
||||||
.queueFamilyIndexCount = 0,
|
|
||||||
.pQueueFamilyIndices = NULL,
|
|
||||||
.initialLayout = vk::ImageLayout::eUndefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
depth_image = dev.createImage(depth_image_info);
|
|
||||||
|
|
||||||
auto depth_mem_reqs = dev.getImageMemoryRequirements(depth_image);
|
|
||||||
|
|
||||||
auto depth_alloc_info = vk::MemoryAllocateInfo{
|
|
||||||
.allocationSize = depth_mem_reqs.size,
|
|
||||||
.memoryTypeIndex = mem::choose_heap(phys_dev, depth_mem_reqs, vk::MemoryPropertyFlagBits::eDeviceLocal),
|
|
||||||
};
|
|
||||||
|
|
||||||
depth_alloc = dev.allocateMemory(depth_alloc_info);
|
|
||||||
dev.bindImageMemory(depth_image, depth_alloc, 0);
|
|
||||||
|
|
||||||
auto depth_view_info = vk::ImageViewCreateInfo {
|
auto depth_view_info = vk::ImageViewCreateInfo {
|
||||||
.image = depth_image,
|
.image = depth_image->image,
|
||||||
.viewType = vk::ImageViewType::e2D,
|
.viewType = vk::ImageViewType::e2D,
|
||||||
.format = vk::Format::eD16Unorm,
|
.format = vk::Format::eD16Unorm,
|
||||||
.components = {
|
.components = {
|
||||||
@ -152,7 +126,6 @@ void Swapchain::create(vk::SwapchainKHR old_swapchain) {
|
|||||||
|
|
||||||
framebuffers[i] = dev.createFramebuffer(framebuffer_info);
|
framebuffers[i] = dev.createFramebuffer(framebuffer_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -172,8 +145,7 @@ void Swapchain::cleanup() {
|
|||||||
dev.destroyImageView(view);
|
dev.destroyImageView(view);
|
||||||
|
|
||||||
dev.destroyImageView(depth_image_view);
|
dev.destroyImageView(depth_image_view);
|
||||||
dev.destroyImage(depth_image);
|
depth_image->cleanup();
|
||||||
dev.freeMemory(depth_alloc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Swapchain::~Swapchain() {
|
Swapchain::~Swapchain() {
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <Renderer/RenderPass.hpp>
|
#include <Renderer/RenderPass.hpp>
|
||||||
|
|
||||||
struct Window;
|
struct Window;
|
||||||
|
struct Image;
|
||||||
|
|
||||||
struct Swapchain {
|
struct Swapchain {
|
||||||
Swapchain(Window& win, vk::Device dev, vk::PhysicalDevice phys_dev, const vk::SurfaceKHR& surface, RenderPass render_pass);
|
Swapchain(Window& win, vk::Device dev, vk::PhysicalDevice phys_dev, const vk::SurfaceKHR& surface, RenderPass render_pass);
|
||||||
@ -34,9 +35,8 @@ struct Swapchain {
|
|||||||
std::vector<vk::ImageView> views;
|
std::vector<vk::ImageView> views;
|
||||||
std::vector<vk::Framebuffer> framebuffers;
|
std::vector<vk::Framebuffer> framebuffers;
|
||||||
|
|
||||||
vk::Image depth_image;
|
std::unique_ptr<Image> depth_image;
|
||||||
vk::ImageView depth_image_view;
|
vk::ImageView depth_image_view;
|
||||||
vk::DeviceMemory depth_alloc;
|
|
||||||
|
|
||||||
vk::Format format;
|
vk::Format format;
|
||||||
|
|
||||||
|
|||||||
@ -1,46 +1,34 @@
|
|||||||
#include <Resources/Texture.hpp>
|
#include <Resources/Texture.hpp>
|
||||||
|
#include <Memory/Buffer.hpp>
|
||||||
#include <Memory/Memory.hpp>
|
#include <Memory/Memory.hpp>
|
||||||
|
|
||||||
|
#include <Renderer/CommandBuffer.hpp>
|
||||||
|
|
||||||
#include <util/file.hpp>
|
#include <util/file.hpp>
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
|
||||||
Texture::Texture(vk::Device dev, vk::PhysicalDevice phys_dev, const std::string& fname) {
|
Texture::Texture(vk::PhysicalDevice phys_dev, vk::Device dev, CommandBuffer command_buffer, const std::string& fname) {
|
||||||
|
int n_channels;
|
||||||
vk::Extent3D extent;
|
vk::Extent3D extent;
|
||||||
auto image_data = stbi_load(fname.c_str(), reinterpret_cast<int*>(&extent.width), reinterpret_cast<int*>(&extent.height), NULL, NULL);
|
|
||||||
|
auto image_data = stbi_load(fname.c_str(), reinterpret_cast<int*>(&extent.width), reinterpret_cast<int*>(&extent.height), &n_channels, STBI_rgb_alpha);
|
||||||
extent.depth = 1;
|
extent.depth = 1;
|
||||||
|
|
||||||
auto image_info = vk::ImageCreateInfo{
|
image = std::make_unique<Image>(phys_dev, dev, extent, vk::Format::eR8G8B8A8Srgb,
|
||||||
.imageType = vk::ImageType::e2D,
|
vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eSampled,
|
||||||
.format = vk::Format::eR8G8B8A8Unorm,
|
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
.extent = extent,
|
|
||||||
.mipLevels = 1,
|
|
||||||
.arrayLayers = 1,
|
|
||||||
.samples = vk::SampleCountFlagBits::e1,
|
|
||||||
.tiling = vk::ImageTiling::eOptimal,
|
|
||||||
.usage = vk::ImageUsageFlagBits::eSampled,
|
|
||||||
.sharingMode = vk::SharingMode::eExclusive,
|
|
||||||
.initialLayout = vk::ImageLayout::eUndefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
image = dev.createImage(image_info);
|
vk::DeviceSize sz = extent.width * extent.height * sizeof(uint32_t);
|
||||||
|
|
||||||
auto reqs = dev.getImageMemoryRequirements(image);
|
/* staging buffer to hold image data from the CPU */
|
||||||
|
Buffer staging(phys_dev, dev, sz, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
|
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||||
|
|
||||||
|
staging.map(image_data);
|
||||||
|
stbi_image_free(image_data);
|
||||||
|
|
||||||
auto image_alloc_info = vk::MemoryAllocateInfo{
|
command_buffer.copy(staging, *image);
|
||||||
.allocationSize = reqs.size,
|
|
||||||
.memoryTypeIndex = mem::choose_heap(phys_dev, reqs, vk::MemoryPropertyFlagBits::eHostVisible),
|
|
||||||
};
|
|
||||||
|
|
||||||
image_alloc = dev.allocateMemory(image_alloc_info);
|
|
||||||
dev.bindImageMemory(image, image_alloc, 0);
|
|
||||||
|
|
||||||
/* TODO: Copy memory into image using buffers */
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::cleanup(vk::Device dev) {
|
|
||||||
dev.freeMemory(image_alloc);
|
|
||||||
}
|
}
|
||||||
@ -3,9 +3,11 @@
|
|||||||
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
|
#include <Memory/Image.hpp>
|
||||||
|
|
||||||
|
struct CommandBuffer;
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
vk::Image image;
|
std::unique_ptr<Image> image;
|
||||||
vk::DeviceMemory image_alloc;
|
Texture(vk::PhysicalDevice phys_dev, vk::Device dev, CommandBuffer command_buffer, const std::string& fname);
|
||||||
Texture(vk::Device dev, vk::PhysicalDevice phys_dev, const std::string& fname);
|
|
||||||
void cleanup(vk::Device dev);
|
|
||||||
};
|
};
|
||||||
@ -3,6 +3,8 @@
|
|||||||
#include <Renderer/Renderer.hpp>
|
#include <Renderer/Renderer.hpp>
|
||||||
|
|
||||||
#include <util/log.hpp>
|
#include <util/log.hpp>
|
||||||
|
#include <util/Timer.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
@ -12,6 +14,7 @@ int main(int argc, char* argv[]) {
|
|||||||
Renderer ren(win);
|
Renderer ren(win);
|
||||||
|
|
||||||
while (!in->shouldClose()) {
|
while (!in->shouldClose()) {
|
||||||
|
Timer frame_timer;
|
||||||
in->poll();
|
in->poll();
|
||||||
|
|
||||||
while (in->queue.size()) {
|
while (in->queue.size()) {
|
||||||
@ -39,6 +42,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
ren.draw();
|
ren.draw();
|
||||||
ren.present();
|
ren.present();
|
||||||
|
Log::debug("Frame: %lf milliseconds (60fps ~ 16.67)\n", frame_timer.stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (const std::string& e) {
|
} catch (const std::string& e) {
|
||||||
|
|||||||
38
util/Timer.hpp
Normal file
38
util/Timer.hpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
/* get the time in milliseconds */
|
||||||
|
struct Timer {
|
||||||
|
std::chrono::time_point<std::chrono::steady_clock> start_time, end_time;
|
||||||
|
bool running = false;
|
||||||
|
|
||||||
|
|
||||||
|
Timer() {
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void start() {
|
||||||
|
start_time = std::chrono::steady_clock::now();
|
||||||
|
running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void reset() {
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double read() {
|
||||||
|
if (running) {
|
||||||
|
auto end = std::chrono::steady_clock::now();
|
||||||
|
return std::chrono::duration_cast<std::chrono::microseconds>(end - start_time).count() / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time).count() / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double stop() {
|
||||||
|
end_time = std::chrono::steady_clock::now();
|
||||||
|
running = false;
|
||||||
|
return read();
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -12,7 +12,7 @@ namespace Log {
|
|||||||
return static_cast<MessageLevelBit>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
|
return static_cast<MessageLevelBit>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const MessageLevelBit log_mask = ERROR | INFO;
|
static const MessageLevelBit log_mask = ERROR | INFO | DEBUG;
|
||||||
|
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
static void print(MessageLevelBit level, const std::string& fmt, Args... args) {
|
static void print(MessageLevelBit level, const std::string& fmt, Args... args) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user