Vertex buffers.
This commit is contained in:
@@ -1,20 +1,11 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 inPosition;
|
||||||
|
layout(location = 1) in vec3 inColor;
|
||||||
|
|
||||||
layout(location = 0) out vec3 fragColor;
|
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() {
|
void main() {
|
||||||
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
gl_Position = vec4(inPosition, 0.0, 1.0);
|
||||||
fragColor = colors[gl_VertexIndex];
|
fragColor = inColor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,39 @@ PFN_vkCreateDebugUtilsMessengerEXT vkeCreateDebugUtilsMessengerEXT = nullptr;
|
|||||||
PFN_vkDestroyDebugUtilsMessengerEXT vkeDestroyDebugUtilsMessengerEXT = 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() {
|
VulkanTutorial::VulkanTutorial() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,6 +69,7 @@ void VulkanTutorial::initialize(SDL_Window* window) {
|
|||||||
create_graphic_pipeline();
|
create_graphic_pipeline();
|
||||||
create_framebuffers();
|
create_framebuffers();
|
||||||
create_command_pool();
|
create_command_pool();
|
||||||
|
create_vertex_buffer();
|
||||||
create_command_buffers();
|
create_command_buffers();
|
||||||
create_sync_objects();
|
create_sync_objects();
|
||||||
}
|
}
|
||||||
@@ -64,6 +98,16 @@ void VulkanTutorial::shutdown() {
|
|||||||
m_command_pool = VK_NULL_HANDLE;
|
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();
|
cleanup_swap_chain();
|
||||||
|
|
||||||
if(m_device) {
|
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 {
|
VkPipelineVertexInputStateCreateInfo vertex_info {
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||||
.vertexBindingDescriptionCount = 0,
|
.vertexBindingDescriptionCount = 1,
|
||||||
.pVertexBindingDescriptions = nullptr,
|
.pVertexBindingDescriptions = vertex_bindings,
|
||||||
.vertexAttributeDescriptionCount = 0,
|
.vertexAttributeDescriptionCount = uint32_t(vertex_attributes.size()),
|
||||||
.pVertexAttributeDescriptions = nullptr,
|
.pVertexAttributeDescriptions = vertex_attributes.data(),
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPipelineInputAssemblyStateCreateInfo assembly_info {
|
VkPipelineInputAssemblyStateCreateInfo assembly_info {
|
||||||
@@ -748,6 +797,42 @@ void VulkanTutorial::create_command_pool() {
|
|||||||
throw std::runtime_error("failed to 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() {
|
void VulkanTutorial::create_command_buffers() {
|
||||||
m_command_buffers.resize(m_framebuffers.size());
|
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);
|
vkCmdBeginRenderPass(command_buffer, &pass_info, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline);
|
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);
|
vkCmdEndRenderPass(command_buffer);
|
||||||
|
|
||||||
if(vkEndCommandBuffer(command_buffer) != VK_SUCCESS)
|
if(vkEndCommandBuffer(command_buffer) != VK_SUCCESS)
|
||||||
@@ -902,6 +998,19 @@ VkShaderModule VulkanTutorial::create_shader_module_from_file(const char* path)
|
|||||||
return VK_NULL_HANDLE;
|
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 {
|
std::vector<VkPhysicalDevice> VulkanTutorial::get_physical_devices() const {
|
||||||
uint32_t devices_count = 0;
|
uint32_t devices_count = 0;
|
||||||
vkEnumeratePhysicalDevices(m_instance, &devices_count, nullptr);
|
vkEnumeratePhysicalDevices(m_instance, &devices_count, nullptr);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
#include <Eigen/Dense>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
@@ -15,6 +16,15 @@ extern PFN_vkCreateDebugUtilsMessengerEXT vkeCreateDebugUtilsMessengerEXT;
|
|||||||
extern PFN_vkDestroyDebugUtilsMessengerEXT vkeDestroyDebugUtilsMessengerEXT;
|
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 {
|
class VulkanTutorial {
|
||||||
public:
|
public:
|
||||||
VulkanTutorial();
|
VulkanTutorial();
|
||||||
@@ -49,6 +59,7 @@ private:
|
|||||||
void create_graphic_pipeline();
|
void create_graphic_pipeline();
|
||||||
void create_framebuffers();
|
void create_framebuffers();
|
||||||
void create_command_pool();
|
void create_command_pool();
|
||||||
|
void create_vertex_buffer();
|
||||||
void create_command_buffers();
|
void create_command_buffers();
|
||||||
void create_sync_objects();
|
void create_sync_objects();
|
||||||
|
|
||||||
@@ -58,6 +69,8 @@ private:
|
|||||||
VkShaderModule create_shader_module(const std::vector<char> bytecode);
|
VkShaderModule create_shader_module(const std::vector<char> bytecode);
|
||||||
VkShaderModule create_shader_module_from_file(const char* path);
|
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<VkPhysicalDevice> get_physical_devices() const;
|
||||||
std::vector<VkQueueFamilyProperties> get_queue_families(VkPhysicalDevice physical_device) const;
|
std::vector<VkQueueFamilyProperties> get_queue_families(VkPhysicalDevice physical_device) const;
|
||||||
std::vector<VkExtensionProperties> get_device_extensions(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;
|
VkPipeline m_pipeline = VK_NULL_HANDLE;
|
||||||
std::vector<VkFramebuffer> m_framebuffers;
|
std::vector<VkFramebuffer> m_framebuffers;
|
||||||
VkCommandPool m_command_pool = VK_NULL_HANDLE;
|
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<VkCommandBuffer> m_command_buffers;
|
||||||
std::vector<VkSemaphore> m_image_available_semaphores;
|
std::vector<VkSemaphore> m_image_available_semaphores;
|
||||||
std::vector<VkSemaphore> m_render_finished_semaphores;
|
std::vector<VkSemaphore> m_render_finished_semaphores;
|
||||||
|
|||||||
Reference in New Issue
Block a user