TMP / Fixed vulkan_adapter.cpp

This commit is contained in:
OLEGSHA 2023-03-28 15:12:34 +02:00
parent 2c45f519fb
commit 2dc60d589c
4 changed files with 118 additions and 105 deletions

View File

@ -50,7 +50,7 @@ auto getVertexFieldProperties() {
namespace { namespace {
std::vector<char> tmp_readFile(const std::string &path) { std::vector<char> tmp_readFile(const std::string &path) {
auto resource = __embedded_resources::getEmbeddedResource(path.c_str()); auto resource = __embedded_resources::getEmbeddedResource(path);
if (resource.data == nullptr) { if (resource.data == nullptr) {
// REPORT_ERROR // REPORT_ERROR
@ -59,7 +59,7 @@ std::vector<char> tmp_readFile(const std::string &path) {
exit(1); exit(1);
} }
return std::vector<char>(resource.data, resource.data + resource.length); return {resource.data, resource.data + resource.length};
} }
} // namespace } // namespace
@ -82,25 +82,26 @@ Adapter::Adapter(Vulkan &vulkan)
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR,
VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
{1.0f, 0}, {1.0F, 0},
nullptr}); nullptr});
} }
Adapter::~Adapter() { Adapter::~Adapter() = default;
// Do nothing
}
std::vector<Attachment> &Adapter::getAttachments() { return attachments; } std::vector<Attachment> &Adapter::getAttachments() { return attachments; }
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
std::vector<char> Adapter::loadVertexShader() { std::vector<char> Adapter::loadVertexShader() {
return tmp_readFile("shader.vert.spv"); return tmp_readFile("shader.vert.spv");
} }
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
std::vector<char> Adapter::loadFragmentShader() { std::vector<char> Adapter::loadFragmentShader() {
return tmp_readFile("shader.frag.spv"); return tmp_readFile("shader.frag.spv");
} }
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
VkVertexInputBindingDescription Adapter::getVertexInputBindingDescription() { VkVertexInputBindingDescription Adapter::getVertexInputBindingDescription() {
VkVertexInputBindingDescription bindingDescription{}; VkVertexInputBindingDescription bindingDescription{};
bindingDescription.binding = 0; bindingDescription.binding = 0;
@ -111,6 +112,7 @@ VkVertexInputBindingDescription Adapter::getVertexInputBindingDescription() {
} }
std::vector<VkVertexInputAttributeDescription> std::vector<VkVertexInputAttributeDescription>
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
Adapter::getVertexInputAttributeDescriptions() { Adapter::getVertexInputAttributeDescriptions() {
std::vector<VkVertexInputAttributeDescription> attributeDescriptions; std::vector<VkVertexInputAttributeDescription> attributeDescriptions;
@ -163,122 +165,125 @@ struct DrawRequest {
glm::mat4 modelTransform; glm::mat4 modelTransform;
}; };
// NOLINTNEXTLINE: TODO
std::vector<DrawRequest> pendingDrawCommands; std::vector<DrawRequest> pendingDrawCommands;
constexpr std::size_t PENDING_DRAW_COMMANDS_MAX_SIZE = 100000;
// NOLINTNEXTLINE: TODO
glm::mat4 currentModelTransform; glm::mat4 currentModelTransform;
} // namespace } // namespace
progressia::main::Texture::Texture(Backend backend) : backend(backend) {} struct progressia::main::Texture::Backend {
progressia::desktop::Texture texture;
};
progressia::main::Texture::~Texture() { progressia::main::Texture::Texture(std::unique_ptr<Backend> backend)
delete static_cast<progressia::desktop::Texture *>(this->backend); : backend(std::move(backend)) {}
}
namespace { progressia::main::Texture::~Texture() = default;
struct PrimitiveBackend {
struct Primitive::Backend {
IndexedBuffer<Vertex> buf; IndexedBuffer<Vertex> buf;
progressia::main::Texture *tex; progressia::main::Texture *tex;
}; };
} // namespace
Primitive::Primitive(Backend backend) : backend(backend) {} Primitive::Primitive(std::unique_ptr<Backend> backend)
: backend(std::move(backend)) {}
Primitive::~Primitive() { Primitive::~Primitive() = default;
delete static_cast<PrimitiveBackend *>(this->backend);
}
void Primitive::draw() { void Primitive::draw() {
auto backend = static_cast<PrimitiveBackend *>(this->backend); if (pendingDrawCommands.size() > PENDING_DRAW_COMMANDS_MAX_SIZE) {
if (pendingDrawCommands.size() > 100000) {
backend->buf.getVulkan().getGint().flush(); backend->buf.getVulkan().getGint().flush();
} }
pendingDrawCommands.push_back( pendingDrawCommands.push_back({&backend->tex->backend->texture,
{static_cast<progressia::desktop::Texture *>(backend->tex->backend),
&backend->buf, currentModelTransform}); &backend->buf, currentModelTransform});
} }
const progressia::main::Texture *Primitive::getTexture() const { const progressia::main::Texture *Primitive::getTexture() const {
return static_cast<PrimitiveBackend *>(this->backend)->tex; return backend->tex;
} }
View::View(Backend backend) : backend(backend) {} struct View::Backend {
Adapter::ViewUniform::State state;
};
View::~View() { View::View(std::unique_ptr<Backend> backend) : backend(std::move(backend)) {}
delete static_cast<Adapter::ViewUniform::State *>(this->backend);
} View::~View() = default;
void View::configure(const glm::mat4 &proj, const glm::mat4 &view) { void View::configure(const glm::mat4 &proj, const glm::mat4 &view) {
backend->state.update(proj, view);
static_cast<Adapter::ViewUniform::State *>(this->backend)
->update(proj, view);
} }
void View::use() { void View::use() {
auto backend = static_cast<Adapter::ViewUniform::State *>(this->backend); backend->state.uniform->getVulkan().getGint().flush();
backend->uniform->getVulkan().getGint().flush(); backend->state.bind();
backend->bind();
} }
Light::Light(Backend backend) : backend(backend) {} struct Light::Backend {
Adapter::LightUniform::State state;
};
Light::~Light() { Light::Light(std::unique_ptr<Backend> backend) : backend(std::move(backend)) {}
delete static_cast<Adapter::LightUniform::State *>(this->backend); Light::~Light() = default;
}
void Light::configure(const glm::vec3 &color, const glm::vec3 &from, void Light::configure(const glm::vec3 &color, const glm::vec3 &from,
float contrast, float softness) { float contrast, float softness) {
static_cast<Adapter::LightUniform::State *>(this->backend) backend->state.update(Adapter::Light{glm::vec4(color, 1.0F),
->update(Adapter::Light{glm::vec4(color, 1.0f), glm::vec4(glm::normalize(from), 1.0F),
glm::vec4(glm::normalize(from), 1.0f), contrast, contrast, softness});
softness});
} }
void Light::use() { void Light::use() {
auto backend = static_cast<Adapter::LightUniform::State *>(this->backend); backend->state.uniform->getVulkan().getGint().flush();
backend->uniform->getVulkan().getGint().flush(); backend->state.bind();
backend->bind();
} }
GraphicsInterface::GraphicsInterface(Backend backend) : backend(backend) {} GraphicsInterface::GraphicsInterface(Backend backend) : backend(backend) {}
GraphicsInterface::~GraphicsInterface() { GraphicsInterface::~GraphicsInterface() = default;
// Do nothing
}
progressia::main::Texture * std::unique_ptr<progressia::main::Texture>
GraphicsInterface::newTexture(const progressia::main::Image &src) { GraphicsInterface::newTexture(const progressia::main::Image &src) {
auto backend = new progressia::desktop::Texture( using Backend = progressia::main::Texture::Backend;
src, *static_cast<Vulkan *>(this->backend));
return new Texture(backend); return std::make_unique<progressia::main::Texture>(
std::unique_ptr<Backend>(new Backend{progressia::desktop::Texture(
src, *static_cast<Vulkan *>(this->backend))}));
} }
Primitive * std::unique_ptr<Primitive>
GraphicsInterface::newPrimitive(const std::vector<Vertex> &vertices, GraphicsInterface::newPrimitive(const std::vector<Vertex> &vertices,
const std::vector<Vertex::Index> &indices, const std::vector<Vertex::Index> &indices,
progressia::main::Texture *texture) { progressia::main::Texture *texture) {
auto backend = new PrimitiveBackend{ auto primitive = std::make_unique<Primitive>(
std::unique_ptr<Primitive::Backend>(new Primitive::Backend{
IndexedBuffer<Vertex>(vertices.size(), indices.size(), IndexedBuffer<Vertex>(vertices.size(), indices.size(),
*static_cast<Vulkan *>(this->backend)), *static_cast<Vulkan *>(this->backend)),
texture}; texture}));
backend->buf.load(vertices.data(), indices.data()); primitive->backend->buf.load(vertices.data(), indices.data());
return new Primitive(backend); return primitive;
} }
View *GraphicsInterface::newView() { std::unique_ptr<View> GraphicsInterface::newView() {
return new View(new Adapter::ViewUniform::State( return std::make_unique<View>(std::unique_ptr<View::Backend>(
static_cast<Vulkan *>(this->backend)->getAdapter().createView())); new View::Backend{Adapter::ViewUniform::State(
static_cast<Vulkan *>(this->backend)->getAdapter().createView())}));
} }
Light *GraphicsInterface::newLight() { std::unique_ptr<Light> GraphicsInterface::newLight() {
return new Light(new Adapter::LightUniform::State( return std::make_unique<Light>(
static_cast<Vulkan *>(this->backend)->getAdapter().createLight())); std::unique_ptr<Light::Backend>(new Light::Backend{
Adapter::LightUniform::State(static_cast<Vulkan *>(this->backend)
->getAdapter()
.createLight())}));
} }
glm::vec2 GraphicsInterface::getViewport() const { glm::vec2 GraphicsInterface::getViewport() const {
@ -287,16 +292,17 @@ glm::vec2 GraphicsInterface::getViewport() const {
return {extent.width, extent.height}; return {extent.width, extent.height};
} }
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
void GraphicsInterface::setModelTransform(const glm::mat4 &m) { void GraphicsInterface::setModelTransform(const glm::mat4 &m) {
currentModelTransform = m; currentModelTransform = m;
} }
void GraphicsInterface::flush() { void GraphicsInterface::flush() {
auto commandBuffer = static_cast<Vulkan *>(this->backend) auto *commandBuffer = static_cast<Vulkan *>(this->backend)
->getCurrentFrame() ->getCurrentFrame()
->getCommandBuffer(); ->getCommandBuffer();
auto pipelineLayout = auto *pipelineLayout =
static_cast<Vulkan *>(this->backend)->getPipeline().getLayout(); static_cast<Vulkan *>(this->backend)->getPipeline().getLayout();
progressia::desktop::Texture *lastTexture = nullptr; progressia::desktop::Texture *lastTexture = nullptr;
@ -328,6 +334,7 @@ void GraphicsInterface::flush() {
pendingDrawCommands.clear(); pendingDrawCommands.clear();
} }
// NOLINTNEXTLINE: TODO
float GraphicsInterface::tmp_getTime() { return glfwGetTime(); } float GraphicsInterface::tmp_getTime() { return glfwGetTime(); }
uint64_t GraphicsInterface::getLastStartedFrame() { uint64_t GraphicsInterface::getLastStartedFrame() {

View File

@ -62,10 +62,10 @@ void initialize(GraphicsInterface &gintp) {
debug("game init begin"); debug("game init begin");
gint = &gintp; gint = &gintp;
texture1.reset( texture1 =
gint->newTexture(progressia::main::loadImage("assets/texture.png"))); gint->newTexture(progressia::main::loadImage("assets/texture.png"));
texture2.reset( texture2 =
gint->newTexture(progressia::main::loadImage("assets/texture2.png"))); gint->newTexture(progressia::main::loadImage("assets/texture2.png"));
// Cube 1 // Cube 1
{ {
@ -91,7 +91,7 @@ void initialize(GraphicsInterface &gintp) {
c.normal = normal; c.normal = normal;
} }
cube1.reset(gint->newPrimitive(vertices, indices, &*texture1)); cube1 = gint->newPrimitive(vertices, indices, &*texture1);
} }
// Cube 2 // Cube 2
@ -118,11 +118,11 @@ void initialize(GraphicsInterface &gintp) {
c.normal = normal; c.normal = normal;
} }
cube2.reset(gint->newPrimitive(vertices, indices, &*texture2)); cube2 = gint->newPrimitive(vertices, indices, &*texture2);
} }
perspective.reset(gint->newView()); perspective = gint->newView();
light.reset(gint->newLight()); light = gint->newLight();
debug("game init complete"); debug("game init complete");
} }

