diff --git a/Core/Core/RenderEngine.cpp b/Core/Core/RenderEngine.cpp index b31458d..0043dd4 100644 --- a/Core/Core/RenderEngine.cpp +++ b/Core/Core/RenderEngine.cpp @@ -73,6 +73,30 @@ bool RenderEngine::QueueFamilyIndices::is_complete() return graphycs_family.has_value() && present_family.has_value(); } +VkVertexInputBindingDescription RenderEngine::Vertex::get_binding_description() +{ + VkVertexInputBindingDescription description{}; + description.binding = 0; + description.stride = sizeof(Vertex); + description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + return description; +} + +std::array RenderEngine::Vertex::get_vertex_attribute_descriptions() +{ + std::array descriptions; + descriptions[0].binding = 0; + descriptions[0].location = 0; + descriptions[0].format = VK_FORMAT_R32G32_SFLOAT; + descriptions[0].offset = offsetof(Vertex, pos); + descriptions[1].binding = 0; + descriptions[1].location = 1; + descriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT; + descriptions[1].offset = offsetof(Vertex, color); + + return descriptions; +} + bool RenderEngine::is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR surface) { VkPhysicalDeviceProperties device_properties; @@ -446,12 +470,15 @@ void RenderEngine::create_graphics_pipeline() dynamic_state_info.dynamicStateCount = static_cast(dynamic_states.size()); dynamic_state_info.pDynamicStates = dynamic_states.data(); + VkVertexInputBindingDescription binding_description = Vertex::get_binding_description(); + std::array attribute_descriptions = Vertex::get_vertex_attribute_descriptions(); + VkPipelineVertexInputStateCreateInfo vertex_input_info{}; vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertex_input_info.vertexAttributeDescriptionCount = 0; - vertex_input_info.pVertexAttributeDescriptions = nullptr; - vertex_input_info.vertexBindingDescriptionCount = 0; - vertex_input_info.pVertexBindingDescriptions = nullptr; + vertex_input_info.vertexBindingDescriptionCount = 1; + vertex_input_info.pVertexBindingDescriptions = &binding_description; + vertex_input_info.vertexAttributeDescriptionCount = static_cast(attribute_descriptions.size()); + vertex_input_info.pVertexAttributeDescriptions = attribute_descriptions.data(); VkPipelineInputAssemblyStateCreateInfo input_assembly_info{}; input_assembly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; @@ -535,7 +562,7 @@ void RenderEngine::create_graphics_pipeline() graphics_pipeline_info.basePipelineHandle = nullptr; graphics_pipeline_info.basePipelineIndex = -1; - VK_CHECK(vkCreateGraphicsPipelines(device_, nullptr, 1, &graphics_pipeline_info, nullptr, &graphycs_pipeline_)); + VK_CHECK(vkCreateGraphicsPipelines(device_, nullptr, 1, &graphics_pipeline_info, nullptr, &graphics_pipeline_)); vkDestroyShaderModule(device_, vertex_shader, nullptr); vkDestroyShaderModule(device_, fragment_shader, nullptr); @@ -572,6 +599,47 @@ void RenderEngine::create_command_pool() VK_CHECK(vkCreateCommandPool(device_, &command_pool_info, nullptr, &command_pool_)); } +uint32_t RenderEngine::find_memory_type(uint32_t typeFilter, VkMemoryPropertyFlags properties) +{ + VkPhysicalDeviceMemoryProperties memory_properties{}; + vkGetPhysicalDeviceMemoryProperties(physical_device_, &memory_properties); + + for (uint32_t i = 0; i < memory_properties.memoryTypeCount; ++i) + { + if (typeFilter & (1 << i) && (memory_properties.memoryTypes[i].propertyFlags & properties) == properties) + return i; + } + + throw std::runtime_error("failed to find suitable memory type!"); +} + +void RenderEngine::allocate_vertex_buffer() +{ + VkBufferCreateInfo buffer_info{}; + buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_info.size = sizeof(vertices[0]) * vertices.size(); + buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + VK_CHECK(vkCreateBuffer(device_, &buffer_info, nullptr, &vertex_buffer_)); + + VkMemoryRequirements requirements{}; + vkGetBufferMemoryRequirements(device_, vertex_buffer_, &requirements); + + VkMemoryAllocateInfo allocate_info{}; + allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocate_info.allocationSize = requirements.size; + allocate_info.memoryTypeIndex = find_memory_type(requirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + VK_CHECK(vkAllocateMemory(device_, &allocate_info, nullptr, &vertex_buffer_memory_)); + VK_CHECK(vkBindBufferMemory(device_, vertex_buffer_, vertex_buffer_memory_, 0)); + + void* data; + VK_CHECK(vkMapMemory(device_, vertex_buffer_memory_, 0, buffer_info.size, 0, &data)); + memcpy(data, vertices.data(), (size_t) buffer_info.size); + vkUnmapMemory(device_, vertex_buffer_memory_); +} + void RenderEngine::allocate_command_buffers() { command_buffers_.resize(swapchain_images_.size()); @@ -623,7 +691,11 @@ void RenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint32_ render_pass_begin_info.pClearValues = &clear_color; vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE); - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphycs_pipeline_); + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline_); + + VkBuffer vertex_buffers[] = {vertex_buffer_}; + VkDeviceSize offset[] = {0}; + vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offset); VkViewport viewport{}; viewport.x = 0.0f; @@ -639,7 +711,7 @@ void RenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint32_ scissor.extent = swapchain_extent_; vkCmdSetScissor(command_buffer, 0, 1, &scissor); - vkCmdDraw(command_buffer, 3, 1, 0, 0); + vkCmdDraw(command_buffer, static_cast(vertices.size()), 1, 0, 0); vkCmdEndRenderPass(command_buffer); VK_CHECK(vkEndCommandBuffer(command_buffer)); @@ -705,6 +777,7 @@ window_(window) create_graphics_pipeline(); create_framebuffers(); create_command_pool(); + allocate_vertex_buffer(); allocate_command_buffers(); create_sync_objects(); } @@ -712,6 +785,12 @@ window_(window) RenderEngine::~RenderEngine() { vkDeviceWaitIdle(device_); + + if (vertex_buffer_memory_ != VK_NULL_HANDLE) + vkFreeMemory(device_, vertex_buffer_memory_, nullptr); + + if (vertex_buffer_ != VK_NULL_HANDLE) + vkDestroyBuffer(device_, vertex_buffer_, nullptr); for (auto& i : image_available_semaphores_) vkDestroySemaphore(device_, i, nullptr); @@ -731,8 +810,8 @@ RenderEngine::~RenderEngine() for (auto& i : framebuffers_) vkDestroyFramebuffer(device_, i, nullptr); - if (graphycs_pipeline_ != VK_NULL_HANDLE) - vkDestroyPipeline(device_, graphycs_pipeline_, nullptr); + if (graphics_pipeline_ != VK_NULL_HANDLE) + vkDestroyPipeline(device_, graphics_pipeline_, nullptr); if (pipeline_layout_ != VK_NULL_HANDLE) vkDestroyPipelineLayout(device_, pipeline_layout_, nullptr); diff --git a/Core/Core/RenderEngine.h b/Core/Core/RenderEngine.h index 5dddb5e..5cae440 100644 --- a/Core/Core/RenderEngine.h +++ b/Core/Core/RenderEngine.h @@ -1,13 +1,15 @@ #pragma once +#include #include #include +#include #define GLFW_INCLUDE_VULKAN -#include #include #include +#include #ifdef _DEBUG #include @@ -33,6 +35,25 @@ class RenderEngine std::vector present_modes; }; +#pragma region Experemental + struct Vertex + { + glm::vec2 pos; + glm::vec3 color; + static VkVertexInputBindingDescription get_binding_description(); + static std::array get_vertex_attribute_descriptions(); + }; + const std::vector 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}} + }; + VkBuffer vertex_buffer_ = VK_NULL_HANDLE; + VkDeviceMemory vertex_buffer_memory_ = VK_NULL_HANDLE; + uint32_t find_memory_type(uint32_t typeFilter, VkMemoryPropertyFlags properties); + void allocate_vertex_buffer(); +#pragma endregion + static const std::vector deviceExtensions; int current_frame_ = 0; @@ -52,7 +73,7 @@ class RenderEngine std::vector swapchain_image_views_; VkRenderPass render_pass_ = VK_NULL_HANDLE; VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE; - VkPipeline graphycs_pipeline_ = VK_NULL_HANDLE; + VkPipeline graphics_pipeline_ = VK_NULL_HANDLE; std::vector framebuffers_; VkCommandPool command_pool_ = VK_NULL_HANDLE; std::vector command_buffers_; diff --git a/TestGame/Shaders/vertex.vert b/TestGame/Shaders/vertex.vert index fe613ef..92ceacd 100644 --- a/TestGame/Shaders/vertex.vert +++ b/TestGame/Shaders/vertex.vert @@ -1,20 +1,12 @@ #version 450 +layout(location = 0) in vec2 inPosition; +layout(location = 1) in vec3 inColor; + layout(location = 0) out vec3 fragColor; -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) -); - -vec2 positions[3] = vec2[]( - vec2(0.0, -0.5), - vec2(0.5, 0.5), - vec2(-0.5, 0.5) -); - -void main() { - gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); - fragColor = colors[gl_VertexIndex]; +void main() +{ + gl_Position = vec4(inPosition, 0.0, 1.0); + fragColor = inColor; } \ No newline at end of file