Browse Source

Vertex buffers.

master
Draklaw 4 years ago
parent
commit
684de6c57b
  1. 19
      shaders/shader.vert
  2. 119
      src/VulkanTutorial.cpp
  3. 15
      src/VulkanTutorial.h

19
shaders/shader.vert

@ -1,20 +1,11 @@
#version 450
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)
);
layout(location = 0) in vec2 inPosition;
layout(location = 1) in vec3 inColor;
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)
);
layout(location = 0) out vec3 fragColor;
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;
}

119
src/VulkanTutorial.cpp

@ -17,6 +17,39 @@ PFN_vkCreateDebugUtilsMessengerEXT vkeCreateDebugUtilsMessengerEXT = nullptr;
PFN_vkDestroyDebugUtilsMessengerEXT vkeDestroyDebugUtilsMessengerEXT = nullptr;
VkVertexInputBindingDescription Vertex::binding_description() {
return {
.binding = 0,
.stride = sizeof(Vertex),
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
};
}
std::array<VkVertexInputAttributeDescription, 2> Vertex::attributes_description() {
return {
VkVertexInputAttributeDescription {
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = offsetof(Vertex, position),
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(Vertex, color),
},
};
}
const std::vector<Vertex> vertices = {
{{0.0f, -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}}
};
VulkanTutorial::VulkanTutorial() {
}
@ -36,6 +69,7 @@ void VulkanTutorial::initialize(SDL_Window* window) {
create_graphic_pipeline();
create_framebuffers();
create_command_pool();
create_vertex_buffer();
create_command_buffers();
create_sync_objects();
}
@ -64,6 +98,16 @@ void VulkanTutorial::shutdown() {
m_command_pool = VK_NULL_HANDLE;
}
if(m_vertex_buffer != VK_NULL_HANDLE) {
vkDestroyBuffer(m_device, m_vertex_buffer, nullptr);
m_vertex_buffer = VK_NULL_HANDLE;
}
if(m_vertex_buffer_memory != VK_NULL_HANDLE) {
vkFreeMemory(m_device, m_vertex_buffer_memory, nullptr);
m_vertex_buffer_memory = VK_NULL_HANDLE;
}
cleanup_swap_chain();
if(m_device) {
@ -600,12 +644,17 @@ void VulkanTutorial::create_graphic_pipeline() {
},
};
const VkVertexInputBindingDescription vertex_bindings[] = {
Vertex::binding_description(),
};
const auto vertex_attributes = Vertex::attributes_description();
VkPipelineVertexInputStateCreateInfo vertex_info {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = 0,
.pVertexBindingDescriptions = nullptr,
.vertexAttributeDescriptionCount = 0,
.pVertexAttributeDescriptions = nullptr,
.vertexBindingDescriptionCount = 1,
.pVertexBindingDescriptions = vertex_bindings,
.vertexAttributeDescriptionCount = uint32_t(vertex_attributes.size()),
.pVertexAttributeDescriptions = vertex_attributes.data(),
};
VkPipelineInputAssemblyStateCreateInfo assembly_info {
@ -748,6 +797,42 @@ void VulkanTutorial::create_command_pool() {
throw std::runtime_error("failed to create command pool");
}
void VulkanTutorial::create_vertex_buffer() {
VkBufferCreateInfo buffer_info {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = sizeof(vertices[0]) * vertices.size(),
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
if(vkCreateBuffer(m_device, &buffer_info, nullptr, &m_vertex_buffer) != VK_SUCCESS)
throw std::runtime_error("failed to create vertex buffer");
VkMemoryRequirements memory_requirements;
vkGetBufferMemoryRequirements(m_device, m_vertex_buffer, &memory_requirements);
const auto memory_type = find_memory(memory_requirements.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
if(memory_type < 0)
throw std::runtime_error("failed to find suitable memory type for vertex buffer");
VkMemoryAllocateInfo alloc_info {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = memory_requirements.size,
.memoryTypeIndex = uint32_t(memory_type),
};
if(vkAllocateMemory(m_device, &alloc_info, nullptr, &m_vertex_buffer_memory) != VK_SUCCESS)
throw std::runtime_error("failed to allocate vertex buffer memory");
vkBindBufferMemory(m_device, m_vertex_buffer, m_vertex_buffer_memory, 0);
void* buffer = nullptr;
vkMapMemory(m_device, m_vertex_buffer_memory, 0, buffer_info.size, 0, &buffer);
memcpy(buffer, vertices.data(), size_t(buffer_info.size));
vkUnmapMemory(m_device, m_vertex_buffer_memory);
}
void VulkanTutorial::create_command_buffers() {
m_command_buffers.resize(m_framebuffers.size());
@ -794,8 +879,19 @@ void VulkanTutorial::create_command_buffers() {
};
vkCmdBeginRenderPass(command_buffer, &pass_info, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline);
vkCmdDraw(command_buffer, 3, 1, 0, 0);
VkBuffer vertex_buffers[] = {
m_vertex_buffer,
};
VkDeviceSize offsets[] = {
0,
};
vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offsets);
vkCmdDraw(command_buffer, uint32_t(vertices.size()), 1, 0, 0);
vkCmdEndRenderPass(command_buffer);
if(vkEndCommandBuffer(command_buffer) != VK_SUCCESS)
@ -902,6 +998,19 @@ VkShaderModule VulkanTutorial::create_shader_module_from_file(const char* path)
return VK_NULL_HANDLE;
}
int32_t VulkanTutorial::find_memory(uint32_t type_filter, VkMemoryPropertyFlags properties) {
VkPhysicalDeviceMemoryProperties memory_properties;
vkGetPhysicalDeviceMemoryProperties(m_physical_device, &memory_properties);
for(uint32_t type_index = 0; type_index < memory_properties.memoryTypeCount; type_index += 1) {
if(((1 << type_index) & type_filter) &&
(memory_properties.memoryTypes[type_index].propertyFlags & properties) == properties)
return type_index;
}
return -1;
}
std::vector<VkPhysicalDevice> VulkanTutorial::get_physical_devices() const {
uint32_t devices_count = 0;
vkEnumeratePhysicalDevices(m_instance, &devices_count, nullptr);

15
src/VulkanTutorial.h

@ -2,6 +2,7 @@
#include <SDL2/SDL.h>
#include <vulkan/vulkan.h>
#include <Eigen/Dense>
#include <vector>
@ -15,6 +16,15 @@ extern PFN_vkCreateDebugUtilsMessengerEXT vkeCreateDebugUtilsMessengerEXT;
extern PFN_vkDestroyDebugUtilsMessengerEXT vkeDestroyDebugUtilsMessengerEXT;
struct Vertex {
Eigen::Vector2f position;
Eigen::Vector3f color;
static VkVertexInputBindingDescription binding_description();
static std::array<VkVertexInputAttributeDescription, 2> attributes_description();
};
class VulkanTutorial {
public:
VulkanTutorial();
@ -49,6 +59,7 @@ private:
void create_graphic_pipeline();
void create_framebuffers();
void create_command_pool();
void create_vertex_buffer();
void create_command_buffers();
void create_sync_objects();
@ -58,6 +69,8 @@ private:
VkShaderModule create_shader_module(const std::vector<char> bytecode);
VkShaderModule create_shader_module_from_file(const char* path);
int32_t find_memory(uint32_t type_filter, VkMemoryPropertyFlags properties);
std::vector<VkPhysicalDevice> get_physical_devices() const;
std::vector<VkQueueFamilyProperties> get_queue_families(VkPhysicalDevice physical_device) const;
std::vector<VkExtensionProperties> get_device_extensions(VkPhysicalDevice physical_device) const;
@ -84,6 +97,8 @@ private:
VkPipeline m_pipeline = VK_NULL_HANDLE;
std::vector<VkFramebuffer> m_framebuffers;
VkCommandPool m_command_pool = VK_NULL_HANDLE;
VkBuffer m_vertex_buffer = VK_NULL_HANDLE;
VkDeviceMemory m_vertex_buffer_memory = VK_NULL_HANDLE;
std::vector<VkCommandBuffer> m_command_buffers;
std::vector<VkSemaphore> m_image_available_semaphores;
std::vector<VkSemaphore> m_render_finished_semaphores;

Loading…
Cancel
Save