View File

@ -25,30 +25,26 @@ struct Vertex {
}; };
class Texture : private progressia::main::NonCopyable { class Texture : private progressia::main::NonCopyable {
public:
using Backend = void *;
private: private:
Backend backend; struct Backend;
std::unique_ptr<Backend> backend;
friend class GraphicsInterface;
friend class Primitive; friend class Primitive;
public: public:
Texture(Backend); Texture(std::unique_ptr<Backend>);
~Texture(); ~Texture();
}; };
class Primitive : private progressia::main::NonCopyable { class Primitive : private progressia::main::NonCopyable {
public:
using Backend = void *;
private: private:
Backend backend; struct Backend;
std::unique_ptr<Backend> backend;
friend class GraphicsInterface; friend class GraphicsInterface;
public: public:
Primitive(Backend); Primitive(std::unique_ptr<Backend>);
~Primitive(); ~Primitive();
void draw(); void draw();
@ -57,14 +53,13 @@ class Primitive : private progressia::main::NonCopyable {
}; };
class View : private progressia::main::NonCopyable { class View : private progressia::main::NonCopyable {
public:
using Backend = void *;
private: private:
Backend backend; struct Backend;
std::unique_ptr<Backend> backend;
friend class GraphicsInterface;
public: public:
View(Backend); View(std::unique_ptr<Backend>);
~View(); ~View();
void configure(const glm::mat4 &proj, const glm::mat4 &view); void configure(const glm::mat4 &proj, const glm::mat4 &view);
@ -72,14 +67,13 @@ class View : private progressia::main::NonCopyable {
}; };
class Light : private progressia::main::NonCopyable { class Light : private progressia::main::NonCopyable {
public:
using Backend = void *;
private: private:
Backend backend; struct Backend;
std::unique_ptr<Backend> backend;
friend class GraphicsInterface;
public: public:
Light(Backend); Light(std::unique_ptr<Backend>);
~Light(); ~Light();
void configure(const glm::vec3 &color, const glm::vec3 &from, void configure(const glm::vec3 &color, const glm::vec3 &from,
@ -98,9 +92,9 @@ class GraphicsInterface : private progressia::main::NonCopyable {
GraphicsInterface(Backend); GraphicsInterface(Backend);
~GraphicsInterface(); ~GraphicsInterface();
Texture *newTexture(const Image &); std::unique_ptr<Texture> newTexture(const Image &);
Primitive *newPrimitive(const std::vector<Vertex> &, std::unique_ptr<Primitive> newPrimitive(const std::vector<Vertex> &,
const std::vector<Vertex::Index> &, const std::vector<Vertex::Index> &,
Texture *texture); Texture *texture);
@ -108,8 +102,8 @@ class GraphicsInterface : private progressia::main::NonCopyable {
void setModelTransform(const glm::mat4 &); void setModelTransform(const glm::mat4 &);
View *newView(); std::unique_ptr<View> newView();
Light *newLight(); std::unique_ptr<Light> newLight();
void flush(); void flush();
void startNextLayer(); void startNextLayer();

View File

@ -14,7 +14,9 @@ Checks: "-*,\
-readability-else-after-return,\ -readability-else-after-return,\
-readability-named-parameter,\ -readability-named-parameter,\
-readability-use-anyofallof,\ -readability-use-anyofallof,\
-cppcoreguidelines-pro-bounds-pointer-arithmetic" -cppcoreguidelines-pro-bounds-pointer-arithmetic,\
-performance-trivially-destructible,\
-modernize-make-unique"
# modernize-use-trailing-return-type # modernize-use-trailing-return-type
# ignore reason: reduces readability # ignore reason: reduces readability
@ -47,3 +49,13 @@ Checks: "-*,\
# cppcoreguidelines-pro-bounds-pointer-arithmetic # cppcoreguidelines-pro-bounds-pointer-arithmetic
# ignore reason: infeasible to avoid in C++17 # ignore reason: infeasible to avoid in C++17
# performance-trivially-destructible
# ignore reason: breaks incapsulation too often
# modernize-make-unique
# ignore reason: impossible with brace-init lists:
# struct S { int a; int b; };
# std::unique_ptr<S>(new S { 1, 2 }) // works
# std::make_unique<S>(1, 2) // error
# std::make_unique<S>({1, 2}) // error