From 31b93deecb3363ead4fbf43a5b123a059c53f33a Mon Sep 17 00:00:00 2001 From: Mars Date: Wed, 9 Oct 2024 23:00:45 -0400 Subject: [PATCH] Vertex buffer input description & creation --- .clang-tidy | 1 + src/main.cpp | 95 +++++++++++++++++++++++++++++++++++++--- src/shaders/shader.vert | 19 +++----- src/shaders/vert.spv | Bin 1504 -> 1080 bytes 4 files changed, 95 insertions(+), 20 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 7005ab5..1346ff1 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -7,6 +7,7 @@ Checks: > -bugprone-implicit-widening-of-multiplication-result, -cert-env33-c, -concurrency-mt-unsafe, + -cppcoreguidelines-avoid-const-or-ref-data-members, -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-owning-memory, -cppcoreguidelines-pro-type-member-init, diff --git a/src/main.cpp b/src/main.cpp index 6e6249c..737acfb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -76,9 +77,45 @@ class VulkanApp { std::vector mRenderFinishedSemaphores; std::vector mInFlightFences; + vk::UniqueBuffer mVertexBuffer; + vk::UniqueDeviceMemory mVertexBufferMemory; + bool mFramebufferResized = false; u32 mCurrentFrame = 0; + 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 { + std::array 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; + } + }; + + const std::vector mVertices = { + { { 0.0F, -0.5F }, { 1.0F, 1.0F, 1.0F } }, + { { 0.5F, 0.5F }, { 0.0F, 1.0F, 0.0F } }, + { { -0.5F, 0.5F }, { 0.0F, 0.0F, 1.0F } } + }; + struct QueueFamilyIndices { std::optional graphics_family; std::optional present_family; @@ -115,7 +152,6 @@ class VulkanApp { vkfw::WindowHints hints; hints.clientAPI = vkfw::ClientAPI::eNone; - // hints.resizable = false; mWindow = vkfw::createWindowUnique(WIDTH, HEIGHT, "Vulkan", hints); mWindow->setUserPointer(this); @@ -140,6 +176,7 @@ class VulkanApp { createGraphicsPipeline(); createFramebuffers(); createCommandPool(); + createVertexBuffer(); createCommandBuffers(); createSyncObjects(); } @@ -422,11 +459,15 @@ class VulkanApp { std::array shaderStages = { vertShaderStageInfo, fragShaderStageInfo }; + vk::VertexInputBindingDescription bindingDescription = Vertex::getBindingDescription(); + std::array attributeDescriptions = + Vertex::getAttributeDescriptions(); + vk::PipelineVertexInputStateCreateInfo vertexInputInfo { - .vertexBindingDescriptionCount = 0, - .pVertexBindingDescriptions = nullptr, - .vertexAttributeDescriptionCount = 0, - .pVertexAttributeDescriptions = nullptr, + .vertexBindingDescriptionCount = 1, + .pVertexBindingDescriptions = &bindingDescription, + .vertexAttributeDescriptionCount = static_cast(attributeDescriptions.size()), + .pVertexAttributeDescriptions = attributeDescriptions.data(), }; vk::PipelineInputAssemblyStateCreateInfo inputAssembly { @@ -536,6 +577,45 @@ class VulkanApp { mCommandPool = mDevice->createCommandPoolUnique(poolInfo); } + fn createVertexBuffer() -> void { + vk::BufferCreateInfo bufferInfo { + .size = sizeof(mVertices[0]) * mVertices.size(), + .usage = vk::BufferUsageFlagBits::eVertexBuffer, + .sharingMode = vk::SharingMode::eExclusive, + }; + + mVertexBuffer = mDevice->createBufferUnique(bufferInfo, nullptr); + + vk::MemoryRequirements memRequirements = mDevice->getBufferMemoryRequirements(mVertexBuffer.get()); + + vk::MemoryAllocateInfo allocInfo { + .allocationSize = memRequirements.size, + .memoryTypeIndex = findMemoryType( + memRequirements.memoryTypeBits, + vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent + ), + }; + + mVertexBufferMemory = mDevice->allocateMemoryUnique(allocInfo); + + mDevice->bindBufferMemory(mVertexBuffer.get(), mVertexBufferMemory.get(), 0); + + void* data = mDevice->mapMemory(mVertexBufferMemory.get(), 0, bufferInfo.size); + memcpy(data, mVertices.data(), static_cast(bufferInfo.size)); + mDevice->unmapMemory(mVertexBufferMemory.get()); + } + + fn findMemoryType(u32 typeFilter, vk::MemoryPropertyFlags properties) -> u32 { + vk::PhysicalDeviceMemoryProperties memProperties = mPhysicalDevice.getMemoryProperties(); + + for (u32 i = 0; i < memProperties.memoryTypeCount; i++) + if ((typeFilter & (1 << i)) && + (memProperties.memoryTypes.at(i).propertyFlags & properties) == properties) + return i; + + throw std::runtime_error("Failed to find a suitable memory type!"); + } + fn createCommandBuffers() -> void { mCommandBuffers.resize(MAX_FRAMES_IN_FLIGHT); @@ -573,6 +653,7 @@ class VulkanApp { .minDepth = 0.0F, .maxDepth = 1.0F, }; + vk::Rect2D scissor { .offset = { 0, 0 }, .extent = mSwapChainExtent, @@ -581,7 +662,9 @@ class VulkanApp { commandBuffer.setViewport(0, viewport); commandBuffer.setScissor(0, scissor); - commandBuffer.draw(3, 1, 0, 0); + commandBuffer.bindVertexBuffers(0, mVertexBuffer.get(), { 0 }); + + commandBuffer.draw(static_cast(mVertices.size()), 1, 0, 0); commandBuffer.endRenderPass(); diff --git a/src/shaders/shader.vert b/src/shaders/shader.vert index f5b2f8d..9f27f54 100644 --- a/src/shaders/shader.vert +++ b/src/shaders/shader.vert @@ -1,20 +1,11 @@ #version 450 +layout(location = 0) in vec2 inPosition; +layout(location = 1) in vec3 inColor; + layout(location = 0) out vec3 fragColor; -vec2 positions[3] = vec2[]( - vec2(0.0, -0.5), - vec2(0.5, 0.5), - vec2(-0.5, 0.5) -); - -vec3 colors[3] = vec3[]( - vec3(1.0, 0.0, 0.0), - vec3(0.0, 1.0, 0.0), - vec3(0.0, 0.0, 1.0) -); - void main() { - gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); - fragColor = colors[gl_VertexIndex]; + gl_Position = vec4(inPosition, 0.0, 1.0); + fragColor = inColor; } diff --git a/src/shaders/vert.spv b/src/shaders/vert.spv index a41dd2cd675e3469d59dc6e98d84c97a7d2d2693..1e4ce0c041e7ee15f8cf030b9c3e352942361e75 100644 GIT binary patch literal 1080 zcmYk4Uuzmc6vZd%Mx)Wx7-O5JsUeSr(1)fJN*h8_whw}qKwlTpZ5Y_BvTjP-r+l`2 zs=gF@ezQB`$o1ZP?!Pm4wpux>8?$9vrfp75ak{1=#0cAVIvm}O&R6;T{N2S{GCHQ} z63N*!JI=1@|9)yyoVH|N@=EerQq`{_{iK4LX_{~ph2wEJ`V!5S%V?GVPU0xBX&lXM z7SD3~GbXRGk!RCc@-W{_2$ZooGZ5F7X51ywB+kCaSswqAE409|i7i$(w~JJ0-Q{x! zhubv2wSP33nj!{g#jX>(ys@i%n$F^Nj13TbNRo9d&^@_3C(w@_*mOP8VeI5bHod!E zB#X@D)!dG3S|DGQ#XUG)d#rd9UdtGd!I3=pcnlki{e+5OlNSns(}{$G51&n+_rhmJ zPgT^Nss}x>4`ppj4*H}gv-Rwj>{|hG6#Q8!hzQ_Y39J0eqCuefYT43U4T(f?tz5k{l4=aFR6bao7r%s z|4V6Vz=$80HaPw9*{zTJo%%RFyJr4-y*WJDA%~j3LIUYeLgCz#!1tR_<{p-q)EXO< u7(FLq3fJcna*1(2?sTOd+~-KbPTAXMO~oglneZG+;7E+S;Qtfj50d|?qgO8g literal 1504 zcmYk5ZBNud6oqGZ>4G32BH#;R0mT<^MFnDF)EG3?WD_tXer-10N+zk@OW-Q!$6U%CCwBbK=EWe5;z^DZB6pD_lbols z;A~j*!x>3aHS;kY(h;+8ZeOy&`7ymK{vghmXU$b^!qFcb-s$KIjvgFG49B?z%J}l= z0x|SK?oo}|e?!JvmI~dbYWN26s-mvEFI!W+9#DzNtqAiXd>L!E#+MXRzb-s0PYs+e z%-(zt{$-81PdMuF^D>sh3l;pmr?cT(i!wCuPIE=E)*Gi;5`e=TcU3Vp71u3$SQh4c z=*ctVHF^4QGps0vb2F^gd3a_3^ZuGMTo*Rxm-^|JwKs&|=o@qV%^JI$<8L*zhH;ugQp(6Q*-1WD5ekY5ZsgJ+w=n7uQ6v$J(%~2hWvAR>d7DJE${}JnT6)B z7*GDS5O0dRCFX88w^vfr+kF{*y_K4t9?H(LSvj4QYY=-~<