format src and tests with clang-format

This commit is contained in:
nmzik
2026-07-31 11:34:38 +02:00
parent 68be13345a
commit d8a4c83cc7
81 changed files with 19582 additions and 21405 deletions
+61 -83
View File
@@ -61,7 +61,7 @@ namespace Libs::Graphics {
struct Presenter::Frame {
VulkanImage image;
std::unique_ptr<CommandBuffer> present_commands;
bool busy = false;
bool busy = false;
bool reusing_last = false;
void Configure(GraphicContext& graphics, vk::Extent2D extent, vk::Format format);
@@ -155,7 +155,7 @@ public:
EXIT("last submitted frame is not available for reuse\n");
}
m_free.erase(free);
m_last_frame = nullptr;
m_last_frame = nullptr;
frame->busy = true;
frame->reusing_last = true;
m_mutex.Unlock();
@@ -197,30 +197,27 @@ private:
}
}
WindowContext& m_window;
Common::Mutex m_mutex;
Common::CondVar m_available;
WindowContext& m_window;
Common::Mutex m_mutex;
Common::CondVar m_available;
std::vector<std::unique_ptr<Presenter::Frame>> m_frames;
std::deque<Presenter::Frame*> m_free;
Presenter::Frame* m_last_frame = nullptr;
vk::Format m_format = vk::Format::eUndefined;
vk::Format m_format = vk::Format::eUndefined;
};
void Presenter::Frame::Configure(GraphicContext& graphics, vk::Extent2D extent,
vk::Format format) {
void Presenter::Frame::Configure(GraphicContext& graphics, vk::Extent2D extent, vk::Format format) {
if (extent.width == 0 || extent.height == 0 || format == vk::Format::eUndefined) {
EXIT("unsupported prepared frame, extent=%ux%u format=%d\n", extent.width, extent.height,
static_cast<int>(format));
}
const auto features = graphics.GetFormatProperties(format).optimalTilingFeatures;
const auto required = vk::FormatFeatureFlagBits::eBlitSrc |
vk::FormatFeatureFlagBits::eSampledImageFilterLinear |
vk::FormatFeatureFlagBits::eTransferSrc |
vk::FormatFeatureFlagBits::eTransferDst;
const auto required =
vk::FormatFeatureFlagBits::eBlitSrc | vk::FormatFeatureFlagBits::eSampledImageFilterLinear |
vk::FormatFeatureFlagBits::eTransferSrc | vk::FormatFeatureFlagBits::eTransferDst;
if ((features & required) != required) {
EXIT("prepared presentation format lacks optimal blit support: format=%d features=0x%x\n",
static_cast<int>(format),
static_cast<vk::FormatFeatureFlags::MaskType>(features));
static_cast<int>(format), static_cast<vk::FormatFeatureFlags::MaskType>(features));
}
auto& dst = image;
@@ -234,11 +231,11 @@ void Presenter::Frame::Configure(GraphicContext& graphics, vk::Extent2D extent,
dst.memory = {};
}
dst.extent = {extent.width, extent.height, 1};
dst.format = format;
dst.layers = 1;
dst.mip_levels = 1;
dst.state = {};
dst.extent = {extent.width, extent.height, 1};
dst.format = format;
dst.layers = 1;
dst.mip_levels = 1;
dst.state = {};
dst.subresource_states.clear();
dst.memory.property = vk::MemoryPropertyFlagBits::eDeviceLocal;
@@ -262,13 +259,12 @@ void Presenter::Frame::Configure(GraphicContext& graphics, vk::Extent2D extent,
void Presenter::Frame::Transit(vk::CommandBuffer command, vk::ImageLayout layout,
vk::AccessFlags2 access) {
const auto stage = access == vk::AccessFlagBits2::eTransferRead ||
access == vk::AccessFlagBits2::eTransferWrite
? vk::PipelineStageFlagBits2::eTransfer
: vk::PipelineStageFlagBits2::eAllCommands;
const auto stage = access == vk::AccessFlagBits2::eTransferRead ||
access == vk::AccessFlagBits2::eTransferWrite
? vk::PipelineStageFlagBits2::eTransfer
: vk::PipelineStageFlagBits2::eAllCommands;
constexpr auto writes = vk::AccessFlagBits2::eTransferWrite |
vk::AccessFlagBits2::eShaderWrite |
vk::AccessFlagBits2::eMemoryWrite;
vk::AccessFlagBits2::eShaderWrite | vk::AccessFlagBits2::eMemoryWrite;
if (image.state.layout == layout && image.state.access_mask == access &&
!static_cast<bool>(image.state.access_mask & writes)) {
return;
@@ -299,35 +295,27 @@ void Presenter::Frame::Transit(vk::CommandBuffer command, vk::ImageLayout layout
void Presenter::Frame::CopyFrom(CommandBuffer& command_buffer, Image& source) {
command_buffer.EndRendering();
auto command = command_buffer.Handle();
source.Transit(vk::ImageLayout::eTransferSrcOptimal,
vk::AccessFlagBits2::eTransferRead, {}, command);
Transit(command, vk::ImageLayout::eTransferDstOptimal,
vk::AccessFlagBits2::eTransferWrite);
source.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits2::eTransferRead, {},
command);
Transit(command, vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits2::eTransferWrite);
vk::ImageCopy copy {};
copy.srcSubresource = {vk::ImageAspectFlagBits::eColor, 0, 0,
source.backing.layers};
copy.srcSubresource = {vk::ImageAspectFlagBits::eColor, 0, 0, source.backing.layers};
copy.dstSubresource = {vk::ImageAspectFlagBits::eColor, 0, 0, image.layers};
copy.extent = {std::min(source.backing.extent.width, image.extent.width),
std::min(source.backing.extent.height, image.extent.height), 1};
copy.extent = {std::min(source.backing.extent.width, image.extent.width),
std::min(source.backing.extent.height, image.extent.height), 1};
EXIT_IF(copy.srcSubresource.layerCount != copy.dstSubresource.layerCount);
command.copyImage(source.backing.image, vk::ImageLayout::eTransferSrcOptimal,
image.image, vk::ImageLayout::eTransferDstOptimal, copy);
Transit(command, vk::ImageLayout::eTransferSrcOptimal,
vk::AccessFlagBits2::eTransferRead);
command.copyImage(source.backing.image, vk::ImageLayout::eTransferSrcOptimal, image.image,
vk::ImageLayout::eTransferDstOptimal, copy);
Transit(command, vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits2::eTransferRead);
}
void Presenter::Frame::Clear(CommandBuffer& command_buffer,
const vk::ClearColorValue& color) {
void Presenter::Frame::Clear(CommandBuffer& command_buffer, const vk::ClearColorValue& color) {
command_buffer.EndRendering();
auto command = command_buffer.Handle();
Transit(command, vk::ImageLayout::eTransferDstOptimal,
vk::AccessFlagBits2::eTransferWrite);
const vk::ImageSubresourceRange range {
vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1};
command.clearColorImage(image.image, vk::ImageLayout::eTransferDstOptimal, &color, 1,
&range);
Transit(command, vk::ImageLayout::eTransferSrcOptimal,
vk::AccessFlagBits2::eTransferRead);
Transit(command, vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits2::eTransferWrite);
const vk::ImageSubresourceRange range {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1};
command.clearColorImage(image.image, vk::ImageLayout::eTransferDstOptimal, &color, 1, &range);
Transit(command, vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits2::eTransferRead);
}
class Swapchain final {
@@ -338,8 +326,8 @@ public:
~Swapchain();
KYTY_CLASS_NO_COPY(Swapchain);
void Create();
void Recreate(bool surface_lost = false);
void Create();
void Recreate(bool surface_lost = false);
[[nodiscard]] Status AcquireNextImage();
void RecordPresentCommands(CommandBuffer& command, VulkanImage& source);
void Submit(CommandBuffer& command);
@@ -395,17 +383,17 @@ struct Presenter::Impl {
desc.view_info.usage = vk::ImageUsageFlagBits::eTransferSrc;
desc.type = TextureCache::BindingType::VideoOut;
auto& cache = renderer.GetTextureCache();
auto& image = cache.GetImage(cache.FindImage(desc));
auto& cache = renderer.GetTextureCache();
auto& image = cache.GetImage(cache.FindImage(desc));
image.usage.video_out = true;
return image;
}
RenderContext& renderer;
WindowContext& window;
Swapchain swapchain;
RenderContext& renderer;
WindowContext& window;
Swapchain swapchain;
CommandScheduler present_scheduler;
FramePool frames;
FramePool frames;
};
void Swapchain::Create() {
@@ -441,25 +429,20 @@ void Swapchain::Create() {
? vk::CompositeAlphaFlagBitsKHR::eOpaque
: vk::CompositeAlphaFlagBitsKHR::eInherit;
vk::SurfaceFormatKHR format {vk::Format::eR8G8B8A8Unorm,
vk::ColorSpaceKHR::eSrgbNonlinear};
if (surface.formats.size() != 1 ||
surface.formats.front().format != vk::Format::eUndefined) {
vk::SurfaceFormatKHR format {vk::Format::eR8G8B8A8Unorm, vk::ColorSpaceKHR::eSrgbNonlinear};
if (surface.formats.size() != 1 || surface.formats.front().format != vk::Format::eUndefined) {
const auto it = std::find_if(surface.formats.begin(), surface.formats.end(),
[](const vk::SurfaceFormatKHR& candidate) {
return candidate.format ==
vk::Format::eB8G8R8A8Unorm ||
candidate.format ==
vk::Format::eR8G8B8A8Unorm;
return candidate.format == vk::Format::eB8G8R8A8Unorm ||
candidate.format == vk::Format::eR8G8B8A8Unorm;
});
if (it == surface.formats.end()) {
EXIT("no supported UNORM swapchain format\n");
}
format = *it;
}
m_format = format.format;
const auto swapchain_features =
graphics.GetFormatProperties(m_format).optimalTilingFeatures;
m_format = format.format;
const auto swapchain_features = graphics.GetFormatProperties(m_format).optimalTilingFeatures;
if (!static_cast<bool>(swapchain_features & vk::FormatFeatureFlagBits::eBlitDst)) {
EXIT("swapchain format cannot be a blit destination: format=%d\n",
static_cast<int>(m_format));
@@ -503,9 +486,8 @@ void Swapchain::Create() {
view.subresourceRange.baseMipLevel = 0;
view.subresourceRange.layerCount = 1;
view.subresourceRange.levelCount = 1;
RequireVulkanSuccess(
graphics.device.createImageView(&view, nullptr, &m_image_views[i]),
"vkCreateImageView");
RequireVulkanSuccess(graphics.device.createImageView(&view, nullptr, &m_image_views[i]),
"vkCreateImageView");
EXIT_IF(m_image_views[i] == nullptr);
}
@@ -600,7 +582,7 @@ void Swapchain::Recreate(bool surface_lost) {
Swapchain::Status Swapchain::AcquireNextImage() {
EXIT_IF(m_handle == nullptr || m_frame_index >= m_image_acquired.size());
m_image_index = static_cast<uint32_t>(-1);
m_image_index = static_cast<uint32_t>(-1);
const auto result = m_window.graphic_ctx.device.acquireNextImageKHR(
m_handle, std::numeric_limits<uint64_t>::max(), m_image_acquired[m_frame_index], nullptr,
&m_image_index);
@@ -683,10 +665,9 @@ void Swapchain::RecordPresentCommands(CommandBuffer& command, VulkanImage& sourc
to_present.subresourceRange.levelCount = 1;
to_present.subresourceRange.baseArrayLayer = 0;
to_present.subresourceRange.layerCount = 1;
vk_command.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands,
vk::PipelineStageFlagBits::eAllCommands,
vk::DependencyFlagBits::eByRegion, 0,
nullptr, 0, nullptr, 1, &to_present);
vk_command.pipelineBarrier(
vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eAllCommands,
vk::DependencyFlagBits::eByRegion, 0, nullptr, 0, nullptr, 1, &to_present);
command.End();
}
@@ -700,7 +681,7 @@ void Swapchain::Submit(CommandBuffer& command) {
Swapchain::Status Swapchain::Present() {
EXIT_IF(m_image_index >= m_render_complete.size());
const auto ready = m_render_complete[m_image_index];
const auto ready = m_render_complete[m_image_index];
vk::PresentInfoKHR present {};
present.sType = vk::StructureType::ePresentInfoKHR;
present.swapchainCount = 1;
@@ -738,7 +719,7 @@ Presenter::~Presenter() = default;
Presenter::Frame& Presenter::PrepareFrame(CommandBuffer& buffer, const ImageInfo& info) {
KYTY_PROFILER_FUNCTION();
EXIT_IF(buffer.IsInvalid());
auto* frame = m_impl->frames.Acquire();
auto* frame = m_impl->frames.Acquire();
Common::LockGuard render_lock(m_impl->renderer.GetMutex());
auto& image = m_impl->ResolveSurface(info);
if (image.backing.format == vk::Format::eUndefined) {
@@ -752,14 +733,13 @@ Presenter::Frame& Presenter::PrepareFrame(CommandBuffer& buffer, const ImageInfo
default: break;
}
frame->Configure(m_impl->window.graphic_ctx,
{image.backing.extent.width, image.backing.extent.height},
frame_format);
{image.backing.extent.width, image.backing.extent.height}, frame_format);
frame->CopyFrom(buffer, image);
return *frame;
}
Presenter::Frame& Presenter::PrepareBlankFrame(uint32_t width, uint32_t height, bool opaque,
CommandBuffer* producer) {
CommandBuffer* producer) {
KYTY_PROFILER_FUNCTION();
auto format = m_impl->frames.GetFormat();
auto* frame = m_impl->frames.Acquire();
@@ -772,8 +752,7 @@ Presenter::Frame& Presenter::PrepareBlankFrame(uint32_t width, uint32_t height,
frame->Clear(*producer, clear);
} else {
if (frame->present_commands == nullptr) {
frame->present_commands =
std::make_unique<CommandBuffer>(m_impl->present_scheduler);
frame->present_commands = std::make_unique<CommandBuffer>(m_impl->present_scheduler);
}
auto& command = *frame->present_commands;
command.WaitForFenceAndReset();
@@ -830,8 +809,7 @@ void Presenter::Present(Frame& frame, bool reuse) {
continue;
}
if (frame.present_commands == nullptr) {
frame.present_commands =
std::make_unique<CommandBuffer>(m_impl->present_scheduler);
frame.present_commands = std::make_unique<CommandBuffer>(m_impl->present_scheduler);
}
{
Common::LockGuard render_lock(m_impl->renderer.GetMutex());
@@ -32,11 +32,11 @@
#include "graphics/host_gpu/vma.h"
#include "graphics/host_gpu/vulkanCommon.h"
#include "graphics/presentation/presenter.h"
#include "kernel/memory.h"
#include "graphics/presentation/renderDoc.h"
#include "graphics/presentation/videoOut.h"
#include "graphics/presentation/window.h"
#include "graphics/presentation/window/windowInternal.h"
#include "kernel/memory.h"
#include "libs/controller.h"
#include "loader/systemContent.h"
@@ -475,9 +475,9 @@ static void VulkanInitSubgroupSizeControl(vk::PhysicalDevice physical_device,
}
static vk::Device VulkanCreateDevice(vk::PhysicalDevice physical_device, const VulkanExtensions& r,
uint32_t queue_family,
uint32_t queue_family,
const std::vector<const char*>& device_extensions,
GraphicContext& graphics) {
GraphicContext& graphics) {
EXIT_IF(physical_device == nullptr);
EXIT_IF(queue_family == static_cast<uint32_t>(-1));
@@ -551,19 +551,19 @@ static vk::Device VulkanCreateDevice(vk::PhysicalDevice physical_device, const V
features12.timelineSemaphore = VK_TRUE;
vk::PhysicalDeviceFeatures device_features {};
device_features.fragmentStoresAndAtomics = VK_TRUE;
device_features.samplerAnisotropy = VK_TRUE;
device_features.robustBufferAccess = VK_TRUE;
device_features.fragmentStoresAndAtomics = VK_TRUE;
device_features.samplerAnisotropy = VK_TRUE;
device_features.robustBufferAccess = VK_TRUE;
#if !defined(__APPLE__)
device_features.depthBounds = VK_TRUE; // unsupported by MoltenVK
device_features.depthBounds = VK_TRUE; // unsupported by MoltenVK
#endif
device_features.shaderStorageImageWriteWithoutFormat = VK_TRUE;
device_features.shaderStorageImageReadWithoutFormat = VK_TRUE;
device_features.shaderImageGatherExtended = VK_TRUE;
device_features.independentBlend = VK_TRUE;
device_features.tessellationShader = VK_TRUE;
device_features.sampleRateShading = VK_TRUE;
graphics.sample_rate_shading_enabled = true;
device_features.sampleRateShading = VK_TRUE;
graphics.sample_rate_shading_enabled = true;
device_features.vertexPipelineStoresAndAtomics =
supported_features2.features.vertexPipelineStoresAndAtomics;
@@ -909,10 +909,9 @@ void WindowContext::CreateVulkan() {
}
surface = native_surface;
std::vector<const char*> device_extensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME,
VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME,
"VK_KHR_maintenance1"};
std::vector<const char*> device_extensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME,
VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, "VK_KHR_maintenance1"};
#if defined(__APPLE__)
// MoltenVK lacks VK_EXT_depth_clip_enable and VK_EXT_color_write_enable; the renderer
@@ -932,8 +931,8 @@ void WindowContext::CreateVulkan() {
uint32_t queue_family = static_cast<uint32_t>(-1);
VulkanFindPhysicalDevice(graphic_ctx.instance, surface, device_extensions,
surface_capabilities, graphic_ctx.physical_device, queue_family);
VulkanFindPhysicalDevice(graphic_ctx.instance, surface, device_extensions, surface_capabilities,
graphic_ctx.physical_device, queue_family);
if (graphic_ctx.physical_device == nullptr) {
EXIT("Could not find suitable device");
@@ -949,9 +948,8 @@ void WindowContext::CreateVulkan() {
auto available_extensions = EnumerateVulkan<vk::ExtensionProperties>(
"vkEnumerateDeviceExtensionProperties",
[&](uint32_t* count, vk::ExtensionProperties* values) {
return graphic_ctx.physical_device.enumerateDeviceExtensionProperties(nullptr,
count,
values);
return graphic_ctx.physical_device.enumerateDeviceExtensionProperties(
nullptr, count, values);
});
if (HasExtension(available_extensions, VK_EXT_MEMORY_BUDGET_EXTENSION_NAME)) {
@@ -985,7 +983,7 @@ void WindowContext::CreateVulkan() {
render_context = std::make_unique<RenderContext>(graphic_ctx);
LibKernel::Memory::InstallGpuResources(&render_context->GetGpuResources());
presenter = std::make_unique<Presenter>(*this);
presenter = std::make_unique<Presenter>(*this);
RenderDocSetActiveWindow(graphic_ctx.instance, window);
}
+23 -25
View File
@@ -1,7 +1,5 @@
#include "graphics/presentation/window.h"
#include <cstdlib>
#include "SDL.h"
#include "SDL_error.h"
#include "SDL_events.h"
@@ -40,6 +38,7 @@
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>
@@ -59,7 +58,7 @@
namespace Libs::Graphics {
constexpr int KEYBOARD_CONTROLLER_ID = -1000;
constexpr int KEYBOARD_CONTROLLER_ID = -1000;
struct EventKeyboard {
bool down;
@@ -251,9 +250,7 @@ static void GameEventKeyboard(WindowLoopState& game, const EventKeyboard& key) {
if (key.down) {
switch (key.key_code) {
case SDLK_ESCAPE: game.need_exit = true; break;
case SDLK_SPACE:
SetPause(game, !game.paused.load(std::memory_order_acquire));
break;
case SDLK_SPACE: SetPause(game, !game.paused.load(std::memory_order_acquire)); break;
case SDLK_F1:
if (!key.repeat) {
RenderDocRequestCapture();
@@ -390,7 +387,9 @@ void WindowContext::Resize(uint32_t new_width, uint32_t new_height) {
void WindowContext::ProcessWindowEvent(const SDL_WindowEvent& event) {
const auto& window_event = event;
switch (window_event.event) {
case SDL_WINDOWEVENT_SHOWN: LOGF("Window %" PRIu32 " shown\n", window_event.windowID); break;
case SDL_WINDOWEVENT_SHOWN:
LOGF("Window %" PRIu32 " shown\n", window_event.windowID);
break;
case SDL_WINDOWEVENT_HIDDEN:
LOGF("Window %" PRIu32 " hidden\n", window_event.windowID);
@@ -401,13 +400,13 @@ void WindowContext::ProcessWindowEvent(const SDL_WindowEvent& event) {
break;
case SDL_WINDOWEVENT_MOVED:
LOGF("Window %" PRIu32 " moved to %" PRId32 ",%" PRId32 "\n",
window_event.windowID, window_event.data1, window_event.data2);
LOGF("Window %" PRIu32 " moved to %" PRId32 ",%" PRId32 "\n", window_event.windowID,
window_event.data1, window_event.data2);
break;
case SDL_WINDOWEVENT_RESIZED:
LOGF("Window %" PRIu32 " resized to %" PRId32 "x%" PRId32 "\n",
window_event.windowID, window_event.data1, window_event.data2);
LOGF("Window %" PRIu32 " resized to %" PRId32 "x%" PRId32 "\n", window_event.windowID,
window_event.data1, window_event.data2);
LOGF("m: %d\n", static_cast<int>(SDL_ThreadID()));
Resize(window_event.data1, window_event.data2);
@@ -807,9 +806,8 @@ static void WindowCreate(WindowContext& context) {
window_flags |= static_cast<uint32_t>(SDL_WINDOW_BORDERLESS);
}
#endif
context.window =
SDL_CreateWindow(KYTY_SDL_WINDOW_CAPTION, KYTY_SDL_WINDOWPOS_CENTERED,
KYTY_SDL_WINDOWPOS_CENTERED, width, height, window_flags);
context.window = SDL_CreateWindow(KYTY_SDL_WINDOW_CAPTION, KYTY_SDL_WINDOWPOS_CENTERED,
KYTY_SDL_WINDOWPOS_CENTERED, width, height, window_flags);
context.window_hidden = true;
@@ -832,7 +830,7 @@ Presenter& WindowInit(uint32_t width, uint32_t height) {
WindowCreate(*window);
window->CreateVulkan();
auto& presenter = *window->presenter;
g_window = std::move(window);
g_window = std::move(window);
return presenter;
}
@@ -934,9 +932,9 @@ void WindowContext::UpdateTitle() {
Loader::SystemContentParamSfoGetString("TITLE_ID", title_id, sizeof(title_id));
static bool has_app_ver =
Loader::SystemContentParamSfoGetString("APP_VER", app_ver, sizeof(app_ver));
static uint64_t fps_start = Common::Timer::QueryPerformanceCounter();
static uint64_t frame_num = 0;
static uint64_t fps_frames = 0;
static uint64_t fps_start = Common::Timer::QueryPerformanceCounter();
static uint64_t frame_num = 0;
static uint64_t fps_frames = 0;
static double current_fps = 0.0;
const auto now = Common::Timer::QueryPerformanceCounter();
@@ -946,15 +944,15 @@ void WindowContext::UpdateTitle() {
if (now - fps_start >= frequency) {
current_fps = static_cast<double>(fps_frames) * static_cast<double>(frequency) /
static_cast<double>(now - fps_start);
fps_start = now;
fps_frames = 0;
fps_start = now;
fps_frames = 0;
}
auto fps = fmt::format("{}{}{}{}{}{}[{}] [{}], frame: {}, fps: {:f}", (has_title ? title : ""),
(has_title ? ", " : ""), (has_title_id ? title_id : ""),
(has_title_id ? ", " : ""), (has_app_ver ? app_ver : ""),
(has_app_ver ? " " : ""), device_name, processor_name,
frame_num, current_fps);
auto fps =
fmt::format("{}{}{}{}{}{}[{}] [{}], frame: {}, fps: {:f}", (has_title ? title : ""),
(has_title ? ", " : ""), (has_title_id ? title_id : ""),
(has_title_id ? ", " : ""), (has_app_ver ? app_ver : ""),
(has_app_ver ? " " : ""), device_name, processor_name, frame_num, current_fps);
#if defined(__APPLE__)
// AppKit traps on title changes off the main thread; fire-and-forget keeps present pacing.
@@ -28,8 +28,8 @@ struct SurfaceCapabilities {
};
struct WindowLoopState {
SDL_Event event {};
bool need_exit = false;
SDL_Event event {};
bool need_exit = false;
std::atomic_bool paused = false;
};
@@ -38,14 +38,13 @@ struct WindowContext {
~WindowContext();
KYTY_CLASS_NO_COPY(WindowContext);
[[nodiscard]] static vk::PhysicalDeviceVulkan13Features
RequiredVulkan13Features() noexcept;
void CreateVulkan();
void RecreateSurface();
void RefreshSurfaceCapabilities();
void UpdateIcon();
void UpdateTitle();
void Resize(uint32_t width, uint32_t height);
[[nodiscard]] static vk::PhysicalDeviceVulkan13Features RequiredVulkan13Features() noexcept;
void CreateVulkan();
void RecreateSurface();
void RefreshSurfaceCapabilities();
void UpdateIcon();
void UpdateTitle();
void Resize(uint32_t width, uint32_t height);
void ProcessWindowEvent(const SDL_WindowEvent& event);
void ProcessDisplayEvent(const SDL_DisplayEvent& event);
void ProcessEvent(double time_seconds);
@@ -59,14 +58,14 @@ struct WindowContext {
void DrainMainThreadTasks();
#endif
GraphicContext graphic_ctx;
SDL_Window* window = nullptr;
bool window_hidden = true;
vk::SurfaceKHR surface = nullptr;
SurfaceCapabilities surface_capabilities;
GraphicContext graphic_ctx;
SDL_Window* window = nullptr;
bool window_hidden = true;
vk::SurfaceKHR surface = nullptr;
SurfaceCapabilities surface_capabilities;
std::unique_ptr<RenderContext> render_context;
std::unique_ptr<Presenter> presenter;
WindowLoopState loop;
std::unique_ptr<Presenter> presenter;
WindowLoopState loop;
char device_name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE] = {0};
char processor_name[64] = {0};
@@ -76,7 +75,7 @@ struct WindowContext {
#if defined(__APPLE__)
Common::Mutex main_task_mutex;
Common::CondVar main_task_done;
std::vector<std::function<void()>> main_tasks; // guarded by main_task_mutex
std::vector<std::function<void()>> main_tasks; // guarded by main_task_mutex
uint64_t main_tasks_queued = 0; // guarded by main_task_mutex
uint64_t main_tasks_run = 0; // guarded by main_task_mutex
#endif