mirror of https://github.com/auygun/kaliber.git
Renderer code refactoring.
This commit is contained in:
parent
79d9d294e6
commit
042bffaff3
|
@ -81,7 +81,6 @@ add_library(kaliber SHARED
|
|||
../../../src/engine/renderer/opengl/render_command.cc
|
||||
../../../src/engine/renderer/opengl/renderer_opengl_android.cc
|
||||
../../../src/engine/renderer/opengl/renderer_opengl.cc
|
||||
../../../src/engine/renderer/render_resource.cc
|
||||
../../../src/engine/renderer/renderer_types.cc
|
||||
../../../src/engine/renderer/shader.cc
|
||||
../../../src/engine/renderer/texture.cc
|
||||
|
|
|
@ -106,7 +106,6 @@ GLTEST_SRC := \
|
|||
$(SRC_ROOT)/engine/renderer/opengl/render_command.cc \
|
||||
$(SRC_ROOT)/engine/renderer/opengl/renderer_opengl_linux.cc \
|
||||
$(SRC_ROOT)/engine/renderer/opengl/renderer_opengl.cc \
|
||||
$(SRC_ROOT)/engine/renderer/render_resource.cc \
|
||||
$(SRC_ROOT)/engine/renderer/renderer_types.cc \
|
||||
$(SRC_ROOT)/engine/renderer/shader.cc \
|
||||
$(SRC_ROOT)/engine/renderer/texture.cc \
|
||||
|
|
|
@ -8,7 +8,6 @@ source_set("engine") {
|
|||
"audio/audio_base.cc",
|
||||
"audio/audio_base.h",
|
||||
"audio/audio_forward.h",
|
||||
"audio/audio_sample.h",
|
||||
"audio/audio.h",
|
||||
"drawable.cc",
|
||||
"drawable.h",
|
||||
|
@ -29,9 +28,7 @@ source_set("engine") {
|
|||
"persistent_data.h",
|
||||
"platform/asset_file.cc",
|
||||
"platform/asset_file.h",
|
||||
"platform/platform_base.cc",
|
||||
"platform/platform_base.h",
|
||||
"platform/platform_forward.h",
|
||||
"platform/platform.cc",
|
||||
"platform/platform.h",
|
||||
"renderer/geometry.cc",
|
||||
"renderer/geometry.h",
|
||||
|
@ -40,7 +37,6 @@ source_set("engine") {
|
|||
"renderer/opengl/render_command.h",
|
||||
"renderer/opengl/renderer_opengl.cc",
|
||||
"renderer/opengl/renderer_opengl.h",
|
||||
"renderer/render_resource.cc",
|
||||
"renderer/render_resource.h",
|
||||
"renderer/renderer_types.cc",
|
||||
"renderer/renderer_types.h",
|
||||
|
|
|
@ -440,16 +440,13 @@ bool Engine::IsMobile() const {
|
|||
return platform_->mobile_device();
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderResource> Engine::CreateRenderResourceInternal(
|
||||
RenderResourceFactoryBase& factory) {
|
||||
return renderer_->CreateResource(factory);
|
||||
}
|
||||
|
||||
void Engine::ContextLost() {
|
||||
CreateRenderResources();
|
||||
|
||||
for (auto& t : textures_)
|
||||
for (auto& t : textures_) {
|
||||
t.second.texture->Destroy();
|
||||
RefreshImage(t.first);
|
||||
}
|
||||
|
||||
game_->ContextLost();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "../base/vecmath.h"
|
||||
#include "audio/audio_forward.h"
|
||||
#include "persistent_data.h"
|
||||
#include "renderer/render_resource.h"
|
||||
|
||||
class TextureCompressor;
|
||||
|
||||
|
@ -65,10 +64,7 @@ class Engine {
|
|||
|
||||
template <typename T>
|
||||
std::unique_ptr<T> CreateRenderResource() {
|
||||
RenderResourceFactory<T> factory;
|
||||
std::unique_ptr<RenderResource> resource =
|
||||
CreateRenderResourceInternal(factory);
|
||||
return std::unique_ptr<T>(static_cast<T*>(resource.release()));
|
||||
return std::unique_ptr<T>(static_cast<T*>(new T(renderer_)));
|
||||
}
|
||||
|
||||
void SetImageSource(const std::string& asset_name,
|
||||
|
@ -212,9 +208,6 @@ class Engine {
|
|||
|
||||
base::Random random_;
|
||||
|
||||
std::unique_ptr<RenderResource> CreateRenderResourceInternal(
|
||||
RenderResourceFactoryBase& factory);
|
||||
|
||||
void ContextLost();
|
||||
|
||||
bool CreateRenderResources();
|
||||
|
|
|
@ -5,10 +5,7 @@
|
|||
|
||||
namespace eng {
|
||||
|
||||
Geometry::Geometry(unsigned resource_id,
|
||||
std::shared_ptr<void> impl_data,
|
||||
Renderer* renderer)
|
||||
: RenderResource(resource_id, impl_data, renderer) {}
|
||||
Geometry::Geometry(Renderer* renderer) : RenderResource(renderer) {}
|
||||
|
||||
Geometry::~Geometry() {
|
||||
Destroy();
|
||||
|
@ -16,22 +13,21 @@ Geometry::~Geometry() {
|
|||
|
||||
void Geometry::Create(std::unique_ptr<Mesh> mesh) {
|
||||
Destroy();
|
||||
valid_ = true;
|
||||
vertex_description_ = mesh->vertex_description();
|
||||
primitive_ = mesh->primitive();
|
||||
renderer_->CreateGeometry(impl_data_, std::move(mesh));
|
||||
resource_id_ = renderer_->CreateGeometry(std::move(mesh));
|
||||
}
|
||||
|
||||
void Geometry::Destroy() {
|
||||
if (valid_) {
|
||||
renderer_->DestroyGeometry(impl_data_);
|
||||
valid_ = false;
|
||||
if (IsValid()) {
|
||||
renderer_->DestroyGeometry(resource_id_);
|
||||
resource_id_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Geometry::Draw() {
|
||||
if (valid_)
|
||||
renderer_->Draw(impl_data_);
|
||||
if (IsValid())
|
||||
renderer_->Draw(resource_id_);
|
||||
}
|
||||
|
||||
} // namespace eng
|
||||
|
|
|
@ -14,14 +14,12 @@ class Mesh;
|
|||
|
||||
class Geometry : public RenderResource {
|
||||
public:
|
||||
Geometry(unsigned resource_id,
|
||||
std::shared_ptr<void> impl_data,
|
||||
Renderer* renderer);
|
||||
~Geometry() override;
|
||||
Geometry(Renderer* renderer);
|
||||
~Geometry();
|
||||
|
||||
void Create(std::unique_ptr<Mesh> mesh);
|
||||
|
||||
void Destroy() override;
|
||||
void Destroy();
|
||||
|
||||
void Draw();
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
namespace eng {
|
||||
|
||||
RENDER_COMMAND_IMPL(CmdPresent, false);
|
||||
RENDER_COMMAND_IMPL(CmdInvalidateAllResources, true);
|
||||
RENDER_COMMAND_IMPL(CmdCreateTexture, true);
|
||||
RENDER_COMMAND_IMPL(CmdUpdateTexture, true);
|
||||
RENDER_COMMAND_IMPL(CmdDestoryTexture, true);
|
||||
RENDER_COMMAND_IMPL(CmdActivateTexture, false);
|
||||
|
|
|
@ -50,81 +50,88 @@ struct RenderCommand {
|
|||
RENDER_COMMAND_BEGIN(CmdPresent)
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdInvalidateAllResources)
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdCreateTexture)
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdUpdateTexture)
|
||||
std::unique_ptr<Image> image;
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdDestoryTexture)
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdActivateTexture)
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdCreateGeometry)
|
||||
std::unique_ptr<Mesh> mesh;
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdDestroyGeometry)
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdDrawGeometry)
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdCreateShader)
|
||||
std::unique_ptr<ShaderSource> source;
|
||||
VertexDescripton vertex_description;
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
bool enable_depth_test;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdDestroyShader)
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdActivateShader)
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdSetUniformVec2)
|
||||
std::string name;
|
||||
base::Vector2f v;
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdSetUniformVec3)
|
||||
std::string name;
|
||||
base::Vector3f v;
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdSetUniformVec4)
|
||||
std::string name;
|
||||
base::Vector4f v;
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdSetUniformMat4)
|
||||
std::string name;
|
||||
base::Matrix4f m;
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdSetUniformInt)
|
||||
std::string name;
|
||||
int i;
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
RENDER_COMMAND_BEGIN(CmdSetUniformFloat)
|
||||
std::string name;
|
||||
float f;
|
||||
std::shared_ptr<void> impl_data;
|
||||
uint64_t resource_id;
|
||||
RENDER_COMMAND_END
|
||||
|
||||
} // namespace eng
|
||||
|
|
|
@ -45,47 +45,54 @@ RendererOpenGL::RendererOpenGL() = default;
|
|||
|
||||
RendererOpenGL::~RendererOpenGL() = default;
|
||||
|
||||
void RendererOpenGL::CreateGeometry(std::shared_ptr<void> impl_data,
|
||||
std::unique_ptr<Mesh> mesh) {
|
||||
uint64_t RendererOpenGL::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
||||
auto cmd = std::make_unique<CmdCreateGeometry>();
|
||||
cmd->mesh = std::move(mesh);
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = ++last_resource_id_;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
return last_resource_id_;
|
||||
}
|
||||
|
||||
void RendererOpenGL::DestroyGeometry(std::shared_ptr<void> impl_data) {
|
||||
void RendererOpenGL::DestroyGeometry(uint64_t resource_id) {
|
||||
auto cmd = std::make_unique<CmdDestroyGeometry>();
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::Draw(std::shared_ptr<void> impl_data) {
|
||||
void RendererOpenGL::Draw(uint64_t resource_id) {
|
||||
auto cmd = std::make_unique<CmdDrawGeometry>();
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::UpdateTexture(std::shared_ptr<void> impl_data,
|
||||
uint64_t RendererOpenGL::CreateTexture() {
|
||||
auto cmd = std::make_unique<CmdCreateTexture>();
|
||||
cmd->resource_id = ++last_resource_id_;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
return last_resource_id_;
|
||||
}
|
||||
|
||||
void RendererOpenGL::UpdateTexture(uint64_t resource_id,
|
||||
std::unique_ptr<Image> image) {
|
||||
auto cmd = std::make_unique<CmdUpdateTexture>();
|
||||
cmd->image = std::move(image);
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::DestroyTexture(std::shared_ptr<void> impl_data) {
|
||||
void RendererOpenGL::DestroyTexture(uint64_t resource_id) {
|
||||
auto cmd = std::make_unique<CmdDestoryTexture>();
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::ActivateTexture(std::shared_ptr<void> impl_data) {
|
||||
void RendererOpenGL::ActivateTexture(uint64_t resource_id) {
|
||||
auto cmd = std::make_unique<CmdActivateTexture>();
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::CreateShader(std::shared_ptr<void> impl_data,
|
||||
uint64_t RendererOpenGL::CreateShader(
|
||||
std::unique_ptr<ShaderSource> source,
|
||||
const VertexDescripton& vertex_description,
|
||||
Primitive primitive,
|
||||
|
@ -93,80 +100,81 @@ void RendererOpenGL::CreateShader(std::shared_ptr<void> impl_data,
|
|||
auto cmd = std::make_unique<CmdCreateShader>();
|
||||
cmd->source = std::move(source);
|
||||
cmd->vertex_description = vertex_description;
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = ++last_resource_id_;
|
||||
cmd->enable_depth_test = enable_depth_test;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
return last_resource_id_;
|
||||
}
|
||||
|
||||
void RendererOpenGL::DestroyShader(std::shared_ptr<void> impl_data) {
|
||||
void RendererOpenGL::DestroyShader(uint64_t resource_id) {
|
||||
auto cmd = std::make_unique<CmdDestroyShader>();
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::ActivateShader(std::shared_ptr<void> impl_data) {
|
||||
void RendererOpenGL::ActivateShader(uint64_t resource_id) {
|
||||
auto cmd = std::make_unique<CmdActivateShader>();
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererOpenGL::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector2f& val) {
|
||||
auto cmd = std::make_unique<CmdSetUniformVec2>();
|
||||
cmd->name = name;
|
||||
cmd->v = val;
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererOpenGL::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector3f& val) {
|
||||
auto cmd = std::make_unique<CmdSetUniformVec3>();
|
||||
cmd->name = name;
|
||||
cmd->v = val;
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererOpenGL::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector4f& val) {
|
||||
auto cmd = std::make_unique<CmdSetUniformVec4>();
|
||||
cmd->name = name;
|
||||
cmd->v = val;
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererOpenGL::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Matrix4f& val) {
|
||||
auto cmd = std::make_unique<CmdSetUniformMat4>();
|
||||
cmd->name = name;
|
||||
cmd->m = val;
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererOpenGL::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
float val) {
|
||||
auto cmd = std::make_unique<CmdSetUniformFloat>();
|
||||
cmd->name = name;
|
||||
cmd->f = val;
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
void RendererOpenGL::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererOpenGL::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
int val) {
|
||||
auto cmd = std::make_unique<CmdSetUniformInt>();
|
||||
cmd->name = name;
|
||||
cmd->i = val;
|
||||
cmd->impl_data = impl_data;
|
||||
cmd->resource_id = resource_id;
|
||||
EnqueueCommand(std::move(cmd));
|
||||
}
|
||||
|
||||
|
@ -182,47 +190,21 @@ void RendererOpenGL::ContextLost() {
|
|||
LOG << "Context lost.";
|
||||
|
||||
#ifdef THREADED_RENDERING
|
||||
{
|
||||
std::unique_lock<std::mutex> scoped_lock(mutex_);
|
||||
global_commands_.clear();
|
||||
draw_commands_[0].clear();
|
||||
draw_commands_[1].clear();
|
||||
}
|
||||
|
||||
main_thread_task_runner_->PostTask(
|
||||
HERE, std::bind(&RendererOpenGL::InvalidateAllResources, this));
|
||||
DestroyAllResources();
|
||||
main_thread_task_runner_->PostTask(HERE, context_lost_cb_);
|
||||
#else
|
||||
InvalidateAllResources();
|
||||
DestroyAllResources();
|
||||
context_lost_cb_();
|
||||
#endif // THREADED_RENDERING
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderResource> RendererOpenGL::CreateResource(
|
||||
RenderResourceFactoryBase& factory) {
|
||||
static unsigned last_id = 0;
|
||||
|
||||
// Set implementation specific data. This data will be sent with render
|
||||
// commands to the render thread and sould not be used in any other thread.
|
||||
std::shared_ptr<void> impl_data;
|
||||
if (factory.IsTypeOf<Geometry>())
|
||||
impl_data = std::make_shared<GeometryOpenGL>();
|
||||
else if (factory.IsTypeOf<Shader>())
|
||||
impl_data = std::make_shared<ShaderOpenGL>();
|
||||
else if (factory.IsTypeOf<Texture>())
|
||||
impl_data = std::make_shared<TextureOpenGL>();
|
||||
else
|
||||
NOTREACHED << "- Unknown resource type.";
|
||||
|
||||
unsigned resource_id = ++last_id;
|
||||
auto resource = factory.Create(resource_id, impl_data, this);
|
||||
resources_[resource_id] = resource.get();
|
||||
return resource;
|
||||
}
|
||||
|
||||
void RendererOpenGL::ReleaseResource(unsigned resource_id) {
|
||||
auto it = resources_.find(resource_id);
|
||||
if (it != resources_.end())
|
||||
resources_.erase(it);
|
||||
}
|
||||
|
||||
size_t RendererOpenGL::GetAndResetFPS() {
|
||||
int ret = fps_;
|
||||
fps_ = 0;
|
||||
|
@ -309,9 +291,37 @@ bool RendererOpenGL::InitCommon() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void RendererOpenGL::InvalidateAllResources() {
|
||||
for (auto& r : resources_)
|
||||
r.second->Destroy();
|
||||
void RendererOpenGL::DestroyAllResources() {
|
||||
std::vector<uint64_t> resource_ids;
|
||||
for (auto& r : geometries_)
|
||||
resource_ids.push_back(r.first);
|
||||
for (auto& r : resource_ids) {
|
||||
auto cmd = std::make_unique<CmdDestroyGeometry>();
|
||||
cmd->resource_id = r;
|
||||
ProcessCommand(cmd.get());
|
||||
}
|
||||
|
||||
resource_ids.clear();
|
||||
for (auto& r : shaders_)
|
||||
resource_ids.push_back(r.first);
|
||||
for (auto& r : resource_ids) {
|
||||
auto cmd = std::make_unique<CmdDestroyShader>();
|
||||
cmd->resource_id = r;
|
||||
ProcessCommand(cmd.get());
|
||||
}
|
||||
|
||||
resource_ids.clear();
|
||||
for (auto& r : textures_)
|
||||
resource_ids.push_back(r.first);
|
||||
for (auto& r : resource_ids) {
|
||||
auto cmd = std::make_unique<CmdDestoryTexture>();
|
||||
cmd->resource_id = r;
|
||||
ProcessCommand(cmd.get());
|
||||
}
|
||||
|
||||
DCHECK(geometries_.size() == 0);
|
||||
DCHECK(shaders_.size() == 0);
|
||||
DCHECK(textures_.size() == 0);
|
||||
}
|
||||
|
||||
bool RendererOpenGL::StartRenderThread() {
|
||||
|
@ -425,6 +435,9 @@ void RendererOpenGL::ProcessCommand(RenderCommand* cmd) {
|
|||
case CmdPresent::CMD_ID:
|
||||
HandleCmdPresent(cmd);
|
||||
break;
|
||||
case CmdCreateTexture::CMD_ID:
|
||||
HandleCmdCreateTexture(cmd);
|
||||
break;
|
||||
case CmdUpdateTexture::CMD_ID:
|
||||
HandleCmdUpdateTexture(cmd);
|
||||
break;
|
||||
|
@ -475,18 +488,29 @@ void RendererOpenGL::ProcessCommand(RenderCommand* cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdUpdateTexture(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdUpdateTexture*>(cmd);
|
||||
auto impl_data = reinterpret_cast<TextureOpenGL*>(c->impl_data.get());
|
||||
bool new_texture = impl_data->id == 0;
|
||||
void RendererOpenGL::HandleCmdCreateTexture(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdCreateTexture*>(cmd);
|
||||
|
||||
GLuint gl_id = 0;
|
||||
if (new_texture)
|
||||
glGenTextures(1, &gl_id);
|
||||
else
|
||||
gl_id = impl_data->id;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gl_id);
|
||||
BindTexture(gl_id);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
textures_.insert({c->resource_id, {gl_id}});
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdUpdateTexture(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdUpdateTexture*>(cmd);
|
||||
auto it = textures_.find(c->resource_id);
|
||||
if (it == textures_.end())
|
||||
return;
|
||||
|
||||
BindTexture(it->second.id);
|
||||
if (c->image->IsCompressed()) {
|
||||
GLenum format = 0;
|
||||
switch (c->image->GetFormat()) {
|
||||
|
@ -515,8 +539,8 @@ void RendererOpenGL::HandleCmdUpdateTexture(RenderCommand* cmd) {
|
|||
c->image->GetHeight(), 0, c->image->GetSize(),
|
||||
c->image->GetBuffer());
|
||||
|
||||
// Sometimes the first glCompressedTexImage2D call after context-lost
|
||||
// generates GL_INVALID_VALUE.
|
||||
// On some devices the first glCompressedTexImage2D call after context-lost
|
||||
// returns GL_INVALID_VALUE for some reason.
|
||||
GLenum err = glGetError();
|
||||
if (err == GL_INVALID_VALUE) {
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, c->image->GetWidth(),
|
||||
|
@ -532,40 +556,30 @@ void RendererOpenGL::HandleCmdUpdateTexture(RenderCommand* cmd) {
|
|||
c->image->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
c->image->GetBuffer());
|
||||
}
|
||||
|
||||
if (new_texture) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
*impl_data = {gl_id};
|
||||
}
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdDestoryTexture(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdDestoryTexture*>(cmd);
|
||||
auto impl_data = reinterpret_cast<TextureOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->id > 0) {
|
||||
glDeleteTextures(1, &(impl_data->id));
|
||||
*impl_data = {};
|
||||
}
|
||||
auto it = textures_.find(c->resource_id);
|
||||
if (it == textures_.end())
|
||||
return;
|
||||
|
||||
glDeleteTextures(1, &(it->second.id));
|
||||
textures_.erase(it);
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdActivateTexture(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdActivateTexture*>(cmd);
|
||||
auto impl_data = reinterpret_cast<TextureOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->id > 0 && impl_data->id != active_texture_id_) {
|
||||
glBindTexture(GL_TEXTURE_2D, impl_data->id);
|
||||
active_texture_id_ = impl_data->id;
|
||||
auto it = textures_.find(c->resource_id);
|
||||
if (it == textures_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BindTexture(it->second.id);
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdCreateGeometry(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdCreateGeometry*>(cmd);
|
||||
auto impl_data = reinterpret_cast<GeometryOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->vertex_buffer_id > 0)
|
||||
return;
|
||||
|
||||
// Verify that we have a valid layout and get the total byte size per vertex.
|
||||
GLuint vertex_size = c->mesh->GetVertexSize();
|
||||
|
@ -613,7 +627,7 @@ void RendererOpenGL::HandleCmdCreateGeometry(RenderCommand* cmd) {
|
|||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
*impl_data = {(GLsizei)c->mesh->num_vertices(),
|
||||
geometries_[c->resource_id] = {(GLsizei)c->mesh->num_vertices(),
|
||||
(GLsizei)c->mesh->num_indices(),
|
||||
kGlPrimitive[c->mesh->primitive()],
|
||||
kGlDataType[c->mesh->index_description()],
|
||||
|
@ -626,58 +640,58 @@ void RendererOpenGL::HandleCmdCreateGeometry(RenderCommand* cmd) {
|
|||
|
||||
void RendererOpenGL::HandleCmdDestroyGeometry(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdDestroyGeometry*>(cmd);
|
||||
auto impl_data = reinterpret_cast<GeometryOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->vertex_buffer_id == 0)
|
||||
auto it = geometries_.find(c->resource_id);
|
||||
if (it == geometries_.end())
|
||||
return;
|
||||
|
||||
if (impl_data->index_buffer_id)
|
||||
glDeleteBuffers(1, &(impl_data->index_buffer_id));
|
||||
if (impl_data->vertex_buffer_id)
|
||||
glDeleteBuffers(1, &(impl_data->vertex_buffer_id));
|
||||
if (impl_data->vertex_array_id)
|
||||
glDeleteVertexArrays(1, &(impl_data->vertex_array_id));
|
||||
if (it->second.index_buffer_id)
|
||||
glDeleteBuffers(1, &(it->second.index_buffer_id));
|
||||
if (it->second.vertex_buffer_id)
|
||||
glDeleteBuffers(1, &(it->second.vertex_buffer_id));
|
||||
if (it->second.vertex_array_id)
|
||||
glDeleteVertexArrays(1, &(it->second.vertex_array_id));
|
||||
|
||||
*impl_data = {};
|
||||
geometries_.erase(it);
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdDrawGeometry(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdDrawGeometry*>(cmd);
|
||||
auto impl_data = reinterpret_cast<GeometryOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->vertex_buffer_id == 0)
|
||||
auto it = geometries_.find(c->resource_id);
|
||||
if (it == geometries_.end())
|
||||
return;
|
||||
|
||||
// Set up the vertex data.
|
||||
if (impl_data->vertex_array_id)
|
||||
glBindVertexArray(impl_data->vertex_array_id);
|
||||
if (it->second.vertex_array_id)
|
||||
glBindVertexArray(it->second.vertex_array_id);
|
||||
else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, impl_data->vertex_buffer_id);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, it->second.vertex_buffer_id);
|
||||
for (GLuint attribute_index = 0;
|
||||
attribute_index < (GLuint)impl_data->vertex_layout.size();
|
||||
attribute_index < (GLuint)it->second.vertex_layout.size();
|
||||
++attribute_index) {
|
||||
GeometryOpenGL::Element& e = impl_data->vertex_layout[attribute_index];
|
||||
GeometryOpenGL::Element& e = it->second.vertex_layout[attribute_index];
|
||||
glEnableVertexAttribArray(attribute_index);
|
||||
glVertexAttribPointer(attribute_index, e.num_elements, e.type, GL_FALSE,
|
||||
impl_data->vertex_size,
|
||||
it->second.vertex_size,
|
||||
(const GLvoid*)e.vertex_offset);
|
||||
}
|
||||
|
||||
if (impl_data->num_indices > 0)
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, impl_data->index_buffer_id);
|
||||
if (it->second.num_indices > 0)
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, it->second.index_buffer_id);
|
||||
}
|
||||
|
||||
// Draw the primitive.
|
||||
if (impl_data->num_indices > 0)
|
||||
glDrawElements(impl_data->primitive, impl_data->num_indices,
|
||||
impl_data->index_type, NULL);
|
||||
if (it->second.num_indices > 0)
|
||||
glDrawElements(it->second.primitive, it->second.num_indices,
|
||||
it->second.index_type, NULL);
|
||||
else
|
||||
glDrawArrays(impl_data->primitive, 0, impl_data->num_vertices);
|
||||
glDrawArrays(it->second.primitive, 0, it->second.num_vertices);
|
||||
|
||||
// Clean up states.
|
||||
if (impl_data->vertex_array_id)
|
||||
if (it->second.vertex_array_id)
|
||||
glBindVertexArray(0);
|
||||
else {
|
||||
for (GLuint attribute_index = 0;
|
||||
attribute_index < (GLuint)impl_data->vertex_layout.size();
|
||||
attribute_index < (GLuint)it->second.vertex_layout.size();
|
||||
++attribute_index)
|
||||
glDisableVertexAttribArray(attribute_index);
|
||||
|
||||
|
@ -688,9 +702,6 @@ void RendererOpenGL::HandleCmdDrawGeometry(RenderCommand* cmd) {
|
|||
|
||||
void RendererOpenGL::HandleCmdCreateShader(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdCreateShader*>(cmd);
|
||||
auto impl_data = reinterpret_cast<ShaderOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->id > 0)
|
||||
return;
|
||||
|
||||
GLuint vertex_shader =
|
||||
CreateShader(c->source->GetVertexSource(), GL_VERTEX_SHADER);
|
||||
|
@ -728,25 +739,29 @@ void RendererOpenGL::HandleCmdCreateShader(RenderCommand* cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
*impl_data = {id, {}, c->enable_depth_test};
|
||||
shaders_[c->resource_id] = {id, {}, c->enable_depth_test};
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdDestroyShader(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdDestroyShader*>(cmd);
|
||||
auto impl_data = reinterpret_cast<ShaderOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->id > 0) {
|
||||
glDeleteProgram(impl_data->id);
|
||||
*impl_data = {};
|
||||
}
|
||||
auto it = shaders_.find(c->resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
glDeleteProgram(it->second.id);
|
||||
shaders_.erase(it);
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdActivateShader(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdActivateShader*>(cmd);
|
||||
auto impl_data = reinterpret_cast<ShaderOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->id > 0 && impl_data->id != active_shader_id_) {
|
||||
glUseProgram(impl_data->id);
|
||||
active_shader_id_ = impl_data->id;
|
||||
if (impl_data->enable_depth_test)
|
||||
auto it = shaders_.find(c->resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
if (it->second.id != active_shader_id_) {
|
||||
glUseProgram(it->second.id);
|
||||
active_shader_id_ = it->second.id;
|
||||
if (it->second.enable_depth_test)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
else
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
@ -755,67 +770,74 @@ void RendererOpenGL::HandleCmdActivateShader(RenderCommand* cmd) {
|
|||
|
||||
void RendererOpenGL::HandleCmdSetUniformVec2(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdSetUniformVec2*>(cmd);
|
||||
auto impl_data = reinterpret_cast<ShaderOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->id > 0) {
|
||||
GLint index =
|
||||
GetUniformLocation(impl_data->id, c->name, impl_data->uniforms);
|
||||
auto it = shaders_.find(c->resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms);
|
||||
if (index >= 0)
|
||||
glUniform2fv(index, 1, c->v.GetData());
|
||||
}
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdSetUniformVec3(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdSetUniformVec3*>(cmd);
|
||||
auto impl_data = reinterpret_cast<ShaderOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->id > 0) {
|
||||
GLint index =
|
||||
GetUniformLocation(impl_data->id, c->name, impl_data->uniforms);
|
||||
auto it = shaders_.find(c->resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms);
|
||||
if (index >= 0)
|
||||
glUniform3fv(index, 1, c->v.GetData());
|
||||
}
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdSetUniformVec4(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdSetUniformVec4*>(cmd);
|
||||
auto impl_data = reinterpret_cast<ShaderOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->id > 0) {
|
||||
GLint index =
|
||||
GetUniformLocation(impl_data->id, c->name, impl_data->uniforms);
|
||||
auto it = shaders_.find(c->resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms);
|
||||
if (index >= 0)
|
||||
glUniform4fv(index, 1, c->v.GetData());
|
||||
}
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdSetUniformMat4(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdSetUniformMat4*>(cmd);
|
||||
auto impl_data = reinterpret_cast<ShaderOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->id > 0) {
|
||||
GLint index =
|
||||
GetUniformLocation(impl_data->id, c->name, impl_data->uniforms);
|
||||
auto it = shaders_.find(c->resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms);
|
||||
if (index >= 0)
|
||||
glUniformMatrix4fv(index, 1, GL_FALSE, c->m.GetData());
|
||||
}
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdSetUniformFloat(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdSetUniformFloat*>(cmd);
|
||||
auto impl_data = reinterpret_cast<ShaderOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->id > 0) {
|
||||
GLint index =
|
||||
GetUniformLocation(impl_data->id, c->name, impl_data->uniforms);
|
||||
auto it = shaders_.find(c->resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms);
|
||||
if (index >= 0)
|
||||
glUniform1f(index, c->f);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererOpenGL::HandleCmdSetUniformInt(RenderCommand* cmd) {
|
||||
auto* c = static_cast<CmdSetUniformInt*>(cmd);
|
||||
auto impl_data = reinterpret_cast<ShaderOpenGL*>(c->impl_data.get());
|
||||
if (impl_data->id > 0) {
|
||||
GLint index =
|
||||
GetUniformLocation(impl_data->id, c->name, impl_data->uniforms);
|
||||
auto it = shaders_.find(c->resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms);
|
||||
if (index >= 0)
|
||||
glUniform1i(index, c->i);
|
||||
}
|
||||
|
||||
void RendererOpenGL::BindTexture(GLuint id) {
|
||||
if (id != active_texture_id_) {
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
active_texture_id_ = id;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include "opengl.h"
|
||||
|
||||
#include "../render_resource.h"
|
||||
#include "../renderer.h"
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
@ -50,51 +49,46 @@ class RendererOpenGL : public Renderer {
|
|||
|
||||
void Shutdown() override;
|
||||
|
||||
void CreateGeometry(std::shared_ptr<void> impl_data,
|
||||
std::unique_ptr<Mesh> mesh) override;
|
||||
void DestroyGeometry(std::shared_ptr<void> impl_data) override;
|
||||
void Draw(std::shared_ptr<void> impl_data) override;
|
||||
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) override;
|
||||
void DestroyGeometry(uint64_t resource_id) override;
|
||||
void Draw(uint64_t resource_id) override;
|
||||
|
||||
void UpdateTexture(std::shared_ptr<void> impl_data,
|
||||
uint64_t CreateTexture() override;
|
||||
void UpdateTexture(uint64_t resource_id,
|
||||
std::unique_ptr<Image> image) override;
|
||||
void DestroyTexture(std::shared_ptr<void> impl_data) override;
|
||||
void ActivateTexture(std::shared_ptr<void> impl_data) override;
|
||||
void DestroyTexture(uint64_t resource_id) override;
|
||||
void ActivateTexture(uint64_t resource_id) override;
|
||||
|
||||
void CreateShader(std::shared_ptr<void> impl_data,
|
||||
std::unique_ptr<ShaderSource> source,
|
||||
uint64_t CreateShader(std::unique_ptr<ShaderSource> source,
|
||||
const VertexDescripton& vertex_description,
|
||||
Primitive primitive,
|
||||
bool enable_depth_test) override;
|
||||
void DestroyShader(std::shared_ptr<void> impl_data) override;
|
||||
void ActivateShader(std::shared_ptr<void> impl_data) override;
|
||||
void DestroyShader(uint64_t resource_id) override;
|
||||
void ActivateShader(uint64_t resource_id) override;
|
||||
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector2f& val) override;
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector3f& val) override;
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector4f& val) override;
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Matrix4f& val) override;
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
float val) override;
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
int val) override;
|
||||
void UploadUniforms(std::shared_ptr<void> impl_data) override {}
|
||||
void UploadUniforms(uint64_t resource_id) override {}
|
||||
|
||||
void PrepareForDrawing() override {}
|
||||
void Present() override;
|
||||
|
||||
std::unique_ptr<RenderResource> CreateResource(
|
||||
RenderResourceFactoryBase& factory) override;
|
||||
void ReleaseResource(unsigned resource_id) override;
|
||||
|
||||
size_t GetAndResetFPS() override;
|
||||
|
||||
#if defined(__linux__) && !defined(__ANDROID__)
|
||||
|
@ -130,14 +124,17 @@ class RendererOpenGL : public Renderer {
|
|||
GLuint id = 0;
|
||||
};
|
||||
|
||||
std::unordered_map<uint64_t, GeometryOpenGL> geometries_;
|
||||
std::unordered_map<uint64_t, ShaderOpenGL> shaders_;
|
||||
std::unordered_map<uint64_t, TextureOpenGL> textures_;
|
||||
uint64_t last_resource_id_ = 0;
|
||||
|
||||
GLuint active_shader_id_ = 0;
|
||||
GLuint active_texture_id_ = 0;
|
||||
|
||||
bool vertex_array_objects_ = false;
|
||||
bool npot_ = false;
|
||||
|
||||
std::unordered_map<unsigned, RenderResource*> resources_;
|
||||
|
||||
#ifdef THREADED_RENDERING
|
||||
// Global commands are independent from frames and guaranteed to be processed.
|
||||
std::deque<std::unique_ptr<RenderCommand>> global_commands_;
|
||||
|
@ -172,7 +169,7 @@ class RendererOpenGL : public Renderer {
|
|||
|
||||
void ContextLost();
|
||||
|
||||
void InvalidateAllResources();
|
||||
void DestroyAllResources();
|
||||
|
||||
bool StartRenderThread();
|
||||
void TerminateRenderThread();
|
||||
|
@ -185,6 +182,7 @@ class RendererOpenGL : public Renderer {
|
|||
void ProcessCommand(RenderCommand* cmd);
|
||||
|
||||
void HandleCmdPresent(RenderCommand* cmd);
|
||||
void HandleCmdCreateTexture(RenderCommand* cmd);
|
||||
void HandleCmdUpdateTexture(RenderCommand* cmd);
|
||||
void HandleCmdDestoryTexture(RenderCommand* cmd);
|
||||
void HandleCmdActivateTexture(RenderCommand* cmd);
|
||||
|
@ -201,6 +199,7 @@ class RendererOpenGL : public Renderer {
|
|||
void HandleCmdSetUniformFloat(RenderCommand* cmd);
|
||||
void HandleCmdSetUniformInt(RenderCommand* cmd);
|
||||
|
||||
void BindTexture(GLuint id);
|
||||
bool SetupVertexLayout(const VertexDescripton& vd,
|
||||
GLuint vertex_size,
|
||||
bool use_vao,
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
#include "render_resource.h"
|
||||
|
||||
#include "renderer.h"
|
||||
|
||||
namespace eng {
|
||||
|
||||
RenderResource::RenderResource(unsigned resource_id,
|
||||
std::shared_ptr<void> impl_data,
|
||||
Renderer* renderer)
|
||||
: resource_id_(resource_id), impl_data_(impl_data), renderer_(renderer) {}
|
||||
|
||||
RenderResource::~RenderResource() {
|
||||
renderer_->ReleaseResource(resource_id_);
|
||||
}
|
||||
|
||||
} // namespace eng
|
|
@ -1,10 +1,7 @@
|
|||
#ifndef RENDER_RESOURCE_H
|
||||
#define RENDER_RESOURCE_H
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <typeindex>
|
||||
#include <typeinfo>
|
||||
#include <cstdint>
|
||||
|
||||
namespace eng {
|
||||
|
||||
|
@ -12,60 +9,22 @@ class Renderer;
|
|||
|
||||
class RenderResource {
|
||||
public:
|
||||
RenderResource(unsigned resource_id,
|
||||
std::shared_ptr<void> impl_data,
|
||||
Renderer* renderer);
|
||||
virtual ~RenderResource();
|
||||
RenderResource(Renderer* renderer) : renderer_(renderer){};
|
||||
|
||||
virtual void Destroy() = 0;
|
||||
bool IsValid() const { return resource_id_ != 0; }
|
||||
|
||||
bool IsValid() const { return valid_; }
|
||||
|
||||
std::shared_ptr<void> impl_data() { return impl_data_; }
|
||||
uint64_t resource_id() { return resource_id_; }
|
||||
|
||||
protected:
|
||||
unsigned resource_id_ = 0;
|
||||
std::shared_ptr<void> impl_data_; // For use in render thread only.
|
||||
bool valid_ = false;
|
||||
|
||||
uint64_t resource_id_ = 0;
|
||||
Renderer* renderer_ = nullptr;
|
||||
|
||||
~RenderResource() = default;
|
||||
|
||||
RenderResource(const RenderResource&) = delete;
|
||||
RenderResource& operator=(const RenderResource&) = delete;
|
||||
};
|
||||
|
||||
class RenderResourceFactoryBase {
|
||||
public:
|
||||
RenderResourceFactoryBase(std::type_index resource_type)
|
||||
: resource_type_(resource_type) {}
|
||||
virtual ~RenderResourceFactoryBase() = default;
|
||||
|
||||
virtual std::unique_ptr<eng::RenderResource>
|
||||
Create(unsigned id, std::shared_ptr<void> impl_data, Renderer* renderer) = 0;
|
||||
|
||||
template <typename T>
|
||||
bool IsTypeOf() const {
|
||||
return resource_type_ == std::type_index(typeid(T));
|
||||
}
|
||||
|
||||
private:
|
||||
std::type_index resource_type_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class RenderResourceFactory : public RenderResourceFactoryBase {
|
||||
public:
|
||||
RenderResourceFactory()
|
||||
: RenderResourceFactoryBase(std::type_index(typeid(T))) {}
|
||||
~RenderResourceFactory() override = default;
|
||||
|
||||
std::unique_ptr<eng::RenderResource> Create(unsigned id,
|
||||
std::shared_ptr<void> impl_data,
|
||||
Renderer* renderer) override {
|
||||
return std::make_unique<T>(id, impl_data, renderer);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace eng
|
||||
|
||||
#endif // RENDER_RESOURCE_H
|
||||
|
|
|
@ -40,51 +40,46 @@ class Renderer {
|
|||
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual void CreateGeometry(std::shared_ptr<void> impl_data,
|
||||
std::unique_ptr<Mesh> mesh) = 0;
|
||||
virtual void DestroyGeometry(std::shared_ptr<void> impl_data) = 0;
|
||||
virtual void Draw(std::shared_ptr<void> impl_data) = 0;
|
||||
virtual uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) = 0;
|
||||
virtual void DestroyGeometry(uint64_t resource_id) = 0;
|
||||
virtual void Draw(uint64_t resource_id) = 0;
|
||||
|
||||
virtual void UpdateTexture(std::shared_ptr<void> impl_data,
|
||||
virtual uint64_t CreateTexture() = 0;
|
||||
virtual void UpdateTexture(uint64_t resource_id,
|
||||
std::unique_ptr<Image> image) = 0;
|
||||
virtual void DestroyTexture(std::shared_ptr<void> impl_data) = 0;
|
||||
virtual void ActivateTexture(std::shared_ptr<void> impl_data) = 0;
|
||||
virtual void DestroyTexture(uint64_t resource_id) = 0;
|
||||
virtual void ActivateTexture(uint64_t resource_id) = 0;
|
||||
|
||||
virtual void CreateShader(std::shared_ptr<void> impl_data,
|
||||
std::unique_ptr<ShaderSource> source,
|
||||
virtual uint64_t CreateShader(std::unique_ptr<ShaderSource> source,
|
||||
const VertexDescripton& vertex_description,
|
||||
Primitive primitive,
|
||||
bool enable_depth_test) = 0;
|
||||
virtual void DestroyShader(std::shared_ptr<void> impl_data) = 0;
|
||||
virtual void ActivateShader(std::shared_ptr<void> impl_data) = 0;
|
||||
virtual void DestroyShader(uint64_t resource_id) = 0;
|
||||
virtual void ActivateShader(uint64_t resource_id) = 0;
|
||||
|
||||
virtual void SetUniform(std::shared_ptr<void> impl_data,
|
||||
virtual void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector2f& val) = 0;
|
||||
virtual void SetUniform(std::shared_ptr<void> impl_data,
|
||||
virtual void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector3f& val) = 0;
|
||||
virtual void SetUniform(std::shared_ptr<void> impl_data,
|
||||
virtual void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector4f& val) = 0;
|
||||
virtual void SetUniform(std::shared_ptr<void> impl_data,
|
||||
virtual void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Matrix4f& val) = 0;
|
||||
virtual void SetUniform(std::shared_ptr<void> impl_data,
|
||||
virtual void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
float val) = 0;
|
||||
virtual void SetUniform(std::shared_ptr<void> impl_data,
|
||||
virtual void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
int val) = 0;
|
||||
virtual void UploadUniforms(std::shared_ptr<void> impl_data) = 0;
|
||||
virtual void UploadUniforms(uint64_t resource_id) = 0;
|
||||
|
||||
virtual void PrepareForDrawing() = 0;
|
||||
virtual void Present() = 0;
|
||||
|
||||
virtual std::unique_ptr<RenderResource> CreateResource(
|
||||
RenderResourceFactoryBase& factory) = 0;
|
||||
virtual void ReleaseResource(unsigned resource_id) = 0;
|
||||
|
||||
bool SupportsETC1() const { return texture_compression_.etc1; }
|
||||
bool SupportsDXT1() const {
|
||||
return texture_compression_.dxt1 || texture_compression_.s3tc;
|
||||
|
|
|
@ -7,10 +7,7 @@ using namespace base;
|
|||
|
||||
namespace eng {
|
||||
|
||||
Shader::Shader(unsigned resource_id,
|
||||
std::shared_ptr<void> impl_data,
|
||||
Renderer* renderer)
|
||||
: RenderResource(resource_id, impl_data, renderer) {}
|
||||
Shader::Shader(Renderer* renderer) : RenderResource(renderer) {}
|
||||
|
||||
Shader::~Shader() {
|
||||
Destroy();
|
||||
|
@ -21,56 +18,55 @@ void Shader::Create(std::unique_ptr<ShaderSource> source,
|
|||
Primitive primitive,
|
||||
bool enable_depth_test) {
|
||||
Destroy();
|
||||
valid_ = true;
|
||||
renderer_->CreateShader(impl_data_, std::move(source), vd, primitive,
|
||||
resource_id_ = renderer_->CreateShader(std::move(source), vd, primitive,
|
||||
enable_depth_test);
|
||||
}
|
||||
|
||||
void Shader::Destroy() {
|
||||
if (valid_) {
|
||||
renderer_->DestroyShader(impl_data_);
|
||||
valid_ = false;
|
||||
if (IsValid()) {
|
||||
renderer_->DestroyShader(resource_id_);
|
||||
resource_id_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::Activate() {
|
||||
if (valid_)
|
||||
renderer_->ActivateShader(impl_data_);
|
||||
if (IsValid())
|
||||
renderer_->ActivateShader(resource_id_);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string& name, const Vector2f& v) {
|
||||
if (valid_)
|
||||
renderer_->SetUniform(impl_data_, name, v);
|
||||
if (IsValid())
|
||||
renderer_->SetUniform(resource_id_, name, v);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string& name, const Vector3f& v) {
|
||||
if (valid_)
|
||||
renderer_->SetUniform(impl_data_, name, v);
|
||||
if (IsValid())
|
||||
renderer_->SetUniform(resource_id_, name, v);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string& name, const Vector4f& v) {
|
||||
if (valid_)
|
||||
renderer_->SetUniform(impl_data_, name, v);
|
||||
if (IsValid())
|
||||
renderer_->SetUniform(resource_id_, name, v);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string& name, const Matrix4f& m) {
|
||||
if (valid_)
|
||||
renderer_->SetUniform(impl_data_, name, m);
|
||||
if (IsValid())
|
||||
renderer_->SetUniform(resource_id_, name, m);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string& name, float f) {
|
||||
if (valid_)
|
||||
renderer_->SetUniform(impl_data_, name, f);
|
||||
if (IsValid())
|
||||
renderer_->SetUniform(resource_id_, name, f);
|
||||
}
|
||||
|
||||
void Shader::SetUniform(const std::string& name, int i) {
|
||||
if (valid_)
|
||||
renderer_->SetUniform(impl_data_, name, i);
|
||||
if (IsValid())
|
||||
renderer_->SetUniform(resource_id_, name, i);
|
||||
}
|
||||
|
||||
void Shader::UploadUniforms() {
|
||||
if (valid_)
|
||||
renderer_->UploadUniforms(impl_data_);
|
||||
if (IsValid())
|
||||
renderer_->UploadUniforms(resource_id_);
|
||||
}
|
||||
|
||||
} // namespace eng
|
||||
|
|
|
@ -15,17 +15,15 @@ class ShaderSource;
|
|||
|
||||
class Shader : public RenderResource {
|
||||
public:
|
||||
Shader(unsigned resource_id,
|
||||
std::shared_ptr<void> impl_data,
|
||||
Renderer* renderer);
|
||||
~Shader() override;
|
||||
Shader(Renderer* renderer);
|
||||
~Shader();
|
||||
|
||||
void Create(std::unique_ptr<ShaderSource> source,
|
||||
const VertexDescripton& vd,
|
||||
Primitive primitive,
|
||||
bool enable_depth_test);
|
||||
|
||||
void Destroy() override;
|
||||
void Destroy();
|
||||
|
||||
void Activate();
|
||||
|
||||
|
|
|
@ -6,33 +6,31 @@
|
|||
|
||||
namespace eng {
|
||||
|
||||
Texture::Texture(unsigned resource_id,
|
||||
std::shared_ptr<void> impl_data,
|
||||
Renderer* renderer)
|
||||
: RenderResource(resource_id, impl_data, renderer) {}
|
||||
Texture::Texture(Renderer* renderer) : RenderResource(renderer) {}
|
||||
|
||||
Texture::~Texture() {
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void Texture::Update(std::unique_ptr<Image> image) {
|
||||
valid_ = true;
|
||||
if (!IsValid())
|
||||
resource_id_ = renderer_->CreateTexture();
|
||||
width_ = image->GetWidth();
|
||||
height_ = image->GetHeight();
|
||||
renderer_->UpdateTexture(impl_data_, std::move(image));
|
||||
renderer_->UpdateTexture(resource_id_, std::move(image));
|
||||
}
|
||||
|
||||
void Texture::Destroy() {
|
||||
if (valid_) {
|
||||
renderer_->DestroyTexture(impl_data_);
|
||||
valid_ = false;
|
||||
if (IsValid()) {
|
||||
renderer_->DestroyTexture(resource_id_);
|
||||
resource_id_ = 0;
|
||||
DLOG << "Texture destroyed. resource_id: " << resource_id_;
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::Activate() {
|
||||
if (valid_)
|
||||
renderer_->ActivateTexture(impl_data_);
|
||||
if (IsValid())
|
||||
renderer_->ActivateTexture(resource_id_);
|
||||
}
|
||||
|
||||
} // namespace eng
|
||||
|
|
|
@ -13,15 +13,12 @@ class Renderer;
|
|||
|
||||
class Texture : public RenderResource {
|
||||
public:
|
||||
Texture(unsigned resource_id,
|
||||
std::shared_ptr<void> impl_data,
|
||||
Renderer* renderer);
|
||||
~Texture() override;
|
||||
Texture(Renderer* renderer);
|
||||
~Texture();
|
||||
|
||||
// Uploads image.
|
||||
void Update(std::unique_ptr<Image> image);
|
||||
|
||||
void Destroy() override;
|
||||
void Destroy();
|
||||
|
||||
void Activate();
|
||||
|
||||
|
|
|
@ -259,39 +259,39 @@ RendererVulkan::RendererVulkan() = default;
|
|||
|
||||
RendererVulkan::~RendererVulkan() = default;
|
||||
|
||||
void RendererVulkan::CreateGeometry(std::shared_ptr<void> impl_data,
|
||||
std::unique_ptr<Mesh> mesh) {
|
||||
auto geometry = reinterpret_cast<GeometryVulkan*>(impl_data.get());
|
||||
geometry->num_vertices = mesh->num_vertices();
|
||||
size_t vertex_data_size = mesh->GetVertexSize() * geometry->num_vertices;
|
||||
uint64_t RendererVulkan::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
||||
auto& geometry = geometries_[++last_resource_id_] = {};
|
||||
|
||||
geometry.num_vertices = mesh->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;
|
||||
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_DST_BIT |
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
VMA_MEMORY_USAGE_GPU_ONLY);
|
||||
|
||||
task_runner_.PostTask(HERE, std::bind(&RendererVulkan::UpdateBuffer, this,
|
||||
std::get<0>(geometry->buffer), 0,
|
||||
std::get<0>(geometry.buffer), 0,
|
||||
mesh->GetVertices(), vertex_data_size));
|
||||
if (geometry->num_indices > 0) {
|
||||
geometry->indices_offset = 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,
|
||||
std::get<0>(geometry.buffer), geometry.indices_offset,
|
||||
mesh->GetIndices(), index_data_size));
|
||||
}
|
||||
task_runner_.PostTask(HERE,
|
||||
std::bind(&RendererVulkan::BufferMemoryBarrier, this,
|
||||
std::get<0>(geometry->buffer), 0, data_size,
|
||||
std::get<0>(geometry.buffer), 0, data_size,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
|
@ -301,70 +301,87 @@ void RendererVulkan::CreateGeometry(std::shared_ptr<void> impl_data,
|
|||
std::unique_ptr<Mesh> own(mesh);
|
||||
});
|
||||
semaphore_.Release();
|
||||
|
||||
return last_resource_id_;
|
||||
}
|
||||
|
||||
void RendererVulkan::DestroyGeometry(std::shared_ptr<void> impl_data) {
|
||||
auto geometry = reinterpret_cast<GeometryVulkan*>(impl_data.get());
|
||||
FreeBuffer(std::move(geometry->buffer));
|
||||
geometry = {};
|
||||
void RendererVulkan::DestroyGeometry(uint64_t resource_id) {
|
||||
auto it = geometries_.find(resource_id);
|
||||
if (it == geometries_.end())
|
||||
return;
|
||||
|
||||
FreeBuffer(std::move(it->second.buffer));
|
||||
geometries_.erase(it);
|
||||
}
|
||||
|
||||
void RendererVulkan::Draw(std::shared_ptr<void> impl_data) {
|
||||
auto geometry = reinterpret_cast<GeometryVulkan*>(impl_data.get());
|
||||
void RendererVulkan::Draw(uint64_t resource_id) {
|
||||
auto it = geometries_.find(resource_id);
|
||||
if (it == geometries_.end())
|
||||
return;
|
||||
|
||||
VkDeviceSize offset = 0;
|
||||
vkCmdBindVertexBuffers(frames_[current_frame_].draw_command_buffer, 0, 1,
|
||||
&std::get<0>(geometry->buffer), &offset);
|
||||
if (geometry->num_indices > 0) {
|
||||
&std::get<0>(it->second.buffer), &offset);
|
||||
if (it->second.num_indices > 0) {
|
||||
vkCmdBindIndexBuffer(frames_[current_frame_].draw_command_buffer,
|
||||
std::get<0>(geometry->buffer),
|
||||
geometry->indices_offset, geometry->index_type);
|
||||
std::get<0>(it->second.buffer),
|
||||
it->second.indices_offset, it->second.index_type);
|
||||
vkCmdDrawIndexed(frames_[current_frame_].draw_command_buffer,
|
||||
geometry->num_indices, 1, 0, 0, 0);
|
||||
it->second.num_indices, 1, 0, 0, 0);
|
||||
} else {
|
||||
vkCmdDraw(frames_[current_frame_].draw_command_buffer,
|
||||
geometry->num_vertices, 1, 0, 0);
|
||||
it->second.num_vertices, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererVulkan::UpdateTexture(std::shared_ptr<void> impl_data,
|
||||
uint64_t RendererVulkan::CreateTexture() {
|
||||
textures_.insert({++last_resource_id_, {}});
|
||||
return last_resource_id_;
|
||||
}
|
||||
|
||||
void RendererVulkan::UpdateTexture(uint64_t resource_id,
|
||||
std::unique_ptr<Image> image) {
|
||||
auto texture = reinterpret_cast<TextureVulkan*>(impl_data.get());
|
||||
auto it = textures_.find(resource_id);
|
||||
if (it == textures_.end())
|
||||
return;
|
||||
|
||||
VkImageLayout old_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
VkFormat format = GetImageFormat(image->GetFormat());
|
||||
|
||||
if (texture->view != VK_NULL_HANDLE &&
|
||||
(texture->width != image->GetWidth() ||
|
||||
texture->height != image->GetHeight())) {
|
||||
if (it->second.view != VK_NULL_HANDLE &&
|
||||
(it->second.width != image->GetWidth() ||
|
||||
it->second.height != image->GetHeight())) {
|
||||
// Size mismatch. Recreate the texture.
|
||||
FreeTexture(std::move(texture->image), texture->view,
|
||||
std::move(texture->desc_set));
|
||||
*texture = {};
|
||||
FreeTexture(std::move(it->second.image), it->second.view,
|
||||
std::move(it->second.desc_set));
|
||||
it->second = {};
|
||||
}
|
||||
|
||||
if (texture->view == VK_NULL_HANDLE) {
|
||||
CreateTexture(texture->image, texture->view, texture->desc_set, format,
|
||||
image->GetWidth(), image->GetHeight(),
|
||||
if (it->second.view == VK_NULL_HANDLE) {
|
||||
CreateTexture(it->second.image, it->second.view, it->second.desc_set,
|
||||
format, image->GetWidth(), image->GetHeight(),
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VMA_MEMORY_USAGE_GPU_ONLY);
|
||||
old_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
texture->width = image->GetWidth();
|
||||
texture->height = image->GetHeight();
|
||||
it->second.width = image->GetWidth();
|
||||
it->second.height = image->GetHeight();
|
||||
}
|
||||
|
||||
task_runner_.PostTask(
|
||||
HERE,
|
||||
std::bind(&RendererVulkan::ImageMemoryBarrier, this,
|
||||
std::get<0>(texture->image),
|
||||
std::get<0>(it->second.image),
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
old_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL));
|
||||
task_runner_.PostTask(
|
||||
HERE, std::bind(&RendererVulkan::UpdateImage, this,
|
||||
std::get<0>(texture->image), format, image->GetBuffer(),
|
||||
std::get<0>(it->second.image), format, image->GetBuffer(),
|
||||
image->GetWidth(), image->GetHeight()));
|
||||
task_runner_.PostTask(
|
||||
HERE, std::bind(&RendererVulkan::ImageMemoryBarrier, this,
|
||||
std::get<0>(texture->image), VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
HERE,
|
||||
std::bind(&RendererVulkan::ImageMemoryBarrier, this,
|
||||
std::get<0>(it->second.image), VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
|
@ -378,26 +395,30 @@ void RendererVulkan::UpdateTexture(std::shared_ptr<void> impl_data,
|
|||
semaphore_.Release();
|
||||
}
|
||||
|
||||
void RendererVulkan::DestroyTexture(std::shared_ptr<void> impl_data) {
|
||||
auto texture = reinterpret_cast<TextureVulkan*>(impl_data.get());
|
||||
FreeTexture(std::move(texture->image), texture->view,
|
||||
std::move(texture->desc_set));
|
||||
*texture = {};
|
||||
void RendererVulkan::DestroyTexture(uint64_t resource_id) {
|
||||
auto it = textures_.find(resource_id);
|
||||
if (it == textures_.end())
|
||||
return;
|
||||
|
||||
FreeTexture(std::move(it->second.image), it->second.view,
|
||||
std::move(it->second.desc_set));
|
||||
textures_.erase(it);
|
||||
}
|
||||
|
||||
void RendererVulkan::ActivateTexture(std::shared_ptr<void> impl_data) {
|
||||
auto texture = reinterpret_cast<TextureVulkan*>(impl_data.get());
|
||||
void RendererVulkan::ActivateTexture(uint64_t resource_id) {
|
||||
auto it = textures_.find(resource_id);
|
||||
if (it == textures_.end())
|
||||
return;
|
||||
|
||||
// Keep as pengind and bind later in ActivateShader.
|
||||
penging_descriptor_sets_[/*TODO*/ 0] = std::get<0>(texture->desc_set);
|
||||
penging_descriptor_sets_[/*TODO*/ 0] = std::get<0>(it->second.desc_set);
|
||||
}
|
||||
|
||||
void RendererVulkan::CreateShader(std::shared_ptr<void> impl_data,
|
||||
uint64_t RendererVulkan::CreateShader(
|
||||
std::unique_ptr<ShaderSource> source,
|
||||
const VertexDescripton& vertex_description,
|
||||
Primitive primitive,
|
||||
bool enable_depth_test) {
|
||||
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
||||
|
||||
auto it = spirv_cache_.find(source->name());
|
||||
if (it == spirv_cache_.end()) {
|
||||
std::array<std::vector<uint8_t>, 2> spirv;
|
||||
|
@ -426,7 +447,7 @@ void RendererVulkan::CreateShader(std::shared_ptr<void> impl_data,
|
|||
if (vkCreateShaderModule(device_, &shader_module_info, nullptr,
|
||||
&vert_shader_module) != VK_SUCCESS) {
|
||||
DLOG << "vkCreateShaderModule failed!";
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -441,12 +462,14 @@ void RendererVulkan::CreateShader(std::shared_ptr<void> impl_data,
|
|||
if (vkCreateShaderModule(device_, &shader_module_info, nullptr,
|
||||
&frag_shader_module) != VK_SUCCESS) {
|
||||
DLOG << "vkCreateShaderModule failed!";
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
auto& shader = shaders_[++last_resource_id_] = {};
|
||||
|
||||
if (!CreatePipelineLayout(shader, spirv_vertex, spirv_fragment))
|
||||
return;
|
||||
DLOG << "Failed to create pipeline layout!";
|
||||
|
||||
VkPipelineShaderStageCreateInfo vert_shader_stage_info{};
|
||||
vert_shader_stage_info.sType =
|
||||
|
@ -567,97 +590,125 @@ void RendererVulkan::CreateShader(std::shared_ptr<void> impl_data,
|
|||
pipeline_info.pColorBlendState = &color_blending;
|
||||
pipeline_info.pDepthStencilState = &depth_stencil;
|
||||
pipeline_info.pDynamicState = &dynamic_state_create_info;
|
||||
pipeline_info.layout = shader->pipeline_layout;
|
||||
pipeline_info.layout = shader.pipeline_layout;
|
||||
pipeline_info.renderPass = context_.GetRenderPass();
|
||||
pipeline_info.subpass = 0;
|
||||
pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
|
||||
|
||||
if (vkCreateGraphicsPipelines(device_, VK_NULL_HANDLE, 1, &pipeline_info,
|
||||
nullptr, &shader->pipeline) != VK_SUCCESS)
|
||||
nullptr, &shader.pipeline) != VK_SUCCESS)
|
||||
DLOG << "failed to create graphics pipeline.";
|
||||
|
||||
vkDestroyShaderModule(device_, frag_shader_module, nullptr);
|
||||
vkDestroyShaderModule(device_, vert_shader_module, nullptr);
|
||||
return last_resource_id_;
|
||||
}
|
||||
|
||||
void RendererVulkan::DestroyShader(std::shared_ptr<void> impl_data) {
|
||||
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
||||
void RendererVulkan::DestroyShader(uint64_t resource_id) {
|
||||
auto it = shaders_.find(resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
frames_[current_frame_].pipelines_to_destroy.push_back(
|
||||
std::make_tuple(shader->pipeline, shader->pipeline_layout));
|
||||
*shader = {};
|
||||
std::make_tuple(it->second.pipeline, it->second.pipeline_layout));
|
||||
shaders_.erase(it);
|
||||
}
|
||||
|
||||
void RendererVulkan::ActivateShader(std::shared_ptr<void> impl_data) {
|
||||
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
||||
if (active_pipeline_ != shader->pipeline) {
|
||||
active_pipeline_ = shader->pipeline;
|
||||
void RendererVulkan::ActivateShader(uint64_t resource_id) {
|
||||
auto it = shaders_.find(resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
if (active_pipeline_ != it->second.pipeline) {
|
||||
active_pipeline_ = it->second.pipeline;
|
||||
vkCmdBindPipeline(frames_[current_frame_].draw_command_buffer,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS, shader->pipeline);
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS, it->second.pipeline);
|
||||
}
|
||||
for (int i = 0; i < shader->desc_set_count; ++i) {
|
||||
for (int i = 0; i < it->second.desc_set_count; ++i) {
|
||||
if (active_descriptor_sets_[i] != penging_descriptor_sets_[i]) {
|
||||
active_descriptor_sets_[i] = penging_descriptor_sets_[i];
|
||||
vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
shader->pipeline_layout, 0, 1,
|
||||
it->second.pipeline_layout, 0, 1,
|
||||
&active_descriptor_sets_[i], 0, nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RendererVulkan::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererVulkan::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector2f& val) {
|
||||
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
||||
SetUniformInternal(shader, name, val);
|
||||
auto it = shaders_.find(resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
SetUniformInternal(it->second, name, val);
|
||||
}
|
||||
|
||||
void RendererVulkan::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererVulkan::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector3f& val) {
|
||||
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
||||
SetUniformInternal(shader, name, val);
|
||||
auto it = shaders_.find(resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
SetUniformInternal(it->second, name, val);
|
||||
}
|
||||
|
||||
void RendererVulkan::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererVulkan::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector4f& val) {
|
||||
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
||||
SetUniformInternal(shader, name, val);
|
||||
auto it = shaders_.find(resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
SetUniformInternal(it->second, name, val);
|
||||
}
|
||||
|
||||
void RendererVulkan::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererVulkan::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Matrix4f& val) {
|
||||
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
||||
SetUniformInternal(shader, name, val);
|
||||
auto it = shaders_.find(resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
SetUniformInternal(it->second, name, val);
|
||||
}
|
||||
|
||||
void RendererVulkan::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererVulkan::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
float val) {
|
||||
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
||||
SetUniformInternal(shader, name, val);
|
||||
auto it = shaders_.find(resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
SetUniformInternal(it->second, name, val);
|
||||
}
|
||||
|
||||
void RendererVulkan::SetUniform(std::shared_ptr<void> impl_data,
|
||||
void RendererVulkan::SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
int val) {
|
||||
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
||||
for (auto& sampler_name : shader->sampler_uniform_names) {
|
||||
auto it = shaders_.find(resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
for (auto& sampler_name : it->second.sampler_uniform_names) {
|
||||
if (name == sampler_name)
|
||||
return;
|
||||
}
|
||||
SetUniformInternal(shader, name, val);
|
||||
SetUniformInternal(it->second, name, val);
|
||||
}
|
||||
|
||||
void RendererVulkan::UploadUniforms(std::shared_ptr<void> impl_data) {
|
||||
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
||||
void RendererVulkan::UploadUniforms(uint64_t resource_id) {
|
||||
auto it = shaders_.find(resource_id);
|
||||
if (it == shaders_.end())
|
||||
return;
|
||||
|
||||
vkCmdPushConstants(
|
||||
frames_[current_frame_].draw_command_buffer, shader->pipeline_layout,
|
||||
frames_[current_frame_].draw_command_buffer, it->second.pipeline_layout,
|
||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0,
|
||||
shader->push_constants_size, shader->push_constants.get());
|
||||
it->second.push_constants_size, it->second.push_constants.get());
|
||||
}
|
||||
|
||||
void RendererVulkan::PrepareForDrawing() {
|
||||
|
@ -818,7 +869,7 @@ void RendererVulkan::Shutdown() {
|
|||
return;
|
||||
|
||||
LOG << "Shutting down renderer.";
|
||||
InvalidateAllResources();
|
||||
DestroyAllResources();
|
||||
|
||||
quit_.store(true, std::memory_order_relaxed);
|
||||
semaphore_.Release();
|
||||
|
@ -1520,7 +1571,7 @@ void RendererVulkan::ImageMemoryBarrier(VkImage image,
|
|||
}
|
||||
|
||||
bool RendererVulkan::CreatePipelineLayout(
|
||||
ShaderVulkan* shader,
|
||||
ShaderVulkan& shader,
|
||||
const std::vector<uint8_t>& spirv_vertex,
|
||||
const std::vector<uint8_t>& spirv_fragment) {
|
||||
SpvReflectShaderModule module_vertex;
|
||||
|
@ -1608,14 +1659,14 @@ bool RendererVulkan::CreatePipelineLayout(
|
|||
break;
|
||||
}
|
||||
|
||||
shader->sampler_uniform_names.push_back(binding.name);
|
||||
shader->desc_set_count++;
|
||||
shader.sampler_uniform_names.push_back(binding.name);
|
||||
shader.desc_set_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (active_descriptor_sets_.size() < shader->desc_set_count) {
|
||||
active_descriptor_sets_.resize(shader->desc_set_count);
|
||||
penging_descriptor_sets_.resize(shader->desc_set_count);
|
||||
if (active_descriptor_sets_.size() < shader.desc_set_count) {
|
||||
active_descriptor_sets_.resize(shader.desc_set_count);
|
||||
penging_descriptor_sets_.resize(shader.desc_set_count);
|
||||
}
|
||||
|
||||
// Parse push constants.
|
||||
|
@ -1679,10 +1730,10 @@ bool RendererVulkan::CreatePipelineLayout(
|
|||
break;
|
||||
}
|
||||
|
||||
shader->push_constants_size = pconstants_vertex[0]->size;
|
||||
shader->push_constants =
|
||||
std::make_unique<char[]>(shader->push_constants_size);
|
||||
memset(shader->push_constants.get(), 0, shader->push_constants_size);
|
||||
shader.push_constants_size = pconstants_vertex[0]->size;
|
||||
shader.push_constants =
|
||||
std::make_unique<char[]>(shader.push_constants_size);
|
||||
memset(shader.push_constants.get(), 0, shader.push_constants_size);
|
||||
|
||||
size_t offset = 0;
|
||||
for (uint32_t j = 0; j < pconstants_vertex[0]->member_count; j++) {
|
||||
|
@ -1691,7 +1742,7 @@ bool RendererVulkan::CreatePipelineLayout(
|
|||
<< " padded_size: "
|
||||
<< pconstants_vertex[0]->members[j].padded_size;
|
||||
|
||||
shader->variables[pconstants_vertex[0]->members[j].name] = {
|
||||
shader.variables[pconstants_vertex[0]->members[j].name] = {
|
||||
pconstants_vertex[0]->members[j].size, offset};
|
||||
offset += pconstants_vertex[0]->members[j].padded_size;
|
||||
}
|
||||
|
@ -1716,11 +1767,11 @@ bool RendererVulkan::CreatePipelineLayout(
|
|||
}
|
||||
|
||||
VkPushConstantRange push_constant_range;
|
||||
if (shader->push_constants_size) {
|
||||
if (shader.push_constants_size) {
|
||||
push_constant_range.stageFlags =
|
||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
push_constant_range.offset = 0;
|
||||
push_constant_range.size = shader->push_constants_size;
|
||||
push_constant_range.size = shader.push_constants_size;
|
||||
|
||||
pipeline_layout_create_info.pushConstantRangeCount = 1;
|
||||
pipeline_layout_create_info.pPushConstantRanges = &push_constant_range;
|
||||
|
@ -1730,7 +1781,7 @@ bool RendererVulkan::CreatePipelineLayout(
|
|||
}
|
||||
|
||||
if (vkCreatePipelineLayout(device_, &pipeline_layout_create_info, nullptr,
|
||||
&shader->pipeline_layout) != VK_SUCCESS) {
|
||||
&shader.pipeline_layout) != VK_SUCCESS) {
|
||||
DLOG << "Failed to create pipeline layout!";
|
||||
break;
|
||||
}
|
||||
|
@ -1855,11 +1906,11 @@ void RendererVulkan::SetupThreadMain(int preallocate) {
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
bool RendererVulkan::SetUniformInternal(ShaderVulkan* shader,
|
||||
bool RendererVulkan::SetUniformInternal(ShaderVulkan& shader,
|
||||
const std::string& name,
|
||||
T val) {
|
||||
auto it = shader->variables.find(name);
|
||||
if (it == shader->variables.end()) {
|
||||
auto it = shader.variables.find(name);
|
||||
if (it == shader.variables.end()) {
|
||||
DLOG << "No variable found with name " << name;
|
||||
return false;
|
||||
}
|
||||
|
@ -1868,8 +1919,7 @@ bool RendererVulkan::SetUniformInternal(ShaderVulkan* shader,
|
|||
return false;
|
||||
}
|
||||
|
||||
auto* dst =
|
||||
reinterpret_cast<T*>(shader->push_constants.get() + it->second[1]);
|
||||
auto* dst = reinterpret_cast<T*>(shader.push_constants.get() + it->second[1]);
|
||||
*dst = val;
|
||||
return true;
|
||||
}
|
||||
|
@ -1881,39 +1931,32 @@ bool RendererVulkan::IsFormatSupported(VkFormat format) {
|
|||
return properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderResource> RendererVulkan::CreateResource(
|
||||
RenderResourceFactoryBase& factory) {
|
||||
static unsigned last_id = 0;
|
||||
|
||||
std::shared_ptr<void> impl_data;
|
||||
if (factory.IsTypeOf<Geometry>())
|
||||
impl_data = std::make_shared<GeometryVulkan>();
|
||||
else if (factory.IsTypeOf<Shader>())
|
||||
impl_data = std::make_shared<ShaderVulkan>();
|
||||
else if (factory.IsTypeOf<Texture>())
|
||||
impl_data = std::make_shared<TextureVulkan>();
|
||||
else
|
||||
NOTREACHED << "- Unknown resource type.";
|
||||
|
||||
unsigned resource_id = ++last_id;
|
||||
auto resource = factory.Create(resource_id, impl_data, this);
|
||||
resources_[resource_id] = resource.get();
|
||||
return resource;
|
||||
}
|
||||
|
||||
void RendererVulkan::ReleaseResource(unsigned resource_id) {
|
||||
auto it = resources_.find(resource_id);
|
||||
if (it != resources_.end())
|
||||
resources_.erase(it);
|
||||
}
|
||||
|
||||
size_t RendererVulkan::GetAndResetFPS() {
|
||||
return context_.GetAndResetFPS();
|
||||
}
|
||||
|
||||
void RendererVulkan::InvalidateAllResources() {
|
||||
for (auto& r : resources_)
|
||||
r.second->Destroy();
|
||||
void RendererVulkan::DestroyAllResources() {
|
||||
std::vector<uint64_t> resource_ids;
|
||||
for (auto& r : geometries_)
|
||||
resource_ids.push_back(r.first);
|
||||
for (auto& r : resource_ids)
|
||||
DestroyGeometry(r);
|
||||
|
||||
resource_ids.clear();
|
||||
for (auto& r : shaders_)
|
||||
resource_ids.push_back(r.first);
|
||||
for (auto& r : resource_ids)
|
||||
DestroyShader(r);
|
||||
|
||||
resource_ids.clear();
|
||||
for (auto& r : textures_)
|
||||
resource_ids.push_back(r.first);
|
||||
for (auto& r : resource_ids)
|
||||
DestroyTexture(r);
|
||||
|
||||
DCHECK(geometries_.size() == 0);
|
||||
DCHECK(shaders_.size() == 0);
|
||||
DCHECK(textures_.size() == 0);
|
||||
}
|
||||
|
||||
} // namespace eng
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "../../../base/semaphore.h"
|
||||
#include "../../../base/task_runner.h"
|
||||
#include "../../../third_party/vma/vk_mem_alloc.h"
|
||||
#include "../render_resource.h"
|
||||
#include "../renderer.h"
|
||||
|
||||
namespace eng {
|
||||
|
@ -33,51 +32,46 @@ class RendererVulkan : public Renderer {
|
|||
|
||||
void Shutdown() override;
|
||||
|
||||
void CreateGeometry(std::shared_ptr<void> impl_data,
|
||||
std::unique_ptr<Mesh> mesh) override;
|
||||
void DestroyGeometry(std::shared_ptr<void> impl_data) override;
|
||||
void Draw(std::shared_ptr<void> impl_data) override;
|
||||
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) override;
|
||||
void DestroyGeometry(uint64_t resource_id) override;
|
||||
void Draw(uint64_t resource_id) override;
|
||||
|
||||
void UpdateTexture(std::shared_ptr<void> impl_data,
|
||||
uint64_t CreateTexture() override;
|
||||
void UpdateTexture(uint64_t resource_id,
|
||||
std::unique_ptr<Image> image) override;
|
||||
void DestroyTexture(std::shared_ptr<void> impl_data) override;
|
||||
void ActivateTexture(std::shared_ptr<void> impl_data) override;
|
||||
void DestroyTexture(uint64_t resource_id) override;
|
||||
void ActivateTexture(uint64_t resource_id) override;
|
||||
|
||||
void CreateShader(std::shared_ptr<void> impl_data,
|
||||
std::unique_ptr<ShaderSource> source,
|
||||
uint64_t CreateShader(std::unique_ptr<ShaderSource> source,
|
||||
const VertexDescripton& vertex_description,
|
||||
Primitive primitive,
|
||||
bool enable_depth_test) override;
|
||||
void DestroyShader(std::shared_ptr<void> impl_data) override;
|
||||
void ActivateShader(std::shared_ptr<void> impl_data) override;
|
||||
void DestroyShader(uint64_t resource_id) override;
|
||||
void ActivateShader(uint64_t resource_id) override;
|
||||
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector2f& val) override;
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector3f& val) override;
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Vector4f& val) override;
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
const base::Matrix4f& val) override;
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
float val) override;
|
||||
void SetUniform(std::shared_ptr<void> impl_data,
|
||||
void SetUniform(uint64_t resource_id,
|
||||
const std::string& name,
|
||||
int val) override;
|
||||
void UploadUniforms(std::shared_ptr<void> impl_data) override;
|
||||
void UploadUniforms(uint64_t resource_id) override;
|
||||
|
||||
void PrepareForDrawing() override;
|
||||
void Present() override;
|
||||
|
||||
std::unique_ptr<RenderResource> CreateResource(
|
||||
RenderResourceFactoryBase& factory) override;
|
||||
void ReleaseResource(unsigned resource_id) override;
|
||||
|
||||
size_t GetAndResetFPS() override;
|
||||
|
||||
#if defined(__linux__) && !defined(__ANDROID__)
|
||||
|
@ -155,6 +149,11 @@ class RendererVulkan : public Renderer {
|
|||
VmaAllocationInfo alloc_info;
|
||||
};
|
||||
|
||||
std::unordered_map<uint64_t, GeometryVulkan> geometries_;
|
||||
std::unordered_map<uint64_t, ShaderVulkan> shaders_;
|
||||
std::unordered_map<uint64_t, TextureVulkan> textures_;
|
||||
uint64_t last_resource_id_ = 0;
|
||||
|
||||
VulkanContext context_;
|
||||
|
||||
VmaAllocator allocator_ = nullptr;
|
||||
|
@ -179,8 +178,6 @@ class RendererVulkan : public Renderer {
|
|||
|
||||
VkSampler sampler_ = VK_NULL_HANDLE;
|
||||
|
||||
std::unordered_map<unsigned, RenderResource*> resources_;
|
||||
|
||||
std::thread setup_thread_;
|
||||
base::TaskRunner task_runner_;
|
||||
base::Semaphore semaphore_;
|
||||
|
@ -250,7 +247,7 @@ class RendererVulkan : public Renderer {
|
|||
VkImageLayout old_layout,
|
||||
VkImageLayout new_layout);
|
||||
|
||||
bool CreatePipelineLayout(ShaderVulkan* shader,
|
||||
bool CreatePipelineLayout(ShaderVulkan& shader,
|
||||
const std::vector<uint8_t>& spirv_vertex,
|
||||
const std::vector<uint8_t>& spirv_fragment);
|
||||
|
||||
|
@ -262,11 +259,11 @@ class RendererVulkan : public Renderer {
|
|||
void SetupThreadMain(int preallocate);
|
||||
|
||||
template <typename T>
|
||||
bool SetUniformInternal(ShaderVulkan* shader, const std::string& name, T val);
|
||||
bool SetUniformInternal(ShaderVulkan& shader, const std::string& name, T val);
|
||||
|
||||
bool IsFormatSupported(VkFormat format);
|
||||
|
||||
void InvalidateAllResources();
|
||||
void DestroyAllResources();
|
||||
};
|
||||
|
||||
} // namespace eng
|
||||
|
|
Loading…
Reference in New Issue