Add vsync configuration

This commit is contained in:
Luke Street
2026-04-06 23:04:43 -06:00
parent c2ea378f3d
commit 79507b88b9
6 changed files with 56 additions and 17 deletions
+1
View File
@@ -80,6 +80,7 @@ typedef struct {
AuroraBackend desiredBackend;
uint32_t msaa;
uint16_t maxTextureAnisotropy;
bool vsync;
bool startFullscreen;
bool allowJoystickBackgroundEvents;
bool allowTextureReplacements;
+2
View File
@@ -30,6 +30,8 @@ typedef struct {
const AuroraStats* aurora_get_stats();
void aurora_enable_vsync(bool enabled);
#ifdef __cplusplus
}
#endif
+4
View File
@@ -17,6 +17,7 @@
namespace aurora {
AuroraConfig g_config;
uint32_t g_sdlCustomEventsStart;
namespace {
Module Log("aurora");
@@ -78,6 +79,9 @@ AuroraInfo initialize(int argc, char* argv[], const AuroraConfig& config) noexce
}
ASSERT(window::initialize(), "Error initializing window");
g_sdlCustomEventsStart = SDL_RegisterEvents(2);
ASSERT(g_sdlCustomEventsStart, "Failed to allocate user events: {}", SDL_GetError());
#ifdef AURORA_ENABLE_GX
/* Attempt to create a window using the calling application's desired backend */
AuroraBackend selectedBackend = config.desiredBackend;
+1
View File
@@ -124,6 +124,7 @@ auto underlying(T value) -> std::underlying_type_t<T> {
namespace aurora {
extern AuroraConfig g_config;
extern uint32_t g_sdlCustomEventsStart;
template <typename T>
class ArrayRef {
+40 -9
View File
@@ -7,6 +7,7 @@
#include <vector>
#include <aurora/aurora.h>
#include <aurora/gfx.h>
#include <magic_enum.hpp>
#include <webgpu/webgpu.h>
#include <webgpu/webgpu_cpp.h>
@@ -46,6 +47,31 @@ wgpu::BindGroup g_CopyBindGroup;
static wgpu::Adapter g_adapter;
wgpu::Instance g_instance;
static wgpu::AdapterInfo g_adapterInfo;
static wgpu::SurfaceCapabilities g_surfaceCapabilities;
static wgpu::PresentMode best_present_mode(bool vsync) {
const auto supports = [](const wgpu::PresentMode candidate) {
for (size_t i = 0; i < g_surfaceCapabilities.presentModeCount; ++i) {
if (g_surfaceCapabilities.presentModes[i] == candidate) {
return true;
}
}
return false;
};
if (vsync) {
if (supports(wgpu::PresentMode::FifoRelaxed)) {
return wgpu::PresentMode::FifoRelaxed;
}
} else {
if (supports(wgpu::PresentMode::Mailbox)) {
return wgpu::PresentMode::Mailbox;
}
if (supports(wgpu::PresentMode::Immediate)) {
return wgpu::PresentMode::Immediate;
}
}
return wgpu::PresentMode::Fifo;
}
TextureWithSampler create_render_texture(uint32_t width, uint32_t height, bool multisampled) {
const wgpu::Extent3D size{
@@ -70,13 +96,13 @@ TextureWithSampler create_render_texture(uint32_t width, uint32_t height, bool m
};
auto texture = g_device.CreateTexture(&textureDescriptor);
const wgpu::TextureViewDescriptor viewDescriptor{
constexpr wgpu::TextureViewDescriptor viewDescriptor{
.label = "Render texture view",
.dimension = wgpu::TextureViewDimension::e2D,
};
auto view = texture.CreateView(&viewDescriptor);
const wgpu::SamplerDescriptor samplerDescriptor{
constexpr wgpu::SamplerDescriptor samplerDescriptor{
.label = "Render sampler",
.addressModeU = wgpu::AddressMode::ClampToEdge,
.addressModeV = wgpu::AddressMode::ClampToEdge,
@@ -441,7 +467,7 @@ bool initialize(AuroraBackend auroraBackend) {
requiredLimits.minUniformBufferOffsetAlignment, requiredLimits.minStorageBufferOffsetAlignment);
std::vector requiredFeatures{wgpu::FeatureName::TextureComponentSwizzle};
#ifdef WEBGPU_DAWN
const std::array enableToggles{
constexpr std::array enableToggles{
/* clang-format off */
#if _WIN32
"use_dxc",
@@ -520,22 +546,21 @@ bool initialize(AuroraBackend auroraBackend) {
}
g_queue = g_device.GetQueue();
wgpu::SurfaceCapabilities surfaceCapabilities;
const wgpu::Status status = g_surface.GetCapabilities(g_adapter, &surfaceCapabilities);
const wgpu::Status status = g_surface.GetCapabilities(g_adapter, &g_surfaceCapabilities);
if (status != wgpu::Status::Success) {
Log.error("Failed to get surface capabilities: {}", magic_enum::enum_name(status));
return false;
}
if (surfaceCapabilities.formatCount == 0) {
if (g_surfaceCapabilities.formatCount == 0) {
Log.error("Surface has no formats");
return false;
}
if (surfaceCapabilities.presentModeCount == 0) {
if (g_surfaceCapabilities.presentModeCount == 0) {
Log.error("Surface has no present modes");
return false;
}
auto surfaceFormat = surfaceCapabilities.formats[0];
auto presentMode = surfaceCapabilities.presentModes[0];
auto surfaceFormat = g_surfaceCapabilities.formats[0];
auto presentMode = best_present_mode(g_config.vsync);
if (surfaceFormat == wgpu::TextureFormat::RGBA8UnormSrgb) {
surfaceFormat = wgpu::TextureFormat::RGBA8Unorm;
} else if (surfaceFormat == wgpu::TextureFormat::BGRA8UnormSrgb) {
@@ -625,3 +650,9 @@ void resize_swapchain(uint32_t width, uint32_t height, uint32_t native_width, ui
create_copy_bind_group();
}
} // namespace aurora::webgpu
void aurora_enable_vsync(const bool enabled) {
aurora::webgpu::g_graphicsConfig.surfaceConfiguration.presentMode = aurora::webgpu::best_present_mode(enabled);
SDL_Event event{.type = aurora::g_sdlCustomEventsStart + 1};
SDL_PushEvent(&event);
}
+8 -8
View File
@@ -27,7 +27,6 @@ namespace aurora::window {
namespace {
Module Log("aurora::window");
uint32_t g_sdlResizeAspectRatioEvent;
SDL_Window* g_window;
SDL_Renderer* g_renderer;
bool g_aspectRatioLocked;
@@ -160,12 +159,18 @@ const AuroraEvent* poll_events() {
.type = AURORA_EXIT,
});
default:
if (event.type == g_sdlResizeAspectRatioEvent) {
if (event.type == g_sdlCustomEventsStart) {
// Future resize event
resize_swapchain();
g_events.push_back(AuroraEvent{
.type = AURORA_WINDOW_RESIZED,
.windowSize = get_window_size(),
});
} else if (event.type == g_sdlCustomEventsStart + 1) {
// Refresh surface (vsync changed)
#ifdef AURORA_ENABLE_GX
webgpu::refresh_surface(false);
#endif
}
break;
}
@@ -314,10 +319,6 @@ bool initialize() {
SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, SDL_GetError());
}
TRY(
(g_sdlResizeAspectRatioEvent = SDL_RegisterEvents(1)),
"Failed to allocate user events: {}", SDL_GetError());
return true;
}
@@ -388,8 +389,7 @@ void center_window() {
}
static void push_future_resize_event() {
SDL_Event event = {};
event.type = g_sdlResizeAspectRatioEvent;
SDL_Event event{.type = g_sdlCustomEventsStart};
TRY_WARN(SDL_PushEvent(&event), "Failed to push SDL event for future resize: {}", SDL_GetError());
}