idk why this isnt working rn but whatever

This commit is contained in:
Mars 2024-10-10 20:39:04 -04:00
parent 1732d56e22
commit f0e85c0d88
Signed by untrusted user: pupbrained
GPG key ID: 874E22DF2F9DFCB5
3 changed files with 188 additions and 50 deletions

View file

@ -1,9 +1,13 @@
#include <chrono>
#include <fmt/format.h> #include <fmt/format.h>
#include <fstream> #include <fstream>
#include <glm/glm.hpp>
#include <iostream> #include <iostream>
#include <set> #include <set>
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
#define VK_ENABLE_BETA_EXTENSIONS #define VK_ENABLE_BETA_EXTENSIONS
#define VULKAN_HPP_NO_CONSTRUCTORS #define VULKAN_HPP_NO_CONSTRUCTORS
@ -21,42 +25,6 @@ constexpr i32 HEIGHT = 600;
constexpr i32 MAX_FRAMES_IN_FLIGHT = 2; 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" }; constexpr std::array<const char*, 1> validationLayers = { "VK_LAYER_KHRONOS_validation" };
#ifdef __APPLE__ #ifdef __APPLE__
@ -72,6 +40,31 @@ constexpr bool enableValidationLayers = false;
constexpr bool enableValidationLayers = true; constexpr bool enableValidationLayers = true;
#endif #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 { class VulkanApp {
public: public:
fn run() -> void { fn run() -> void {
@ -103,21 +96,30 @@ class VulkanApp {
std::vector<vk::UniqueFramebuffer> mSwapChainFramebuffers; std::vector<vk::UniqueFramebuffer> mSwapChainFramebuffers;
vk::UniqueRenderPass mRenderPass; vk::UniqueRenderPass mRenderPass;
vk::UniqueDescriptorSetLayout mDescriptorSetLayout;
vk::UniquePipelineLayout mPipelineLayout; vk::UniquePipelineLayout mPipelineLayout;
vk::UniquePipeline mGraphicsPipeline; vk::UniquePipeline mGraphicsPipeline;
vk::UniqueCommandPool mCommandPool; vk::UniqueCommandPool mCommandPool;
std::vector<vk::UniqueCommandBuffer> mCommandBuffers;
std::vector<vk::UniqueSemaphore> mImageAvailableSemaphores;
std::vector<vk::UniqueSemaphore> mRenderFinishedSemaphores;
std::vector<vk::UniqueFence> mInFlightFences;
vk::UniqueBuffer mVertexBuffer; vk::UniqueBuffer mVertexBuffer;
vk::UniqueDeviceMemory mVertexBufferMemory; vk::UniqueDeviceMemory mVertexBufferMemory;
vk::UniqueBuffer mIndexBuffer; vk::UniqueBuffer mIndexBuffer;
vk::UniqueDeviceMemory mIndexBufferMemory; 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; bool mFramebufferResized = false;
u32 mCurrentFrame = 0; u32 mCurrentFrame = 0;
@ -134,6 +136,12 @@ class VulkanApp {
std::vector<vk::PresentModeKHR> present_modes; 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> { static fn readFile(const std::string& filename) -> std::vector<char> {
std::ifstream file(filename, std::ios::ate | std::ios::binary); std::ifstream file(filename, std::ios::ate | std::ios::binary);
@ -178,11 +186,15 @@ class VulkanApp {
createSwapChain(); createSwapChain();
createImageViews(); createImageViews();
createRenderPass(); createRenderPass();
createDescriptorSetLayout();
createGraphicsPipeline(); createGraphicsPipeline();
createFramebuffers(); createFramebuffers();
createCommandPool(); createCommandPool();
createVertexBuffer(); createVertexBuffer();
createIndexBuffer(); createIndexBuffer();
createUniformBuffers();
createDescriptorPool();
createDescriptorSets();
createCommandBuffers(); createCommandBuffers();
createSyncObjects(); createSyncObjects();
} }
@ -445,6 +457,23 @@ class VulkanApp {
mRenderPass = mDevice->createRenderPassUnique(renderPassInfo); 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 { fn createGraphicsPipeline() -> void {
std::vector<char> vertShaderCode = readFile("src/shaders/vert.spv"); std::vector<char> vertShaderCode = readFile("src/shaders/vert.spv");
std::vector<char> fragShaderCode = readFile("src/shaders/frag.spv"); std::vector<char> fragShaderCode = readFile("src/shaders/frag.spv");
@ -493,7 +522,7 @@ class VulkanApp {
.rasterizerDiscardEnable = vk::False, .rasterizerDiscardEnable = vk::False,
.polygonMode = vk::PolygonMode::eFill, .polygonMode = vk::PolygonMode::eFill,
.cullMode = vk::CullModeFlagBits::eBack, .cullMode = vk::CullModeFlagBits::eBack,
.frontFace = vk::FrontFace::eClockwise, .frontFace = vk::FrontFace::eCounterClockwise,
.depthBiasEnable = vk::False, .depthBiasEnable = vk::False,
.lineWidth = 1.0F, .lineWidth = 1.0F,
}; };
@ -516,6 +545,7 @@ class VulkanApp {
.pAttachments = &colorBlendAttachment, .pAttachments = &colorBlendAttachment,
.blendConstants = std::array<float, 4> { 0.0F, 0.0F, 0.0F, 0.0F }, .blendConstants = std::array<float, 4> { 0.0F, 0.0F, 0.0F, 0.0F },
}; };
std::vector<vk::DynamicState> dynamicStates = { vk::DynamicState::eViewport, vk::DynamicState::eScissor }; std::vector<vk::DynamicState> dynamicStates = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
vk::PipelineDynamicStateCreateInfo dynamicState { vk::PipelineDynamicStateCreateInfo dynamicState {
@ -524,8 +554,8 @@ class VulkanApp {
}; };
vk::PipelineLayoutCreateInfo pipelineLayoutInfo { vk::PipelineLayoutCreateInfo pipelineLayoutInfo {
.setLayoutCount = 0, .setLayoutCount = 1,
.pushConstantRangeCount = 0, .pSetLayouts = &mDescriptorSetLayout.get(),
}; };
mPipelineLayout = mDevice->createPipelineLayoutUnique(pipelineLayoutInfo); mPipelineLayout = mDevice->createPipelineLayoutUnique(pipelineLayoutInfo);
@ -593,7 +623,7 @@ class VulkanApp {
createBuffer( createBuffer(
bufferSize, bufferSize,
vk::BufferUsageFlagBits::eVertexBuffer, vk::BufferUsageFlagBits::eTransferSrc,
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent,
stagingBuffer, stagingBuffer,
stagingBufferMemory stagingBufferMemory
@ -649,6 +679,72 @@ class VulkanApp {
stagingBufferMemory.reset(); 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( fn createBuffer(
vk::DeviceSize deviceSize, vk::DeviceSize deviceSize,
vk::BufferUsageFlags bufferUsageFlags, vk::BufferUsageFlags bufferUsageFlags,
@ -762,6 +858,16 @@ class VulkanApp {
commandBuffer.bindIndexBuffer(mIndexBuffer.get(), 0, vk::IndexType::eUint16); 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.drawIndexed(static_cast<u32>(indices.size()), 1, 0, 0, 0);
commandBuffer.endRenderPass(); 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 { fn drawFrame() -> void {
try { try {
vk::Result result = vk::Result result =
@ -807,6 +937,8 @@ class VulkanApp {
if (imageIndexResult != vk::Result::eSuccess && imageIndexResult != vk::Result::eSuboptimalKHR) if (imageIndexResult != vk::Result::eSuccess && imageIndexResult != vk::Result::eSuboptimalKHR)
throw std::runtime_error("Failed to acquire swap chain image!"); throw std::runtime_error("Failed to acquire swap chain image!");
updateUniformBuffer(mCurrentFrame);
mDevice->resetFences(mInFlightFences[mCurrentFrame].get()); mDevice->resetFences(mInFlightFences[mCurrentFrame].get());
mCommandBuffers[mCurrentFrame]->reset(vk::CommandBufferResetFlagBits::eReleaseResources); mCommandBuffers[mCurrentFrame]->reset(vk::CommandBufferResetFlagBits::eReleaseResources);

View file

@ -1,5 +1,11 @@
#version 450 #version 450
layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 view;
mat4 proj;
} ubo;
layout(location = 0) in vec2 inPosition; layout(location = 0) in vec2 inPosition;
layout(location = 1) in vec3 inColor; layout(location = 1) in vec3 inColor;

Binary file not shown.