1
0
Fork 0

osgXR: Update to 0.3.8

Update 3rdparty/osgXR to version 0.3.8, which gets us non-linear sRGB
swapchain formats by default. This avoids double gamma correction with
Monado when FlightGear renders non-linear sRGB data into linear RGB
swapchain images.
This commit is contained in:
James Hogan 2022-01-21 22:47:02 +00:00
parent fe8b7bea21
commit 276835f74c
No known key found for this signature in database
GPG key ID: 35CEE4862B1023F2
9 changed files with 516 additions and 34 deletions

View file

@ -1,3 +1,57 @@
Version 0.3.8
-------------
Highlights:
* Swapchain format preferences, allowing more formats to be chosen, and using
sRGB formats by default.
* Handle building as a CMake subproject.
New/expanded APIs:
* Settings::preferRGBEncoding(), Settings::allowRGBEncoding() - For choosing
preferred and allowed RGB encodings from linear, floating point (linear), and
sRGB (non-linear).
* Settings::preferDepthEncoding(), Settings::allowDepthEncoding() - For
choosing preferred and allowed depth encodings from linear, and floating
point.
* Settings::getRGBBits(), Settings::setRGBBits() - For choosing preferred
number of bits per RGB channel (for linear & float encodings only),
overriding the graphics window traits bit depths.
* Settings::getAlphaBits(), Settings::setAlphaBits() - For choosing preferred
number of alpha channel bits, overriding the graphics window traits bit
depths.
* Settings::getDepthBits(), Settings::setDepthBits() - For choosing preferred
number of depth channel bits, overriding the graphics window traits bit
depths.
* Settings::getStencilBits(), Settings::setStencilBits() - For choosing
preferred number of stencil channel bits, overriding the graphics window
traits bit depths.
* Settings::getPreferredRGBEncodingMask(),
Settings::setPreferredRGBEncodingMask(),
Settings::getAllowedRGBEncodingMask(),
Settings::setAllowedRGBEncodingMask() - Largely internal for directly
accessing the masks of preferred and allowed RGB encodings.
* Settings::getPreferredDepthEncodingMask(),
Settings::setPreferredDepthEncodingMask(),
Settings::getAllowedDepthEncodingMask(),
Settings::setAllowedDepthEncodingMask() - Largely internal for directly
accessing the masks of preferred and allowed depth encodings.
Documentation:
* Settings: Tweak comment wording for consistency.
Behaviour changes:
* Determine swapchain formats using new preferences specified in Settings,
using sRGB formats by default instead of linear.
* Choose a suitable depth/stencil fallback for when a depth swapchain cannot be
used.
* Enable gamma correction when rendering VR mirror to sRGB framebuffer.
Build system:
* Handle building as a subproject.
* Reduce minimum CMake version to 3.11.
* Add OSGXR\_WARNINGS option to enable compiler warnings (for development use).
* Drop osgXR\_INCLUDE\_DIR use since newer CMake handles automatically.
Version 0.3.7
-------------

View file

@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.11)
set(osgXR_MAJOR_VERSION 0)
set(osgXR_MINOR_VERSION 3)
set(osgXR_PATCH_VERSION 7)
set(osgXR_SOVERSION 5)
set(osgXR_PATCH_VERSION 8)
set(osgXR_SOVERSION 6)
set(osgXR_VERSION "${osgXR_MAJOR_VERSION}.${osgXR_MINOR_VERSION}.${osgXR_PATCH_VERSION}")
@ -22,6 +22,7 @@ if(CMAKE_PROJECT_NAME STREQUAL osgXR)
# Build options
option(BUILD_SHARED_LIBS "Whether to build as a shared library" ON)
option(BUILD_OSGXR_EXAMPLES "Enable to build osgXR examples" OFF)
option(OSGXR_WARNINGS "Enable compiler warnings for osgXR" OFF)
# Source files in src/
add_subdirectory(src)

View file

