forked from pupbrained/vulkan-test
idk why this isnt working rn but whatever
This commit is contained in:
parent
1732d56e22
commit
f0e85c0d88
232
src/main.cpp
232
src/main.cpp
|
@ -1,9 +1,13 @@
|
|||
#include <chrono>
|
||||
#include <fmt/format.h>
|
||||
#include <fstream>
|
||||
#include <glm/glm.hpp>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
#define GLM_FORCE_RADIANS
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
|
||||
#define VK_ENABLE_BETA_EXTENSIONS
|
||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
||||
|
@ -21,42 +25,6 @@ constexpr i32 HEIGHT = 600;
|
|||
|
||||
constexpr i32 MAX_FRAMES_IN_FLIGHT = 2;
|
||||
|
||||
struct Vertex {
|
||||
glm::vec2 pos;
|
||||
glm::vec3 color;
|
||||
|
||||
static fn getBindingDescription() -> vk::VertexInputBindingDescription {
|
||||
vk::VertexInputBindingDescription bindingDescription { .binding = 0,
|
||||
.stride = sizeof(Vertex),
|
||||
.inputRate = vk::VertexInputRate::eVertex };
|
||||
|
||||
return bindingDescription;
|
||||
}
|
||||
|
||||
static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 2> {
|
||||
std::array<vk::VertexInputAttributeDescription, 2> attributeDescriptions {};
|
||||
|
||||
attributeDescriptions[0] = {
|
||||
.location = 0, .binding = 0, .format = vk::Format::eR32G32Sfloat, .offset = offsetof(Vertex, pos)
|
||||
};
|
||||
|
||||
attributeDescriptions[1] = {
|
||||
.location = 1, .binding = 0, .format = vk::Format::eR32G32B32Sfloat, .offset = offsetof(Vertex, color)
|
||||
};
|
||||
|
||||
return attributeDescriptions;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr std::array<Vertex, 4> vertices = {
|
||||
{ { { -0.5F, -0.5F }, { 1.0F, 0.0F, 0.0F } },
|
||||
{ { 0.5F, -0.5F }, { 0.0F, 1.0F, 0.0F } },
|
||||
{ { 0.5F, 0.5F }, { 0.0F, 0.0F, 1.0F } },
|
||||
{ { -0.5F, 0.5F }, { 1.0F, 1.0F, 1.0F } } }
|
||||
};
|
||||
|
||||
constexpr std::array<u16, 6> indices = { 0, 1, 2, 2, 3, 0 };
|
||||
|
||||
constexpr std::array<const char*, 1> validationLayers = { "VK_LAYER_KHRONOS_validation" };
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -72,6 +40,31 @@ constexpr bool enableValidationLayers = false;
|
|||
constexpr bool enableValidationLayers = true;
|
||||
#endif
|
||||
|
||||
struct Vertex {
|
||||
glm::vec2 pos;
|
||||
glm::vec3 color;
|
||||
|
||||
static fn getBindingDescription() -> vk::VertexInputBindingDescription {
|
||||
return { .binding = 0, .stride = sizeof(Vertex), .inputRate = vk::VertexInputRate::eVertex };
|
||||
}
|
||||
|
||||
static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 2> {
|
||||
return {
|
||||
vk::VertexInputAttributeDescription { 0, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, pos) },
|
||||
vk::VertexInputAttributeDescription { 1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color) }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
constexpr std::array<Vertex, 4> vertices = {
|
||||
{ { { -0.5F, -0.5F }, { 1.0F, 0.0F, 0.0F } },
|
||||
{ { 0.5F, -0.5F }, { 0.0F, 1.0F, 0.0F } },
|
||||
{ { 0.5F, 0.5F }, { 0.0F, 0.0F, 1.0F } },
|
||||
{ { -0.5F, 0.5F }, { 1.0F, 1.0F, 1.0F } } }
|
||||
};
|
||||
|
||||
constexpr std::array<u16, 6> indices = { 0, 1, 2, 2, 3, 0 };
|
||||
|
||||
class VulkanApp {
|
||||
public:
|
||||
fn run() -> void {
|
||||
|
@ -102,22 +95,31 @@ class VulkanApp {
|
|||
std::vector<vk::UniqueImageView> mSwapChainImageViews;
|
||||
std::vector<vk::UniqueFramebuffer> mSwapChainFramebuffers;
|
||||
|
||||
vk::UniqueRenderPass mRenderPass;
|
||||
vk::UniquePipelineLayout mPipelineLayout;
|
||||
vk::UniquePipeline mGraphicsPipeline;
|
||||
vk::UniqueRenderPass mRenderPass;
|
||||
vk::UniqueDescriptorSetLayout mDescriptorSetLayout;
|
||||
vk::UniquePipelineLayout mPipelineLayout;
|
||||
vk::UniquePipeline mGraphicsPipeline;
|
||||
|
||||
vk::UniqueCommandPool mCommandPool;
|
||||
std::vector<vk::UniqueCommandBuffer> mCommandBuffers;
|
||||
|
||||
std::vector<vk::UniqueSemaphore> mImageAvailableSemaphores;
|
||||
std::vector<vk::UniqueSemaphore> mRenderFinishedSemaphores;
|
||||
std::vector<vk::UniqueFence> mInFlightFences;
|
||||
vk::UniqueCommandPool mCommandPool;
|
||||
|
||||
vk::UniqueBuffer mVertexBuffer;
|
||||
vk::UniqueDeviceMemory mVertexBufferMemory;
|
||||
vk::UniqueBuffer mIndexBuffer;
|
||||
vk::UniqueDeviceMemory mIndexBufferMemory;
|
||||
|
||||
std::vector<vk::UniqueBuffer> mUniformBuffers;
|
||||
std::vector<vk::UniqueDeviceMemory> mUniformBuffersMemory;
|
||||
std::vector<void*> mUniformBuffersMapped;
|
||||
|
||||
vk::UniqueDescriptorPool mDescriptorPool;
|
||||
std::vector<vk::DescriptorSet> mDescriptorSets;
|
||||
|
||||
std::vector<vk::UniqueCommandBuffer> mCommandBuffers;
|
||||
|
||||
std::vector<vk::UniqueSemaphore> mImageAvailableSemaphores;
|
||||
std::vector<vk::UniqueSemaphore> mRenderFinishedSemaphores;
|
||||
std::vector<vk::UniqueFence> mInFlightFences;
|
||||
|
||||
bool mFramebufferResized = false;
|
||||
u32 mCurrentFrame = 0;
|
||||
|
||||
|
@ -134,6 +136,12 @@ class VulkanApp {
|
|||
std::vector<vk::PresentModeKHR> present_modes;
|
||||
};
|
||||
|
||||
struct UniformBufferObject {
|
||||
alignas(16) glm::mat4 model;
|
||||
alignas(16) glm::mat4 view;
|
||||
alignas(16) glm::mat4 proj;
|
||||
};
|
||||
|
||||
static fn readFile(const std::string& filename) -> std::vector<char> {
|
||||
std::ifstream file(filename, std::ios::ate | std::ios::binary);
|
||||
|
||||
|
@ -178,11 +186,15 @@ class VulkanApp {
|
|||
createSwapChain();
|
||||
createImageViews();
|
||||
createRenderPass();
|
||||
createDescriptorSetLayout();
|
||||
createGraphicsPipeline();
|
||||
createFramebuffers();
|
||||
createCommandPool();
|
||||
createVertexBuffer();
|
||||
createIndexBuffer();
|
||||
createUniformBuffers();
|
||||
createDescriptorPool();
|
||||
createDescriptorSets();
|
||||
createCommandBuffers();
|
||||
createSyncObjects();
|
||||
}
|
||||
|
@ -445,6 +457,23 @@ class VulkanApp {
|
|||
mRenderPass = mDevice->createRenderPassUnique(renderPassInfo);
|
||||
}
|
||||
|
||||
fn createDescriptorSetLayout() -> void {
|
||||
vk::DescriptorSetLayoutBinding uboLayoutBinding {
|
||||
.binding = 0,
|
||||
.descriptorType = vk::DescriptorType::eUniformBuffer,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = vk::ShaderStageFlagBits::eVertex,
|
||||
.pImmutableSamplers = nullptr,
|
||||
};
|
||||
|
||||
vk::DescriptorSetLayoutCreateInfo layoutInfo {
|
||||
.bindingCount = 1,
|
||||
.pBindings = &uboLayoutBinding,
|
||||
};
|
||||
|
||||
mDescriptorSetLayout = mDevice->createDescriptorSetLayoutUnique(layoutInfo);
|
||||
}
|
||||
|
||||
fn createGraphicsPipeline() -> void {
|
||||
std::vector<char> vertShaderCode = readFile("src/shaders/vert.spv");
|
||||
std::vector<char> fragShaderCode = readFile("src/shaders/frag.spv");
|
||||
|
@ -493,7 +522,7 @@ class VulkanApp {
|
|||
.rasterizerDiscardEnable = vk::False,
|
||||
.polygonMode = vk::PolygonMode::eFill,
|
||||
.cullMode = vk::CullModeFlagBits::eBack,
|
||||
.frontFace = vk::FrontFace::eClockwise,
|
||||
.frontFace = vk::FrontFace::eCounterClockwise,
|
||||
.depthBiasEnable = vk::False,
|
||||
.lineWidth = 1.0F,
|
||||
};
|
||||
|
@ -516,6 +545,7 @@ class VulkanApp {
|
|||
.pAttachments = &colorBlendAttachment,
|
||||
.blendConstants = std::array<float, 4> { 0.0F, 0.0F, 0.0F, 0.0F },
|
||||
};
|
||||
|
||||
std::vector<vk::DynamicState> dynamicStates = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
||||
|
||||
vk::PipelineDynamicStateCreateInfo dynamicState {
|
||||
|
@ -524,8 +554,8 @@ class VulkanApp {
|
|||
};
|
||||
|
||||
vk::PipelineLayoutCreateInfo pipelineLayoutInfo {
|
||||
.setLayoutCount = 0,
|
||||
.pushConstantRangeCount = 0,
|
||||
.setLayoutCount = 1,
|
||||
.pSetLayouts = &mDescriptorSetLayout.get(),
|
||||
};
|
||||
|
||||
mPipelineLayout = mDevice->createPipelineLayoutUnique(pipelineLayoutInfo);
|
||||
|
@ -593,7 +623,7 @@ class VulkanApp {
|
|||
|
||||
createBuffer(
|
||||
bufferSize,
|
||||
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||
vk::BufferUsageFlagBits::eTransferSrc,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent,
|
||||
stagingBuffer,
|
||||
stagingBufferMemory
|
||||
|
@ -649,6 +679,72 @@ class VulkanApp {
|
|||
stagingBufferMemory.reset();
|
||||
}
|
||||
|
||||
fn createUniformBuffers() -> void {
|
||||
vk::DeviceSize bufferSize = sizeof(UniformBufferObject);
|
||||
|
||||
mUniformBuffers.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
mUniformBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
mUniformBuffersMapped.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
|
||||
for (usize i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
||||
createBuffer(
|
||||
bufferSize,
|
||||
vk::BufferUsageFlagBits::eUniformBuffer,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent,
|
||||
mUniformBuffers[i],
|
||||
mUniformBuffersMemory[i]
|
||||
);
|
||||
|
||||
mUniformBuffersMapped[i] = mDevice->mapMemory(mUniformBuffersMemory[i].get(), 0, bufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
fn createDescriptorPool() -> void {
|
||||
vk::DescriptorPoolSize poolSize {
|
||||
.type = vk::DescriptorType::eUniformBuffer,
|
||||
.descriptorCount = static_cast<u32>(MAX_FRAMES_IN_FLIGHT),
|
||||
};
|
||||
|
||||
vk::DescriptorPoolCreateInfo poolInfo {
|
||||
.maxSets = static_cast<u32>(MAX_FRAMES_IN_FLIGHT),
|
||||
.poolSizeCount = 1,
|
||||
.pPoolSizes = &poolSize,
|
||||
};
|
||||
|
||||
mDescriptorPool = mDevice->createDescriptorPoolUnique(poolInfo);
|
||||
}
|
||||
|
||||
fn createDescriptorSets() -> void {
|
||||
std::vector<vk::DescriptorSetLayout> layouts(MAX_FRAMES_IN_FLIGHT, mDescriptorSetLayout.get());
|
||||
|
||||
vk::DescriptorSetAllocateInfo allocInfo {
|
||||
.descriptorPool = mDescriptorPool.get(),
|
||||
.descriptorSetCount = static_cast<u32>(MAX_FRAMES_IN_FLIGHT),
|
||||
.pSetLayouts = layouts.data(),
|
||||
};
|
||||
|
||||
mDescriptorSets = mDevice->allocateDescriptorSets(allocInfo);
|
||||
|
||||
for (usize i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
||||
vk::DescriptorBufferInfo bufferInfo {
|
||||
.buffer = mUniformBuffers[i].get(),
|
||||
.offset = 0,
|
||||
.range = sizeof(UniformBufferObject),
|
||||
};
|
||||
|
||||
vk::WriteDescriptorSet descriptorWrite {
|
||||
.dstSet = mDescriptorSets[i],
|
||||
.dstBinding = 0,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = vk::DescriptorType::eUniformBuffer,
|
||||
.pBufferInfo = &bufferInfo,
|
||||
};
|
||||
|
||||
mDevice->updateDescriptorSets(1, &descriptorWrite, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
fn createBuffer(
|
||||
vk::DeviceSize deviceSize,
|
||||
vk::BufferUsageFlags bufferUsageFlags,
|
||||
|
@ -762,6 +858,16 @@ class VulkanApp {
|
|||
|
||||
commandBuffer.bindIndexBuffer(mIndexBuffer.get(), 0, vk::IndexType::eUint16);
|
||||
|
||||
commandBuffer.bindDescriptorSets(
|
||||
vk::PipelineBindPoint::eGraphics,
|
||||
mPipelineLayout.get(),
|
||||
0,
|
||||
1,
|
||||
&mDescriptorSets[mCurrentFrame],
|
||||
0,
|
||||
nullptr
|
||||
);
|
||||
|
||||
commandBuffer.drawIndexed(static_cast<u32>(indices.size()), 1, 0, 0, 0);
|
||||
|
||||
commandBuffer.endRenderPass();
|
||||
|
@ -784,6 +890,30 @@ class VulkanApp {
|
|||
}
|
||||
}
|
||||
|
||||
fn updateUniformBuffer(u32 currentImage) -> void {
|
||||
static auto StartTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
auto currentTime = std::chrono::high_resolution_clock::now();
|
||||
f32 time = std::chrono::duration<f32, std::chrono::seconds::period>(currentTime - StartTime).count();
|
||||
|
||||
UniformBufferObject ubo {
|
||||
.model = glm::rotate(glm::mat4(1.0F), time * glm::radians(90.0F), glm::vec3(0.0F, 0.0F, 1.0F)),
|
||||
.view =
|
||||
glm::lookAt(glm::vec3(2.0F, 2.0F, 2.0F), glm::vec3(0.0F, 0.0F, 0.0F), glm::vec3(0.0F, 0.0F, 1.0F)),
|
||||
.proj = glm::perspective(
|
||||
glm::radians(45.0F),
|
||||
static_cast<f32>(mSwapChainExtent.width) / static_cast<f32>(mSwapChainExtent.height),
|
||||
0.1F,
|
||||
10.0F
|
||||
)
|
||||
};
|
||||
|
||||
// Flip the Y axis, because glm was designed for OpenGL
|
||||
ubo.proj[1][1] *= -1;
|
||||
|
||||
memcpy(mUniformBuffersMapped[currentImage], &ubo, sizeof(ubo));
|
||||
}
|
||||
|
||||
fn drawFrame() -> void {
|
||||
try {
|
||||
vk::Result result =
|
||||
|
@ -807,6 +937,8 @@ class VulkanApp {
|
|||
if (imageIndexResult != vk::Result::eSuccess && imageIndexResult != vk::Result::eSuboptimalKHR)
|
||||
throw std::runtime_error("Failed to acquire swap chain image!");
|
||||
|
||||
updateUniformBuffer(mCurrentFrame);
|
||||
|
||||
mDevice->resetFences(mInFlightFences[mCurrentFrame].get());
|
||||
|
||||
mCommandBuffers[mCurrentFrame]->reset(vk::CommandBufferResetFlagBits::eReleaseResources);
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
#version 450
|
||||
|
||||
layout(binding = 0) uniform UniformBufferObject {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
} ubo;
|
||||
|
||||
layout(location = 0) in vec2 inPosition;
|
||||
layout(location = 1) in vec3 inColor;
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue