mirror of https://github.com/auygun/kaliber.git
Add Renderer::UpdateGeometry()
Also add its implementations in Vulkan and OpenGL renderers. Use it in ImguiBackend instead of recreating geometry buffers every frame.
This commit is contained in:
parent
a02d1ba71e
commit
0d64c98854
|
@ -139,28 +139,16 @@ bool Mesh::Load(const std::string& file_name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: Load indices
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Mesh::GetVertexSize() const {
|
size_t Mesh::GetVertexSize() const {
|
||||||
unsigned int size = 0;
|
return eng::GetVertexSize(vertex_description_);
|
||||||
for (auto& attr : vertex_description_) {
|
|
||||||
size += std::get<2>(attr) * std::get<3>(attr);
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Mesh::GetIndexSize() const {
|
size_t Mesh::GetIndexSize() const {
|
||||||
switch (index_description_) {
|
return eng::GetIndexSize(index_description_);
|
||||||
case kDataType_Byte:
|
|
||||||
return sizeof(char);
|
|
||||||
case kDataType_UShort:
|
|
||||||
return sizeof(unsigned short);
|
|
||||||
case kDataType_UInt:
|
|
||||||
return sizeof(unsigned int);
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace eng
|
} // namespace eng
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
#include "engine/asset/image.h"
|
#include "engine/asset/image.h"
|
||||||
#include "engine/asset/mesh.h"
|
|
||||||
#include "engine/asset/shader_source.h"
|
#include "engine/asset/shader_source.h"
|
||||||
#include "engine/engine.h"
|
#include "engine/engine.h"
|
||||||
#include "engine/input_event.h"
|
#include "engine/input_event.h"
|
||||||
|
@ -29,6 +28,9 @@ void ImguiBackend::Initialize() {
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGui::GetIO().IniFilename = nullptr;
|
ImGui::GetIO().IniFilename = nullptr;
|
||||||
|
|
||||||
|
if (!ParseVertexDescription(vertex_description, vertex_description_))
|
||||||
|
LOG(0) << "Failed to parse vertex description.";
|
||||||
|
|
||||||
size_t buffer_size = 0;
|
size_t buffer_size = 0;
|
||||||
auto buffer = AssetFile::ReadWholeFile("engine/RobotoMono-Regular.ttf",
|
auto buffer = AssetFile::ReadWholeFile("engine/RobotoMono-Regular.ttf",
|
||||||
Engine::Get().GetRootPath().c_str(),
|
Engine::Get().GetRootPath().c_str(),
|
||||||
|
@ -68,6 +70,9 @@ void ImguiBackend::Initialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImguiBackend::Shutdown() {
|
void ImguiBackend::Shutdown() {
|
||||||
|
for (auto& id : geometries_)
|
||||||
|
renderer_->DestroyGeometry(id);
|
||||||
|
geometries_.clear();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
shader_.reset();
|
shader_.reset();
|
||||||
}
|
}
|
||||||
|
@ -75,6 +80,7 @@ void ImguiBackend::Shutdown() {
|
||||||
void ImguiBackend::CreateRenderResources(Renderer* renderer) {
|
void ImguiBackend::CreateRenderResources(Renderer* renderer) {
|
||||||
renderer_ = renderer;
|
renderer_ = renderer;
|
||||||
shader_->SetRenderer(renderer);
|
shader_->SetRenderer(renderer);
|
||||||
|
geometries_.clear();
|
||||||
|
|
||||||
auto source = std::make_unique<ShaderSource>();
|
auto source = std::make_unique<ShaderSource>();
|
||||||
if (source->Load("engine/imgui.glsl")) {
|
if (source->Load("engine/imgui.glsl")) {
|
||||||
|
@ -115,10 +121,6 @@ std::unique_ptr<InputEvent> ImguiBackend::OnInputEvent(
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImguiBackend::NewFrame(float delta_time) {
|
void ImguiBackend::NewFrame(float delta_time) {
|
||||||
for (auto& id : geometries_)
|
|
||||||
renderer_->DestroyGeometry(id);
|
|
||||||
geometries_.clear();
|
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.DisplaySize = ImVec2((float)renderer_->GetScreenWidth(),
|
io.DisplaySize = ImVec2((float)renderer_->GetScreenWidth(),
|
||||||
(float)renderer_->GetScreenHeight());
|
(float)renderer_->GetScreenHeight());
|
||||||
|
@ -129,15 +131,16 @@ void ImguiBackend::NewFrame(float delta_time) {
|
||||||
void ImguiBackend::Render() {
|
void ImguiBackend::Render() {
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
ImDrawData* draw_data = ImGui::GetDrawData();
|
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||||
geometries_.resize(draw_data->CmdListsCount);
|
if (geometries_.size() < draw_data->CmdListsCount)
|
||||||
|
geometries_.resize(draw_data->CmdListsCount, 0);
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++) {
|
for (int n = 0; n < draw_data->CmdListsCount; n++) {
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
auto mesh = std::make_unique<Mesh>();
|
if (geometries_[n] == 0)
|
||||||
mesh->Create(kPrimitive_Triangles, vertex_description,
|
geometries_[n] = renderer_->CreateGeometry(
|
||||||
cmd_list->VtxBuffer.Size, cmd_list->VtxBuffer.Data,
|
kPrimitive_Triangles, vertex_description_, kDataType_UShort);
|
||||||
kDataType_UShort, cmd_list->IdxBuffer.Size,
|
renderer_->UpdateGeometry(
|
||||||
cmd_list->IdxBuffer.Data);
|
geometries_[n], cmd_list->VtxBuffer.Size, cmd_list->VtxBuffer.Data,
|
||||||
geometries_[n] = renderer_->CreateGeometry(std::move(mesh));
|
cmd_list->IdxBuffer.Size, cmd_list->IdxBuffer.Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "engine/renderer/renderer_types.h"
|
||||||
|
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
||||||
class InputEvent;
|
class InputEvent;
|
||||||
|
@ -27,6 +29,7 @@ class ImguiBackend {
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
VertexDescription vertex_description_;
|
||||||
std::vector<uint64_t> geometries_;
|
std::vector<uint64_t> geometries_;
|
||||||
std::unique_ptr<Shader> shader_;
|
std::unique_ptr<Shader> shader_;
|
||||||
Renderer* renderer_ = nullptr;
|
Renderer* renderer_ = nullptr;
|
||||||
|
|
|
@ -72,11 +72,22 @@ void RendererOpenGL::ResetScissor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t RendererOpenGL::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
uint64_t RendererOpenGL::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
||||||
|
auto id = CreateGeometry(mesh->primitive(), mesh->vertex_description(),
|
||||||
|
mesh->index_description());
|
||||||
|
if (id != kInvalidId)
|
||||||
|
UpdateGeometry(id, mesh->num_vertices(), mesh->GetVertices(),
|
||||||
|
mesh->num_indices(), mesh->GetIndices());
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t RendererOpenGL::CreateGeometry(Primitive primitive,
|
||||||
|
VertexDescription vertex_description,
|
||||||
|
DataType index_description) {
|
||||||
// Verify that we have a valid layout and get the total byte size per vertex.
|
// Verify that we have a valid layout and get the total byte size per vertex.
|
||||||
GLuint vertex_size = mesh->GetVertexSize();
|
GLuint vertex_size = GetVertexSize(vertex_description);
|
||||||
if (!vertex_size) {
|
if (!vertex_size) {
|
||||||
LOG(0) << "Invalid vertex layout";
|
LOG(0) << "Invalid vertex layout";
|
||||||
return 0;
|
return kInvalidId;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint vertex_array_id = 0;
|
GLuint vertex_array_id = 0;
|
||||||
|
@ -85,30 +96,25 @@ uint64_t RendererOpenGL::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
||||||
glBindVertexArray(vertex_array_id);
|
glBindVertexArray(vertex_array_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the vertex buffer and upload the data.
|
// Create the vertex buffer.
|
||||||
GLuint vertex_buffer_id = 0;
|
GLuint vertex_buffer_id = 0;
|
||||||
glGenBuffers(1, &vertex_buffer_id);
|
glGenBuffers(1, &vertex_buffer_id);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id);
|
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id);
|
||||||
glBufferData(GL_ARRAY_BUFFER, mesh->num_vertices() * vertex_size,
|
|
||||||
mesh->GetVertices(), GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
// Make sure the vertex format is understood and the attribute pointers are
|
// Make sure the vertex format is understood and the attribute pointers are
|
||||||
// set up.
|
// set up.
|
||||||
std::vector<GeometryOpenGL::Element> vertex_layout;
|
std::vector<GeometryOpenGL::Element> vertex_layout;
|
||||||
if (!SetupVertexLayout(mesh->vertex_description(), vertex_size,
|
if (!SetupVertexLayout(vertex_description, vertex_size, vertex_array_objects_,
|
||||||
vertex_array_objects_, vertex_layout)) {
|
vertex_layout)) {
|
||||||
LOG(0) << "Invalid vertex layout";
|
LOG(0) << "Invalid vertex layout";
|
||||||
return 0;
|
return kInvalidId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the index buffer and upload the data.
|
// Create the index buffer.
|
||||||
GLuint index_buffer_id = 0;
|
GLuint index_buffer_id = 0;
|
||||||
if (mesh->GetIndices()) {
|
if (index_description != kDataType_Invalid) {
|
||||||
glGenBuffers(1, &index_buffer_id);
|
glGenBuffers(1, &index_buffer_id);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
|
||||||
mesh->num_indices() * mesh->GetIndexSize(), mesh->GetIndices(),
|
|
||||||
GL_STATIC_DRAW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vertex_array_id) {
|
if (vertex_array_id) {
|
||||||
|
@ -121,18 +127,48 @@ uint64_t RendererOpenGL::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t resource_id = ++last_resource_id_;
|
uint64_t resource_id = ++last_resource_id_;
|
||||||
geometries_[resource_id] = {(GLsizei)mesh->num_vertices(),
|
geometries_[resource_id] = {0,
|
||||||
(GLsizei)mesh->num_indices(),
|
0,
|
||||||
kGlPrimitive[mesh->primitive()],
|
kGlPrimitive[primitive],
|
||||||
kGlDataType[mesh->index_description()],
|
kGlDataType[index_description],
|
||||||
vertex_layout,
|
vertex_layout,
|
||||||
vertex_size,
|
vertex_size,
|
||||||
vertex_array_id,
|
vertex_array_id,
|
||||||
vertex_buffer_id,
|
vertex_buffer_id,
|
||||||
|
(GLuint)GetIndexSize(index_description),
|
||||||
index_buffer_id};
|
index_buffer_id};
|
||||||
return resource_id;
|
return resource_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RendererOpenGL::UpdateGeometry(uint64_t resource_id,
|
||||||
|
size_t num_vertices,
|
||||||
|
const void* vertices,
|
||||||
|
size_t num_indices,
|
||||||
|
const void* indices) {
|
||||||
|
auto it = geometries_.find(resource_id);
|
||||||
|
if (it == geometries_.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Go with GL_STATIC_DRAW for the first update.
|
||||||
|
GLenum usage = it->second.num_vertices > 0 ? GL_STREAM_DRAW : GL_STATIC_DRAW;
|
||||||
|
|
||||||
|
// Upload the vertex data.
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, it->second.vertex_buffer_id);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, num_vertices * it->second.vertex_size, vertices,
|
||||||
|
usage);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
it->second.num_vertices = (GLsizei)num_vertices;
|
||||||
|
|
||||||
|
// Upload the index data.
|
||||||
|
if (it->second.index_buffer_id) {
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, it->second.index_buffer_id);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_indices * it->second.index_size,
|
||||||
|
indices, usage);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
it->second.num_indices = (GLsizei)num_indices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RendererOpenGL::DestroyGeometry(uint64_t resource_id) {
|
void RendererOpenGL::DestroyGeometry(uint64_t resource_id) {
|
||||||
auto it = geometries_.find(resource_id);
|
auto it = geometries_.find(resource_id);
|
||||||
if (it == geometries_.end())
|
if (it == geometries_.end())
|
||||||
|
|
|
@ -39,6 +39,15 @@ class RendererOpenGL final : public Renderer {
|
||||||
void ResetScissor() final;
|
void ResetScissor() final;
|
||||||
|
|
||||||
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;
|
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;
|
||||||
|
uint64_t CreateGeometry(Primitive primitive,
|
||||||
|
VertexDescription vertex_description,
|
||||||
|
DataType index_description = kDataType_Invalid) final;
|
||||||
|
void UpdateGeometry(uint64_t resource_id,
|
||||||
|
size_t num_vertices,
|
||||||
|
const void* vertices,
|
||||||
|
size_t num_indices,
|
||||||
|
const void* indices) final;
|
||||||
|
|
||||||
void DestroyGeometry(uint64_t resource_id) final;
|
void DestroyGeometry(uint64_t resource_id) final;
|
||||||
void Draw(uint64_t resource_id,
|
void Draw(uint64_t resource_id,
|
||||||
uint64_t num_indices = 0,
|
uint64_t num_indices = 0,
|
||||||
|
@ -99,6 +108,7 @@ class RendererOpenGL final : public Renderer {
|
||||||
GLuint vertex_size = 0;
|
GLuint vertex_size = 0;
|
||||||
GLuint vertex_array_id = 0;
|
GLuint vertex_array_id = 0;
|
||||||
GLuint vertex_buffer_id = 0;
|
GLuint vertex_buffer_id = 0;
|
||||||
|
GLuint index_size = 0;
|
||||||
GLuint index_buffer_id = 0;
|
GLuint index_buffer_id = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,15 @@ class Renderer {
|
||||||
virtual void ResetScissor() = 0;
|
virtual void ResetScissor() = 0;
|
||||||
|
|
||||||
virtual uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) = 0;
|
virtual uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) = 0;
|
||||||
|
virtual uint64_t CreateGeometry(
|
||||||
|
Primitive primitive,
|
||||||
|
VertexDescription vertex_description,
|
||||||
|
DataType index_description = kDataType_Invalid) = 0;
|
||||||
|
virtual void UpdateGeometry(uint64_t resource_id,
|
||||||
|
size_t num_vertices,
|
||||||
|
const void* vertices,
|
||||||
|
size_t num_indices,
|
||||||
|
const void* indices) = 0;
|
||||||
virtual void DestroyGeometry(uint64_t resource_id) = 0;
|
virtual void DestroyGeometry(uint64_t resource_id) = 0;
|
||||||
virtual void Draw(uint64_t resource_id,
|
virtual void Draw(uint64_t resource_id,
|
||||||
uint64_t num_indices = 0,
|
uint64_t num_indices = 0,
|
||||||
|
|
|
@ -14,6 +14,27 @@ const char kLayoutDelimiter[] = ";/ \t";
|
||||||
|
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
||||||
|
size_t GetVertexSize(const VertexDescription& vertex_description) {
|
||||||
|
size_t size = 0;
|
||||||
|
for (auto& attr : vertex_description) {
|
||||||
|
size += std::get<2>(attr) * std::get<3>(attr);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetIndexSize(DataType index_description) {
|
||||||
|
switch (index_description) {
|
||||||
|
case kDataType_Byte:
|
||||||
|
return sizeof(char);
|
||||||
|
case kDataType_UShort:
|
||||||
|
return sizeof(unsigned short);
|
||||||
|
case kDataType_UInt:
|
||||||
|
return sizeof(unsigned int);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ParseVertexDescription(const std::string& vd_str, VertexDescription& out) {
|
bool ParseVertexDescription(const std::string& vd_str, VertexDescription& out) {
|
||||||
// Parse the description.
|
// Parse the description.
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
|
|
|
@ -41,6 +41,9 @@ using DataTypeSize = size_t;
|
||||||
using VertexDescription =
|
using VertexDescription =
|
||||||
std::vector<std::tuple<AttribType, DataType, ElementCount, DataTypeSize>>;
|
std::vector<std::tuple<AttribType, DataType, ElementCount, DataTypeSize>>;
|
||||||
|
|
||||||
|
size_t GetVertexSize(const VertexDescription& vertex_description);
|
||||||
|
size_t GetIndexSize(DataType index_description);
|
||||||
|
|
||||||
bool ParseVertexDescription(const std::string& vd_str, VertexDescription& out);
|
bool ParseVertexDescription(const std::string& vd_str, VertexDescription& out);
|
||||||
|
|
||||||
} // namespace eng
|
} // namespace eng
|
||||||
|
|
|
@ -307,6 +307,8 @@ VertexInputDescription GetVertexInputDescription(
|
||||||
|
|
||||||
VkIndexType GetIndexType(eng::DataType data_type) {
|
VkIndexType GetIndexType(eng::DataType data_type) {
|
||||||
switch (data_type) {
|
switch (data_type) {
|
||||||
|
case eng::kDataType_Invalid:
|
||||||
|
return VK_INDEX_TYPE_NONE_KHR;
|
||||||
case eng::kDataType_UInt:
|
case eng::kDataType_UInt:
|
||||||
return VK_INDEX_TYPE_UINT32;
|
return VK_INDEX_TYPE_UINT32;
|
||||||
case eng::kDataType_UShort:
|
case eng::kDataType_UShort:
|
||||||
|
@ -315,7 +317,7 @@ VkIndexType GetIndexType(eng::DataType data_type) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
NOTREACHED() << "Invalid index type: " << data_type;
|
NOTREACHED() << "Invalid index type: " << data_type;
|
||||||
return VK_INDEX_TYPE_UINT16;
|
return VK_INDEX_TYPE_NONE_KHR;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkFormat GetImageFormat(eng::Image::Format format) {
|
VkFormat GetImageFormat(eng::Image::Format format) {
|
||||||
|
@ -442,47 +444,76 @@ void RendererVulkan::ResetScissor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t RendererVulkan::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
uint64_t RendererVulkan::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
||||||
auto& geometry = geometries_[++last_resource_id_] = {};
|
auto id = CreateGeometry(mesh->primitive(), mesh->vertex_description(),
|
||||||
|
mesh->index_description());
|
||||||
|
if (id != kInvalidId)
|
||||||
|
UpdateGeometry(id, mesh->num_vertices(), mesh->GetVertices(),
|
||||||
|
mesh->num_indices(), mesh->GetIndices());
|
||||||
|
task_runner_.Delete(HERE, std::move(mesh));
|
||||||
|
semaphore_.release();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
geometry.num_vertices = mesh->num_vertices();
|
uint64_t RendererVulkan::CreateGeometry(Primitive primitive,
|
||||||
size_t vertex_data_size = mesh->GetVertexSize() * geometry.num_vertices;
|
VertexDescription vertex_description,
|
||||||
|
DataType index_description) {
|
||||||
|
auto& geometry = geometries_[++last_resource_id_] = {};
|
||||||
|
geometry.vertex_size = GetVertexSize(vertex_description);
|
||||||
|
geometry.index_type = GetIndexType(index_description);
|
||||||
|
geometry.index_type_size = GetIndexSize(index_description);
|
||||||
|
return last_resource_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererVulkan::UpdateGeometry(uint64_t resource_id,
|
||||||
|
size_t num_vertices,
|
||||||
|
const void* vertices,
|
||||||
|
size_t num_indices,
|
||||||
|
const void* indices) {
|
||||||
|
auto it = geometries_.find(resource_id);
|
||||||
|
if (it == geometries_.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
it->second.num_vertices = num_vertices;
|
||||||
|
size_t vertex_data_size = it->second.vertex_size * it->second.num_vertices;
|
||||||
size_t index_data_size = 0;
|
size_t index_data_size = 0;
|
||||||
|
|
||||||
if (mesh->GetIndices()) {
|
if (indices) {
|
||||||
geometry.num_indices = mesh->num_indices();
|
DCHECK(it->second.index_type != VK_INDEX_TYPE_NONE_KHR);
|
||||||
geometry.index_type = GetIndexType(mesh->index_description());
|
it->second.num_indices = num_indices;
|
||||||
geometry.index_type_size = mesh->GetIndexSize();
|
index_data_size = it->second.index_type_size * it->second.num_indices;
|
||||||
index_data_size = geometry.index_type_size * geometry.num_indices;
|
|
||||||
}
|
}
|
||||||
size_t data_size = vertex_data_size + index_data_size;
|
|
||||||
|
|
||||||
AllocateBuffer(geometry.buffer, data_size,
|
size_t data_size = vertex_data_size + index_data_size;
|
||||||
|
if (it->second.buffer_size < data_size) {
|
||||||
|
DLOG(1) << __func__ << "Reallocate buffer " << data_size;
|
||||||
|
if (it->second.buffer_size > 0)
|
||||||
|
FreeBuffer(std::move(it->second.buffer));
|
||||||
|
AllocateBuffer(it->second.buffer, data_size,
|
||||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
|
VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
|
||||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||||
VMA_MEMORY_USAGE_GPU_ONLY);
|
VMA_MEMORY_USAGE_GPU_ONLY);
|
||||||
|
it->second.buffer_size = data_size;
|
||||||
|
}
|
||||||
|
|
||||||
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>(it->second.buffer), 0,
|
||||||
mesh->GetVertices(), vertex_data_size));
|
vertices, vertex_data_size));
|
||||||
if (geometry.num_indices > 0) {
|
if (it->second.num_indices > 0) {
|
||||||
geometry.index_data_offset = vertex_data_size;
|
it->second.index_data_offset = vertex_data_size;
|
||||||
task_runner_.PostTask(HERE, std::bind(&RendererVulkan::UpdateBuffer, this,
|
task_runner_.PostTask(HERE, std::bind(&RendererVulkan::UpdateBuffer, this,
|
||||||
std::get<0>(geometry.buffer),
|
std::get<0>(it->second.buffer),
|
||||||
geometry.index_data_offset,
|
it->second.index_data_offset, indices,
|
||||||
mesh->GetIndices(), index_data_size));
|
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>(it->second.buffer), 0, data_size,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
|
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT));
|
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT));
|
||||||
task_runner_.Delete(HERE, std::move(mesh));
|
|
||||||
semaphore_.release();
|
semaphore_.release();
|
||||||
|
|
||||||
return last_resource_id_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererVulkan::DestroyGeometry(uint64_t resource_id) {
|
void RendererVulkan::DestroyGeometry(uint64_t resource_id) {
|
||||||
|
|
|
@ -40,6 +40,14 @@ class RendererVulkan final : public Renderer {
|
||||||
void ResetScissor() final;
|
void ResetScissor() final;
|
||||||
|
|
||||||
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;
|
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;
|
||||||
|
uint64_t CreateGeometry(Primitive primitive,
|
||||||
|
VertexDescription vertex_description,
|
||||||
|
DataType index_description = kDataType_Invalid) final;
|
||||||
|
void UpdateGeometry(uint64_t resource_id,
|
||||||
|
size_t num_vertices,
|
||||||
|
const void* vertices,
|
||||||
|
size_t num_indices,
|
||||||
|
const void* indices) final;
|
||||||
void DestroyGeometry(uint64_t resource_id) final;
|
void DestroyGeometry(uint64_t resource_id) final;
|
||||||
void Draw(uint64_t resource_id,
|
void Draw(uint64_t resource_id,
|
||||||
uint64_t num_indices = 0,
|
uint64_t num_indices = 0,
|
||||||
|
@ -107,11 +115,13 @@ class RendererVulkan final : public Renderer {
|
||||||
|
|
||||||
struct GeometryVulkan {
|
struct GeometryVulkan {
|
||||||
Buffer<VkBuffer> buffer;
|
Buffer<VkBuffer> buffer;
|
||||||
|
size_t buffer_size = 0;
|
||||||
uint32_t num_vertices = 0;
|
uint32_t num_vertices = 0;
|
||||||
uint32_t num_indices = 0;
|
uint32_t num_indices = 0;
|
||||||
|
size_t vertex_size = 0;
|
||||||
uint64_t index_data_offset = 0;
|
uint64_t index_data_offset = 0;
|
||||||
uint64_t index_type_size = 0;
|
uint64_t index_type_size = 0;
|
||||||
VkIndexType index_type = VK_INDEX_TYPE_UINT16;
|
VkIndexType index_type = VK_INDEX_TYPE_NONE_KHR;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ShaderVulkan {
|
struct ShaderVulkan {
|
||||||
|
|
Loading…
Reference in New Issue