@ -41,7 +41,7 @@ Getting Started
To import osgXR into a CMake based project, you can use the included CMake
module, adding something like this to your CMakeLists.txt:
```cmake
find_package(osgXR 0.3.5 REQUIRED)
find_package(osgXR 0.3.8 REQUIRED)
target_link_libraries(target
..

View file

@ -171,7 +171,7 @@ class OSGXR_EXPORT Settings : public osg::Referenced
} BlendMode;
/**
* Specify a preferred environment blend mode.
* The chosen environment blend mode is permitted for use, and will be
* The chosen environment blend mode is allowed for use, and will be
* chosen in preference to any other supported environment blend modes
* specified by allowEnvBlendMode() if supported by OpenXR.
* @param mode Environment blend mode to prefer.
@ -183,8 +183,8 @@ class OSGXR_EXPORT Settings : public osg::Referenced
_allowedEnvBlendModeMask |= mask;
}
/**
* Specify a permitted environment blend mode.
* The chosen environment blend mode is permitted for use, and may be
* Specify an allowed environment blend mode.
* The chosen environment blend mode is allowed for use, and may be
* chosen if supported by OpenXR when none of the preferred environment
* blend modes specified by preferEnvBlenMode() are supported by OpenXR.
* @param mode Environment blend mode to prefer.
@ -204,7 +204,7 @@ class OSGXR_EXPORT Settings : public osg::Referenced
{
_preferredEnvBlendModeMask = preferredEnvBlendModeMask;
}
/// Get the bitmask of permitted environment blend modes.
/// Get the bitmask of allowed environment blend modes.
uint32_t getAllowedEnvBlendModeMask() const
{
return _allowedEnvBlendModeMask;
@ -264,6 +264,172 @@ class OSGXR_EXPORT Settings : public osg::Referenced
return _swapchainMode;
}
/// RGB(A) / depth encodings.
typedef enum Encoding
{
/** Discrete linear encoding of RGB(A).
* The OpenXR runtime may perform its own conversion from RGB to
* sRGB for display on HMD, so the app should ensure it leaves RGB
* values linear to avoid an over-bright image.
*/
ENCODING_LINEAR = 0,
/** Floating-point linear encoding of RGB(A).
* The OpenXR runtime may perform its own conversion from RGB to
* sRGB for display on HMD, so the app should ensure it leaves RGB
* values linear to avoid an over-bright image.
*/
ENCODING_FLOAT = 1,
/** Discrete non-linear sRGB encoding with linear (A).
* Linear RGB values should be converted to sRGB, for example with
* GL_FRAMEBUFFER_SRGB or via fragment shader code, as the OpenXR
* runtime will treat them as non-linear.
* Not applicable to depth/stencil swapchains.
*/
ENCODING_SRGB = 2,
} Encoding;
/**
* Specify a preferred RGB(A) encoding.
* The chosen RGB(A) encoding is allowed for use, and a format with this
* encoding will be chosen in preference to other allowed encodings
* specified by allowRGBEncoding() if possible.
* @param encoding RGB(A) encoding to prefer.
*/
void preferRGBEncoding(Encoding encoding)
{
uint32_t mask = (1u << (unsigned int)encoding);
_preferredRGBEncodingMask |= mask;
_allowedRGBEncodingMask |= mask;
}
/**
* Specify an allowed RGB(A) encoding.
* The chosen RGB(A) encoding is allowed for use, and a format with this
* encoding may be chosen when none of the preferred color encodings
* specified by preferRGBEncoding() are useable.
* @param encoding RGB(A) encoding to permit.
*/
void allowRGBEncoding(Encoding encoding)
{
uint32_t mask = (1u << (unsigned int)encoding);
_allowedRGBEncodingMask |= mask;
}
/// Get the bitmask of preferred RGB(A) encodings.
uint32_t getPreferredRGBEncodingMask() const
{
return _preferredRGBEncodingMask;
}
/// Set the bitmask of preferred RGB(A) encodings.
void setPreferredRGBEncodingMask(uint32_t preferredRGBEncodingMask)
{
_preferredRGBEncodingMask = preferredRGBEncodingMask;
}
/// Get the bitmask of allowed RGB(A) encodings.
uint32_t getAllowedRGBEncodingMask() const
{
return _allowedRGBEncodingMask;
}
/// Set the bitmask of allowed RGB(A) encodings.
void setAllowedRGBEncodingMask(uint32_t allowedRGBEncodingMask)
{
_allowedRGBEncodingMask = allowedRGBEncodingMask;
}
/**
* Specify a preferred depth encoding.
* The chosen depth encoding is allowed for use, and a format with this
* encoding will be chosen in preference to other allowed encodings
* specified by allowDepthEncoding() if possible.
* @param encoding Depth encoding to prefer.
*/
void preferDepthEncoding(Encoding encoding)
{
uint32_t mask = (1u << (unsigned int)encoding);
_preferredDepthEncodingMask |= mask;
_allowedDepthEncodingMask |= mask;
}
/**
* Specify an allowed depth encoding.
* The chosen depth encoding is allowed for use, and a format with this
* encoding may be chosen when none of the preferred color encodings
* specified by preferDepthEncoding() are useable.
* @param encoding Depth encoding to permit.
*/
void allowDepthEncoding(Encoding encoding)
{
uint32_t mask = (1u << (unsigned int)encoding);
_allowedDepthEncodingMask |= mask;
}
/// Get the bitmask of preferred depth encodings.
uint32_t getPreferredDepthEncodingMask() const
{
return _preferredDepthEncodingMask;
}
/// Set the bitmask of preferred depth encodings.
void setPreferredDepthEncodingMask(uint32_t preferredDepthEncodingMask)
{
_preferredDepthEncodingMask = preferredDepthEncodingMask;
}
/// Get the bitmask of allowed depth encodings.
uint32_t getAllowedDepthEncodingMask() const
{
return _allowedDepthEncodingMask;
}
/// Set the bitmask of allowed depth encodings.
void setAllowedDepthEncodingMask(uint32_t allowedDepthEncodingMask)
{
_allowedDepthEncodingMask = allowedDepthEncodingMask;
}
/**
* Get number of desired bits for each RGB channel in RGB(A) swapchain.
* This only applies to linear RGB formats, not sRGB formats.
*/
int getRGBBits() const
{
return _rgbBits;
}
/**
* Set number of desired bits for each RGB channel in RGB(A) swapchain.
* This only applies to linear RGB formats, not sRGB formats.
*/
void setRGBBits(int rgbBits = -1)
{
_rgbBits = rgbBits;
}
/// Get number of desired alpha bits in RGB(A) swapchain.
int getAlphaBits() const
{
return _alphaBits;
}
/// Set the number of desired alpha bits in RGB(A) swapchain.
void setAlphaBits(int alphaBits = -1)
{
_alphaBits = alphaBits;
}
/// Get number of desired depth bits in depth/stencil swapchain.
int getDepthBits() const
{
return _depthBits;
}
/// Set the number of desired depth bits in depth/stencil swapchain.
void setDepthBits(int depthBits = -1)
{
_depthBits = depthBits;
}
/// Get number of desired stencil bits in depth/stencil swapchain.
int getStencilBits() const
{
return _stencilBits;
}
/// Set the number of desired stenil bits in depth/stencil swapchain.
void setStencilBits(int stencilBits = -1)
{
_stencilBits = stencilBits;
}
/// Get mirror settings.
MirrorSettings &getMirrorSettings()
{
@ -303,8 +469,14 @@ class OSGXR_EXPORT Settings : public osg::Referenced
DIFF_BLEND_MODE = (1u << 5),
DIFF_VR_MODE = (1u << 6),
DIFF_SWAPCHAIN_MODE = (1u << 7),
DIFF_MIRROR = (1u << 8),
DIFF_SCALE = (1u << 9),
DIFF_RGB_ENCODING = (1u << 8),
DIFF_DEPTH_ENCODING = (1u << 9),
DIFF_RGB_BITS = (1u << 10),
DIFF_ALPHA_BITS = (1u << 11),
DIFF_DEPTH_BITS = (1u << 12),
DIFF_STENCIL_BITS = (1u << 13),
DIFF_MIRROR = (1u << 14),
DIFF_SCALE = (1u << 15),
} _ChangeMask;
unsigned int _diff(const Settings &other) const;
@ -333,6 +505,17 @@ class OSGXR_EXPORT Settings : public osg::Referenced
VRMode _vrMode;
SwapchainMode _swapchainMode;
// Swapchain requirements
uint32_t _preferredRGBEncodingMask;
uint32_t _allowedRGBEncodingMask;
uint32_t _preferredDepthEncodingMask;
uint32_t _allowedDepthEncodingMask;
// These default to -1: get bit depths from graphics window traits
int _rgbBits; // for linear RGB formats, per channel
int _alphaBits;
int _depthBits;
int _stencilBits;
// Mirror settings
MirrorSettings _mirrorSettings;

View file

@ -97,7 +97,20 @@ target_compile_features(osgXR
# smart pointers
PUBLIC cxx_std_11
# std::optional
PRIVATE cxx_std_17)
PRIVATE cxx_std_17
)
# Enable compiler warnings
if(OSGXR_WARNINGS)
target_compile_options(osgXR PRIVATE
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
-Wall -pedantic
-Wextra -Wno-missing-field-initializers
-Wno-unused-parameter>
$<$<CXX_COMPILER_ID:MSVC>:
/W4>
)
endif()
target_include_directories(osgXR
PRIVATE

View file

@ -127,8 +127,10 @@ void Mirror::setupQuad(unsigned int viewIndex,
osg::ref_ptr<osg::StateSet> state = quad->getOrCreateStateSet();
int forceOff = osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED;
int forceOn = osg::StateAttribute::ON | osg::StateAttribute::PROTECTED;
state->setMode(GL_LIGHTING, forceOff);
state->setMode(GL_DEPTH_TEST, forceOff);
state->setMode(GL_FRAMEBUFFER_SRGB, forceOn);
_camera->addChild(quad);

View file

@ -20,6 +20,14 @@ Settings::Settings() :
_allowedEnvBlendModeMask(0),
_vrMode(VRMODE_AUTOMATIC),
_swapchainMode(SWAPCHAIN_AUTOMATIC),
_preferredRGBEncodingMask(0),
_allowedRGBEncodingMask(0),
_preferredDepthEncodingMask(0),
_allowedDepthEncodingMask(0),
_rgbBits(-1),
_alphaBits(-1),
_depthBits(-1),
_stencilBits(-1),
_unitsPerMeter(1.0f)
{
}
@ -55,6 +63,20 @@ unsigned int Settings::_diff(const Settings &other) const
ret |= DIFF_VR_MODE;
if (_swapchainMode != other._swapchainMode)
ret |= DIFF_SWAPCHAIN_MODE;
if (_preferredRGBEncodingMask != other._preferredRGBEncodingMask ||
_allowedRGBEncodingMask != other._allowedRGBEncodingMask)
ret |= DIFF_RGB_ENCODING;
if (_preferredDepthEncodingMask != other._preferredDepthEncodingMask ||
_allowedDepthEncodingMask != other._allowedDepthEncodingMask)
ret |= DIFF_DEPTH_ENCODING;
if (_rgbBits != other._rgbBits)
ret |= DIFF_RGB_BITS;
if (_alphaBits != other._alphaBits)
ret |= DIFF_ALPHA_BITS;
if (_depthBits != other._depthBits)
ret |= DIFF_DEPTH_BITS;
if (_stencilBits != other._stencilBits)
ret |= DIFF_STENCIL_BITS;
if (_mirrorSettings != other._mirrorSettings)
ret |= DIFF_MIRROR;
if (_unitsPerMeter != other._unitsPerMeter)

View file

@ -62,7 +62,8 @@ XRState::XRSwapchain::XRSwapchain(XRState *state,
osg::ref_ptr<OpenXR::Session> session,
const OpenXR::System::ViewConfiguration::View &view,
int64_t chosenSwapchainFormat,
int64_t chosenDepthSwapchainFormat) :
int64_t chosenDepthSwapchainFormat,
GLenum fallbackDepthFormat) :
OpenXR::SwapchainGroup(session, view,
XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT,
chosenSwapchainFormat,
@ -95,6 +96,7 @@ XRState::XRSwapchain::XRSwapchain(XRState *state,
XRFramebuffer *fb = new XRFramebuffer(getWidth(),
getHeight(),
texture, depthTexture);
fb->setDepthFormat(fallbackDepthFormat);
_imageFramebuffers.push_back(fb);
}
}
@ -518,7 +520,13 @@ void XRState::syncSettings()
else if (diff & (Settings::DIFF_DEPTH_INFO |
Settings::DIFF_VISIBILITY_MASK |
Settings::DIFF_VR_MODE |
Settings::DIFF_SWAPCHAIN_MODE))
Settings::DIFF_SWAPCHAIN_MODE |
Settings::DIFF_RGB_ENCODING |
Settings::DIFF_DEPTH_ENCODING |
Settings::DIFF_RGB_BITS |
Settings::DIFF_ALPHA_BITS |
Settings::DIFF_DEPTH_BITS |
Settings::DIFF_STENCIL_BITS))
// Recreate session
setDownState(VRSTATE_SYSTEM);
}
@ -952,6 +960,14 @@ XRState::UpResult XRState::upSession()
_settingsCopy.setVisibilityMask(_settings->getVisibilityMask());
_settingsCopy.setVRMode(_settings->getVRMode());
_settingsCopy.setSwapchainMode(_settings->getSwapchainMode());
_settingsCopy.setPreferredRGBEncodingMask(_settings->getPreferredRGBEncodingMask());
_settingsCopy.setAllowedRGBEncodingMask(_settings->getAllowedRGBEncodingMask());
_settingsCopy.setPreferredDepthEncodingMask(_settings->getPreferredDepthEncodingMask());
_settingsCopy.setAllowedDepthEncodingMask(_settings->getAllowedDepthEncodingMask());
_settingsCopy.setRGBBits(_settings->getRGBBits());
_settingsCopy.setAlphaBits(_settings->getAlphaBits());
_settingsCopy.setDepthBits(_settings->getDepthBits());
_settingsCopy.setStencilBits(_settings->getStencilBits());
_useDepthInfo = _settingsCopy.getDepthInfo();
_useVisibilityMask = _settingsCopy.getVisibilityMask();
_vrMode = _settingsCopy.getVRMode();
@ -967,6 +983,31 @@ XRState::UpResult XRState::upSession()
OSG_WARN << "osgXR: VisibilityMask extension not supported, visibility masking will be disabled" << std::endl;
_useVisibilityMask = false;
}
if (_settingsCopy.getAllowedRGBEncodingMask() == 0)
{
// Play safe and default to preferring sRGB over linear/float RGB, since
// this is what apps are normally tuned for. This avoids incorrect
// behaviour in SteamVR (no gamma correction) and also correct but
// potentially unexpected behaviour in Monado (extra gamma correction of
// linear RGB framebuffer when app produces sRGBish images already).
_settingsCopy.allowRGBEncoding(Settings::ENCODING_SRGB);
}
if (_settingsCopy.getPreferredRGBEncodingMask() == 0)
{
// If no preferred RGB encodings, mark all allowed ones as preferred.
_settingsCopy.setPreferredRGBEncodingMask(_settingsCopy.getAllowedRGBEncodingMask());
}
if (_settingsCopy.getAllowedDepthEncodingMask() == 0)
{
// Default to allowing both discrete or floating point depth.
_settingsCopy.allowDepthEncoding(Settings::ENCODING_LINEAR);
_settingsCopy.allowDepthEncoding(Settings::ENCODING_FLOAT);
}
if (_settingsCopy.getPreferredDepthEncodingMask() == 0)
{
// If no preferred depth encodings, mark all allowed ones as preferred.
_settingsCopy.setPreferredDepthEncodingMask(_settingsCopy.getAllowedDepthEncodingMask());
}
// Decide on the algorithm to use. SceneView mode is faster.
if (_vrMode == VRMode::VRMODE_AUTOMATIC)
@ -1009,52 +1050,209 @@ XRState::UpResult XRState::upSession()
return UP_ABORT;
}
// Decide on ideal depth bits
unsigned int bestDepthBits = 24;
// Decide on ideal bit depths
unsigned int bestRGBBits = 24; // combined
unsigned int bestAlphaBits = 0;
unsigned int bestDepthBits = 16;
unsigned int bestStencilBits = 0;
// Use graphics window traits
auto *traits = _window->getTraits();
if (traits)
{
bestRGBBits = traits->red + traits->green + traits->blue;
bestAlphaBits = traits->alpha;
bestDepthBits = traits->depth;
bestStencilBits = traits->stencil;
}
// Override from osgXR::Settings
if (_settingsCopy.getRGBBits() >= 0)
bestRGBBits = _settingsCopy.getRGBBits() * 3;
if (_settingsCopy.getAlphaBits() >= 0)
bestAlphaBits = _settingsCopy.getAlphaBits();
if (_settingsCopy.getDepthBits() >= 0)
bestDepthBits = _settingsCopy.getDepthBits();
if (_settingsCopy.getStencilBits() >= 0)
bestStencilBits = _settingsCopy.getStencilBits();
// Choose a fallback depth format in case we can't submit depth to OpenXR
GLenum fallbackDepthFormat = 0;
if (_settingsCopy.getPreferredDepthEncodingMask() &
(1u << (unsigned int)Settings::ENCODING_LINEAR))
{
bool allowFloatDepth = _settingsCopy.getAllowedDepthEncodingMask() &
(1u << (unsigned int)Settings::ENCODING_FLOAT);
if (bestDepthBits > 24 && allowFloatDepth)
fallbackDepthFormat = bestStencilBits ? GL_DEPTH32F_STENCIL8
: GL_DEPTH_COMPONENT32F;
else if (bestStencilBits)
fallbackDepthFormat = GL_DEPTH24_STENCIL8;
else if (bestDepthBits > 16)
fallbackDepthFormat = GL_DEPTH_COMPONENT24;
else
fallbackDepthFormat = GL_DEPTH_COMPONENT16;
}
else // getPreferredDepthEncodingMask & (1 << ENCODING_FLOAT)
{
if (bestStencilBits)
fallbackDepthFormat = GL_DEPTH32F_STENCIL8;
else
fallbackDepthFormat = GL_DEPTH_COMPONENT32F;
}
// Choose a swapchain format
int64_t chosenSwapchainFormat = 0;
int64_t chosenDepthSwapchainFormat = 0;
unsigned int chosenAlphaBits = 0;
unsigned int chosenDepthBits = 0;
unsigned int chosenStencilBits = 0;
uint32_t chosenRGBSat = 0;
uint32_t chosenDepthSat = 0;
for (int64_t format: _session->getSwapchainFormats())
{
auto thisEncoding = Settings::ENCODING_LINEAR;
uint32_t encodingMask = 0;
unsigned int thisRGBBits = 0;
unsigned int thisAlphaBits = 0;
unsigned int thisDepthBits = 0;
unsigned int thisStencilBits = 0;
unsigned int thisSat = 0;
switch (format)
{
// Discrete linear RGB(A)
case GL_RGBA16:
thisRGBBits = 16 * 3;
thisAlphaBits = 16;
goto handleRGBA;
case GL_RGB10_A2:
thisRGBBits = 10 * 3;
thisAlphaBits = 2;
goto handleRGBA;
case GL_RGBA8:
// Choose the first supported format suggested by the runtime
if (!chosenSwapchainFormat)
chosenSwapchainFormat = format;
break;
thisRGBBits = 8 * 3;
thisAlphaBits = 8;
goto handleRGBA;
// Linear floating point RGB(A)
case GL_RGB16F:
thisRGBBits = 16 * 3;
thisEncoding = Settings::ENCODING_FLOAT;
goto handleRGBA;
case GL_RGBA16F:
thisRGBBits = 16 * 3;
thisEncoding = Settings::ENCODING_FLOAT;
thisAlphaBits = 16;
goto handleRGBA;
// Discrete sRGB (linear A)
case GL_SRGB8_ALPHA8:
thisEncoding = Settings::ENCODING_SRGB;
thisAlphaBits = 8;
goto handleRGBA;
case GL_SRGB8:
thisEncoding = Settings::ENCODING_SRGB;
goto handleRGBA;
// Discrete depth (stencil)
case GL_DEPTH_COMPONENT16:
thisDepthBits = 16;
goto handle_depth;
goto handleDepth;
case GL_DEPTH_COMPONENT24:
thisDepthBits = 24;
goto handle_depth;
goto handleDepth;
#if 0 // crashes nvidia (495.46, with monado)
case GL_DEPTH24_STENCIL8:
thisDepthBits = 24;
thisStencilBits = 8;
goto handleDepth;
#endif
case GL_DEPTH_COMPONENT32:
thisDepthBits = 32;
// fall through
handle_depth:
goto handleDepth;
// Floating point depth, discrete stencil
case GL_DEPTH_COMPONENT32F:
thisEncoding = Settings::ENCODING_FLOAT;
thisDepthBits = 32;
goto handleDepth;
case GL_DEPTH32F_STENCIL8:
thisEncoding = Settings::ENCODING_FLOAT;
thisDepthBits = 32;
thisStencilBits = 8;
goto handleDepth;
handleRGBA:
// Don't even consider a disallowed RGB encoding
encodingMask = (1u << (unsigned int)thisEncoding);
if (!(_settingsCopy.getAllowedRGBEncodingMask() & encodingMask))
break;
// Consider whether our preferences are satisfied
if (_settingsCopy.getPreferredRGBEncodingMask() & encodingMask)
thisSat |= 0x1;
if (thisEncoding == Settings::ENCODING_SRGB || thisRGBBits >= bestRGBBits)
thisSat |= 0x2;
if (thisAlphaBits >= bestAlphaBits)
thisSat |= 0x4;
// Skip formats that no longer satisfies some preference
if (chosenRGBSat & ~thisSat)
break;
// Decide whether to choose this format
if (// Anything is better than nothing
!chosenSwapchainFormat ||
// New preferences satisfied is always better
(~chosenRGBSat & thisSat) ||
// All else being equal, allow improved alpha bits
// A higher number of alpha bits is better than not enough
(thisAlphaBits > chosenAlphaBits && chosenAlphaBits < bestAlphaBits))
{
chosenSwapchainFormat = format;
chosenAlphaBits = thisAlphaBits;
chosenRGBSat = thisSat;
}
break;
handleDepth:
if (_useDepthInfo)
{
// Don't even consider a disallowed depth encoding
encodingMask = (1u << (unsigned int)thisEncoding);
if (!(_settingsCopy.getAllowedDepthEncodingMask() & encodingMask))
break;
// Consider whether our preferences are satisfied
if (_settingsCopy.getPreferredDepthEncodingMask() & encodingMask)
thisSat |= 0x1;
if (thisDepthBits >= bestDepthBits)
thisSat |= 0x2;
if (thisStencilBits >= bestStencilBits)
thisSat |= 0x4;
// Skip formats that no longer satisfies some preference
if (chosenDepthSat & ~thisSat)
break;
if (// Anything is better than nothing
!chosenDepthSwapchainFormat ||
// A higher number of bits is better than not enough
// New preferences satisfied is always better
(~chosenRGBSat & thisSat) ||
// A higher number of depth bits is better than not enough
(thisDepthBits > chosenDepthBits && chosenDepthBits < bestDepthBits) ||
// A lower number of bits may still be enough
(bestDepthBits < thisDepthBits && thisDepthBits < chosenDepthBits))
// A higher number of stencil bits is better than not enough
// so long as depth bits are no worse or good enough
((thisDepthBits >= chosenDepthBits || thisDepthBits >= bestDepthBits) &&
thisStencilBits > chosenStencilBits && chosenStencilBits < bestStencilBits) ||
// A lower number of depth bits may still be enough
// so long as stencil bits are no worse or good enough
((thisStencilBits >= chosenStencilBits || thisStencilBits >= bestStencilBits) &&
bestDepthBits < thisDepthBits && thisDepthBits < chosenDepthBits))
{
chosenDepthSwapchainFormat = format;
chosenDepthBits = thisDepthBits;
chosenStencilBits = thisStencilBits;
chosenDepthSat = thisSat;
}
}
break;
default:
break;
}
@ -1086,7 +1284,8 @@ XRState::UpResult XRState::upSession()
{
case SwapchainMode::SWAPCHAIN_SINGLE:
if (!setupSingleSwapchain(chosenSwapchainFormat,
chosenDepthSwapchainFormat))
chosenDepthSwapchainFormat,
fallbackDepthFormat))
{
_session = nullptr;
return UP_ABORT;
@ -1097,7 +1296,8 @@ XRState::UpResult XRState::upSession()
// Should already have been handled by upSession()
case SwapchainMode::SWAPCHAIN_MULTIPLE:
if (!setupMultipleSwapchains(chosenSwapchainFormat,
chosenDepthSwapchainFormat))
chosenDepthSwapchainFormat,
fallbackDepthFormat))
{
_session = nullptr;
return UP_ABORT;
@ -1172,7 +1372,8 @@ XRState::DownResult XRState::downActions()
return DOWN_SUCCESS;
}
bool XRState::setupSingleSwapchain(int64_t format, int64_t depthFormat)
bool XRState::setupSingleSwapchain(int64_t format, int64_t depthFormat,
GLenum fallbackDepthFormat)
{
const auto &views = _chosenViewConfig->getViews();
_xrViews.reserve(views.size());
@ -1187,7 +1388,8 @@ bool XRState::setupSingleSwapchain(int64_t format, int64_t depthFormat)
// Create a single swapchain
osg::ref_ptr<XRSwapchain> xrSwapchain = new XRSwapchain(this, _session,
singleView, format,
depthFormat);
depthFormat,
fallbackDepthFormat);
// And the views
_xrViews.reserve(views.size());
for (uint32_t i = 0; i < views.size(); ++i)
@ -1205,7 +1407,8 @@ bool XRState::setupSingleSwapchain(int64_t format, int64_t depthFormat)
return true;
}
bool XRState::setupMultipleSwapchains(int64_t format, int64_t depthFormat)
bool XRState::setupMultipleSwapchains(int64_t format, int64_t depthFormat,
GLenum fallbackDepthFormat)
{
const auto &views = _chosenViewConfig->getViews();
_xrViews.reserve(views.size());
@ -1215,7 +1418,8 @@ bool XRState::setupMultipleSwapchains(int64_t format, int64_t depthFormat)
const auto &vcView = views[i];
osg::ref_ptr<XRSwapchain> xrSwapchain = new XRSwapchain(this, _session,
vcView, format,
depthFormat);
depthFormat,
fallbackDepthFormat);
osg::ref_ptr<XRView> xrView = new XRView(this, i, xrSwapchain);
if (!xrView.valid())
{

View file

@ -62,7 +62,8 @@ class XRState : public OpenXR::EventHandler
osg::ref_ptr<OpenXR::Session> session,
const OpenXR::System::ViewConfiguration::View &view,
int64_t chosenSwapchainFormat,
int64_t chosenDepthSwapchainFormat);
int64_t chosenDepthSwapchainFormat,
GLenum fallbackDepthFormat);
// GL context must be current (for XRFramebuffer)
virtual ~XRSwapchain();
@ -502,9 +503,11 @@ class XRState : public OpenXR::EventHandler
DownResult downActions();
// Set up a single swapchain containing multiple viewports
bool setupSingleSwapchain(int64_t format, int64_t depthFormat = 0);
bool setupSingleSwapchain(int64_t format, int64_t depthFormat = 0,
GLenum fallbackDepthFormat = 0);
// Set up a swapchain for each view
bool setupMultipleSwapchains(int64_t format, int64_t depthFormat = 0);
bool setupMultipleSwapchains(int64_t format, int64_t depthFormat = 0,
GLenum fallbackDepthFormat = 0);
// Set up slave cameras
void setupSlaveCameras();
// Set up SceneView VR mode cameras