Index buffer support for Vulkan.

This commit is contained in:
Attila Uygun 2021-01-06 12:13:04 +01:00
parent 128fa659a8
commit 823e56ee13
2 changed files with 43 additions and 6 deletions

View File

@ -185,6 +185,18 @@ VertexInputDescription GetVertexInputDescription(
return std::make_tuple(std::move(bindings), std::move(attributes)); return std::make_tuple(std::move(bindings), std::move(attributes));
} }
VkIndexType GetIndexType(eng::DataType data_type) {
switch (data_type) {
case eng::kDataType_UInt:
return VK_INDEX_TYPE_UINT32;
case eng::kDataType_UShort:
return VK_INDEX_TYPE_UINT16;
default:
break;
}
NOTREACHED << "Invalid index type";
}
} // namespace } // namespace
namespace eng { namespace eng {
@ -193,12 +205,19 @@ RendererVulkan::RendererVulkan() = default;
RendererVulkan::~RendererVulkan() = default; RendererVulkan::~RendererVulkan() = default;
// TODO: Support for index buffer.
void RendererVulkan::CreateGeometry(std::shared_ptr<void> impl_data, void RendererVulkan::CreateGeometry(std::shared_ptr<void> impl_data,
std::unique_ptr<Mesh> mesh) { std::unique_ptr<Mesh> mesh) {
auto geometry = reinterpret_cast<GeometryVulkan*>(impl_data.get()); auto geometry = reinterpret_cast<GeometryVulkan*>(impl_data.get());
geometry->num_vertices = mesh->num_vertices(); geometry->num_vertices = mesh->num_vertices();
size_t data_size = mesh->GetVertexSize() * geometry->num_vertices; size_t vertex_data_size = mesh->GetVertexSize() * geometry->num_vertices;
size_t index_data_size = 0;
if (mesh->GetIndices()) {
geometry->num_indices = mesh->num_indices();
geometry->index_type = GetIndexType(mesh->index_description());
index_data_size = mesh->GetIndexSize() * geometry->num_indices;
}
size_t data_size = vertex_data_size + index_data_size;
AllocateBuffer(geometry->buffer, data_size, AllocateBuffer(geometry->buffer, data_size,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
@ -208,7 +227,14 @@ void RendererVulkan::CreateGeometry(std::shared_ptr<void> impl_data,
task_runner_.PostTask(HERE, std::bind(&RendererVulkan::UpdateBuffer, this, task_runner_.PostTask(HERE, std::bind(&RendererVulkan::UpdateBuffer, this,
std::get<0>(geometry->buffer), 0, std::get<0>(geometry->buffer), 0,
mesh->GetVertices(), data_size)); mesh->GetVertices(), vertex_data_size));
if (geometry->num_indices > 0) {
geometry->indices_offset = vertex_data_size;
task_runner_.PostTask(
HERE, std::bind(&RendererVulkan::UpdateBuffer, this,
std::get<0>(geometry->buffer), geometry->indices_offset,
mesh->GetIndices(), index_data_size));
}
task_runner_.PostTask(HERE, task_runner_.PostTask(HERE,
std::bind(&RendererVulkan::BufferMemoryBarrier, this, std::bind(&RendererVulkan::BufferMemoryBarrier, this,
std::get<0>(geometry->buffer), 0, data_size, std::get<0>(geometry->buffer), 0, data_size,
@ -234,8 +260,16 @@ void RendererVulkan::Draw(std::shared_ptr<void> impl_data) {
VkDeviceSize offset = 0; VkDeviceSize offset = 0;
vkCmdBindVertexBuffers(frames_[current_frame_].draw_command_buffer, 0, 1, vkCmdBindVertexBuffers(frames_[current_frame_].draw_command_buffer, 0, 1,
&std::get<0>(geometry->buffer), &offset); &std::get<0>(geometry->buffer), &offset);
vkCmdDraw(frames_[current_frame_].draw_command_buffer, geometry->num_vertices, if (geometry->num_indices > 0) {
1, 0, 0); vkCmdBindIndexBuffer(frames_[current_frame_].draw_command_buffer,
std::get<0>(geometry->buffer),
geometry->indices_offset, geometry->index_type);
vkCmdDrawIndexed(frames_[current_frame_].draw_command_buffer,
geometry->num_indices, 1, 0, 0, 0);
} else {
vkCmdDraw(frames_[current_frame_].draw_command_buffer,
geometry->num_vertices, 1, 0, 0);
}
} }
void RendererVulkan::UpdateTexture(std::shared_ptr<void> impl_data, void RendererVulkan::UpdateTexture(std::shared_ptr<void> impl_data,

View File

@ -103,7 +103,10 @@ class RendererVulkan : public Renderer {
struct GeometryVulkan { struct GeometryVulkan {
Buffer<VkBuffer> buffer; Buffer<VkBuffer> buffer;
size_t num_vertices = 0; uint32_t num_vertices = 0;
uint32_t num_indices = 0;
uint64_t indices_offset = 0;
VkIndexType index_type = VK_INDEX_TYPE_UINT16;
}; };
struct ShaderVulkan { struct ShaderVulkan {