Skip to content

Commit

Permalink
merian: rework GLFW extension
Browse files Browse the repository at this point in the history
  • Loading branch information
LDAP committed Nov 12, 2024
1 parent 4991742 commit fa4cf97
Show file tree
Hide file tree
Showing 19 changed files with 265 additions and 186 deletions.
6 changes: 3 additions & 3 deletions include/merian-nodes/nodes/glfw_window/glfw_window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "merian-nodes/graph/errors.hpp"
#include "merian-nodes/graph/node.hpp"

#include "merian/vk/extension/extension_vk_glfw.hpp"
#include "merian/vk/extension/extension_glfw.hpp"
#include "merian/vk/utils/barriers.hpp"
#include "merian/vk/utils/blits.hpp"
#include "merian/vk/utils/subresource_ranges.hpp"
Expand All @@ -20,7 +20,7 @@ namespace merian_nodes {
class GLFWWindow : public Node {
public:
GLFWWindow(const ContextHandle& context) : Node() {
if (context->get_extension<ExtensionVkGLFW>()) {
if (context->get_extension<ExtensionGLFW>()) {
window = std::make_shared<merian::GLFWWindow>(context);
swapchain = std::make_shared<merian::Swapchain>(context, window->get_surface());
vsync = swapchain->vsync_enabled();
Expand Down Expand Up @@ -116,7 +116,7 @@ class GLFWWindow : public Node {
if (fullscreen != 0) {
try {
glfwGetWindowPos(*window, &windowed_pos_size[0], &windowed_pos_size[1]);
} catch (const ExtensionVkGLFW::glfw_error& e) {
} catch (const ExtensionGLFW::glfw_error& e) {
if (e.id != GLFW_FEATURE_UNAVAILABLE) {
throw e;
}
Expand Down
70 changes: 35 additions & 35 deletions include/merian/vk/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,42 +67,53 @@ class ExtensionContainer {
std::unordered_map<std::type_index, std::shared_ptr<Extension>> extensions;
};

struct QueueInfo {
// A queue family index guaranteed to support graphics+compute+transfer (or -1)
int32_t queue_family_idx_GCT = -1;
// A queue family index guaranteed to support compute (or -1)
int32_t queue_family_idx_C = -1;
// A queue family index guaranteed to support transfer (or -1)
int32_t queue_family_idx_T = -1;

// The queue indices (not family!) used for the graphics queue
int32_t queue_idx_GCT = -1;
// The queue indices (not family!) used for the compute queue
std::vector<uint32_t> queue_idx_C;
// The queue indices (not family!) used for the transfer queue
int32_t queue_idx_T = -1;
};

/* Initializes the Vulkan instance and device and holds core objects.
*
* Common features are automatically enabled.
*
* Extensions can extend the functionality and hook into the creation process.
* Use ContextHandle instead of Context directly. This way it is ensured that Context is destroyed
* last.
*/
class Context : public std::enable_shared_from_this<Context>, public ExtensionContainer {

public:
/**
* @brief Use this method to create the context.
*
*
* Needed for enable_shared_from_this, see
* https://en.cppreference.com/w/cpp/memory/enable_shared_from_this.
*/
static ContextHandle
create(const std::vector<std::shared_ptr<Extension>>& extensions,
const std::string& application_name = "",
uint32_t application_vk_version = VK_MAKE_VERSION(1, 0, 0),
uint32_t preffered_number_compute_queues = 1, // Additionally to the GCT queue
uint32_t vk_api_version = VK_API_VERSION_1_3,
uint32_t filter_vendor_id = -1,
uint32_t filter_device_id = -1,
const uint32_t application_vk_version = VK_MAKE_VERSION(1, 0, 0),
const uint32_t preffered_number_compute_queues = 1, // Additionally to the GCT queue
const uint32_t vk_api_version = VK_API_VERSION_1_3,
const bool require_extension_support = false,
const uint32_t filter_vendor_id = -1,
const uint32_t filter_device_id = -1,
const std::string& filter_device_name = "");

private:
Context(const std::vector<std::shared_ptr<Extension>>& extensions,
const std::string& application_name,
uint32_t application_vk_version,
uint32_t preffered_number_compute_queues,
uint32_t vk_api_version,
uint32_t filter_vendor_id,
uint32_t filter_device_id,
const uint32_t application_vk_version,
const uint32_t preffered_number_compute_queues,
const uint32_t vk_api_version,
const bool require_extension_support,
const uint32_t filter_vendor_id,
const uint32_t filter_device_id,
const std::string& filter_device_name);

public:
Expand Down Expand Up @@ -130,11 +141,12 @@ class Context : public std::enable_shared_from_this<Context>, public ExtensionCo
void prepare_shader_include_defines();

private: // Helper
void extensions_check_instance_layer_support();
void extensions_check_instance_extension_support();
void extensions_check_device_extension_support();
void extensions_self_check_support();
void destroy_extensions(const std::vector<std::shared_ptr<Extension>>& extensions);
void extensions_check_instance_layer_support(const bool fail_if_unsupported);
void extensions_check_instance_extension_support(const bool fail_if_unsupported);
void extensions_check_device_extension_support(const bool fail_if_unsupported);
void extensions_self_check_support(const bool fail_if_unsupported);
void destroy_unsupported_extensions(const std::vector<std::shared_ptr<Extension>>& extensions,
const bool fail_if_unsupported);

public: // Getter
// The actual number of compute queues (< preffered_number_compute_queues).
Expand Down Expand Up @@ -227,19 +239,7 @@ class Context : public std::enable_shared_from_this<Context>, public ExtensionCo
private:
// in find_queues. Indexes are -1 if no suitable queue was found!

// A queue family index guaranteed to support graphics+compute+transfer (or -1)
int32_t queue_family_idx_GCT = -1;
// A queue family index guaranteed to support compute (or -1)
int32_t queue_family_idx_C = -1;
// A queue family index guaranteed to support transfer (or -1)
int32_t queue_family_idx_T = -1;

// The queue indices (not family!) used for the graphics queue
int32_t queue_idx_GCT = -1;
// The queue indices (not family!) used for the compute queue
std::vector<uint32_t> queue_idx_C;
// The queue indices (not family!) used for the transfer queue
int32_t queue_idx_T = -1;
QueueInfo queue_info;

// can be nullptr in very rare occasions, you can check that with if (shrd_ptr) {...}
std::weak_ptr<Queue> queue_GCT;
Expand Down
33 changes: 19 additions & 14 deletions include/merian/vk/extension/extension.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,32 +110,37 @@ class Extension {
return p_next;
}

/* Custom check for compatibility after the physical device is ready.
* At this time the structs wired up in pnext_get_features_2 is valid, you can use those to
* check if features are available.
/* E.g. to dismiss a queue that does not support present-to-surface. Similar to
* accpet_physical_device, the context attemps to select a graphics queue that is accepted by
* most extensions.
*/
virtual bool accept_graphics_queue([[maybe_unused]] const vk::Instance& instance,
[[maybe_unused]] const PhysicalDevice& physical_device,
[[maybe_unused]] std::size_t queue_family_index) {
return true;
}

/* Custom check for compatibility after the physical device is ready and queue family indeces
* are determined. At this time the structs wired up in pnext_get_features_2 is valid, you can
* use those to check if features are available.
*
* If this method returns false, it is guaranteed that on_unsupported is called.
*/
virtual bool
extension_supported([[maybe_unused]] const PhysicalDevice& physical_device,
[[maybe_unused]] const ExtensionContainer& extension_container) {
virtual bool extension_supported([[maybe_unused]] const vk::Instance& instance,
[[maybe_unused]] const PhysicalDevice& physical_device,
[[maybe_unused]] const ExtensionContainer& extension_container,
[[maybe_unused]] const QueueInfo& queue_info) {
return true;
}

/**
* Called when extension support should be determined. Can be used to communicate with other
* extensions.
* Called when extension support is confirmed for all extensions. Can be used to communicate
* with other extensions.
*/
virtual void
on_extension_support_confirmed([[maybe_unused]] const ExtensionContainer& extension_container) {
}

/* E.g. to dismiss a queue that does not support present-to-surface. */
virtual bool accept_graphics_queue([[maybe_unused]] const vk::Instance& instance,
[[maybe_unused]] const vk::PhysicalDevice& physical_device,
[[maybe_unused]] std::size_t queue_family_index) {
return true;
}
/**
* Append structs to VkDeviceCreateInfo to enable features of extensions.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace merian {
/*
* @brief Initializes GLFW and makes sure the graphics queue supports present.
*/
class ExtensionVkGLFW : public Extension {
class ExtensionGLFW : public Extension {
public:
struct glfw_error : public std::runtime_error {
glfw_error(int id, const char* desc)
Expand All @@ -27,18 +27,27 @@ class ExtensionVkGLFW : public Extension {
}

public:
ExtensionVkGLFW();
ExtensionGLFW();

~ExtensionVkGLFW();
~ExtensionGLFW();

std::vector<const char*> required_instance_extension_names() const override;

std::vector<const char*>
required_device_extension_names(const vk::PhysicalDevice&) const override;
required_device_extension_names(const vk::PhysicalDevice& /*unused*/) const override;

bool accept_graphics_queue(const vk::Instance& instance,
const vk::PhysicalDevice& physical_device,
const PhysicalDevice& physical_device,
std::size_t queue_family_indext) override;

bool extension_supported(const vk::Instance& instance,
const PhysicalDevice& physical_device,
const ExtensionContainer& extension_container,
const QueueInfo& queue_info) override;

private:
int glfw_initialized = GLFW_FALSE;
int glfw_vulkan_support = GLFW_FALSE;
};

} // namespace merian
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ class ExtensionVkAccelerationStructure : public Extension {
return &acceleration_structure_features;
}

bool extension_supported(const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/) override {
bool extension_supported(const vk::Instance& /*unused*/,
const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/,
const QueueInfo& /*unused*/) override {
return acceleration_structure_features.accelerationStructure == VK_TRUE;
}

Expand Down
6 changes: 4 additions & 2 deletions include/merian/vk/extension/extension_vk_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,10 @@ class ExtensionVkCore : public Extension {

void* pnext_get_features_2(void* const p_next) override;

bool extension_supported(const PhysicalDevice& physical_device,
const ExtensionContainer& /*unused*/) override;
bool extension_supported(const vk::Instance& /*unused*/,
const PhysicalDevice& physical_device,
const ExtensionContainer& /*unused*/,
const QueueInfo& /*unused*/) override;

void* pnext_device_create_info(void* const p_next) override;

Expand Down
6 changes: 4 additions & 2 deletions include/merian/vk/extension/extension_vk_float_atomics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ class ExtensionVkFloatAtomics : public Extension {

void* pnext_get_features_2(void* const p_next) override;

bool extension_supported(const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/) override;
bool extension_supported(const vk::Instance& /*unused*/,
const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/,
const QueueInfo& /*unused*/) override;

void* pnext_device_create_info(void* const p_next) override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ class ExtensionVkNvComputeShaderDerivatives : public Extension {
return &supported_features;
}

bool extension_supported(const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/) override {
bool extension_supported(const vk::Instance& /*unused*/,
const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/,
const QueueInfo& /*unused*/) override {
return supported_features.computeDerivativeGroupLinear == VK_TRUE ||
supported_features.computeDerivativeGroupQuads == VK_TRUE;
}
Expand Down
6 changes: 4 additions & 2 deletions include/merian/vk/extension/extension_vk_ray_query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ class ExtensionVkRayQuery : public Extension {
return &physical_device_ray_query_features;
}

bool extension_supported(const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/) override {
bool extension_supported(const vk::Instance& /*unused*/,
const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/,
const QueueInfo& /*unused*/) override {
return physical_device_ray_query_features.rayQuery == VK_TRUE;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ class ExtensionVkRayTracingPipeline : public Extension {
return &ray_tracing_pipeline_features;
}

bool extension_supported(const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/) override {
bool extension_supported(const vk::Instance& /*unused*/,
const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/,
const QueueInfo& /*unused*/) override {
return ray_tracing_pipeline_features.rayTracingPipeline == VK_TRUE;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ class ExtensionVkRayTracingPositionFetch : public Extension {
return &supported_features;
}

bool extension_supported(const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/) override {
bool extension_supported(const vk::Instance& /*unused*/,
const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/,
const QueueInfo& /*unused*/) override {
return supported_features.rayTracingPositionFetch == VK_TRUE;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ class ExtensionVkShaderMaximalReconvergence : public Extension {
return &enabled_features;
}

bool extension_supported(const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/) override {
bool extension_supported(const vk::Instance& /*unused*/,
const PhysicalDevice& /*unused*/,
const ExtensionContainer& /*unused*/,
const QueueInfo& /*unused*/) override {
return supported_features.shaderMaximalReconvergence == VK_TRUE;
}

Expand Down
4 changes: 2 additions & 2 deletions include/merian/vk/window/glfw_window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include "merian/vk/context.hpp"
#include "merian/vk/window/window.hpp"
#include "merian/vk/extension/extension_vk_glfw.hpp"
#include "merian/vk/extension/extension_glfw.hpp"

#include <GLFW/glfw3.h>
#include <spdlog/spdlog.h>
Expand All @@ -16,7 +16,7 @@ class GLFWWindow : public Window {
int height = 720,
const char* title = "")
: context(context) {
if (!context->get_extension<ExtensionVkGLFW>()) {
if (!context->get_extension<ExtensionGLFW>()) {
SPDLOG_WARN("ExtensionVkGLFW not found. You have to init GLFW manually!");
}

Expand Down
2 changes: 1 addition & 1 deletion src/merian/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ merian_src = files(
'vk/context.cpp',
'vk/extension/extension.cpp',
'vk/extension/extension_resources.cpp',
'vk/extension/extension_glfw.cpp',
'vk/extension/extension_vk_core.cpp',
'vk/extension/extension_vk_debug_utils.cpp',
'vk/extension/extension_vk_float_atomics.cpp',
'vk/extension/extension_vk_glfw.cpp',
'vk/memory/buffer_suballocator.cpp',
'vk/memory/memory_allocator.cpp',
'vk/memory/memory_allocator_vma.cpp',
Expand Down
Loading

0 comments on commit fa4cf97

Please sign in to comment.