mirror of
https://gitea.windcorp.ru/Wind-Corporation/Progressia.git
synced 2025-08-28 09:16:51 +03:00
Squash improve-ide-compat into main
Fixes GH-5 - cppcheck replaced with clang-tidy - clang-tidy lint warnings fixed - Reworked build tools from scratch to make IDE setup easier - Added 1.5 IDE setup guides
This commit is contained in:
@@ -8,59 +8,95 @@
|
||||
|
||||
#include "../../main/logging.h"
|
||||
#include "../../main/meta.h"
|
||||
#include "vulkan_mgmt.h"
|
||||
#include "../../main/util.h"
|
||||
|
||||
using namespace progressia::main::logging;
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
|
||||
static GLFWwindow *window = nullptr;
|
||||
namespace progressia::desktop {
|
||||
|
||||
static void onGlfwError(int errorCode, const char *description);
|
||||
static void onWindowGeometryChange(GLFWwindow *window, int width, int height);
|
||||
|
||||
void initializeGlfw() {
|
||||
debug("Beginning GLFW init");
|
||||
class GlfwManagerImpl : public GlfwManager {
|
||||
private:
|
||||
GLFWwindow *window = nullptr;
|
||||
std::function<void()> onScreenResize = nullptr;
|
||||
|
||||
glfwSetErrorCallback(onGlfwError);
|
||||
public:
|
||||
DISABLE_COPYING(GlfwManagerImpl)
|
||||
DISABLE_MOVING(GlfwManagerImpl)
|
||||
|
||||
if (!glfwInit()) {
|
||||
fatal("glfwInit() failed");
|
||||
GlfwManagerImpl() {
|
||||
debug("Beginning GLFW init");
|
||||
|
||||
glfwSetErrorCallback(onGlfwError);
|
||||
|
||||
if (!glfwInit()) {
|
||||
fatal("glfwInit() failed");
|
||||
// REPORT_ERROR
|
||||
exit(1);
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
|
||||
std::string title;
|
||||
|
||||
{
|
||||
std::stringstream accumulator;
|
||||
accumulator << progressia::main::meta::NAME << " "
|
||||
<< progressia::main::meta::VERSION << " build "
|
||||
<< progressia::main::meta::BUILD_ID;
|
||||
title = accumulator.str();
|
||||
}
|
||||
|
||||
constexpr auto windowDimensions = 800;
|
||||
window = glfwCreateWindow(windowDimensions, windowDimensions,
|
||||
title.c_str(), nullptr, nullptr);
|
||||
|
||||
glfwSetWindowSizeCallback(window, onWindowGeometryChange);
|
||||
|
||||
debug("GLFW init complete");
|
||||
}
|
||||
|
||||
~GlfwManagerImpl() override { glfwTerminate(); }
|
||||
|
||||
void setOnScreenResize(std::function<void()> hook) override {
|
||||
onScreenResize = hook;
|
||||
}
|
||||
|
||||
void showWindow() override {
|
||||
glfwShowWindow(window);
|
||||
debug("Window now visible");
|
||||
}
|
||||
|
||||
bool shouldRun() override { return !glfwWindowShouldClose(window); }
|
||||
|
||||
void doGlfwRoutine() override { glfwPollEvents(); }
|
||||
|
||||
friend GLFWwindow *getGLFWWindowHandle();
|
||||
friend void onWindowGeometryChange(GLFWwindow *, int, int);
|
||||
};
|
||||
|
||||
namespace {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables): global variables required by GLFW C callbacks
|
||||
std::weak_ptr<GlfwManagerImpl> theGlfwManager;
|
||||
} // namespace
|
||||
|
||||
std::shared_ptr<GlfwManager> makeGlfwManager() {
|
||||
if (!theGlfwManager.expired()) {
|
||||
fatal("GlfwManager already exists");
|
||||
// REPORT_ERROR
|
||||
exit(1);
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
std::shared_ptr<GlfwManagerImpl> aGlfwManager =
|
||||
std::make_shared<GlfwManagerImpl>();
|
||||
|
||||
std::string title;
|
||||
|
||||
{
|
||||
std::stringstream accumulator;
|
||||
accumulator << progressia::main::meta::NAME << " "
|
||||
<< progressia::main::meta::VERSION << " build "
|
||||
<< progressia::main::meta::BUILD_ID;
|
||||
title = accumulator.str();
|
||||
}
|
||||
|
||||
window = glfwCreateWindow(800, 800, title.c_str(), nullptr, nullptr);
|
||||
|
||||
glfwSetWindowSizeCallback(window, onWindowGeometryChange);
|
||||
|
||||
debug("GLFW init complete");
|
||||
theGlfwManager = aGlfwManager;
|
||||
return aGlfwManager;
|
||||
}
|
||||
|
||||
void showWindow() {
|
||||
glfwShowWindow(window);
|
||||
debug("Window now visible");
|
||||
}
|
||||
|
||||
bool shouldRun() { return !glfwWindowShouldClose(window); }
|
||||
|
||||
void doGlfwRoutine() { glfwPollEvents(); }
|
||||
|
||||
void shutdownGlfw() { glfwTerminate(); }
|
||||
|
||||
void onGlfwError(int errorCode, const char *description) {
|
||||
fatal() << "[GLFW] " << description << " (" << errorCode << ")";
|
||||
// REPORT_ERROR
|
||||
@@ -69,14 +105,25 @@ void onGlfwError(int errorCode, const char *description) {
|
||||
|
||||
void onWindowGeometryChange(GLFWwindow *window, [[maybe_unused]] int width,
|
||||
[[maybe_unused]] int height) {
|
||||
if (window != progressia::desktop::window) {
|
||||
if (auto manager = theGlfwManager.lock()) {
|
||||
if (manager->window != window) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (manager->onScreenResize != nullptr) {
|
||||
manager->onScreenResize();
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
resizeVulkanSurface();
|
||||
}
|
||||
|
||||
GLFWwindow *getGLFWWindowHandle() { return window; }
|
||||
GLFWwindow *getGLFWWindowHandle() {
|
||||
if (auto manager = theGlfwManager.lock()) {
|
||||
return manager->window;
|
||||
}
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -1,13 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
void initializeGlfw();
|
||||
void showWindow();
|
||||
void shutdownGlfw();
|
||||
bool shouldRun();
|
||||
void doGlfwRoutine();
|
||||
namespace progressia::desktop {
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
class GlfwManager {
|
||||
|
||||
public:
|
||||
virtual ~GlfwManager(){};
|
||||
|
||||
virtual void setOnScreenResize(std::function<void()>) = 0;
|
||||
|
||||
virtual void showWindow() = 0;
|
||||
virtual bool shouldRun() = 0;
|
||||
virtual void doGlfwRoutine() = 0;
|
||||
};
|
||||
|
||||
std::shared_ptr<GlfwManager> makeGlfwManager();
|
||||
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -5,10 +5,9 @@
|
||||
#define GLFW_INCLUDE_VULKAN
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
// TODO refactor into OOP
|
||||
GLFWwindow *getGLFWWindowHandle();
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "vulkan_common.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
@@ -25,8 +26,7 @@
|
||||
|
||||
#include <embedded_resources.h>
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
using progressia::main::Vertex;
|
||||
|
||||
@@ -50,7 +50,7 @@ auto getVertexFieldProperties() {
|
||||
|
||||
namespace {
|
||||
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) {
|
||||
// REPORT_ERROR
|
||||
@@ -59,7 +59,7 @@ std::vector<char> tmp_readFile(const std::string &path) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return std::vector<char>(resource.data, resource.data + resource.length);
|
||||
return {resource.data, resource.data + resource.length};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -82,25 +82,26 @@ Adapter::Adapter(Vulkan &vulkan)
|
||||
VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
|
||||
{1.0f, 0},
|
||||
{1.0F, 0},
|
||||
|
||||
nullptr});
|
||||
}
|
||||
|
||||
Adapter::~Adapter() {
|
||||
// Do nothing
|
||||
}
|
||||
Adapter::~Adapter() = default;
|
||||
|
||||
std::vector<Attachment> &Adapter::getAttachments() { return attachments; }
|
||||
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
|
||||
std::vector<char> Adapter::loadVertexShader() {
|
||||
return tmp_readFile("shader.vert.spv");
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
|
||||
std::vector<char> Adapter::loadFragmentShader() {
|
||||
return tmp_readFile("shader.frag.spv");
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
|
||||
VkVertexInputBindingDescription Adapter::getVertexInputBindingDescription() {
|
||||
VkVertexInputBindingDescription bindingDescription{};
|
||||
bindingDescription.binding = 0;
|
||||
@@ -111,6 +112,7 @@ VkVertexInputBindingDescription Adapter::getVertexInputBindingDescription() {
|
||||
}
|
||||
|
||||
std::vector<VkVertexInputAttributeDescription>
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
|
||||
Adapter::getVertexInputAttributeDescriptions() {
|
||||
std::vector<VkVertexInputAttributeDescription> attributeDescriptions;
|
||||
|
||||
@@ -151,8 +153,8 @@ void Adapter::onPreFrame() {
|
||||
* graphics_interface implementation
|
||||
*/
|
||||
|
||||
} // namespace desktop
|
||||
namespace main {
|
||||
} // namespace progressia::desktop
|
||||
namespace progressia::main {
|
||||
|
||||
using namespace progressia::desktop;
|
||||
|
||||
@@ -163,122 +165,125 @@ struct DrawRequest {
|
||||
glm::mat4 modelTransform;
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE: TODO
|
||||
std::vector<DrawRequest> pendingDrawCommands;
|
||||
constexpr std::size_t PENDING_DRAW_COMMANDS_MAX_SIZE = 100000;
|
||||
|
||||
// NOLINTNEXTLINE: TODO
|
||||
glm::mat4 currentModelTransform;
|
||||
|
||||
} // namespace
|
||||
|
||||
progressia::main::Texture::Texture(Backend backend) : backend(backend) {}
|
||||
struct progressia::main::Texture::Backend {
|
||||
progressia::desktop::Texture texture;
|
||||
};
|
||||
|
||||
progressia::main::Texture::~Texture() {
|
||||
delete static_cast<progressia::desktop::Texture *>(this->backend);
|
||||
}
|
||||
progressia::main::Texture::Texture(std::unique_ptr<Backend> backend)
|
||||
: backend(std::move(backend)) {}
|
||||
|
||||
namespace {
|
||||
struct PrimitiveBackend {
|
||||
progressia::main::Texture::~Texture() = default;
|
||||
|
||||
struct Primitive::Backend {
|
||||
IndexedBuffer<Vertex> buf;
|
||||
progressia::main::Texture *tex;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
Primitive::Primitive(Backend backend) : backend(backend) {}
|
||||
Primitive::Primitive(std::unique_ptr<Backend> backend)
|
||||
: backend(std::move(backend)) {}
|
||||
|
||||
Primitive::~Primitive() {
|
||||
delete static_cast<PrimitiveBackend *>(this->backend);
|
||||
}
|
||||
Primitive::~Primitive() = default;
|
||||
|
||||
void Primitive::draw() {
|
||||
auto backend = static_cast<PrimitiveBackend *>(this->backend);
|
||||
|
||||
if (pendingDrawCommands.size() > 100000) {
|
||||
if (pendingDrawCommands.size() > PENDING_DRAW_COMMANDS_MAX_SIZE) {
|
||||
backend->buf.getVulkan().getGint().flush();
|
||||
}
|
||||
|
||||
pendingDrawCommands.push_back(
|
||||
{static_cast<progressia::desktop::Texture *>(backend->tex->backend),
|
||||
&backend->buf, currentModelTransform});
|
||||
pendingDrawCommands.push_back({&backend->tex->backend->texture,
|
||||
&backend->buf, currentModelTransform});
|
||||
}
|
||||
|
||||
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() {
|
||||
delete static_cast<Adapter::ViewUniform::State *>(this->backend);
|
||||
}
|
||||
View::View(std::unique_ptr<Backend> backend) : backend(std::move(backend)) {}
|
||||
|
||||
View::~View() = default;
|
||||
|
||||
void View::configure(const glm::mat4 &proj, const glm::mat4 &view) {
|
||||
|
||||
static_cast<Adapter::ViewUniform::State *>(this->backend)
|
||||
->update(proj, view);
|
||||
backend->state.update(proj, view);
|
||||
}
|
||||
|
||||
void View::use() {
|
||||
auto backend = static_cast<Adapter::ViewUniform::State *>(this->backend);
|
||||
backend->uniform->getVulkan().getGint().flush();
|
||||
backend->bind();
|
||||
backend->state.uniform->getVulkan().getGint().flush();
|
||||
backend->state.bind();
|
||||
}
|
||||
|
||||
Light::Light(Backend backend) : backend(backend) {}
|
||||
struct Light::Backend {
|
||||
Adapter::LightUniform::State state;
|
||||
};
|
||||
|
||||
Light::~Light() {
|
||||
delete static_cast<Adapter::LightUniform::State *>(this->backend);
|
||||
}
|
||||
Light::Light(std::unique_ptr<Backend> backend) : backend(std::move(backend)) {}
|
||||
Light::~Light() = default;
|
||||
|
||||
void Light::configure(const glm::vec3 &color, const glm::vec3 &from,
|
||||
float contrast, float softness) {
|
||||
|
||||
static_cast<Adapter::LightUniform::State *>(this->backend)
|
||||
->update(Adapter::Light{glm::vec4(color, 1.0f),
|
||||
glm::vec4(glm::normalize(from), 1.0f), contrast,
|
||||
softness});
|
||||
backend->state.update(Adapter::Light{glm::vec4(color, 1.0F),
|
||||
glm::vec4(glm::normalize(from), 1.0F),
|
||||
contrast, softness});
|
||||
}
|
||||
|
||||
void Light::use() {
|
||||
auto backend = static_cast<Adapter::LightUniform::State *>(this->backend);
|
||||
backend->uniform->getVulkan().getGint().flush();
|
||||
backend->bind();
|
||||
backend->state.uniform->getVulkan().getGint().flush();
|
||||
backend->state.bind();
|
||||
}
|
||||
|
||||
GraphicsInterface::GraphicsInterface(Backend backend) : backend(backend) {}
|
||||
|
||||
GraphicsInterface::~GraphicsInterface() {
|
||||
// Do nothing
|
||||
}
|
||||
GraphicsInterface::~GraphicsInterface() = default;
|
||||
|
||||
progressia::main::Texture *
|
||||
std::unique_ptr<progressia::main::Texture>
|
||||
GraphicsInterface::newTexture(const progressia::main::Image &src) {
|
||||
auto backend = new progressia::desktop::Texture(
|
||||
src, *static_cast<Vulkan *>(this->backend));
|
||||
using Backend = progressia::main::Texture::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,
|
||||
const std::vector<Vertex::Index> &indices,
|
||||
progressia::main::Texture *texture) {
|
||||
|
||||
auto backend = new PrimitiveBackend{
|
||||
IndexedBuffer<Vertex>(vertices.size(), indices.size(),
|
||||
*static_cast<Vulkan *>(this->backend)),
|
||||
texture};
|
||||
auto primitive = std::make_unique<Primitive>(
|
||||
std::unique_ptr<Primitive::Backend>(new Primitive::Backend{
|
||||
IndexedBuffer<Vertex>(vertices.size(), indices.size(),
|
||||
*static_cast<Vulkan *>(this->backend)),
|
||||
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() {
|
||||
return new View(new Adapter::ViewUniform::State(
|
||||
static_cast<Vulkan *>(this->backend)->getAdapter().createView()));
|
||||
std::unique_ptr<View> GraphicsInterface::newView() {
|
||||
return std::make_unique<View>(std::unique_ptr<View::Backend>(
|
||||
new View::Backend{Adapter::ViewUniform::State(
|
||||
static_cast<Vulkan *>(this->backend)->getAdapter().createView())}));
|
||||
}
|
||||
|
||||
Light *GraphicsInterface::newLight() {
|
||||
return new Light(new Adapter::LightUniform::State(
|
||||
static_cast<Vulkan *>(this->backend)->getAdapter().createLight()));
|
||||
std::unique_ptr<Light> GraphicsInterface::newLight() {
|
||||
return std::make_unique<Light>(
|
||||
std::unique_ptr<Light::Backend>(new Light::Backend{
|
||||
Adapter::LightUniform::State(static_cast<Vulkan *>(this->backend)
|
||||
->getAdapter()
|
||||
.createLight())}));
|
||||
}
|
||||
|
||||
glm::vec2 GraphicsInterface::getViewport() const {
|
||||
@@ -287,16 +292,17 @@ glm::vec2 GraphicsInterface::getViewport() const {
|
||||
return {extent.width, extent.height};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
|
||||
void GraphicsInterface::setModelTransform(const glm::mat4 &m) {
|
||||
currentModelTransform = m;
|
||||
}
|
||||
|
||||
void GraphicsInterface::flush() {
|
||||
|
||||
auto commandBuffer = static_cast<Vulkan *>(this->backend)
|
||||
->getCurrentFrame()
|
||||
->getCommandBuffer();
|
||||
auto pipelineLayout =
|
||||
auto *commandBuffer = static_cast<Vulkan *>(this->backend)
|
||||
->getCurrentFrame()
|
||||
->getCommandBuffer();
|
||||
auto *pipelineLayout =
|
||||
static_cast<Vulkan *>(this->backend)->getPipeline().getLayout();
|
||||
|
||||
progressia::desktop::Texture *lastTexture = nullptr;
|
||||
@@ -328,11 +334,11 @@ void GraphicsInterface::flush() {
|
||||
pendingDrawCommands.clear();
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE: TODO
|
||||
float GraphicsInterface::tmp_getTime() { return glfwGetTime(); }
|
||||
|
||||
uint64_t GraphicsInterface::getLastStartedFrame() {
|
||||
return static_cast<Vulkan *>(this->backend)->getLastStartedFrame();
|
||||
}
|
||||
|
||||
} // namespace main
|
||||
} // namespace progressia
|
||||
} // namespace progressia::main
|
||||
|
@@ -1,13 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "boost/core/noncopyable.hpp"
|
||||
#include "vulkan_common.h"
|
||||
#include "vulkan_descriptor_set.h"
|
||||
#include "vulkan_image.h"
|
||||
#include "vulkan_uniform.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
class Attachment {
|
||||
public:
|
||||
@@ -68,5 +66,4 @@ class Adapter : public VkObjectWrapper {
|
||||
void onPreFrame();
|
||||
};
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -1,12 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "vulkan_common.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
/*
|
||||
* A single buffer with a chunk of allocated memory.
|
||||
@@ -192,5 +190,4 @@ class IndexedBufferBase : public VkObjectWrapper {
|
||||
template <typename Vertex>
|
||||
using IndexedBuffer = IndexedBufferBase<Vertex, uint16_t, VK_INDEX_TYPE_UINT16>;
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -1,8 +1,8 @@
|
||||
#include "vulkan_common.h"
|
||||
|
||||
#include "../config.h"
|
||||
#include "vulkan_adapter.h"
|
||||
#include "vulkan_frame.h"
|
||||
#include "vulkan_physical_device.h"
|
||||
#include "vulkan_pick_device.h"
|
||||
#include "vulkan_pipeline.h"
|
||||
#include "vulkan_render_pass.h"
|
||||
@@ -15,8 +15,7 @@
|
||||
|
||||
using namespace progressia::main::logging;
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
/*
|
||||
* Vulkan
|
||||
@@ -27,7 +26,7 @@ Vulkan::Vulkan(std::vector<const char *> instanceExtensions,
|
||||
std::vector<const char *> validationLayers)
|
||||
:
|
||||
|
||||
frames(MAX_FRAMES_IN_FLIGHT), isRenderingFrame(false),
|
||||
frames(MAX_FRAMES_IN_FLIGHT), currentFrame(0), isRenderingFrame(false),
|
||||
lastStartedFrame(0) {
|
||||
|
||||
/*
|
||||
@@ -58,7 +57,7 @@ Vulkan::Vulkan(std::vector<const char *> instanceExtensions,
|
||||
|
||||
// Enable extensions
|
||||
{
|
||||
uint32_t extensionCount;
|
||||
uint32_t extensionCount = 0;
|
||||
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount,
|
||||
nullptr);
|
||||
std::vector<VkExtensionProperties> available(extensionCount);
|
||||
@@ -89,7 +88,7 @@ Vulkan::Vulkan(std::vector<const char *> instanceExtensions,
|
||||
|
||||
// Enable validation layers
|
||||
{
|
||||
uint32_t layerCount;
|
||||
uint32_t layerCount = 0;
|
||||
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
||||
std::vector<VkLayerProperties> available(layerCount);
|
||||
vkEnumerateInstanceLayerProperties(&layerCount, available.data());
|
||||
@@ -150,31 +149,25 @@ Vulkan::Vulkan(std::vector<const char *> instanceExtensions,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::vector<VkPhysicalDevice> devices(deviceCount);
|
||||
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
|
||||
std::vector<VkPhysicalDevice> vkDevices(deviceCount);
|
||||
vkEnumeratePhysicalDevices(instance, &deviceCount, vkDevices.data());
|
||||
|
||||
std::vector<PhysicalDeviceData> choices;
|
||||
|
||||
for (const auto &device : devices) {
|
||||
PhysicalDeviceData data = {};
|
||||
data.device = device;
|
||||
|
||||
vkGetPhysicalDeviceProperties(device, &data.properties);
|
||||
vkGetPhysicalDeviceFeatures(device, &data.features);
|
||||
|
||||
choices.push_back(data);
|
||||
std::vector<PhysicalDevice> choices;
|
||||
choices.reserve(deviceCount);
|
||||
for (const auto &vkDevice : vkDevices) {
|
||||
choices.emplace_back(PhysicalDevice(vkDevice));
|
||||
}
|
||||
|
||||
const auto &result =
|
||||
pickPhysicalDevice(choices, *this, deviceExtensions);
|
||||
physicalDevice = result.device;
|
||||
physicalDevice = std::make_unique<PhysicalDevice>(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup queues
|
||||
*/
|
||||
|
||||
queues = std::make_unique<Queues>(physicalDevice, *this);
|
||||
queues = std::make_unique<Queues>(physicalDevice->getVk(), *this);
|
||||
|
||||
/*
|
||||
* Create logical device
|
||||
@@ -207,9 +200,9 @@ Vulkan::Vulkan(std::vector<const char *> instanceExtensions,
|
||||
|
||||
// Create logical device
|
||||
|
||||
handleVkResult(
|
||||
"Could not create logical device",
|
||||
vkCreateDevice(physicalDevice, &createInfo, nullptr, &device));
|
||||
handleVkResult("Could not create logical device",
|
||||
vkCreateDevice(physicalDevice->getVk(), &createInfo,
|
||||
nullptr, &device));
|
||||
|
||||
// Store queue handles
|
||||
|
||||
@@ -259,7 +252,6 @@ Vulkan::Vulkan(std::vector<const char *> instanceExtensions,
|
||||
for (auto &container : frames) {
|
||||
container.emplace(*this);
|
||||
}
|
||||
currentFrame = 0;
|
||||
|
||||
gint = std::make_unique<progressia::main::GraphicsInterface>(this);
|
||||
}
|
||||
@@ -275,13 +267,16 @@ Vulkan::~Vulkan() {
|
||||
commandPool.reset();
|
||||
vkDestroyDevice(device, nullptr);
|
||||
surface.reset();
|
||||
physicalDevice.reset();
|
||||
errorHandler.reset();
|
||||
vkDestroyInstance(instance, nullptr);
|
||||
}
|
||||
|
||||
VkInstance Vulkan::getInstance() const { return instance; }
|
||||
|
||||
VkPhysicalDevice Vulkan::getPhysicalDevice() const { return physicalDevice; }
|
||||
const PhysicalDevice &Vulkan::getPhysicalDevice() const {
|
||||
return *physicalDevice;
|
||||
}
|
||||
|
||||
VkDevice Vulkan::getDevice() const { return device; }
|
||||
|
||||
@@ -333,7 +328,8 @@ VkFormat Vulkan::findSupportedFormat(const std::vector<VkFormat> &candidates,
|
||||
|
||||
for (VkFormat format : candidates) {
|
||||
VkFormatProperties props;
|
||||
vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &props);
|
||||
vkGetPhysicalDeviceFormatProperties(physicalDevice->getVk(), format,
|
||||
&props);
|
||||
|
||||
if (tiling == VK_IMAGE_TILING_LINEAR &&
|
||||
(props.linearTilingFeatures & features) == features) {
|
||||
@@ -351,8 +347,7 @@ VkFormat Vulkan::findSupportedFormat(const std::vector<VkFormat> &candidates,
|
||||
|
||||
uint32_t Vulkan::findMemoryType(uint32_t allowedByDevice,
|
||||
VkMemoryPropertyFlags desiredProperties) {
|
||||
VkPhysicalDeviceMemoryProperties memProperties;
|
||||
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
|
||||
auto memProperties = physicalDevice->getMemory();
|
||||
|
||||
for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
|
||||
if (((1 << i) & allowedByDevice) == 0) {
|
||||
@@ -383,9 +378,9 @@ Frame *Vulkan::getCurrentFrame() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint64_t Vulkan::getLastStartedFrame() { return lastStartedFrame; }
|
||||
uint64_t Vulkan::getLastStartedFrame() const { return lastStartedFrame; }
|
||||
|
||||
std::size_t Vulkan::getFrameInFlightIndex() { return currentFrame; }
|
||||
std::size_t Vulkan::getFrameInFlightIndex() const { return currentFrame; }
|
||||
|
||||
bool Vulkan::startRender() {
|
||||
if (currentFrame >= MAX_FRAMES_IN_FLIGHT - 1) {
|
||||
@@ -421,16 +416,21 @@ void Vulkan::waitIdle() {
|
||||
* VulkanErrorHandler
|
||||
*/
|
||||
|
||||
VulkanErrorHandler::VulkanErrorHandler(Vulkan &vulkan) : vulkan(vulkan) {
|
||||
VulkanErrorHandler::VulkanErrorHandler(Vulkan &vulkan)
|
||||
: debugMessenger(nullptr), vulkan(vulkan) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
VulkanErrorHandler::~VulkanErrorHandler() {
|
||||
#ifdef VULKAN_ERROR_CHECKING
|
||||
vulkan.callVoid("vkDestroyDebugUtilsMessengerEXT",
|
||||
(VkDebugUtilsMessengerEXT)debugMessenger, nullptr);
|
||||
#endif
|
||||
VulkanErrorHandler::~VulkanErrorHandler() {
|
||||
if (debugMessenger != nullptr) {
|
||||
vulkan.callVoid("vkDestroyDebugUtilsMessengerEXT",
|
||||
(VkDebugUtilsMessengerEXT)debugMessenger, nullptr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
VulkanErrorHandler::~VulkanErrorHandler() = default;
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN_ERROR_CHECKING
|
||||
namespace {
|
||||
@@ -445,7 +445,8 @@ debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
[[maybe_unused]] auto &vk = *reinterpret_cast<const Vulkan *>(pUserData);
|
||||
[[maybe_unused]] const auto &vk =
|
||||
*reinterpret_cast<const Vulkan *>(pUserData);
|
||||
|
||||
const char *severityStr =
|
||||
messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
|
||||
@@ -456,7 +457,7 @@ debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
? "info"
|
||||
: "verbose";
|
||||
|
||||
const char *typeStr;
|
||||
const char *typeStr = "";
|
||||
switch (messageType) {
|
||||
case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
|
||||
typeStr = "general";
|
||||
@@ -513,8 +514,9 @@ VulkanErrorHandler::attachDebugProbe(VkInstanceCreateInfo &createInfo) {
|
||||
|
||||
#else
|
||||
|
||||
(void)createInfo;
|
||||
return std::unique_ptr<VkDebugUtilsMessengerCreateInfoEXT>();
|
||||
(void)createInfo; // unused argument
|
||||
(void)this; // not static
|
||||
return {};
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -533,6 +535,7 @@ void VulkanErrorHandler::onInstanceReady() {
|
||||
#endif
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
|
||||
void VulkanErrorHandler::handleVkResult(const char *errorMessage,
|
||||
VkResult result) {
|
||||
if (result == VK_SUCCESS) {
|
||||
@@ -548,7 +551,7 @@ void VulkanErrorHandler::handleVkResult(const char *errorMessage,
|
||||
* Surface
|
||||
*/
|
||||
|
||||
Surface::Surface(Vulkan &vulkan) : vulkan(vulkan) {
|
||||
Surface::Surface(Vulkan &vulkan) : vk(), vulkan(vulkan) {
|
||||
vulkan.handleVkResult("Could not create window surface (what?)",
|
||||
glfwCreateWindowSurface(vulkan.getInstance(),
|
||||
getGLFWWindowHandle(),
|
||||
@@ -563,7 +566,7 @@ VkSurfaceKHR Surface::getVk() { return vk; }
|
||||
* Queue
|
||||
*/
|
||||
|
||||
Queue::Queue(Test test) : test(test) {
|
||||
Queue::Queue(Test test) : test(std::move(test)), vk() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@@ -619,7 +622,7 @@ Queues::Queues(VkPhysicalDevice physicalDevice, Vulkan &vulkan)
|
||||
|
||||
for (std::size_t index = 0; index < queueFamilyCount; index++) {
|
||||
|
||||
for (auto queue : {&graphicsQueue, &presentQueue}) {
|
||||
for (auto *queue : {&graphicsQueue, &presentQueue}) {
|
||||
if (!queue->isSuitable(physicalDevice, index, vulkan,
|
||||
properties[index])) {
|
||||
continue;
|
||||
@@ -634,12 +637,10 @@ Queues::Queues(VkPhysicalDevice physicalDevice, Vulkan &vulkan)
|
||||
}
|
||||
}
|
||||
|
||||
Queues::~Queues() {
|
||||
// do nothing
|
||||
}
|
||||
Queues::~Queues() = default;
|
||||
|
||||
void Queues::storeHandles(VkDevice device) {
|
||||
for (auto queue : {&graphicsQueue, &presentQueue}) {
|
||||
for (auto *queue : {&graphicsQueue, &presentQueue}) {
|
||||
vkGetDeviceQueue(device, queue->getFamilyIndex(), 0, &queue->vk);
|
||||
}
|
||||
}
|
||||
@@ -648,7 +649,7 @@ std::unique_ptr<Queues::CreationRequest>
|
||||
Queues::requestCreation(VkDeviceCreateInfo &createInfo) const {
|
||||
|
||||
std::unique_ptr result = std::make_unique<CreationRequest>();
|
||||
result->priority = 1.0f;
|
||||
result->priority = 1.0F;
|
||||
|
||||
std::unordered_set<uint32_t> uniqueQueues;
|
||||
for (const auto *queue : {&graphicsQueue, &presentQueue}) {
|
||||
@@ -673,7 +674,7 @@ Queues::requestCreation(VkDeviceCreateInfo &createInfo) const {
|
||||
}
|
||||
|
||||
bool Queues::isComplete() const {
|
||||
for (auto queue : {&graphicsQueue, &presentQueue}) {
|
||||
for (const auto *queue : {&graphicsQueue, &presentQueue}) {
|
||||
if (!queue->familyIndex.has_value()) {
|
||||
return false;
|
||||
}
|
||||
@@ -691,7 +692,7 @@ const Queue &Queues::getPresentQueue() const { return presentQueue; }
|
||||
*/
|
||||
|
||||
CommandPool::CommandPool(Vulkan &vulkan, const Queue &queue)
|
||||
: queue(queue), vulkan(vulkan) {
|
||||
: pool(), queue(queue), vulkan(vulkan) {
|
||||
|
||||
VkCommandPoolCreateInfo poolInfo{};
|
||||
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
@@ -714,12 +715,13 @@ VkCommandBuffer CommandPool::allocateCommandBuffer() {
|
||||
allocInfo.commandPool = pool;
|
||||
allocInfo.commandBufferCount = 1;
|
||||
|
||||
VkCommandBuffer commandBuffer;
|
||||
auto *commandBuffer = VkCommandBuffer();
|
||||
vkAllocateCommandBuffers(vulkan.getDevice(), &allocInfo, &commandBuffer);
|
||||
|
||||
return commandBuffer;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
|
||||
void CommandPool::beginCommandBuffer(VkCommandBuffer commandBuffer,
|
||||
VkCommandBufferUsageFlags usage) {
|
||||
VkCommandBufferBeginInfo beginInfo{};
|
||||
@@ -773,5 +775,4 @@ void CommandPool::freeMultiUse(VkCommandBuffer buffer) {
|
||||
vkFreeCommandBuffers(vulkan.getDevice(), pool, 1, &buffer);
|
||||
}
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -17,13 +17,12 @@
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include "../../main/util.h"
|
||||
|
||||
#include "../../main/logging.h"
|
||||
#include "../../main/rendering/graphics_interface.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
namespace CstrUtils {
|
||||
struct CstrHash {
|
||||
@@ -54,13 +53,14 @@ struct CstrCompare {
|
||||
using CstrHashSet = std::unordered_set<const char *, CstrHash, CstrEqual>;
|
||||
} // namespace CstrUtils
|
||||
|
||||
class VkObjectWrapper : private boost::noncopyable {
|
||||
class VkObjectWrapper : private progressia::main::NonCopyable {
|
||||
// empty
|
||||
};
|
||||
|
||||
constexpr std::size_t MAX_FRAMES_IN_FLIGHT = 2;
|
||||
|
||||
class VulkanErrorHandler;
|
||||
class PhysicalDevice;
|
||||
class Surface;
|
||||
class Queue;
|
||||
class Queues;
|
||||
@@ -75,10 +75,10 @@ class Frame;
|
||||
class Vulkan : public VkObjectWrapper {
|
||||
private:
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||
VkDevice device = VK_NULL_HANDLE;
|
||||
|
||||
std::unique_ptr<VulkanErrorHandler> errorHandler;
|
||||
std::unique_ptr<PhysicalDevice> physicalDevice;
|
||||
std::unique_ptr<Surface> surface;
|
||||
std::unique_ptr<Queues> queues;
|
||||
std::unique_ptr<CommandPool> commandPool;
|
||||
@@ -103,9 +103,9 @@ class Vulkan : public VkObjectWrapper {
|
||||
~Vulkan();
|
||||
|
||||
VkInstance getInstance() const;
|
||||
VkPhysicalDevice getPhysicalDevice() const;
|
||||
VkDevice getDevice() const;
|
||||
|
||||
const PhysicalDevice &getPhysicalDevice() const;
|
||||
Surface &getSurface();
|
||||
const Surface &getSurface() const;
|
||||
Queues &getQueues();
|
||||
@@ -135,8 +135,8 @@ class Vulkan : public VkObjectWrapper {
|
||||
bool startRender();
|
||||
void endRender();
|
||||
|
||||
uint64_t getLastStartedFrame();
|
||||
std::size_t getFrameInFlightIndex();
|
||||
uint64_t getLastStartedFrame() const;
|
||||
std::size_t getFrameInFlightIndex() const;
|
||||
|
||||
void waitIdle();
|
||||
|
||||
@@ -192,12 +192,13 @@ class VulkanErrorHandler : public VkObjectWrapper {
|
||||
Vulkan &vulkan;
|
||||
|
||||
public:
|
||||
VulkanErrorHandler(Vulkan &);
|
||||
VulkanErrorHandler(Vulkan &vulkan);
|
||||
|
||||
std::unique_ptr<VkDebugUtilsMessengerCreateInfoEXT>
|
||||
attachDebugProbe(VkInstanceCreateInfo &);
|
||||
void onInstanceReady();
|
||||
|
||||
// NOLINTNEXTLINE(performance-trivially-destructible): fixing this makes code less readable due to use of macros in implementation
|
||||
~VulkanErrorHandler();
|
||||
|
||||
void handleVkResult(const char *errorMessage, VkResult result);
|
||||
@@ -209,7 +210,7 @@ class Surface : public VkObjectWrapper {
|
||||
Vulkan &vulkan;
|
||||
|
||||
public:
|
||||
Surface(Vulkan &);
|
||||
Surface(Vulkan &vulkan);
|
||||
~Surface();
|
||||
|
||||
VkSurfaceKHR getVk();
|
||||
@@ -226,7 +227,7 @@ class Queue {
|
||||
|
||||
friend class Queues;
|
||||
|
||||
Queue(Test);
|
||||
Queue(Test test);
|
||||
|
||||
public:
|
||||
bool isSuitable(VkPhysicalDevice, uint32_t familyIndex, Vulkan &,
|
||||
@@ -275,7 +276,7 @@ class CommandPool : public VkObjectWrapper {
|
||||
VkCommandBufferUsageFlags usage);
|
||||
|
||||
public:
|
||||
CommandPool(Vulkan &, const Queue &);
|
||||
CommandPool(Vulkan &vulkan, const Queue &queue);
|
||||
~CommandPool();
|
||||
|
||||
VkCommandBuffer beginSingleUse();
|
||||
@@ -287,5 +288,4 @@ class CommandPool : public VkObjectWrapper {
|
||||
void freeMultiUse(VkCommandBuffer);
|
||||
};
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -1,11 +1,10 @@
|
||||
#include "vulkan_descriptor_set.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
DescriptorSetInterface::DescriptorSetInterface(uint32_t setNumber,
|
||||
Vulkan &vulkan)
|
||||
: setNumber(setNumber), vulkan(vulkan) {}
|
||||
: layout(), setNumber(setNumber), vulkan(vulkan) {}
|
||||
|
||||
VkDescriptorSetLayout DescriptorSetInterface::getLayout() const {
|
||||
return layout;
|
||||
@@ -15,5 +14,4 @@ uint32_t DescriptorSetInterface::getSetNumber() const { return setNumber; }
|
||||
|
||||
Vulkan &DescriptorSetInterface::getVulkan() { return vulkan; }
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -2,8 +2,7 @@
|
||||
|
||||
#include "vulkan_common.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
class DescriptorSetInterface : public VkObjectWrapper {
|
||||
protected:
|
||||
@@ -19,5 +18,4 @@ class DescriptorSetInterface : public VkObjectWrapper {
|
||||
Vulkan &getVulkan();
|
||||
};
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -8,12 +8,11 @@
|
||||
#include "vulkan_render_pass.h"
|
||||
#include "vulkan_swap_chain.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
Frame::Frame(Vulkan &vulkan)
|
||||
: vulkan(vulkan),
|
||||
commandBuffer(vulkan.getCommandPool().allocateMultiUse()) {
|
||||
: vulkan(vulkan), commandBuffer(vulkan.getCommandPool().allocateMultiUse()),
|
||||
imageAvailableSemaphore(), renderFinishedSemaphore(), inFlightFence() {
|
||||
|
||||
VkSemaphoreCreateInfo semaphoreInfo{};
|
||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
@@ -98,12 +97,12 @@ bool Frame::startRender() {
|
||||
vulkan.getPipeline().getVk());
|
||||
|
||||
VkViewport viewport{};
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
viewport.x = 0.0F;
|
||||
viewport.y = 0.0F;
|
||||
viewport.width = (float)extent.width;
|
||||
viewport.height = (float)extent.height;
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
viewport.minDepth = 0.0F;
|
||||
viewport.maxDepth = 1.0F;
|
||||
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
|
||||
|
||||
VkRect2D scissor{};
|
||||
@@ -170,5 +169,4 @@ void Frame::endRender() {
|
||||
|
||||
VkCommandBuffer Frame::getCommandBuffer() { return commandBuffer; }
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -2,8 +2,7 @@
|
||||
|
||||
#include "vulkan_common.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
class Frame : public VkObjectWrapper {
|
||||
private:
|
||||
@@ -32,5 +31,4 @@ class Frame : public VkObjectWrapper {
|
||||
VkCommandBuffer getCommandBuffer();
|
||||
};
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -9,8 +9,7 @@
|
||||
#include "vulkan_pipeline.h"
|
||||
#include "vulkan_texture_descriptors.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
/*
|
||||
* Image
|
||||
@@ -21,9 +20,7 @@ Image::Image(VkImage vk, VkImageView view, VkFormat format)
|
||||
// do nothing
|
||||
}
|
||||
|
||||
Image::~Image() {
|
||||
// do nothing
|
||||
}
|
||||
Image::~Image() = default;
|
||||
|
||||
/*
|
||||
* ManagedImage
|
||||
@@ -34,7 +31,7 @@ ManagedImage::ManagedImage(std::size_t width, std::size_t height,
|
||||
VkImageUsageFlags usage, Vulkan &vulkan)
|
||||
:
|
||||
|
||||
Image(VK_NULL_HANDLE, VK_NULL_HANDLE, format), vulkan(vulkan),
|
||||
Image(VK_NULL_HANDLE, VK_NULL_HANDLE, format), memory(), vulkan(vulkan),
|
||||
|
||||
state{VK_IMAGE_LAYOUT_UNDEFINED, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT} {
|
||||
|
||||
@@ -147,7 +144,8 @@ Texture::Texture(const progressia::main::Image &src, Vulkan &vulkan)
|
||||
ManagedImage(src.width, src.height, VK_FORMAT_R8G8B8A8_SRGB,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
vulkan) {
|
||||
vulkan),
|
||||
sampler() {
|
||||
|
||||
/*
|
||||
* Create a staging buffer
|
||||
@@ -212,9 +210,9 @@ Texture::Texture(const progressia::main::Image &src, Vulkan &vulkan)
|
||||
samplerInfo.compareEnable = VK_FALSE;
|
||||
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerInfo.mipLodBias = 0.0f;
|
||||
samplerInfo.minLod = 0.0f;
|
||||
samplerInfo.maxLod = 0.0f;
|
||||
samplerInfo.mipLodBias = 0.0F;
|
||||
samplerInfo.minLod = 0.0F;
|
||||
samplerInfo.maxLod = 0.0F;
|
||||
|
||||
vulkan.handleVkResult(
|
||||
"Could not create texture sampler",
|
||||
@@ -224,6 +222,7 @@ Texture::Texture(const progressia::main::Image &src, Vulkan &vulkan)
|
||||
* Create descriptor set
|
||||
*/
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer): sampler must be set using vkCreateSampler first
|
||||
descriptorSet = vulkan.getTextureDescriptors().addTexture(view, sampler);
|
||||
}
|
||||
|
||||
@@ -234,8 +233,8 @@ Texture::~Texture() {
|
||||
|
||||
void Texture::bind() {
|
||||
// REPORT_ERROR if getCurrentFrame() == nullptr
|
||||
auto commandBuffer = vulkan.getCurrentFrame()->getCommandBuffer();
|
||||
auto pipelineLayout = vulkan.getPipeline().getLayout();
|
||||
auto *commandBuffer = vulkan.getCurrentFrame()->getCommandBuffer();
|
||||
auto *pipelineLayout = vulkan.getPipeline().getLayout();
|
||||
|
||||
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipelineLayout,
|
||||
@@ -243,5 +242,4 @@ void Texture::bind() {
|
||||
&descriptorSet, 0, nullptr);
|
||||
}
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "vulkan_buffer.h"
|
||||
@@ -8,8 +7,7 @@
|
||||
|
||||
#include "../../main/rendering/image.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
class Image : public VkObjectWrapper {
|
||||
public:
|
||||
@@ -37,8 +35,9 @@ class ManagedImage : public Image {
|
||||
State state;
|
||||
|
||||
public:
|
||||
ManagedImage(std::size_t width, std::size_t height, VkFormat,
|
||||
VkImageAspectFlags, VkImageUsageFlags, Vulkan &);
|
||||
ManagedImage(std::size_t width, std::size_t height, VkFormat format,
|
||||
VkImageAspectFlags aspect, VkImageUsageFlags usage,
|
||||
Vulkan &vulkan);
|
||||
~ManagedImage();
|
||||
|
||||
void transition(State);
|
||||
@@ -50,11 +49,10 @@ class Texture : public ManagedImage {
|
||||
VkSampler sampler;
|
||||
VkDescriptorSet descriptorSet;
|
||||
|
||||
Texture(const progressia::main::Image &, Vulkan &vulkan);
|
||||
Texture(const main::Image &src, Vulkan &vulkan);
|
||||
~Texture();
|
||||
|
||||
void bind();
|
||||
};
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -1,34 +1,32 @@
|
||||
#include "vulkan_mgmt.h"
|
||||
|
||||
#include "../config.h"
|
||||
#include "vulkan_common.h"
|
||||
#include "vulkan_swap_chain.h"
|
||||
|
||||
#include "../../main/logging.h"
|
||||
using namespace progressia::main::logging;
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
Vulkan *vulkan;
|
||||
|
||||
void initializeVulkan() {
|
||||
VulkanManager::VulkanManager() {
|
||||
debug("Vulkan initializing");
|
||||
|
||||
// Instance extensions
|
||||
|
||||
std::vector<const char *> instanceExtensions;
|
||||
{
|
||||
uint32_t glfwExtensionCount;
|
||||
const char **glfwExtensions;
|
||||
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
|
||||
uint32_t glfwExtensionCount = 0;
|
||||
const char **glfwExtensions =
|
||||
glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
|
||||
|
||||
instanceExtensions.reserve(instanceExtensions.size() +
|
||||
glfwExtensionCount);
|
||||
for (std::size_t i = 0; i < glfwExtensionCount; i++) {
|
||||
instanceExtensions.push_back(glfwExtensions[i]);
|
||||
instanceExtensions.emplace_back(glfwExtensions[i]);
|
||||
}
|
||||
|
||||
#ifdef VULKAN_ERROR_CHECKING
|
||||
instanceExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
instanceExtensions.emplace_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -44,29 +42,21 @@ void initializeVulkan() {
|
||||
#endif
|
||||
};
|
||||
|
||||
vulkan = new Vulkan(instanceExtensions, deviceExtensions, validationLayers);
|
||||
vulkan = std::make_unique<Vulkan>(instanceExtensions, deviceExtensions,
|
||||
validationLayers);
|
||||
|
||||
debug("Vulkan initialized");
|
||||
}
|
||||
|
||||
Vulkan *getVulkan() { return vulkan; }
|
||||
VulkanManager::~VulkanManager() { debug("Vulkan terminating"); }
|
||||
|
||||
bool startRender() { return vulkan->startRender(); }
|
||||
Vulkan *VulkanManager::getVulkan() { return vulkan.get(); }
|
||||
const Vulkan *VulkanManager::getVulkan() const { return vulkan.get(); }
|
||||
|
||||
void endRender() { return vulkan->endRender(); }
|
||||
bool VulkanManager::startRender() { return vulkan->startRender(); }
|
||||
|
||||
void resizeVulkanSurface() { vulkan->getSwapChain().recreate(); }
|
||||
void VulkanManager::endRender() { return vulkan->endRender(); }
|
||||
|
||||
void shutdownVulkan() {
|
||||
debug("Vulkan terminating");
|
||||
void VulkanManager::resizeSurface() { vulkan->getSwapChain().recreate(); }
|
||||
|
||||
if (vulkan != nullptr) {
|
||||
delete vulkan;
|
||||
vulkan = nullptr;
|
||||
}
|
||||
|
||||
debug("Vulkan terminated");
|
||||
}
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -2,22 +2,27 @@
|
||||
|
||||
#include "vulkan_common.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
void initializeVulkan();
|
||||
class VulkanManager {
|
||||
|
||||
Vulkan *getVulkan();
|
||||
private:
|
||||
std::unique_ptr<Vulkan> vulkan;
|
||||
|
||||
void resizeVulkanSurface();
|
||||
public:
|
||||
VulkanManager();
|
||||
~VulkanManager();
|
||||
|
||||
/*
|
||||
* Returns false when the frame should be skipped
|
||||
*/
|
||||
bool startRender();
|
||||
void endRender();
|
||||
Vulkan *getVulkan();
|
||||
const Vulkan *getVulkan() const;
|
||||
|
||||
void shutdownVulkan();
|
||||
void resizeSurface();
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
/*
|
||||
* Returns false when the frame should be skipped
|
||||
*/
|
||||
bool startRender();
|
||||
void endRender();
|
||||
};
|
||||
|
||||
} // namespace progressia::desktop
|
||||
|
51
desktop/graphics/vulkan_physical_device.cpp
Normal file
51
desktop/graphics/vulkan_physical_device.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "vulkan_physical_device.h"
|
||||
|
||||
namespace progressia::desktop {
|
||||
|
||||
PhysicalDevice::PhysicalDevice(VkPhysicalDevice vk)
|
||||
: vk(vk), properties(), features(), memory() {
|
||||
vkGetPhysicalDeviceProperties(vk, &properties);
|
||||
vkGetPhysicalDeviceFeatures(vk, &features);
|
||||
vkGetPhysicalDeviceMemoryProperties(vk, &memory);
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
|
||||
bool PhysicalDevice::isSuitable() const {
|
||||
// Add feature, limit, etc. checks here.
|
||||
// Return false and debug() if problems arise.
|
||||
return true;
|
||||
}
|
||||
|
||||
VkPhysicalDevice PhysicalDevice::getVk() const { return vk; }
|
||||
|
||||
const VkPhysicalDeviceProperties &PhysicalDevice::getProperties() const {
|
||||
return properties;
|
||||
}
|
||||
|
||||
const VkPhysicalDeviceFeatures &PhysicalDevice::getFeatures() const {
|
||||
return features;
|
||||
}
|
||||
|
||||
const VkPhysicalDeviceLimits &PhysicalDevice::getLimits() const {
|
||||
return properties.limits;
|
||||
}
|
||||
|
||||
const VkPhysicalDeviceMemoryProperties &PhysicalDevice::getMemory() const {
|
||||
return memory;
|
||||
}
|
||||
|
||||
VkPhysicalDeviceType PhysicalDevice::getType() const {
|
||||
return properties.deviceType;
|
||||
}
|
||||
|
||||
const char *PhysicalDevice::getName() const { return properties.deviceName; }
|
||||
|
||||
VkDeviceSize PhysicalDevice::getMinUniformOffset() const {
|
||||
return getLimits().minUniformBufferOffsetAlignment;
|
||||
}
|
||||
|
||||
uint32_t PhysicalDevice::getMaxTextureSize() const {
|
||||
return getLimits().maxImageDimension2D;
|
||||
}
|
||||
|
||||
} // namespace progressia::desktop
|
33
desktop/graphics/vulkan_physical_device.h
Normal file
33
desktop/graphics/vulkan_physical_device.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "vulkan_common.h"
|
||||
|
||||
namespace progressia::desktop {
|
||||
|
||||
class PhysicalDevice {
|
||||
|
||||
private:
|
||||
VkPhysicalDevice vk;
|
||||
VkPhysicalDeviceProperties properties;
|
||||
VkPhysicalDeviceFeatures features;
|
||||
VkPhysicalDeviceMemoryProperties memory;
|
||||
|
||||
public:
|
||||
PhysicalDevice(VkPhysicalDevice vk);
|
||||
|
||||
bool isSuitable() const;
|
||||
|
||||
VkPhysicalDevice getVk() const;
|
||||
const VkPhysicalDeviceProperties &getProperties() const;
|
||||
const VkPhysicalDeviceFeatures &getFeatures() const;
|
||||
const VkPhysicalDeviceLimits &getLimits() const;
|
||||
const VkPhysicalDeviceMemoryProperties &getMemory() const;
|
||||
|
||||
VkPhysicalDeviceType getType() const;
|
||||
const char *getName() const;
|
||||
|
||||
VkDeviceSize getMinUniformOffset() const;
|
||||
uint32_t getMaxTextureSize() const;
|
||||
};
|
||||
|
||||
} // namespace progressia::desktop
|
@@ -4,8 +4,7 @@
|
||||
#include "vulkan_swap_chain.h"
|
||||
using namespace progressia::main::logging;
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -14,7 +13,7 @@ bool checkDeviceExtensions(VkPhysicalDevice device,
|
||||
CstrUtils::CstrHashSet toFind(deviceExtensions.cbegin(),
|
||||
deviceExtensions.cend());
|
||||
|
||||
uint32_t extensionCount;
|
||||
uint32_t extensionCount = 0;
|
||||
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount,
|
||||
nullptr);
|
||||
|
||||
@@ -29,20 +28,24 @@ bool checkDeviceExtensions(VkPhysicalDevice device,
|
||||
return toFind.empty();
|
||||
}
|
||||
|
||||
bool isDeviceSuitable(const PhysicalDeviceData &data, Vulkan &vulkan,
|
||||
bool isDeviceSuitable(const PhysicalDevice &data, Vulkan &vulkan,
|
||||
const std::vector<const char *> &deviceExtensions) {
|
||||
|
||||
if (!Queues(data.device, vulkan).isComplete()) {
|
||||
if (!data.isSuitable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!checkDeviceExtensions(data.device, deviceExtensions)) {
|
||||
if (!Queues(data.getVk(), vulkan).isComplete()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!checkDeviceExtensions(data.getVk(), deviceExtensions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check requires that the swap chain extension is present
|
||||
if (!SwapChain::isSwapChainSuitable(
|
||||
SwapChain::querySwapChainSupport(data.device, vulkan))) {
|
||||
SwapChain::querySwapChainSupport(data.getVk(), vulkan))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -51,8 +54,8 @@ bool isDeviceSuitable(const PhysicalDeviceData &data, Vulkan &vulkan,
|
||||
|
||||
} // namespace
|
||||
|
||||
const PhysicalDeviceData &
|
||||
pickPhysicalDevice(std::vector<PhysicalDeviceData> &choices, Vulkan &vulkan,
|
||||
const PhysicalDevice &
|
||||
pickPhysicalDevice(std::vector<PhysicalDevice> &choices, Vulkan &vulkan,
|
||||
const std::vector<const char *> &deviceExtensions) {
|
||||
|
||||
// Remove unsuitable devices
|
||||
@@ -82,20 +85,17 @@ pickPhysicalDevice(std::vector<PhysicalDeviceData> &choices, Vulkan &vulkan,
|
||||
{"Virtual GPU", +1},
|
||||
{"CPU", -1}};
|
||||
|
||||
auto type = option.properties.deviceType;
|
||||
m << "\n\t- " << opinions[type].description << " "
|
||||
<< option.properties.deviceName;
|
||||
auto type = option.getType();
|
||||
m << "\n\t- " << opinions[type].description << " " << option.getName();
|
||||
|
||||
if (opinions[pick->properties.deviceType].value <
|
||||
opinions[type].value) {
|
||||
if (opinions[pick->getType()].value < opinions[type].value) {
|
||||
pick = &option;
|
||||
}
|
||||
}
|
||||
m << "\n";
|
||||
|
||||
m << "Picked device " << pick->properties.deviceName;
|
||||
m << "Picked device " << pick->getName();
|
||||
return *pick;
|
||||
}
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -1,21 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "vulkan_common.h"
|
||||
#include "vulkan_physical_device.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
struct PhysicalDeviceData {
|
||||
VkPhysicalDevice device;
|
||||
VkPhysicalDeviceProperties properties;
|
||||
VkPhysicalDeviceFeatures features;
|
||||
};
|
||||
|
||||
const PhysicalDeviceData &
|
||||
pickPhysicalDevice(std::vector<PhysicalDeviceData> &, Vulkan &,
|
||||
const PhysicalDevice &
|
||||
pickPhysicalDevice(std::vector<PhysicalDevice> &, Vulkan &,
|
||||
const std::vector<const char *> &deviceExtensions);
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -5,17 +5,16 @@
|
||||
#include "vulkan_descriptor_set.h"
|
||||
#include "vulkan_render_pass.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
Pipeline::Pipeline(Vulkan &vulkan) : vulkan(vulkan) {
|
||||
Pipeline::Pipeline(Vulkan &vulkan) : layout(), vk(), vulkan(vulkan) {
|
||||
|
||||
auto &adapter = vulkan.getAdapter();
|
||||
|
||||
// Shaders
|
||||
|
||||
auto vertShader = createShaderModule(adapter.loadVertexShader());
|
||||
auto fragShader = createShaderModule(adapter.loadFragmentShader());
|
||||
auto *vertShader = createShaderModule(adapter.loadVertexShader());
|
||||
auto *fragShader = createShaderModule(adapter.loadFragmentShader());
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
|
||||
vertShaderStageInfo.sType =
|
||||
@@ -81,13 +80,13 @@ Pipeline::Pipeline(Vulkan &vulkan) : vulkan(vulkan) {
|
||||
rasterizer.depthClampEnable = VK_FALSE;
|
||||
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
||||
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterizer.lineWidth = 1.0f;
|
||||
rasterizer.lineWidth = 1.0F;
|
||||
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
|
||||
rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
rasterizer.depthBiasEnable = VK_FALSE;
|
||||
rasterizer.depthBiasConstantFactor = 0.0f; // Optional
|
||||
rasterizer.depthBiasClamp = 0.0f; // Optional
|
||||
rasterizer.depthBiasSlopeFactor = 0.0f; // Optional
|
||||
rasterizer.depthBiasConstantFactor = 0.0F; // Optional
|
||||
rasterizer.depthBiasClamp = 0.0F; // Optional
|
||||
rasterizer.depthBiasSlopeFactor = 0.0F; // Optional
|
||||
|
||||
// Multisampling (disabled)
|
||||
|
||||
@@ -96,7 +95,7 @@ Pipeline::Pipeline(Vulkan &vulkan) : vulkan(vulkan) {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
multisampling.sampleShadingEnable = VK_FALSE;
|
||||
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
multisampling.minSampleShading = 1.0f; // Optional
|
||||
multisampling.minSampleShading = 1.0F; // Optional
|
||||
multisampling.pSampleMask = nullptr; // Optional
|
||||
multisampling.alphaToCoverageEnable = VK_FALSE; // Optional
|
||||
multisampling.alphaToOneEnable = VK_FALSE; // Optional
|
||||
@@ -138,10 +137,10 @@ Pipeline::Pipeline(Vulkan &vulkan) : vulkan(vulkan) {
|
||||
colorBlending.logicOp = VK_LOGIC_OP_COPY; // Optional
|
||||
colorBlending.attachmentCount = 1;
|
||||
colorBlending.pAttachments = &colorBlendAttachment;
|
||||
colorBlending.blendConstants[0] = 0.0f; // Optional
|
||||
colorBlending.blendConstants[1] = 0.0f; // Optional
|
||||
colorBlending.blendConstants[2] = 0.0f; // Optional
|
||||
colorBlending.blendConstants[3] = 0.0f; // Optional
|
||||
colorBlending.blendConstants[0] = 0.0F; // Optional
|
||||
colorBlending.blendConstants[1] = 0.0F; // Optional
|
||||
colorBlending.blendConstants[2] = 0.0F; // Optional
|
||||
colorBlending.blendConstants[3] = 0.0F; // Optional
|
||||
|
||||
// Pipeline
|
||||
|
||||
@@ -202,7 +201,7 @@ VkShaderModule Pipeline::createShaderModule(const std::vector<char> &bytecode) {
|
||||
// Important - the buffer must be aligned properly. std::vector does that.
|
||||
createInfo.pCode = reinterpret_cast<const uint32_t *>(bytecode.data());
|
||||
|
||||
VkShaderModule shaderModule;
|
||||
VkShaderModule shaderModule = nullptr;
|
||||
vulkan.handleVkResult("Could not load shader",
|
||||
vkCreateShaderModule(vulkan.getDevice(), &createInfo,
|
||||
nullptr, &shaderModule));
|
||||
@@ -219,5 +218,4 @@ VkPipeline Pipeline::getVk() { return vk; }
|
||||
|
||||
VkPipelineLayout Pipeline::getLayout() { return layout; }
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -2,8 +2,7 @@
|
||||
|
||||
#include "vulkan_common.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
class Pipeline : public VkObjectWrapper {
|
||||
|
||||
@@ -23,5 +22,4 @@ class Pipeline : public VkObjectWrapper {
|
||||
VkPipelineLayout getLayout();
|
||||
};
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -3,10 +3,9 @@
|
||||
#include "vulkan_adapter.h"
|
||||
#include "vulkan_common.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
RenderPass::RenderPass(Vulkan &vulkan) : vulkan(vulkan) {
|
||||
RenderPass::RenderPass(Vulkan &vulkan) : vk(), vulkan(vulkan) {
|
||||
|
||||
std::vector<VkAttachmentDescription> attachmentDescriptions;
|
||||
std::vector<VkAttachmentReference> attachmentReferences;
|
||||
@@ -15,8 +14,8 @@ RenderPass::RenderPass(Vulkan &vulkan) : vulkan(vulkan) {
|
||||
|
||||
for (std::size_t i = 0; i < attachments.size(); i++) {
|
||||
const auto &attachment = attachments[i];
|
||||
VkAttachmentDescription *desc;
|
||||
VkAttachmentReference *ref;
|
||||
VkAttachmentDescription *desc = nullptr;
|
||||
VkAttachmentReference *ref = nullptr;
|
||||
|
||||
attachmentDescriptions.push_back({});
|
||||
desc = &attachmentDescriptions.back();
|
||||
@@ -79,5 +78,4 @@ RenderPass::~RenderPass() {
|
||||
|
||||
VkRenderPass RenderPass::getVk() { return vk; }
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -2,8 +2,7 @@
|
||||
|
||||
#include "vulkan_common.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
class RenderPass : public VkObjectWrapper {
|
||||
|
||||
@@ -19,5 +18,4 @@ class RenderPass : public VkObjectWrapper {
|
||||
VkRenderPass getVk();
|
||||
};
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -7,23 +7,23 @@
|
||||
#include "glfw_mgmt_details.h"
|
||||
#include "vulkan_adapter.h"
|
||||
#include "vulkan_common.h"
|
||||
#include "vulkan_physical_device.h"
|
||||
#include "vulkan_render_pass.h"
|
||||
|
||||
#include "../../main/logging.h"
|
||||
using namespace progressia::main::logging;
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
SwapChain::SupportDetails
|
||||
SwapChain::querySwapChainSupport(VkPhysicalDevice device, Vulkan &vulkan) {
|
||||
SupportDetails details;
|
||||
auto surface = vulkan.getSurface().getVk();
|
||||
auto *surface = vulkan.getSurface().getVk();
|
||||
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface,
|
||||
&details.capabilities);
|
||||
|
||||
uint32_t formatCount;
|
||||
uint32_t formatCount = 0;
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount,
|
||||
nullptr);
|
||||
|
||||
@@ -33,7 +33,7 @@ SwapChain::querySwapChainSupport(VkPhysicalDevice device, Vulkan &vulkan) {
|
||||
details.formats.data());
|
||||
}
|
||||
|
||||
uint32_t presentModeCount;
|
||||
uint32_t presentModeCount = 0;
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface,
|
||||
&presentModeCount, nullptr);
|
||||
|
||||
@@ -51,7 +51,8 @@ bool SwapChain::isSwapChainSuitable(const SupportDetails &details) {
|
||||
}
|
||||
|
||||
void SwapChain::create() {
|
||||
auto details = querySwapChainSupport(vulkan.getPhysicalDevice(), vulkan);
|
||||
auto details =
|
||||
querySwapChainSupport(vulkan.getPhysicalDevice().getVk(), vulkan);
|
||||
auto surfaceFormat = chooseSurfaceFormat(details.formats);
|
||||
auto presentMode = choosePresentMode(details.presentModes, true);
|
||||
this->extent = chooseExtent(details.capabilities);
|
||||
@@ -188,6 +189,7 @@ void SwapChain::create() {
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
|
||||
VkSurfaceFormatKHR SwapChain::chooseSurfaceFormat(
|
||||
const std::vector<VkSurfaceFormatKHR> &supported) {
|
||||
for (const auto &option : supported) {
|
||||
@@ -202,6 +204,7 @@ VkSurfaceFormatKHR SwapChain::chooseSurfaceFormat(
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
|
||||
bool SwapChain::isTripleBufferingSupported(
|
||||
const std::vector<VkPresentModeKHR> &supported) {
|
||||
return std::find(supported.begin(), supported.end(),
|
||||
@@ -219,13 +222,15 @@ SwapChain::choosePresentMode(const std::vector<VkPresentModeKHR> &supported,
|
||||
}
|
||||
|
||||
VkExtent2D
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): future-proofing
|
||||
SwapChain::chooseExtent(const VkSurfaceCapabilitiesKHR &capabilities) {
|
||||
if (capabilities.currentExtent.width !=
|
||||
std::numeric_limits<uint32_t>::max()) {
|
||||
return capabilities.currentExtent;
|
||||
}
|
||||
|
||||
int width, height;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
glfwGetFramebufferSize(getGLFWWindowHandle(), &width, &height);
|
||||
|
||||
VkExtent2D actualExtent = {static_cast<uint32_t>(width),
|
||||
@@ -242,7 +247,7 @@ SwapChain::chooseExtent(const VkSurfaceCapabilitiesKHR &capabilities) {
|
||||
}
|
||||
|
||||
void SwapChain::destroy() {
|
||||
for (auto framebuffer : framebuffers) {
|
||||
for (auto *framebuffer : framebuffers) {
|
||||
vkDestroyFramebuffer(vulkan.getDevice(), framebuffer, nullptr);
|
||||
}
|
||||
framebuffers.clear();
|
||||
@@ -259,7 +264,7 @@ void SwapChain::destroy() {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto colorBufferView : colorBufferViews) {
|
||||
for (auto *colorBufferView : colorBufferViews) {
|
||||
vkDestroyImageView(vulkan.getDevice(), colorBufferView, nullptr);
|
||||
}
|
||||
colorBufferViews.clear();
|
||||
@@ -271,10 +276,10 @@ void SwapChain::destroy() {
|
||||
}
|
||||
|
||||
SwapChain::SwapChain(Vulkan &vulkan)
|
||||
: vk(VK_NULL_HANDLE), colorBuffer(nullptr),
|
||||
colorBufferViews(), extent{0, 0}, depthBuffer(nullptr), framebuffers(),
|
||||
vulkan(vulkan) {
|
||||
auto details = querySwapChainSupport(vulkan.getPhysicalDevice(), vulkan);
|
||||
: vk(VK_NULL_HANDLE), colorBuffer(nullptr), extent{0, 0},
|
||||
depthBuffer(nullptr), vulkan(vulkan) {
|
||||
auto details =
|
||||
querySwapChainSupport(vulkan.getPhysicalDevice().getVk(), vulkan);
|
||||
auto surfaceFormat = chooseSurfaceFormat(details.formats);
|
||||
|
||||
vulkan.getAdapter().getAttachments().push_back(
|
||||
@@ -289,7 +294,7 @@ SwapChain::SwapChain(Vulkan &vulkan)
|
||||
VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
VK_ATTACHMENT_STORE_OP_STORE,
|
||||
|
||||
{{{0.0f, 0.0f, 0.0f, 1.0f}}},
|
||||
{{{0.0F, 0.0F, 0.0F, 1.0F}}},
|
||||
|
||||
std::make_unique<Image>(static_cast<VkImage>(VK_NULL_HANDLE),
|
||||
static_cast<VkImageView>(VK_NULL_HANDLE),
|
||||
@@ -325,5 +330,4 @@ VkFramebuffer SwapChain::getFramebuffer(std::size_t index) const {
|
||||
|
||||
VkExtent2D SwapChain::getExtent() const { return extent; }
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -3,8 +3,7 @@
|
||||
#include "vulkan_adapter.h"
|
||||
#include "vulkan_common.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
class SwapChain : public VkObjectWrapper {
|
||||
|
||||
@@ -54,5 +53,4 @@ class SwapChain : public VkObjectWrapper {
|
||||
VkExtent2D getExtent() const;
|
||||
};
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -1,7 +1,6 @@
|
||||
#include "vulkan_texture_descriptors.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
void TextureDescriptors::allocatePool() {
|
||||
pools.resize(pools.size() + 1);
|
||||
@@ -16,7 +15,7 @@ void TextureDescriptors::allocatePool() {
|
||||
poolInfo.pPoolSizes = &poolSize;
|
||||
poolInfo.maxSets = POOL_SIZE;
|
||||
|
||||
auto output = &pools[pools.size() - 1];
|
||||
auto *output = &pools[pools.size() - 1];
|
||||
vulkan.handleVkResult(
|
||||
"Could not create texture descriptor pool",
|
||||
vkCreateDescriptorPool(vulkan.getDevice(), &poolInfo, nullptr, output));
|
||||
@@ -25,7 +24,7 @@ void TextureDescriptors::allocatePool() {
|
||||
}
|
||||
|
||||
TextureDescriptors::TextureDescriptors(Vulkan &vulkan)
|
||||
: DescriptorSetInterface(SET_NUMBER, vulkan) {
|
||||
: DescriptorSetInterface(SET_NUMBER, vulkan), lastPoolCapacity(0) {
|
||||
VkDescriptorSetLayoutCreateInfo layoutInfo{};
|
||||
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
|
||||
@@ -48,7 +47,7 @@ TextureDescriptors::TextureDescriptors(Vulkan &vulkan)
|
||||
}
|
||||
|
||||
TextureDescriptors::~TextureDescriptors() {
|
||||
for (auto pool : pools) {
|
||||
for (auto *pool : pools) {
|
||||
vkDestroyDescriptorPool(vulkan.getDevice(), pool, nullptr);
|
||||
}
|
||||
|
||||
@@ -72,7 +71,7 @@ VkDescriptorSet TextureDescriptors::addTexture(VkImageView view,
|
||||
allocInfo.descriptorSetCount = 1;
|
||||
allocInfo.pSetLayouts = &layout;
|
||||
|
||||
VkDescriptorSet descriptorSet;
|
||||
VkDescriptorSet descriptorSet = nullptr;
|
||||
vulkan.handleVkResult("Could not create texture descriptor set",
|
||||
vkAllocateDescriptorSets(vulkan.getDevice(),
|
||||
&allocInfo, &descriptorSet));
|
||||
@@ -102,5 +101,4 @@ VkDescriptorSet TextureDescriptors::addTexture(VkImageView view,
|
||||
return descriptorSet;
|
||||
}
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -5,8 +5,7 @@
|
||||
#include "vulkan_common.h"
|
||||
#include "vulkan_descriptor_set.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
class TextureDescriptors : public DescriptorSetInterface {
|
||||
private:
|
||||
@@ -25,5 +24,4 @@ class TextureDescriptors : public DescriptorSetInterface {
|
||||
VkDescriptorSet addTexture(VkImageView, VkSampler);
|
||||
};
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -7,8 +8,7 @@
|
||||
#include "vulkan_common.h"
|
||||
#include "vulkan_descriptor_set.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
template <typename... Entries> class Uniform : public DescriptorSetInterface {
|
||||
|
||||
@@ -70,7 +70,6 @@ template <typename... Entries> class Uniform : public DescriptorSetInterface {
|
||||
void doUpdates();
|
||||
};
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
||||
#include "vulkan_uniform.inl"
|
||||
|
@@ -5,14 +5,29 @@
|
||||
#include "../../main/util.h"
|
||||
#include "vulkan_frame.h"
|
||||
#include "vulkan_pipeline.h"
|
||||
#include "vulkan_physical_device.h"
|
||||
|
||||
namespace progressia {
|
||||
namespace desktop {
|
||||
namespace progressia::desktop {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
std::size_t offsetOf(Vulkan &vulkan) {
|
||||
auto step = vulkan.getPhysicalDevice().getMinUniformOffset();
|
||||
return ((sizeof(T) - 1) / step + 1) * step; // Round up to multiple
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::size_t offsetOf(Vulkan &vulkan, const T&) {
|
||||
return offsetOf<T>(vulkan);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename... Entries>
|
||||
Uniform<Entries...>::StateImpl::Set::Set(VkDescriptorSet vk, Vulkan &vulkan)
|
||||
: vk(vk),
|
||||
contents((sizeof(Entries) + ...), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||
contents((detail::offsetOf<Entries>(vulkan) + ...), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
vulkan) {}
|
||||
@@ -48,7 +63,7 @@ Uniform<Entries...>::StateImpl::StateImpl(
|
||||
writes[index].descriptorCount = 1;
|
||||
writes[index].pBufferInfo = &bufferInfos[index];
|
||||
|
||||
offset += sizeof(Entry);
|
||||
offset += detail::offsetOf<Entry>(vulkan);
|
||||
index++;
|
||||
})
|
||||
}
|
||||
@@ -71,7 +86,7 @@ void Uniform<Entries...>::State::update(const Entries &...entries) {
|
||||
auto *dst = state.newContents.data();
|
||||
FOR_PACK(Entries, entries, e, {
|
||||
std::memcpy(dst, &e, sizeof(e));
|
||||
dst += sizeof(e);
|
||||
dst += detail::offsetOf(uniform->getVulkan(), e);
|
||||
})
|
||||
state.setsToUpdate = state.sets.size();
|
||||
}
|
||||
@@ -190,5 +205,4 @@ template <typename... Entries> void Uniform<Entries...>::doUpdates() {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace desktop
|
||||
} // namespace progressia
|
||||
} // namespace progressia::desktop
|
||||
|
Reference in New Issue
Block a user