Skip to content

Commit

Permalink
now with vertex buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerboa-app committed Sep 7, 2023
1 parent 128504a commit 3fa8c3c
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 20 deletions.
55 changes: 55 additions & 0 deletions include/Renderer/vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>

#include <Renderer/renderer.h>
#include <Shader/shader.h>
Expand All @@ -16,6 +17,8 @@
#include <map>
#include <limits>
#include <algorithm>
#include <array>
#include <cstring>

const int MAX_CONCURRENT_FRAMES = 2;

Expand All @@ -35,6 +38,50 @@ const std::vector<const char *> deviceExtensions =
const bool enableValidationLayers = false;
#endif

struct Vertex
{
glm::vec2 pos;
glm::vec3 colour;

static VkVertexInputBindingDescription getBindingDescription()
{
VkVertexInputBindingDescription bindingDescription{};
bindingDescription.binding = 0;
bindingDescription.stride = sizeof(Vertex);
// can also be VK_VERTEX_INPUT_RATE_INSTANCE to move each instance
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
return bindingDescription;
}

static std::array<VkVertexInputAttributeDescription, 2> getArrtibuteDescriptions()
{
std::array<VkVertexInputAttributeDescription, 2> attributeDescriptions{};
// vertex binding, 0
attributeDescriptions[0].binding = 0;
// layout(location = 0)
attributeDescriptions[0].location = 0;
// we have a vec2, so R32, G32, as single float
attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
// auto calulate offset via macro
attributeDescriptions[0].offset = offsetof(Vertex, pos);

attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[1].offset = offsetof(Vertex, colour);

return attributeDescriptions;
}
};


const std::vector<Vertex> vertices =
{
{{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}}
};

namespace Renderer
{

Expand Down Expand Up @@ -89,6 +136,9 @@ namespace Renderer
VkPipelineLayout pipelineLayout;
VkPipeline pipeline;

VkBuffer vertexBuffer;
VkDeviceMemory vertexBufferMemory;

VkCommandPool commandPool;
std::vector<VkCommandBuffer> commandBuffers;

Expand Down Expand Up @@ -141,6 +191,8 @@ namespace Renderer

void createFramebuffers();

void createVertexBuffer();

void createCommandPool();
void createCommandBuffers();
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex);
Expand Down Expand Up @@ -212,6 +264,9 @@ namespace Renderer
}

void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT & createInfo);

uint32_t findMemoryType(uint32_t typeFiller, VkMemoryPropertyFlags properties);

};

}
Expand Down
19 changes: 4 additions & 15 deletions include/Shaders/trig.vert
Original file line number Diff line number Diff line change
@@ -1,23 +1,12 @@
#version 450

vec2 positions[3] = vec2[]
(
vec2(0.0, -0.5),
vec2(0.5, 0.5),
vec2(-0.5, 0.5)
);

vec3 colours[3] = vec3[]
(
vec3(1.0, 0.0, 0.0),
vec3(0.0, 1.0, 0.0),
vec3(0.0, 0.0, 1.0)
);
layout(location = 0) in vec2 a_position;
layout(location = 1) in vec3 a_colour;

layout(location = 0) out vec3 fragColour;

void main()
{
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
fragColour = colours[gl_VertexIndex];
gl_Position = vec4(a_position, 0.0, 1.0);
fragColour = a_colour;
}
2 changes: 2 additions & 0 deletions launch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cd build && ./HelloVK
cd ..
84 changes: 79 additions & 5 deletions src/Renderer/vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ namespace Renderer

createCommandPool();

createVertexBuffer();

createCommandBuffers();

createSyncObjects();
Expand All @@ -88,6 +90,10 @@ namespace Renderer
{
cleanupSwapChain();

vkDestroyBuffer(device, vertexBuffer, nullptr);

vkFreeMemory(device, vertexBufferMemory, nullptr);

vkDestroyPipeline(device, pipeline, nullptr);

vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
Expand Down Expand Up @@ -660,11 +666,15 @@ namespace Renderer
std::vector<VkPipelineShaderStageCreateInfo> shaderStages = trig.shaderStage();

VkPipelineVertexInputStateCreateInfo vertexInputInfo {};

auto bindingDescription = Vertex::getBindingDescription();
auto attributeDescriptions = Vertex::getArrtibuteDescriptions();

vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputInfo.vertexBindingDescriptionCount = 0;
vertexInputInfo.pVertexBindingDescriptions = nullptr;
vertexInputInfo.vertexAttributeDescriptionCount = 0;
vertexInputInfo.pVertexAttributeDescriptions = nullptr;
vertexInputInfo.vertexBindingDescriptionCount = 1;
vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
vertexInputInfo.vertexAttributeDescriptionCount = attributeDescriptions.size();
vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();

VkPipelineInputAssemblyStateCreateInfo inputAssembly {};
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
Expand Down Expand Up @@ -813,6 +823,48 @@ namespace Renderer
}
}

void VulkanRenderer::createVertexBuffer()
{
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = sizeof(vertices[0]) * vertices.size();
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

if (vkCreateBuffer(device, &bufferInfo, nullptr, &vertexBuffer) != VK_SUCCESS)
{
throw std::runtime_error("Failed to create vertex buffer");
}

VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, vertexBuffer, &memRequirements);

VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;

allocInfo.memoryTypeIndex = findMemoryType
(
memRequirements.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
);

if (vkAllocateMemory(device, &allocInfo, nullptr, &vertexBufferMemory) != VK_SUCCESS)
{
throw std::runtime_error("Failed to allocate vertex buffer memory");
}

// last is an offset in memory
vkBindBufferMemory(device, vertexBuffer, vertexBufferMemory, 0);

void * data;
vkMapMemory(device, vertexBufferMemory, 0, bufferInfo.size, 0, &data);
std::memcpy(data, vertices.data(), (size_t) bufferInfo.size);
vkUnmapMemory(device, vertexBufferMemory);

}

void VulkanRenderer::createCommandPool()
{
QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice);
Expand Down Expand Up @@ -882,9 +934,14 @@ namespace Renderer
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);

// bind vertex buffers
VkBuffer vertexBuffers[] = {vertexBuffer};
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);

// the draw command is issues
// vertexCount, instanceCount, firstVertex, firstInstance
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
vkCmdDraw(commandBuffer, vertices.size(), 1, 0, 0);

// end
vkCmdEndRenderPass(commandBuffer);
Expand Down Expand Up @@ -1026,4 +1083,21 @@ namespace Renderer
currentFrame = (currentFrame+1)%MAX_CONCURRENT_FRAMES;
}

uint32_t VulkanRenderer::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
{
VkPhysicalDeviceMemoryProperties memProperties;
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);

for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++)
{
if (typeFilter & (1 << i) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
{
return i;
}
}

throw std::runtime_error("Failed to find suitable memory type");
}


}

0 comments on commit 3fa8c3c

Please sign in to comment.