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