CLI: move VSync from an environment variable to an argument

Add a command line argument --gpu-vsync on/off/auto.

Prefer command line arguments for GPU settings,
as it means the value is error checked and set when Blender starts.

Also refactor GHOST_Context to take a parameter argument which
includes the stereo-visual & debug arguments and includes the newly
added vsync setting. This makes it possible to add GPU context
parameters more easily in the future.

It also removes redundant parsing & setting the VSync setting for
off-screen contexts.

Changes to recent PR !143049.

Ref !144473
This commit is contained in:
Campbell Barton
2025-08-14 05:16:12 +00:00
parent 248a9653f6
commit 5540b9440a
42 changed files with 330 additions and 205 deletions

View File

@@ -115,6 +115,8 @@ typedef struct GHOST_CursorGenerator {
typedef enum {
GHOST_gpuStereoVisual = (1 << 0),
GHOST_gpuDebugContext = (1 << 1),
GHOST_gpuVSyncIsOverridden = (1 << 2),
} GHOST_GPUFlags;
typedef enum GHOST_DialogOptions {
@@ -790,8 +792,62 @@ typedef struct {
uint device_id;
} GHOST_GPUDevice;
/**
* Options for VSync.
*
* \note with the exception of #GHOST_kVSyncModeUnset,
* these map to the OpenGL "swap interval" argument.
*/
typedef enum {
/** Up to the GPU driver to choose. */
GHOST_kVSyncModeUnset = -2,
/** Adaptive sync (OpenGL only). */
GHOST_kVSyncModeAuto = -1,
/** Disable, useful for unclasped redraws for testing performance. */
GHOST_kVSyncModeOff = 0,
/** Force enable. */
GHOST_kVSyncModeOn = 1,
} GHOST_TVSyncModes;
/**
* Settings used to create a GPU context.
*
* \note Avoid adding values here unless they apply across multiple context implementations.
* Otherwise the settings would be better added as extra arguments, only passed to that class.
*/
typedef struct {
bool is_stereo_visual;
bool is_debug;
GHOST_TVSyncModes vsync;
} GHOST_ContextParams;
#define GHOST_CONTEXT_PARAMS_NONE \
{ \
/*is_stereo_visual*/ false, /*is_debug*/ false, /*vsync*/ GHOST_kVSyncModeUnset, \
}
#define GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS_OFFSCREEN(gpuSettings) \
{ \
/*is_stereo_visual*/ false, \
/*is_debug*/ (((gpuSettings).flags & GHOST_gpuDebugContext) != 0), \
/*vsync*/ GHOST_kVSyncModeUnset, \
}
#define GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS(gpuSettings) \
{ \
/*is_stereo_visual*/ (((gpuSettings).flags & GHOST_gpuStereoVisual) != 0), \
/*is_debug*/ (((gpuSettings).flags & GHOST_gpuDebugContext) != 0), /*vsync*/ \
(((gpuSettings).flags & GHOST_gpuVSyncIsOverridden) ? (gpuSettings).vsync : \
GHOST_kVSyncModeUnset), \
}
typedef struct {
int flags;
/**
* Use when `flags & GHOST_gpuVSyncIsOverridden` is set.
* See #GHOST_ContextParams::vsync.
*/
GHOST_TVSyncModes vsync;
GHOST_TDrawingContextType context_type;
GHOST_GPUDevice preferred_device;
} GHOST_GPUSettings;

View File

@@ -142,9 +142,3 @@ void GHOST_Context::initClearGL()
glClearColor(0.000, 0.000, 0.000, 0.000);
}
#endif
const char *GHOST_Context::getEnvVarVSyncString()
{
const char *ghost_vsync_string = getenv("BLENDER_VSYNC");
return ghost_vsync_string;
}

View File

@@ -13,6 +13,7 @@
#include "GHOST_Types.h"
#include <cstdlib> // for nullptr
#include <optional>
class GHOST_Context : public GHOST_IContext {
protected:
@@ -21,9 +22,9 @@ class GHOST_Context : public GHOST_IContext {
public:
/**
* Constructor.
* \param stereoVisual: Stereo visual for quad buffered stereo.
* \param context_params: Parameters to use when initializing the context.
*/
GHOST_Context(bool stereoVisual) : m_stereoVisual(stereoVisual) {}
GHOST_Context(const GHOST_ContextParams &context_params) : m_context_params(context_params) {}
/**
* Destructor.
@@ -117,7 +118,13 @@ class GHOST_Context : public GHOST_IContext {
*/
bool isStereoVisual() const
{
return m_stereoVisual;
return m_context_params.is_stereo_visual;
}
/** Get the VSync value. */
virtual GHOST_TVSyncModes getVSync()
{
return m_context_params.vsync;
}
/**
@@ -160,7 +167,7 @@ class GHOST_Context : public GHOST_IContext {
#endif
protected:
bool m_stereoVisual;
GHOST_ContextParams m_context_params;
/** Caller specified, not for internal use. */
void *m_user_data = nullptr;
@@ -169,9 +176,6 @@ class GHOST_Context : public GHOST_IContext {
static void initClearGL();
#endif
/** For performance measurements with VSync disabled. */
static const char *getEnvVarVSyncString();
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Context")
};

View File

@@ -20,8 +20,8 @@
HMODULE GHOST_ContextD3D::s_d3d_lib = nullptr;
PFN_D3D11_CREATE_DEVICE GHOST_ContextD3D::s_D3D11CreateDeviceFn = nullptr;
GHOST_ContextD3D::GHOST_ContextD3D(bool stereoVisual, HWND hWnd)
: GHOST_Context(stereoVisual), m_hWnd(hWnd)
GHOST_ContextD3D::GHOST_ContextD3D(const GHOST_ContextParams &context_params, HWND hWnd)
: GHOST_Context(context_params), m_hWnd(hWnd)
{
}

View File

@@ -23,7 +23,7 @@ class GHOST_ContextD3D : public GHOST_Context {
friend class GHOST_XrGraphicsBindingVulkanD3D;
public:
GHOST_ContextD3D(bool stereoVisual, HWND hWnd);
GHOST_ContextD3D(const GHOST_ContextParams &context_params, HWND hWnd);
~GHOST_ContextD3D() override;
/**

View File

@@ -187,7 +187,7 @@ template<typename T> T &choose_api(EGLenum api, T &a, T &b, T &c)
}
GHOST_ContextEGL::GHOST_ContextEGL(const GHOST_System *const system,
bool stereoVisual,
const GHOST_ContextParams &context_params,
EGLNativeWindowType nativeWindow,
EGLNativeDisplayType nativeDisplay,
EGLint contextProfileMask,
@@ -196,7 +196,7 @@ GHOST_ContextEGL::GHOST_ContextEGL(const GHOST_System *const system,
EGLint contextFlags,
EGLint contextResetNotificationStrategy,
EGLenum api)
: GHOST_Context(stereoVisual),
: GHOST_Context(context_params),
m_system(system),
m_nativeDisplay(nativeDisplay),
m_nativeWindow(nativeWindow),
@@ -336,10 +336,10 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
std::vector<EGLint> attrib_list;
EGLint num_config = 0;
if (m_stereoVisual) {
if (m_context_params.is_stereo_visual) {
fprintf(stderr, "Warning! Stereo OpenGL ES contexts are not supported.\n");
}
m_stereoVisual = false; /* It doesn't matter what the Window wants. */
m_context_params.is_stereo_visual = false; /* It doesn't matter what the Window wants. */
EGLDisplay prev_display = eglGetCurrentDisplay();
EGLSurface prev_draw = eglGetCurrentSurface(EGL_DRAW);
@@ -626,10 +626,9 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
}
{
const char *ghost_vsync_string = getEnvVarVSyncString();
if (ghost_vsync_string) {
int swapInterval = atoi(ghost_vsync_string);
setSwapInterval(swapInterval);
const GHOST_TVSyncModes vsync = getVSync();
if (vsync != GHOST_kVSyncModeUnset) {
setSwapInterval(int(vsync));
}
}

View File

@@ -35,7 +35,7 @@ class GHOST_ContextEGL : public GHOST_Context {
* Constructor.
*/
GHOST_ContextEGL(const GHOST_System *const system,
bool stereoVisual,
const GHOST_ContextParams &context_params,
EGLNativeWindowType nativeWindow,
EGLNativeDisplayType nativeDisplay,
EGLint contextProfileMask,

View File

@@ -28,7 +28,7 @@ static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, co
GLXContext GHOST_ContextGLX::s_sharedContext = None;
int GHOST_ContextGLX::s_sharedCount = 0;
GHOST_ContextGLX::GHOST_ContextGLX(bool stereoVisual,
GHOST_ContextGLX::GHOST_ContextGLX(const GHOST_ContextParams &context_params,
Window window,
Display *display,
GLXFBConfig fbconfig,
@@ -37,7 +37,7 @@ GHOST_ContextGLX::GHOST_ContextGLX(bool stereoVisual,
int contextMinorVersion,
int contextFlags,
int contextResetNotificationStrategy)
: GHOST_Context(stereoVisual),
: GHOST_Context(context_params),
m_display(display),
m_fbconfig(fbconfig),
m_window(window),
@@ -244,7 +244,8 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
int glx_attribs[64];
int fbcount = 0;
GHOST_X11_GL_GetAttributes(glx_attribs, 64, m_stereoVisual, false, true);
GHOST_X11_GL_GetAttributes(
glx_attribs, 64, m_context_params.is_stereo_visual, false, true);
framebuffer_config = glXChooseFBConfig(
m_display, DefaultScreen(m_display), glx_attribs, &fbcount);
@@ -281,10 +282,11 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
glXMakeCurrent(m_display, m_window, m_context);
/* For performance measurements with VSync disabled. */
const char *ghost_vsync_string = getEnvVarVSyncString();
if (ghost_vsync_string) {
int swapInterval = atoi(ghost_vsync_string);
setSwapInterval(swapInterval);
{
const GHOST_TVSyncModes vsync = getVSync();
if (vsync != GHOST_kVSyncModeUnset) {
setSwapInterval(int(vsync));
}
}
if (m_window) {

View File

@@ -29,7 +29,7 @@ class GHOST_ContextGLX : public GHOST_Context {
/**
* Constructor.
*/
GHOST_ContextGLX(bool stereoVisual,
GHOST_ContextGLX(const GHOST_ContextParams &context_params,
Window window,
Display *display,
GLXFBConfig fbconfig,

View File

@@ -41,7 +41,9 @@ class GHOST_ContextMTL : public GHOST_Context {
/**
* Constructor.
*/
GHOST_ContextMTL(bool stereoVisual, NSView *metalView, CAMetalLayer *metalLayer, int debug);
GHOST_ContextMTL(const GHOST_ContextParams &context_params,
NSView *metalView,
CAMetalLayer *metalLayer);
/**
* Destructor.
@@ -157,7 +159,6 @@ class GHOST_ContextMTL : public GHOST_Context {
id<CAMetalDrawable>);
int mtl_SwapInterval;
const bool m_debug;
static int s_sharedCount;

View File

@@ -46,15 +46,13 @@ static void ghost_fatal_error_dialog(const char *msg)
MTLCommandQueue *GHOST_ContextMTL::s_sharedMetalCommandQueue = nil;
int GHOST_ContextMTL::s_sharedCount = 0;
GHOST_ContextMTL::GHOST_ContextMTL(bool stereoVisual,
GHOST_ContextMTL::GHOST_ContextMTL(const GHOST_ContextParams &context_params,
NSView *metalView,
CAMetalLayer *metalLayer,
int debug)
: GHOST_Context(stereoVisual),
CAMetalLayer *metalLayer)
: GHOST_Context(context_params),
m_metalView(metalView),
m_metalLayer(metalLayer),
m_metalRenderPipeline(nil),
m_debug(debug)
m_metalRenderPipeline(nil)
{
@autoreleasepool {
/* Initialize Metal Swap-chain. */
@@ -72,7 +70,7 @@ GHOST_ContextMTL::GHOST_ContextMTL(bool stereoVisual,
/* Prepare offscreen GHOST Context Metal device. */
id<MTLDevice> metalDevice = MTLCreateSystemDefaultDevice();
if (m_debug) {
if (m_context_params.is_debug) {
printf("Selected Metal Device: %s\n", [metalDevice.name UTF8String]);
}
@@ -88,10 +86,11 @@ GHOST_ContextMTL::GHOST_ContextMTL(bool stereoVisual,
m_metalLayer.device = metalDevice;
m_metalLayer.allowsNextDrawableTimeout = NO;
const char *ghost_vsync_string = getEnvVarVSyncString();
if (ghost_vsync_string) {
int swapInterval = atoi(ghost_vsync_string);
m_metalLayer.displaySyncEnabled = swapInterval != 0 ? YES : NO;
{
const GHOST_TVSyncModes vsync = getVSync();
if (vsync != GHOST_kVSyncModeUnset) {
m_metalLayer.displaySyncEnabled = (vsync == GHOST_kVSyncModeOff) ? NO : YES;
}
}
/* Enable EDR support. This is done by:

View File

@@ -14,7 +14,7 @@
class GHOST_ContextNone : public GHOST_Context {
public:
GHOST_ContextNone(bool stereoVisual) : GHOST_Context(stereoVisual) {}
GHOST_ContextNone(const GHOST_ContextParams &context_params) : GHOST_Context(context_params) {}
/**
* Dummy function

View File

@@ -16,14 +16,14 @@
SDL_GLContext GHOST_ContextSDL::s_sharedContext = nullptr;
int GHOST_ContextSDL::s_sharedCount = 0;
GHOST_ContextSDL::GHOST_ContextSDL(bool stereoVisual,
GHOST_ContextSDL::GHOST_ContextSDL(const GHOST_ContextParams &context_params,
SDL_Window *window,
int contextProfileMask,
int contextMajorVersion,
int contextMinorVersion,
int contextFlags,
int contextResetNotificationStrategy)
: GHOST_Context(stereoVisual),
: GHOST_Context(context_params),
m_window(window),
m_hidden_window(nullptr),
m_contextProfileMask(contextProfileMask),
@@ -106,7 +106,7 @@ GHOST_TSuccess GHOST_ContextSDL::initializeDrawingContext()
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
}
if (m_stereoVisual) {
if (m_context_params.is_stereo_visual) {
SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
}
@@ -134,10 +134,11 @@ GHOST_TSuccess GHOST_ContextSDL::initializeDrawingContext()
success = (SDL_GL_MakeCurrent(m_window, m_context) < 0) ? GHOST_kFailure : GHOST_kSuccess;
const char *ghost_vsync_string = getEnvVarVSyncString();
if (ghost_vsync_string) {
int swapInterval = atoi(ghost_vsync_string);
setSwapInterval(swapInterval);
{
const GHOST_TVSyncModes vsync = getVSync();
if (vsync != GHOST_kVSyncModeUnset) {
setSwapInterval(int(vsync));
}
}
initClearGL();

View File

@@ -31,7 +31,7 @@ class GHOST_ContextSDL : public GHOST_Context {
/**
* Constructor.
*/
GHOST_ContextSDL(bool stereoVisual,
GHOST_ContextSDL(const GHOST_ContextParams &context_params,
SDL_Window *window,
int contextProfileMask,
int contextMajorVersion,

View File

@@ -554,7 +554,7 @@ static GHOST_TSuccess ensure_vulkan_device(VkInstance vk_instance,
/** \} */
GHOST_ContextVK::GHOST_ContextVK(bool stereoVisual,
GHOST_ContextVK::GHOST_ContextVK(const GHOST_ContextParams &context_params,
#ifdef _WIN32
HWND hwnd,
#elif defined(__APPLE__)
@@ -571,9 +571,8 @@ GHOST_ContextVK::GHOST_ContextVK(bool stereoVisual,
#endif
int contextMajorVersion,
int contextMinorVersion,
int debug,
const GHOST_GPUDevice &preferred_device)
: GHOST_Context(stereoVisual),
: GHOST_Context(context_params),
#ifdef _WIN32
m_hwnd(hwnd),
#elif defined(__APPLE__)
@@ -590,7 +589,6 @@ GHOST_ContextVK::GHOST_ContextVK(bool stereoVisual,
#endif
m_context_major_version(contextMajorVersion),
m_context_minor_version(contextMinorVersion),
m_debug(debug),
m_preferred_device(preferred_device),
m_surface(VK_NULL_HANDLE),
m_swapchain(VK_NULL_HANDLE),
@@ -857,7 +855,7 @@ static void requireExtension(const vector<VkExtensionProperties> &extensions_ava
}
}
static GHOST_TSuccess selectPresentMode(const char *ghost_vsync_string,
static GHOST_TSuccess selectPresentMode(const GHOST_TVSyncModes vsync,
VkPhysicalDevice device,
VkSurfaceKHR surface,
VkPresentModeKHR *r_presentMode)
@@ -867,8 +865,8 @@ static GHOST_TSuccess selectPresentMode(const char *ghost_vsync_string,
vector<VkPresentModeKHR> presents(present_count);
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &present_count, presents.data());
if (ghost_vsync_string) {
bool vsync_off = atoi(ghost_vsync_string) == 0;
if (vsync != GHOST_kVSyncModeUnset) {
const bool vsync_off = (vsync == GHOST_kVSyncModeOff);
if (vsync_off) {
for (auto present_mode : presents) {
if (present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
@@ -877,9 +875,8 @@ static GHOST_TSuccess selectPresentMode(const char *ghost_vsync_string,
}
}
CLOG_WARN(&LOG,
"Vulkan: VSync off was requested via BLENDER_VSYNC, but "
"VK_PRESENT_MODE_IMMEDIATE_KHR is not "
"supported.");
"Vulkan: VSync off was requested via --gpu-vsync, "
"but VK_PRESENT_MODE_IMMEDIATE_KHR is not supported.");
}
}
@@ -984,7 +981,7 @@ GHOST_TSuccess GHOST_ContextVK::recreateSwapchain(bool use_hdr_swapchain)
}
VkPresentModeKHR present_mode;
if (!selectPresentMode(getEnvVarVSyncString(), physical_device, m_surface, &present_mode)) {
if (!selectPresentMode(getVSync(), physical_device, m_surface, &present_mode)) {
return GHOST_kFailure;
}
@@ -1258,7 +1255,7 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext()
vector<const char *> optional_device_extensions;
vector<const char *> extensions_enabled;
if (m_debug) {
if (m_context_params.is_debug) {
requireExtension(extensions_available, extensions_enabled, VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
}

View File

@@ -109,7 +109,7 @@ class GHOST_ContextVK : public GHOST_Context {
/**
* Constructor.
*/
GHOST_ContextVK(bool stereoVisual,
GHOST_ContextVK(const GHOST_ContextParams &context_params,
#ifdef _WIN32
HWND hwnd,
#elif defined(__APPLE__)
@@ -127,7 +127,6 @@ class GHOST_ContextVK : public GHOST_Context {
#endif
int contextMajorVersion,
int contextMinorVersion,
int debug,
const GHOST_GPUDevice &preferred_device);
/**
@@ -229,7 +228,6 @@ class GHOST_ContextVK : public GHOST_Context {
const int m_context_major_version;
const int m_context_minor_version;
const int m_debug;
const GHOST_GPUDevice m_preferred_device;
VkQueue m_graphic_queue;

View File

@@ -25,7 +25,7 @@ static bool is_crappy_intel_card()
return strstr((const char *)glGetString(GL_VENDOR), "Intel") != nullptr;
}
GHOST_ContextWGL::GHOST_ContextWGL(bool stereoVisual,
GHOST_ContextWGL::GHOST_ContextWGL(const GHOST_ContextParams &context_params,
bool alphaBackground,
HWND hWnd,
HDC hDC,
@@ -34,7 +34,7 @@ GHOST_ContextWGL::GHOST_ContextWGL(bool stereoVisual,
int contextMinorVersion,
int contextFlags,
int contextResetNotificationStrategy)
: GHOST_Context(stereoVisual),
: GHOST_Context(context_params),
m_hWnd(hWnd),
m_hDC(hDC),
m_contextProfileMask(contextProfileMask),
@@ -480,7 +480,7 @@ int GHOST_ContextWGL::choose_pixel_format_arb(bool stereoVisual, bool needAlpha)
iPixelFormat = _choose_pixel_format_arb_1(false, needAlpha);
m_stereoVisual = false; // set context property to actual value
m_context_params.is_stereo_visual = false; /* Set context property to actual value. */
}
return iPixelFormat;
@@ -509,13 +509,13 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
{
const bool needAlpha = m_alphaBackground;
DummyContextWGL dummy(m_hDC, m_hWnd, m_stereoVisual, needAlpha);
DummyContextWGL dummy(m_hDC, m_hWnd, m_context_params.is_stereo_visual, needAlpha);
if (!dummy.has_WGL_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) {
int iPixelFormat = 0;
if (dummy.has_WGL_ARB_pixel_format) {
iPixelFormat = choose_pixel_format_arb(m_stereoVisual, needAlpha);
iPixelFormat = choose_pixel_format_arb(m_context_params.is_stereo_visual, needAlpha);
}
if (iPixelFormat == 0) {
@@ -617,10 +617,9 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
}
{
const char *ghost_vsync_string = getEnvVarVSyncString();
if (ghost_vsync_string) {
int swapInterval = atoi(ghost_vsync_string);
setSwapInterval(swapInterval);
const GHOST_TVSyncModes vsync = getVSync();
if (vsync != GHOST_kVSyncModeUnset) {
setSwapInterval(int(vsync));
}
}

View File

@@ -24,7 +24,7 @@ class GHOST_ContextWGL : public GHOST_Context {
/**
* Constructor.
*/
GHOST_ContextWGL(bool stereoVisual,
GHOST_ContextWGL(const GHOST_ContextParams &context_params,
bool alphaBackground,
HWND hWnd,
HDC hDC,

View File

@@ -725,6 +725,7 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
const bool is_dialog,
const GHOST_IWindow *parentWindow)
{
const GHOST_ContextParams context_params = GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS(gpuSettings);
GHOST_IWindow *window = nullptr;
@autoreleasepool {
/* Get the available rect for including window contents. */
@@ -744,8 +745,7 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
height,
state,
gpuSettings.context_type,
gpuSettings.flags & GHOST_gpuStereoVisual,
gpuSettings.flags & GHOST_gpuDebugContext,
context_params,
is_dialog,
(GHOST_WindowCocoa *)parentWindow,
gpuSettings.preferred_device);
@@ -776,13 +776,14 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
*/
GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GPUSettings gpuSettings)
{
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
const GHOST_ContextParams context_params_offscreen =
GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS_OFFSCREEN(gpuSettings);
switch (gpuSettings.context_type) {
#ifdef WITH_VULKAN_BACKEND
case GHOST_kDrawingContextTypeVulkan: {
GHOST_Context *context = new GHOST_ContextVK(
false, nullptr, 1, 2, debug_context, gpuSettings.preferred_device);
context_params_offscreen, nullptr, 1, 2, gpuSettings.preferred_device);
if (context->initializeDrawingContext()) {
return context;
}
@@ -793,7 +794,7 @@ GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GPUSettings gpuS
#ifdef WITH_METAL_BACKEND
case GHOST_kDrawingContextTypeMetal: {
GHOST_Context *context = new GHOST_ContextMTL(false, nullptr, nullptr, debug_context);
GHOST_Context *context = new GHOST_ContextMTL(context_params_offscreen, nullptr, nullptr);
if (context->initializeDrawingContext()) {
return context;
}

View File

@@ -111,18 +111,20 @@ class GHOST_SystemHeadless : public GHOST_System {
}
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings) override
{
const GHOST_ContextParams context_params_offscreen =
GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS_OFFSCREEN(gpuSettings);
switch (gpuSettings.context_type) {
#ifdef WITH_VULKAN_BACKEND
case GHOST_kDrawingContextTypeVulkan: {
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
# ifdef _WIN32
GHOST_Context *context = new GHOST_ContextVK(
false, (HWND)0, 1, 2, debug_context, gpuSettings.preferred_device);
context_params_offscreen, (HWND)0, 1, 2, gpuSettings.preferred_device);
# elif defined(__APPLE__)
GHOST_Context *context = new GHOST_ContextVK(
false, nullptr, 1, 2, debug_context, gpuSettings.preferred_device);
context_params_offscreen, nullptr, 1, 2, gpuSettings.preferred_device);
# else
GHOST_Context *context = new GHOST_ContextVK(false,
GHOST_Context *context = new GHOST_ContextVK(context_params_offscreen,
GHOST_kVulkanPlatformHeadless,
0,
0,
@@ -131,7 +133,6 @@ class GHOST_SystemHeadless : public GHOST_System {
nullptr,
1,
2,
debug_context,
gpuSettings.preferred_device);
# endif
if (context->initializeDrawingContext()) {
@@ -148,7 +149,7 @@ class GHOST_SystemHeadless : public GHOST_System {
GHOST_Context *context;
for (int minor = 6; minor >= 3; --minor) {
context = new GHOST_ContextEGL((GHOST_System *)this,
false,
context_params_offscreen,
EGLNativeWindowType(0),
EGLNativeDisplayType(EGL_DEFAULT_DISPLAY),
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
@@ -205,6 +206,7 @@ class GHOST_SystemHeadless : public GHOST_System {
const bool /*is_dialog*/,
const GHOST_IWindow *parentWindow) override
{
const GHOST_ContextParams context_params = GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS(gpuSettings);
return new GHOST_WindowNULL(title,
left,
top,
@@ -213,7 +215,7 @@ class GHOST_SystemHeadless : public GHOST_System {
state,
parentWindow,
gpuSettings.context_type,
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0));
context_params);
}
GHOST_IWindow *getWindowUnderCursor(int32_t /*x*/, int32_t /*y*/) override

View File

@@ -51,6 +51,8 @@ GHOST_IWindow *GHOST_SystemSDL::createWindow(const char *title,
{
GHOST_WindowSDL *window = nullptr;
const GHOST_ContextParams context_params = GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS(gpuSettings);
window = new GHOST_WindowSDL(this,
title,
left,
@@ -59,7 +61,7 @@ GHOST_IWindow *GHOST_SystemSDL::createWindow(const char *title,
height,
state,
gpuSettings.context_type,
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
context_params,
exclusive,
parentWindow);
@@ -131,12 +133,15 @@ uint8_t GHOST_SystemSDL::getNumDisplays() const
GHOST_IContext *GHOST_SystemSDL::createOffscreenContext(GHOST_GPUSettings gpuSettings)
{
const GHOST_ContextParams context_params_offscreen =
GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS_OFFSCREEN(gpuSettings);
switch (gpuSettings.context_type) {
#ifdef WITH_OPENGL_BACKEND
case GHOST_kDrawingContextTypeOpenGL: {
for (int minor = 6; minor >= 3; --minor) {
GHOST_Context *context = new GHOST_ContextSDL(
false,
context_params_offscreen,
nullptr,
0, /* Profile bit. */
4,

View File

@@ -8584,7 +8584,8 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GPUSettings gp
std::lock_guard lock_server_guard{*server_mutex};
#endif
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
const GHOST_ContextParams context_params_offscreen =
GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS_OFFSCREEN(gpuSettings);
switch (gpuSettings.context_type) {
@@ -8593,7 +8594,7 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GPUSettings gp
/* Create new off-screen surface only for vulkan. */
wl_surface *wl_surface = wl_compositor_create_surface(wl_compositor_get());
GHOST_Context *context = new GHOST_ContextVK(false,
GHOST_Context *context = new GHOST_ContextVK(context_params_offscreen,
GHOST_kVulkanPlatformWayland,
0,
nullptr,
@@ -8602,7 +8603,6 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GPUSettings gp
nullptr,
1,
2,
debug_context,
gpuSettings.preferred_device);
if (context->initializeDrawingContext()) {
@@ -8628,14 +8628,14 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GPUSettings gp
/* Caller must lock `system->server_mutex`. */
GHOST_Context *context = new GHOST_ContextEGL(
this,
false,
context_params_offscreen,
EGLNativeWindowType(egl_window),
EGLNativeDisplayType(display_->wl.display),
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
4,
minor,
GHOST_OPENGL_EGL_CONTEXT_FLAGS |
(debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
(context_params_offscreen.is_debug ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
EGL_OPENGL_API);
@@ -8717,22 +8717,22 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
const bool is_dialog,
const GHOST_IWindow *parentWindow)
{
const GHOST_ContextParams context_params = GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS(gpuSettings);
/* Globally store pointer to window manager. */
GHOST_WindowWayland *window = new GHOST_WindowWayland(
this,
title,
left,
top,
width,
height,
state,
parentWindow,
gpuSettings.context_type,
is_dialog,
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
exclusive,
(gpuSettings.flags & GHOST_gpuDebugContext) != 0,
gpuSettings.preferred_device);
GHOST_WindowWayland *window = new GHOST_WindowWayland(this,
title,
left,
top,
width,
height,
state,
parentWindow,
gpuSettings.context_type,
is_dialog,
context_params,
exclusive,
gpuSettings.preferred_device);
if (window) {
if (window->getValid()) {

View File

@@ -271,20 +271,19 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
const bool is_dialog,
const GHOST_IWindow *parentWindow)
{
GHOST_WindowWin32 *window = new GHOST_WindowWin32(
this,
title,
left,
top,
width,
height,
state,
gpuSettings.context_type,
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
(GHOST_WindowWin32 *)parentWindow,
((gpuSettings.flags & GHOST_gpuDebugContext) != 0),
is_dialog,
gpuSettings.preferred_device);
const GHOST_ContextParams context_params = GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS(gpuSettings);
GHOST_WindowWin32 *window = new GHOST_WindowWin32(this,
title,
left,
top,
width,
height,
state,
gpuSettings.context_type,
context_params,
(GHOST_WindowWin32 *)parentWindow,
is_dialog,
gpuSettings.preferred_device);
if (window->getValid()) {
/* Store the pointer to the window */
@@ -307,13 +306,14 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
*/
GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GPUSettings gpuSettings)
{
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
const GHOST_ContextParams context_params_offscreen =
GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS_OFFSCREEN(gpuSettings);
switch (gpuSettings.context_type) {
#ifdef WITH_VULKAN_BACKEND
case GHOST_kDrawingContextTypeVulkan: {
GHOST_Context *context = new GHOST_ContextVK(
false, (HWND)0, 1, 2, debug_context, gpuSettings.preferred_device);
context_params_offscreen, (HWND)0, 1, 2, gpuSettings.preferred_device);
if (context->initializeDrawingContext()) {
return context;
}
@@ -344,14 +344,14 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GPUSettings gpuS
for (int minor = 6; minor >= 3; --minor) {
GHOST_Context *context = new GHOST_ContextWGL(
false,
context_params_offscreen,
true,
wnd,
mHDC,
WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
4,
minor,
(debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
(context_params_offscreen.is_debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
if (context->initializeDrawingContext()) {
@@ -389,6 +389,8 @@ GHOST_TSuccess GHOST_SystemWin32::disposeContext(GHOST_IContext *context)
*/
GHOST_ContextD3D *GHOST_SystemWin32::createOffscreenContextD3D()
{
/* NOTE: the `gpuSettings` could be passed in here, as it is with similar functions. */
const GHOST_ContextParams context_params_offscreen = GHOST_CONTEXT_PARAMS_NONE;
HWND wnd = CreateWindowA("STATIC",
"Blender XR",
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
@@ -401,7 +403,7 @@ GHOST_ContextD3D *GHOST_SystemWin32::createOffscreenContextD3D()
GetModuleHandle(nullptr),
nullptr);
GHOST_ContextD3D *context = new GHOST_ContextD3D(false, wnd);
GHOST_ContextD3D *context = new GHOST_ContextD3D(context_params_offscreen, wnd);
if (context->initializeDrawingContext()) {
return context;
}

View File

@@ -366,6 +366,7 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
return nullptr;
}
const GHOST_ContextParams context_params = GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS(gpuSettings);
window = new GHOST_WindowX11(this,
m_display,
title,
@@ -377,9 +378,8 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
(GHOST_WindowX11 *)parentWindow,
gpuSettings.context_type,
is_dialog,
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
context_params,
exclusive,
(gpuSettings.flags & GHOST_gpuDebugContext) != 0,
gpuSettings.preferred_device);
if (window) {
@@ -402,11 +402,13 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GPUSettings gpuSettings)
{
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
const GHOST_ContextParams context_params_offscreen =
GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS_OFFSCREEN(gpuSettings);
switch (gpuSettings.context_type) {
#ifdef WITH_VULKAN_BACKEND
case GHOST_kDrawingContextTypeVulkan: {
GHOST_Context *context = new GHOST_ContextVK(false,
GHOST_Context *context = new GHOST_ContextVK(context_params_offscreen,
GHOST_kVulkanPlatformX11,
0,
m_display,
@@ -415,7 +417,6 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GPUSettings gpuSet
nullptr,
1,
2,
debug_context,
gpuSettings.preferred_device);
if (context->initializeDrawingContext()) {
return context;
@@ -429,14 +430,15 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GPUSettings gpuSet
case GHOST_kDrawingContextTypeOpenGL: {
for (int minor = 6; minor >= 3; --minor) {
GHOST_Context *context = new GHOST_ContextGLX(
false,
context_params_offscreen,
(Window) nullptr,
m_display,
(GLXFBConfig) nullptr,
GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
4,
minor,
GHOST_OPENGL_GLX_CONTEXT_FLAGS | (debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
GHOST_OPENGL_GLX_CONTEXT_FLAGS |
(context_params_offscreen.is_debug ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
if (context->initializeDrawingContext()) {
return context;

View File

@@ -19,7 +19,7 @@
GHOST_Window::GHOST_Window(uint32_t width,
uint32_t height,
GHOST_TWindowState state,
const bool wantStereoVisual,
const GHOST_ContextParams &context_params,
const bool /*exclusive*/)
: m_drawingContextType(GHOST_kDrawingContextTypeNone),
m_userData(nullptr),
@@ -34,11 +34,13 @@ GHOST_Window::GHOST_Window(uint32_t width,
m_isUnsavedChanges(false),
m_windowDecorationStyleFlags(GHOST_kDecorationNone),
m_windowDecorationStyleSettings(),
m_wantStereoVisual(wantStereoVisual),
m_want_context_params(context_params),
m_nativePixelSize(1.0f),
m_context(new GHOST_ContextNone(false))
m_context(nullptr)
{
const GHOST_ContextParams context_params_none = GHOST_CONTEXT_PARAMS_NONE;
m_context = new GHOST_ContextNone(context_params_none);
m_fullScreen = state == GHOST_kWindowStateFullScreen;
if (m_fullScreen) {
@@ -86,7 +88,7 @@ GHOST_TSuccess GHOST_Window::setDrawingContextType(GHOST_TDrawingContextType typ
m_drawingContextType = type;
}
else {
m_context = new GHOST_ContextNone(m_wantStereoVisual);
m_context = new GHOST_ContextNone(m_want_context_params);
m_drawingContextType = GHOST_kDrawingContextTypeNone;
}

View File

@@ -35,7 +35,7 @@ class GHOST_Window : public GHOST_IWindow {
GHOST_Window(uint32_t width,
uint32_t height,
GHOST_TWindowState state,
const bool wantStereoVisual = false,
const GHOST_ContextParams &context_params,
const bool exclusive = false);
/**
@@ -347,8 +347,8 @@ class GHOST_Window : public GHOST_IWindow {
GHOST_TWindowDecorationStyleFlags m_windowDecorationStyleFlags;
GHOST_WindowDecorationStyleSettings m_windowDecorationStyleSettings;
/** Whether to attempt to initialize a context with a stereo frame-buffer. */
bool m_wantStereoVisual;
/** The desired parameters to use when initializing the context for this window. */
GHOST_ContextParams m_want_context_params;
/** Full-screen width */
uint32_t m_fullScreenWidth;

View File

@@ -41,7 +41,7 @@ class GHOST_WindowCocoa : public GHOST_Window {
* \param height: The height the window.
* \param state: The state the window is initially opened with.
* \param type: The type of drawing context installed in this window.
* \param stereoVisual: Stereo visual for quad buffered stereo.
* \param context_params: Parameters to use when initializing the context.
* \param preferred_device: Preferred device to use when new device will be created.
*/
GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa,
@@ -52,8 +52,7 @@ class GHOST_WindowCocoa : public GHOST_Window {
uint32_t height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
bool is_debug,
const GHOST_ContextParams &context_params,
bool dialog,
GHOST_WindowCocoa *parentWindow,
const GHOST_GPUDevice &preferred_device);
@@ -313,7 +312,6 @@ class GHOST_WindowCocoa : public GHOST_Window {
GHOST_TabletData m_tablet;
bool m_immediateDraw;
bool m_debug_context; // for debug messages during context setup
bool m_is_dialog;
GHOST_GPUDevice m_preferred_device;
};

View File

@@ -327,19 +327,17 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa,
uint32_t height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
bool is_debug,
const GHOST_ContextParams &context_params,
bool is_dialog,
GHOST_WindowCocoa *parentWindow,
const GHOST_GPUDevice &preferred_device)
: GHOST_Window(width, height, state, stereoVisual, false),
: GHOST_Window(width, height, state, context_params, false),
m_openGLView(nil),
m_metalView(nil),
m_metalLayer(nil),
m_systemCocoa(systemCocoa),
m_customCursor(nullptr),
m_immediateDraw(false),
m_debug_context(is_debug),
m_is_dialog(is_dialog),
m_preferred_device(preferred_device)
{
@@ -900,7 +898,7 @@ GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType ty
#ifdef WITH_VULKAN_BACKEND
case GHOST_kDrawingContextTypeVulkan: {
GHOST_Context *context = new GHOST_ContextVK(
m_wantStereoVisual, m_metalLayer, 1, 2, true, m_preferred_device);
m_want_context_params, m_metalLayer, 1, 2, true, m_preferred_device);
if (context->initializeDrawingContext()) {
return context;
}
@@ -912,7 +910,7 @@ GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType ty
#ifdef WITH_METAL_BACKEND
case GHOST_kDrawingContextTypeMetal: {
GHOST_Context *context = new GHOST_ContextMTL(
m_wantStereoVisual, m_metalView, m_metalLayer, false);
m_want_context_params, m_metalView, m_metalLayer);
if (context->initializeDrawingContext()) {
return context;
}

View File

@@ -30,8 +30,8 @@ class GHOST_WindowNULL : public GHOST_Window {
GHOST_TWindowState state,
const GHOST_IWindow * /*parentWindow*/,
GHOST_TDrawingContextType /*type*/,
const bool stereoVisual)
: GHOST_Window(width, height, state, stereoVisual, false)
const GHOST_ContextParams &context_params)
: GHOST_Window(width, height, state, context_params, false)
{
}

View File

@@ -21,10 +21,10 @@ GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system,
uint32_t height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
const GHOST_ContextParams &context_params,
const bool exclusive,
const GHOST_IWindow * /*parentWindow*/)
: GHOST_Window(width, height, state, stereoVisual, exclusive),
: GHOST_Window(width, height, state, context_params, exclusive),
m_system(system),
m_valid_setup(false),
m_invalid_window(false),
@@ -65,12 +65,13 @@ GHOST_WindowSDL::~GHOST_WindowSDL()
GHOST_Context *GHOST_WindowSDL::newDrawingContext(GHOST_TDrawingContextType type)
{
switch (type) {
#ifdef WITH_OPENGL_BACKEND
case GHOST_kDrawingContextTypeOpenGL: {
for (int minor = 6; minor >= 3; --minor) {
GHOST_Context *context = new GHOST_ContextSDL(
m_wantStereoVisual,
m_want_context_params,
m_sdl_win,
0, /* Profile bit. */
4,

View File

@@ -41,8 +41,8 @@ class GHOST_WindowSDL : public GHOST_Window {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
const bool stereoVisual = false,
GHOST_TDrawingContextType type,
const GHOST_ContextParams &context_params,
const bool exclusive = false,
const GHOST_IWindow *parentWindow = nullptr);

View File

@@ -1734,14 +1734,12 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
const GHOST_IWindow *parentWindow,
const GHOST_TDrawingContextType type,
const bool is_dialog,
const bool stereoVisual,
const GHOST_ContextParams &context_params,
const bool exclusive,
const bool is_debug,
const GHOST_GPUDevice &preferred_device)
: GHOST_Window(width, height, state, stereoVisual, exclusive),
: GHOST_Window(width, height, state, context_params, exclusive),
system_(system),
window_(new GWL_Window),
is_debug_context_(is_debug),
preferred_device_(preferred_device)
{
#ifdef USE_EVENT_BACKGROUND_THREAD
@@ -2459,13 +2457,13 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
{
switch (type) {
case GHOST_kDrawingContextTypeNone: {
GHOST_Context *context = new GHOST_ContextNone(m_wantStereoVisual);
GHOST_Context *context = new GHOST_ContextNone(m_want_context_params);
return context;
}
#ifdef WITH_VULKAN_BACKEND
case GHOST_kDrawingContextTypeVulkan: {
GHOST_ContextVK *context = new GHOST_ContextVK(m_wantStereoVisual,
GHOST_ContextVK *context = new GHOST_ContextVK(m_want_context_params,
GHOST_kVulkanPlatformWayland,
0,
nullptr,
@@ -2474,7 +2472,6 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
window_->backend.vulkan_window_info,
1,
2,
is_debug_context_,
preferred_device_);
if (context->initializeDrawingContext()) {
return context;
@@ -2489,14 +2486,14 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
for (int minor = 6; minor >= 3; --minor) {
GHOST_Context *context = new GHOST_ContextEGL(
system_,
m_wantStereoVisual,
m_want_context_params,
EGLNativeWindowType(window_->backend.egl_window),
EGLNativeDisplayType(system_->wl_display_get()),
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
4,
minor,
GHOST_OPENGL_EGL_CONTEXT_FLAGS |
(is_debug_context_ ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
(m_want_context_params.is_debug ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
EGL_OPENGL_API);

View File

@@ -76,9 +76,8 @@ class GHOST_WindowWayland : public GHOST_Window {
const GHOST_IWindow *parentWindow,
GHOST_TDrawingContextType type,
const bool is_dialog,
const bool stereoVisual,
const GHOST_ContextParams &context_params,
const bool exclusive,
const bool is_debug,
const GHOST_GPUDevice &preferred_device);
~GHOST_WindowWayland() override;
@@ -202,7 +201,6 @@ class GHOST_WindowWayland : public GHOST_Window {
private:
GHOST_SystemWayland *system_;
struct GWL_Window *window_;
bool is_debug_context_;
GHOST_GPUDevice preferred_device_;
/**

View File

@@ -59,12 +59,11 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
uint32_t height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
bool wantStereoVisual,
const GHOST_ContextParams &context_params,
GHOST_WindowWin32 *parentwindow,
bool is_debug,
bool dialog,
const GHOST_GPUDevice &preferred_device)
: GHOST_Window(width, height, state, wantStereoVisual, false),
: GHOST_Window(width, height, state, context_params, false),
m_mousePresent(false),
m_inLiveResize(false),
m_system(system),
@@ -83,8 +82,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_normal_state(GHOST_kWindowStateNormal),
m_user32(::LoadLibrary("user32.dll")),
m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : HWND_DESKTOP),
m_directManipulationHelper(nullptr),
m_debug_context(is_debug)
m_directManipulationHelper(nullptr)
{
DWORD style = parentwindow ?
WS_POPUPWINDOW | WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX :
@@ -622,7 +620,7 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty
#ifdef WITH_VULKAN_BACKEND
case GHOST_kDrawingContextTypeVulkan: {
GHOST_Context *context = new GHOST_ContextVK(
false, m_hWnd, 1, 2, m_debug_context, m_preferred_device);
m_want_context_params, m_hWnd, 1, 2, m_preferred_device);
if (context->initializeDrawingContext()) {
return context;
}
@@ -635,14 +633,14 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty
case GHOST_kDrawingContextTypeOpenGL: {
for (int minor = 6; minor >= 3; --minor) {
GHOST_Context *context = new GHOST_ContextWGL(
m_wantStereoVisual,
m_want_context_params,
false,
m_hWnd,
m_hDC,
WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
4,
minor,
(m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
(m_want_context_params.is_debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
if (context->initializeDrawingContext()) {
@@ -655,7 +653,7 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty
#endif
case GHOST_kDrawingContextTypeD3D: {
GHOST_Context *context = new GHOST_ContextD3D(false, m_hWnd);
GHOST_Context *context = new GHOST_ContextD3D(m_want_context_params, m_hWnd);
if (context->initializeDrawingContext()) {
return context;

View File

@@ -76,9 +76,8 @@ class GHOST_WindowWin32 : public GHOST_Window {
uint32_t height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
bool wantStereoVisual,
const GHOST_ContextParams &context_params,
GHOST_WindowWin32 *parentWindow,
bool is_debug,
bool dialog,
const GHOST_GPUDevice &preferred_device);
@@ -417,5 +416,4 @@ class GHOST_WindowWin32 : public GHOST_Window {
/** Handle input method editors event */
GHOST_ImeWin32 m_imeInput;
#endif
bool m_debug_context;
};

View File

@@ -110,11 +110,10 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
GHOST_WindowX11 *parentWindow,
GHOST_TDrawingContextType type,
const bool is_dialog,
const bool stereoVisual,
const GHOST_ContextParams &context_params,
const bool exclusive,
const bool is_debug,
const GHOST_GPUDevice &preferred_device)
: GHOST_Window(width, height, state, stereoVisual, exclusive),
: GHOST_Window(width, height, state, context_params, exclusive),
m_display(display),
m_visualInfo(nullptr),
m_fbconfig(nullptr),
@@ -132,7 +131,6 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
m_xic(nullptr),
#endif
m_valid_setup(false),
m_is_debug_context(is_debug),
m_preferred_device(preferred_device)
{
#ifdef WITH_OPENGL_BACKEND
@@ -1190,7 +1188,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
switch (type) {
#ifdef WITH_VULKAN_BACKEND
case GHOST_kDrawingContextTypeVulkan: {
GHOST_Context *context = new GHOST_ContextVK(m_wantStereoVisual,
GHOST_Context *context = new GHOST_ContextVK(m_want_context_params,
GHOST_kVulkanPlatformX11,
m_window,
m_display,
@@ -1199,7 +1197,6 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
nullptr,
1,
2,
m_is_debug_context,
m_preferred_device);
if (context->initializeDrawingContext()) {
return context;
@@ -1216,14 +1213,14 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
for (int minor = 6; minor >= 3; --minor) {
GHOST_Context *context = GHOST_ContextEGL(
this->m_system,
m_wantStereoVisual,
m_want_context_params,
EGLNativeWindowType(m_window),
EGLNativeDisplayType(m_display),
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
4,
minor,
GHOST_OPENGL_EGL_CONTEXT_FLAGS |
(m_is_debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
(m_want_context_params.is_debug ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
EGL_OPENGL_API);
if (context->initializeDrawingContext()) {
@@ -1236,14 +1233,15 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
for (int minor = 6; minor >= 3; --minor) {
GHOST_Context *context = new GHOST_ContextGLX(
m_wantStereoVisual,
m_want_context_params,
m_window,
m_display,
(GLXFBConfig)m_fbconfig,
GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
4,
minor,
GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
GHOST_OPENGL_GLX_CONTEXT_FLAGS |
(m_want_context_params.is_debug ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
if (context->initializeDrawingContext()) {
return context;

View File

@@ -44,7 +44,7 @@ class GHOST_WindowX11 : public GHOST_Window {
* \param state: The state the window is initially opened with.
* \param parentWindow: Parent (embedder) window.
* \param type: The type of drawing context installed in this window.
* \param stereoVisual: Stereo visual for quad buffered stereo.
* \param context_params: Parameters to use when initializing the context.
* \param preferred_device: Preferred device to use when new device will be created.
*/
GHOST_WindowX11(GHOST_SystemX11 *system,
@@ -58,9 +58,8 @@ class GHOST_WindowX11 : public GHOST_Window {
GHOST_WindowX11 *parentWindow,
GHOST_TDrawingContextType type,
const bool is_dialog,
const bool stereoVisual,
const GHOST_ContextParams &context_params,
const bool exclusive,
const bool is_debug,
const GHOST_GPUDevice &preferred_device);
bool getValid() const override;
@@ -241,7 +240,6 @@ class GHOST_WindowX11 : public GHOST_Window {
#endif
bool m_valid_setup;
bool m_is_debug_context;
GHOST_GPUDevice m_preferred_device;
void icccmSetState(int state);

View File

@@ -46,6 +46,18 @@ void GPU_backend_type_selection_set_override(eGPUBackendType backend_type);
*/
bool GPU_backend_type_selection_is_overridden();
/**
* Get the VSync value (when set).
*/
int GPU_backend_vsync_get();
/**
* Override the default VSync.
*
* \param vsync: See #GHOST_TVSyncModes for details.
*/
void GPU_backend_vsync_set_override(int vsync);
bool GPU_backend_vsync_is_overridden();
/** Opaque type hiding blender::gpu::Context. */
struct GPUContext;

View File

@@ -343,6 +343,7 @@ void GPU_render_step(bool force_resource_release)
static eGPUBackendType g_backend_type = GPU_BACKEND_OPENGL;
static std::optional<eGPUBackendType> g_backend_type_override = std::nullopt;
static std::optional<bool> g_backend_type_supported = std::nullopt;
static std::optional<int> g_vsync_override = std::nullopt;
static GPUBackend *g_backend = nullptr;
static GHOST_SystemHandle g_ghost_system = nullptr;
@@ -362,6 +363,21 @@ void GPU_backend_type_selection_set(const eGPUBackendType backend)
g_backend_type_supported = std::nullopt;
}
int GPU_backend_vsync_get()
{
return g_vsync_override.value();
}
void GPU_backend_vsync_set_override(const int vsync)
{
g_vsync_override = vsync;
}
bool GPU_backend_vsync_is_overridden()
{
return g_vsync_override.has_value();
}
eGPUBackendType GPU_backend_type_selection_get()
{
return g_backend_type;

View File

@@ -1596,6 +1596,10 @@ static GHOST_WindowHandle playanim_window_open(
gpusettings.preferred_device.index = U.gpu_preferred_index;
gpusettings.preferred_device.vendor_id = U.gpu_preferred_vendor_id;
gpusettings.preferred_device.device_id = U.gpu_preferred_device_id;
if (GPU_backend_vsync_is_overridden()) {
gpusettings.flags |= GHOST_gpuVSyncIsOverridden;
gpusettings.vsync = GHOST_TVSyncModes(GPU_backend_vsync_get());
}
{
bool screen_size_valid = false;

View File

@@ -880,6 +880,10 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm,
gpuSettings.preferred_device.index = U.gpu_preferred_index;
gpuSettings.preferred_device.vendor_id = U.gpu_preferred_vendor_id;
gpuSettings.preferred_device.device_id = U.gpu_preferred_device_id;
if (GPU_backend_vsync_is_overridden()) {
gpuSettings.flags |= GHOST_gpuVSyncIsOverridden;
gpuSettings.vsync = GHOST_TVSyncModes(GPU_backend_vsync_get());
}
int posx = 0;
int posy = 0;
@@ -3160,6 +3164,10 @@ void *WM_system_gpu_context_create()
gpuSettings.preferred_device.index = U.gpu_preferred_index;
gpuSettings.preferred_device.vendor_id = U.gpu_preferred_vendor_id;
gpuSettings.preferred_device.device_id = U.gpu_preferred_device_id;
if (GPU_backend_vsync_is_overridden()) {
gpuSettings.flags |= GHOST_gpuVSyncIsOverridden;
gpuSettings.vsync = GHOST_TVSyncModes(GPU_backend_vsync_get());
}
return GHOST_CreateGPUContext(g_system, gpuSettings);
}

View File

@@ -784,6 +784,7 @@ static void print_help(bArgs *ba, bool all)
PRINT("\n");
PRINT("GPU Options:\n");
BLI_args_print_arg_doc(ba, "--gpu-backend");
BLI_args_print_arg_doc(ba, "--gpu-vsync");
if (defs.with_opengl_backend) {
BLI_args_print_arg_doc(ba, "--gpu-compilation-subprocesses");
}
@@ -871,9 +872,6 @@ static void print_help(bArgs *ba, bool all)
PRINT(" $BLENDER_CUSTOM_SPLASH Full path to an image that replaces the splash screen.\n");
PRINT(
" $BLENDER_CUSTOM_SPLASH_BANNER Full path to an image to overlay on the splash screen.\n");
PRINT(
" $BLENDER_VSYNC Set to 0 to disable VSync.\n"
" With OpenGL, other values set the swap interval.\n");
if (defs.with_opencolorio) {
PRINT(" $OCIO Path to override the OpenColorIO configuration file.\n");
@@ -1614,6 +1612,44 @@ static int arg_handle_gpu_backend_set(int argc, const char **argv, void * /*data
return 1;
}
static const char arg_handle_gpu_vsync_set_doc[] =
"\n"
"\tSet the VSync.\n"
"\tValid options are: 'on', 'off' & 'auto' for adaptive sync.\n"
"\n"
"\t* The default settings depend on the GPU driver.\n"
"\t* Disabling VSync can be useful for testing performance.\n"
"\t* 'auto' is only supported by the OpenGL backend.";
static int arg_handle_gpu_vsync_set(int argc, const char **argv, void * /*data*/)
{
const char *arg_id = "--gpu-vsync";
if (argc < 2) {
fprintf(stderr, "\nError: VSync value must follow '%s'.\n", arg_id);
return 0;
}
/* Must be compatible with #GHOST_TVSyncModes. */
int vsync;
if (STREQ(argv[1], "on")) {
vsync = 1;
}
else if (STREQ(argv[1], "off")) {
vsync = 0;
}
else if (STREQ(argv[1], "auto")) {
vsync = -1;
}
else {
fprintf(stderr, "\nError: expected a value in [on, off, auto] '%s %s'.\n", arg_id, argv[1]);
return 0;
}
GPU_backend_vsync_set_override(vsync);
return 1;
}
static const char arg_handle_gpu_compilation_subprocesses_set_doc[] =
"\n"
"\tOverride the Max Compilation Subprocesses setting (OpenGL only).";
@@ -2758,6 +2794,7 @@ void main_args_setup(bContext *C, bArgs *ba, bool all)
/* GPU backend selection should be part of #ARG_PASS_ENVIRONMENT for correct GPU context
* selection for animation player. */
BLI_args_add(ba, nullptr, "--gpu-backend", CB_ALL(arg_handle_gpu_backend_set), nullptr);
BLI_args_add(ba, nullptr, "--gpu-vsync", CB(arg_handle_gpu_vsync_set), nullptr);
if (defs.with_opengl_backend) {
BLI_args_add(ba,
nullptr,