move transformations to the gpu

This commit is contained in:
Luna 2025-05-30 05:47:09 +02:00
parent 187d62edd3
commit bc7db2106a
2 changed files with 102 additions and 48 deletions

144
main.cpp
View file

@ -28,6 +28,11 @@ struct bounding_box
float height; float height;
}; };
struct uniform
{
glm::mat4 transform;
};
bounding_box player; bounding_box player;
float velocityX = 1.0f; float velocityX = 1.0f;
float velocityY = 0.50f; float velocityY = 0.50f;
@ -156,11 +161,11 @@ std::vector<vertex> convert_quad_to_triangles(std::vector<vertex> vertices)
return vertices; return vertices;
} }
glm::mat2 rotate(float angle) glm::mat4 rotate(float angle)
{ {
float c = glm::cos(glm::radians(angle)); float c = glm::cos(glm::radians(angle));
float s = glm::sin(glm::radians(angle)); float s = glm::sin(glm::radians(angle));
glm::mat2 transform({c, s}, {-s, c}); glm::mat4 transform({c, s, 0.0f, 0.0f}, {-s, c, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f});
return transform; return transform;
} }
@ -170,9 +175,9 @@ glm::mat2 scale(glm::vec2 scale)
return transform; return transform;
} }
glm::mat3 move(glm::vec2 pos) glm::mat4 move(glm::vec2 pos)
{ {
glm::mat3 transform({1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {pos.x, pos.y, 1.0f}); glm::mat4 transform({1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}, {pos.x, pos.y, 0.0f, 1.0f});
return transform; return transform;
} }
@ -204,6 +209,35 @@ void simple_physics_step(float t)
player.y = player.y + (velocityY * t); player.y = player.y + (velocityY * t);
} }
std::pair<vk::DeviceMemory, vk::Buffer> create_buffer(const vk::Device &device, vk::PhysicalDevice selected_physical_device, vk::BufferUsageFlagBits usage, size_t size)
{
vk::BufferCreateInfo buffer_info = vk::BufferCreateInfo(vk::BufferCreateFlags(), size, usage, vk::SharingMode::eExclusive);
vk::Buffer vertex_buffer = device.createBuffer(buffer_info);
VkMemoryRequirements memory_requirements;
vkGetBufferMemoryRequirements(device, vertex_buffer, &memory_requirements);
vk::PhysicalDeviceMemoryProperties memory_properties = selected_physical_device.getMemoryProperties();
int propierty_index = -1;
for (int i = 0; i < memory_properties.memoryTypeCount; i++)
{
if (memory_properties.memoryTypes[i].propertyFlags & vk::MemoryPropertyFlags(vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent))
{
propierty_index = i;
break;
}
}
if (propierty_index == -1)
{
throw std::runtime_error("Didnt find a suitable memory");
}
vk::MemoryAllocateInfo alloc_info = vk::MemoryAllocateInfo(memory_requirements.size, propierty_index);
vk::DeviceMemory vertex_buffer_memory = device.allocateMemory(alloc_info);
device.bindBufferMemory(vertex_buffer, vertex_buffer_memory, 0);
return std::make_pair(vertex_buffer_memory, vertex_buffer);
}
int main() int main()
{ {
using clock = std::chrono::system_clock; using clock = std::chrono::system_clock;
@ -393,9 +427,27 @@ int main()
color_blend_info.attachmentCount = 1; color_blend_info.attachmentCount = 1;
color_blend_info.pAttachments = &color_blend_attachment; color_blend_info.pAttachments = &color_blend_attachment;
vk::DescriptorSetLayoutBinding descriptor_binding;
descriptor_binding.binding = 0;
descriptor_binding.descriptorCount = 1;
descriptor_binding.descriptorType = vk::DescriptorType::eUniformBuffer;
descriptor_binding.stageFlags = vk::ShaderStageFlagBits::eVertex;
vk::DescriptorSetLayoutCreateInfo descriptor_layout_info(vk::DescriptorSetLayoutCreateFlags(), 1, &descriptor_binding);
vk::DescriptorSetLayout descriptor_layout = device.createDescriptorSetLayout(descriptor_layout_info);
vk::PipelineLayoutCreateInfo layout_info = {}; vk::PipelineLayoutCreateInfo layout_info = {};
layout_info.setLayoutCount = 1;
layout_info.pSetLayouts = &descriptor_layout;
vk::PipelineLayout pipeline_layout = device.createPipelineLayout(layout_info); vk::PipelineLayout pipeline_layout = device.createPipelineLayout(layout_info);
uniform u{};
u.transform = glm::mat4(1.0f);
auto rec = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eUniformBuffer, sizeof(uniform));
vk::DeviceMemory uniform_buffer_data = rec.first;
vk::Buffer uniform_buffer = rec.second;
char *uniform_data = (char *)device.mapMemory(uniform_buffer_data, 0, sizeof(uniform));
memcpy(uniform_data, &u, sizeof(uniform));
vk::AttachmentDescription color_attachment = vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), vk::AttachmentDescription color_attachment = vk::AttachmentDescription(vk::AttachmentDescriptionFlags(),
format.format, vk::SampleCountFlagBits::e1, format.format, vk::SampleCountFlagBits::e1,
@ -468,42 +520,11 @@ int main()
{{-0.1f, 0.1f}, {0.0f, 0.0f, 1.0f}} {{-0.1f, 0.1f}, {0.0f, 0.0f, 1.0f}}
}; };
vertices = convert_quad_to_triangles(vertices); vertices = convert_quad_to_triangles(vertices);
glm::mat2 transform = scale({1.0, 1.0}) * rotate(0.0f); auto ret = create_buffer(device, selected_physical_device, vk::BufferUsageFlagBits::eVertexBuffer, sizeof(vertices[0]) * vertices.size());
glm::vec2 movement = {0.0f, 0.0f}; vk::DeviceMemory vertex_buffer_memory = ret.first;
vk::Buffer vertex_buffer = ret.second;
for (auto &[position, color] : vertices) char *data = (char *)device.mapMemory(vertex_buffer_memory, 0, sizeof(vertices[0]) * vertices.size());
{ memcpy(data, vertices.data(), sizeof(vertices[0]) * vertices.size());
position = position + movement;
position = transform * position;
}
vk::BufferCreateInfo buffer_info = vk::BufferCreateInfo(vk::BufferCreateFlags(), sizeof(vertices[0]) * vertices.size(), vk::BufferUsageFlagBits::eVertexBuffer, vk::SharingMode::eExclusive);
vk::Buffer vertex_buffer = device.createBuffer(buffer_info);
VkMemoryRequirements memory_requirements;
vkGetBufferMemoryRequirements(device, vertex_buffer, &memory_requirements);
vk::PhysicalDeviceMemoryProperties memory_propierties = selected_physical_device.getMemoryProperties();
int propierty_index = -1;
for (int i = 0; i < memory_propierties.memoryTypeCount; i++)
{
if (memory_propierties.memoryTypes[i].propertyFlags & vk::MemoryPropertyFlags(vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent))
{
propierty_index = i;
break;
}
}
if (propierty_index == -1)
{
throw std::runtime_error("Didnt find a suitable memory");
}
vk::MemoryAllocateInfo alloc_info = vk::MemoryAllocateInfo(memory_requirements.size, propierty_index);
vk::DeviceMemory vertex_buffer_memory = device.allocateMemory(alloc_info);
device.bindBufferMemory(vertex_buffer, vertex_buffer_memory, 0);
char *data = (char *)device.mapMemory(vertex_buffer_memory, 0, buffer_info.size);
memcpy(data, vertices.data(), buffer_info.size);
vk::CommandPoolCreateInfo command_pool_info = {}; vk::CommandPoolCreateInfo command_pool_info = {};
@ -515,6 +536,35 @@ int main()
vk::CommandBufferLevel::ePrimary, vk::CommandBufferLevel::ePrimary,
1); 1);
auto command_buffers = device.allocateCommandBuffers(cmd_alloc_info); auto command_buffers = device.allocateCommandBuffers(cmd_alloc_info);
vk::DescriptorPoolSize descriptor_pool_size(vk::DescriptorType::eUniformBuffer, sizeof(uniform));
vk::DescriptorPoolCreateInfo descriptor_pool_info;
descriptor_pool_info.maxSets = 1;
descriptor_pool_info.poolSizeCount = 1;
descriptor_pool_info.pPoolSizes = &descriptor_pool_size;
vk::DescriptorPool descriptor_pool = device.createDescriptorPool(descriptor_pool_info);
vk::DescriptorSetAllocateInfo descriptor_set_allocate_info;
descriptor_set_allocate_info.descriptorPool = descriptor_pool;
descriptor_set_allocate_info.descriptorSetCount = 1;
descriptor_set_allocate_info.pSetLayouts = &descriptor_layout;
auto descriptor_sets = device.allocateDescriptorSets(descriptor_set_allocate_info);
vk::DescriptorSet descriptor_set = descriptor_sets[0];
vk::DescriptorBufferInfo descriptor_buffer_info;
descriptor_buffer_info.buffer = uniform_buffer;
descriptor_buffer_info.offset = 0;
descriptor_buffer_info.range = sizeof(uniform);
vk::WriteDescriptorSet write_descriptor;
write_descriptor.descriptorCount = 1;
write_descriptor.descriptorType = vk::DescriptorType::eUniformBuffer;
write_descriptor.dstBinding = 0;
write_descriptor.dstArrayElement = 0;
write_descriptor.dstSet = descriptor_set;
write_descriptor.pBufferInfo = &descriptor_buffer_info;
device.updateDescriptorSets(write_descriptor, nullptr);
vk::SemaphoreCreateInfo semaphore_info = vk::SemaphoreCreateInfo(); vk::SemaphoreCreateInfo semaphore_info = vk::SemaphoreCreateInfo();
vk::FenceCreateInfo fence_info = vk::FenceCreateInfo(); vk::FenceCreateInfo fence_info = vk::FenceCreateInfo();
@ -551,13 +601,11 @@ int main()
auto time_elapsed = clock::now() - before; auto time_elapsed = clock::now() - before;
simple_physics_step(std::chrono::duration_cast<std::chrono::duration<float>>(time_elapsed).count()); simple_physics_step(std::chrono::duration_cast<std::chrono::duration<float>>(time_elapsed).count());
before = clock::now(); before = clock::now();
for (int i = 0; i < vertices.size(); i++) u.transform = move({player.x, player.y}) * rotate(angle);
{ memcpy(uniform_data, &u, sizeof(uniform));
render_vertices[i].position = vertices[i].position * rotate(angle);
render_vertices[i].position = glm::vec2(move({player.x, player.y}) * glm::vec3(render_vertices[i].position, 1.0f));
}
angle -= 1.0f; angle -= 1.0f;
memcpy(data, render_vertices.data(), buffer_info.size); memcpy(data, render_vertices.data(), sizeof(vertices[0]) * vertices.size());
vk::CommandBufferBeginInfo begin_info = {}; vk::CommandBufferBeginInfo begin_info = {};
@ -571,7 +619,7 @@ int main()
command_buffers[0].bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); command_buffers[0].bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
//command_buffers[0].setViewport(0, viewport); //command_buffers[0].setViewport(0, viewport);
//command_buffers[0].setScissor(0, scissor); //command_buffers[0].setScissor(0, scissor);
command_buffers[0].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline_layout, 0, descriptor_sets, nullptr);
command_buffers[0].bindVertexBuffers(0, 1, &vertex_buffer, &offset); command_buffers[0].bindVertexBuffers(0, 1, &vertex_buffer, &offset);
command_buffers[0].draw(vertices.size(), 1, 0, 0); command_buffers[0].draw(vertices.size(), 1, 0, 0);
command_buffers[0].endRenderPass(); command_buffers[0].endRenderPass();
@ -607,6 +655,8 @@ int main()
//phy_thread.join(); //phy_thread.join();
device.unmapMemory(vertex_buffer_memory); device.unmapMemory(vertex_buffer_memory);
device.waitIdle(); device.waitIdle();
device.destroyDescriptorPool(descriptor_pool);
device.destroyDescriptorSetLayout(descriptor_layout);
device.destroyBuffer(vertex_buffer); device.destroyBuffer(vertex_buffer);
device.freeMemory(vertex_buffer_memory); device.freeMemory(vertex_buffer_memory);
for (auto &framebuffer: framebuffers) for (auto &framebuffer: framebuffers)

View file

@ -3,6 +3,10 @@
// x -> -1 (left) 1(right) // x -> -1 (left) 1(right)
// y -> -1 (top) 1(bottom) // y -> -1 (top) 1(bottom)
layout(binding = 0) uniform un{
mat4 transform;
} trans;
layout(location = 0) in vec2 in_position; layout(location = 0) in vec2 in_position;
layout(location = 1) in vec3 in_color; layout(location = 1) in vec3 in_color;
@ -10,6 +14,6 @@ layout(location = 0) out vec3 frag_color;
void main() void main()
{ {
gl_Position = vec4(in_position, 0.0, 1.0); gl_Position = trans.transform * vec4(in_position, 0.0, 1.0);
frag_color = in_color; frag_color = in_color;
} }