Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 29 additions & 27 deletions src/render/backend/filter_chain_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,16 +487,17 @@ auto align_adapter_output(FilterChainController::FilterChainSlot& slot,
return {};
}

auto create_and_load_slot(const FilterChainController::AdapterBuildConfig& config,
auto create_and_load_slot(const FilterChainController::VulkanDeviceInfo& device_info,
const FilterChainController::ChainConfig& chain_config,
const std::filesystem::path& preset_path)
-> Result<FilterChainController::FilterChainSlot> {
FilterChainController::FilterChainSlot new_slot;
GOGGLES_TRY(initialize_slot(new_slot, config.device_info));
GOGGLES_TRY(initialize_slot(new_slot, device_info));

if (preset_path.empty()) {
GOGGLES_TRY(load_passthrough_into_slot(new_slot, config.chain_config));
GOGGLES_TRY(load_passthrough_into_slot(new_slot, chain_config));
} else {
GOGGLES_TRY(load_preset_into_slot(new_slot, preset_path, config.chain_config));
GOGGLES_TRY(load_preset_into_slot(new_slot, preset_path, chain_config));
}

return std::move(new_slot);
Expand Down Expand Up @@ -559,18 +560,17 @@ void shutdown_retired_adapter_tracker(FilterChainController::RetiredAdapterTrack

} // namespace

auto FilterChainController::recreate_filter_chain(const AdapterBuildConfig& config)
-> Result<void> {
auto FilterChainController::recreate_filter_chain(const VulkanDeviceInfo& device_info,
ChainConfig chain_config) -> Result<void> {
GOGGLES_PROFILE_FUNCTION();

auto requested_config = config;
requested_config.chain_config.initial_stage_mask =
chain_config.initial_stage_mask =
stage_mask_from_policy(prechain_policy_enabled, effect_stage_policy_enabled);
requested_config.chain_config.initial_prechain_width = source_resolution.width;
requested_config.chain_config.initial_prechain_height = source_resolution.height;
chain_config.initial_prechain_width = source_resolution.width;
chain_config.initial_prechain_height = source_resolution.height;

authoritative_output_target = OutputTarget{
.format = static_cast<vk::Format>(requested_config.chain_config.target_format),
.format = static_cast<vk::Format>(chain_config.target_format),
.extent = vk::Extent2D{},
};

Expand All @@ -580,7 +580,7 @@ auto FilterChainController::recreate_filter_chain(const AdapterBuildConfig& conf

shutdown_slot(active_slot);

auto slot_result = create_and_load_slot(requested_config, preset_path);
auto slot_result = create_and_load_slot(device_info, chain_config, preset_path);
if (!slot_result) {
return nonstd::make_unexpected(slot_result.error());
}
Expand Down Expand Up @@ -705,7 +705,8 @@ void FilterChainController::load_shader_preset(const std::filesystem::path& new_
}

auto FilterChainController::reload_shader_preset(std::filesystem::path new_preset_path,
AdapterBuildConfig config) -> Result<void> {
const VulkanDeviceInfo& device_info,
ChainConfig chain_config) -> Result<void> {
GOGGLES_PROFILE_FUNCTION();

if (pending_chain_ready.load(std::memory_order_acquire)) {
Expand All @@ -720,22 +721,23 @@ auto FilterChainController::reload_shader_preset(std::filesystem::path new_prese
}

pending_preset_path = new_preset_path;
config.chain_config.initial_stage_mask =
chain_config.initial_stage_mask =
stage_mask_from_policy(prechain_policy_enabled, effect_stage_policy_enabled);
config.chain_config.initial_prechain_width = source_resolution.width;
config.chain_config.initial_prechain_height = source_resolution.height;
chain_config.initial_prechain_width = source_resolution.width;
chain_config.initial_prechain_height = source_resolution.height;
const auto requested_output_target = authoritative_output_target;
auto requested_controls = authoritative_control_overrides.empty()
? snapshot_adapter_controls(active_slot)
: authoritative_control_overrides;

pending_load_future = util::JobSystem::submit(
[this, build_config = std::move(config), requested_preset_path = std::move(new_preset_path),
requested_output_target,
[this, device_info, chain_config = std::move(chain_config),
requested_preset_path = std::move(new_preset_path), requested_output_target,
requested_controls = std::move(requested_controls)]() -> Result<void> {
GOGGLES_PROFILE_SCOPE("AsyncShaderLoad");

auto slot_result = create_and_load_slot(build_config, requested_preset_path);
auto slot_result =
create_and_load_slot(device_info, chain_config, requested_preset_path);
if (!slot_result) {
GOGGLES_LOG_ERROR("Failed to create filter chain adapter");
return nonstd::make_unexpected(slot_result.error());
Expand Down Expand Up @@ -881,22 +883,22 @@ void FilterChainController::set_stage_policy(
}

void FilterChainController::set_prechain_resolution(
const PrechainResolutionConfig& config, const std::function<void()>& wait_for_safe_rebuild) {
if (source_resolution == config.requested_resolution) {
vk::Extent2D resolution, const std::function<void()>& wait_for_safe_rebuild) {
if (source_resolution == resolution) {
return;
}

if (active_slot.chain && wait_for_safe_rebuild) {
wait_for_safe_rebuild();
}

source_resolution = config.requested_resolution;
source_resolution = resolution;
if (active_slot.chain) {
active_slot.prechain_width = config.requested_resolution.width;
active_slot.prechain_height = config.requested_resolution.height;
goggles_fc_extent_2d_t resolution{.width = config.requested_resolution.width,
.height = config.requested_resolution.height};
auto result = active_slot.chain.set_prechain_resolution(&resolution);
active_slot.prechain_width = resolution.width;
active_slot.prechain_height = resolution.height;
goggles_fc_extent_2d_t fc_resolution{.width = resolution.width,
.height = resolution.height};
auto result = active_slot.chain.set_prechain_resolution(&fc_resolution);
if (!result) {
GOGGLES_LOG_WARN("Failed to set prechain resolution: {}", result.error().message);
}
Expand Down
17 changes: 5 additions & 12 deletions src/render/backend/filter_chain_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,22 @@ struct FilterChainController {
uint32_t integer_scale = 1;
};

struct AdapterBuildConfig {
VulkanDeviceInfo device_info;
ChainConfig chain_config;
};

struct OutputTarget {
vk::Format format = vk::Format::eUndefined;
vk::Extent2D extent;
};

struct PrechainResolutionConfig {
vk::Extent2D requested_resolution;
};

[[nodiscard]] auto recreate_filter_chain(const AdapterBuildConfig& config) -> Result<void>;
[[nodiscard]] auto recreate_filter_chain(const VulkanDeviceInfo& device_info,
ChainConfig chain_config) -> Result<void>;
[[nodiscard]] auto retarget_filter_chain(const OutputTarget& output_target) -> Result<void>;
void shutdown(const std::function<void()>& wait_for_gpu_idle);

void load_shader_preset(
const std::filesystem::path& new_preset_path,
const std::function<void()>& wait_for_safe_rebuild = std::function<void()>{});
[[nodiscard]] auto reload_shader_preset(std::filesystem::path new_preset_path,
AdapterBuildConfig config) -> Result<void>;
const VulkanDeviceInfo& device_info,
ChainConfig chain_config) -> Result<void>;

void advance_frame();
void check_pending_chain_swap(const std::function<void()>& wait_all_frames);
Expand All @@ -82,7 +75,7 @@ struct FilterChainController {
set_stage_policy(bool prechain_enabled, bool effect_stage_enabled,
const std::function<void()>& wait_for_safe_rebuild = std::function<void()>{});
void set_prechain_resolution(
const PrechainResolutionConfig& config,
vk::Extent2D resolution,
const std::function<void()>& wait_for_safe_rebuild = std::function<void()>{});
[[nodiscard]] auto handle_resize(vk::Extent2D target_extent) -> Result<void>;
[[nodiscard]] auto record(const RecordParams& record_params) -> Result<void>;
Expand Down
55 changes: 24 additions & 31 deletions src/render/backend/vulkan_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ void VulkanBackend::initialize_settings(const RenderSettings& settings) {
m_integer_scale = settings.integer_scale;
update_target_fps(settings.target_fps);
m_filter_chain_controller.set_prechain_resolution(
backend_internal::FilterChainController::PrechainResolutionConfig{
.requested_resolution = vk::Extent2D{settings.source_width, settings.source_height},
});
vk::Extent2D{settings.source_width, settings.source_height});
}

auto VulkanBackend::create(SDL_Window* window, bool enable_validation,
Expand Down Expand Up @@ -237,19 +235,16 @@ auto VulkanBackend::is_srgb_format(vk::Format format) -> bool {
auto VulkanBackend::init_filter_chain() -> Result<void> {
GOGGLES_PROFILE_FUNCTION();

return m_filter_chain_controller.recreate_filter_chain(make_filter_chain_build_config());
return m_filter_chain_controller.recreate_filter_chain(make_device_info(), make_chain_config());
}

void VulkanBackend::load_shader_preset(const std::filesystem::path& preset_path) {
m_filter_chain_controller.load_shader_preset(preset_path, [this]() { wait_all_frames(); });
}

void VulkanBackend::set_prechain_resolution(uint32_t width, uint32_t height) {
m_filter_chain_controller.set_prechain_resolution(
backend_internal::FilterChainController::PrechainResolutionConfig{
.requested_resolution = vk::Extent2D{width, height},
},
[this]() { wait_all_frames(); });
m_filter_chain_controller.set_prechain_resolution(vk::Extent2D{width, height},
[this]() { wait_all_frames(); });
}

auto VulkanBackend::record_render_commands(vk::CommandBuffer cmd, uint32_t image_index,
Expand Down Expand Up @@ -559,35 +554,33 @@ auto VulkanBackend::reload_shader_preset(const std::filesystem::path& preset_pat
return make_error<void>(ErrorCode::vulkan_init_failed, "Backend not initialized");
}

return m_filter_chain_controller.reload_shader_preset(preset_path,
make_filter_chain_build_config());
return m_filter_chain_controller.reload_shader_preset(preset_path, make_device_info(),
make_chain_config());
}

void VulkanBackend::set_filter_chain_policy(const FilterChainStagePolicy& policy) {
m_filter_chain_controller.set_stage_policy(policy.prechain_enabled, policy.effect_stage_enabled,
[this]() { wait_all_frames(); });
}

auto VulkanBackend::make_filter_chain_build_config() const
-> backend_internal::FilterChainController::AdapterBuildConfig {
return backend_internal::FilterChainController::AdapterBuildConfig{
.device_info =
backend_internal::FilterChainController::VulkanDeviceInfo{
.physical_device = m_vulkan_context.physical_device,
.device = m_vulkan_context.device,
.graphics_queue = m_vulkan_context.graphics_queue,
.graphics_queue_family_index = m_vulkan_context.graphics_queue_family,
.cache_dir = m_cache_dir.string(),
},
.chain_config =
backend_internal::FilterChainController::ChainConfig{
.target_format = static_cast<VkFormat>(m_render_output.swapchain_format),
.frames_in_flight = backend_internal::RenderOutput::MAX_FRAMES_IN_FLIGHT,
.initial_prechain_width =
m_filter_chain_controller.current_prechain_resolution().width,
.initial_prechain_height =
m_filter_chain_controller.current_prechain_resolution().height,
},
auto VulkanBackend::make_device_info() const
-> backend_internal::FilterChainController::VulkanDeviceInfo {
return {
.physical_device = m_vulkan_context.physical_device,
.device = m_vulkan_context.device,
.graphics_queue = m_vulkan_context.graphics_queue,
.graphics_queue_family_index = m_vulkan_context.graphics_queue_family,
.cache_dir = m_cache_dir.string(),
};
}

auto VulkanBackend::make_chain_config() const
-> backend_internal::FilterChainController::ChainConfig {
return {
.target_format = static_cast<VkFormat>(m_render_output.swapchain_format),
.frames_in_flight = backend_internal::RenderOutput::MAX_FRAMES_IN_FLIGHT,
.initial_prechain_width = m_filter_chain_controller.current_prechain_resolution().width,
.initial_prechain_height = m_filter_chain_controller.current_prechain_resolution().height,
};
}

Expand Down
6 changes: 4 additions & 2 deletions src/render/backend/vulkan_backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,10 @@ class VulkanBackend {
void update_target_fps(uint32_t target_fps) { m_render_output.set_target_fps(target_fps); }

[[nodiscard]] auto init_filter_chain() -> Result<void>;
[[nodiscard]] auto make_filter_chain_build_config() const
-> backend_internal::FilterChainController::AdapterBuildConfig;
[[nodiscard]] auto make_device_info() const
-> backend_internal::FilterChainController::VulkanDeviceInfo;
[[nodiscard]] auto make_chain_config() const
-> backend_internal::FilterChainController::ChainConfig;

[[nodiscard]] auto record_render_commands(vk::CommandBuffer cmd, uint32_t image_index,
const UiRenderCallback& ui_callback = nullptr)
Expand Down
13 changes: 7 additions & 6 deletions tests/render/test_filter_boundary_contracts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ TEST_CASE("Async swap and resize safety contract coverage", "[filter_chain][asyn
REQUIRE(backend_text.has_value());
REQUIRE(controller_text.has_value());
REQUIRE(render_output_text.has_value());
REQUIRE(backend_text->find("make_filter_chain_build_config()") != std::string::npos);
REQUIRE(backend_text->find("make_device_info()") != std::string::npos);
REQUIRE(backend_text->find("make_chain_config()") != std::string::npos);

const auto check_swap_pos =
controller_text->find("void FilterChainController::check_pending_chain_swap(");
Expand Down Expand Up @@ -269,9 +270,8 @@ TEST_CASE("Async swap and resize safety contract coverage", "[filter_chain][asyn
std::string::npos);
REQUIRE(controller_text->find("authoritative_control_overrides = snapshot_adapter_controls(") !=
std::string::npos);
REQUIRE(controller_text->find("source_resolution = config.requested_resolution;") !=
std::string::npos);
REQUIRE(controller_text->find("active_slot.chain.set_prechain_resolution(&resolution)") !=
REQUIRE(controller_text->find("source_resolution = resolution;") != std::string::npos);
REQUIRE(controller_text->find("active_slot.chain.set_prechain_resolution(&fc_resolution)") !=
std::string::npos);
REQUIRE(controller_text->find("resolve_initial_prechain_resolution") == std::string::npos);

Expand Down Expand Up @@ -773,8 +773,9 @@ TEST_CASE("filter_chain controller uses standalone API boundary",
REQUIRE(controller_prechain_pos != std::string::npos);
REQUIRE(controller_handle_resize_pos != std::string::npos);
// set_prechain_resolution uses set_prechain_resolution API, not resize
REQUIRE(controller_cpp_text->find("active_slot.chain.set_prechain_resolution(&resolution)",
controller_prechain_pos) != std::string::npos);
REQUIRE(
controller_cpp_text->find("active_slot.chain.set_prechain_resolution(&fc_resolution)",
controller_prechain_pos) != std::string::npos);
// handle_resize uses chain.resize, not set_prechain_resolution
REQUIRE(controller_cpp_text->find("active_slot.chain.resize(&extent)",
controller_handle_resize_pos) != std::string::npos);
Expand Down
Loading
Loading