VR: Properly support outputting sRGB swapchain buffers
Latest SteamVR OpenXR updates brought OpenGL support, but only with sRGB buffers. I think for DirectX it's the same now. It's not a big issue for us to use sRGB buffers, so that's what I will do for now. That way we shouldn't need hardcoded exceptions for specific runtimes that don't transform linear buffers correctly.
This commit is contained in:
parent
5cfbc722d0
commit
b468023aa1
Notes:
blender-bot
2023-06-12 00:52:52 +02:00
Referenced by issue #78043, VR not working with Steam anymore because no supported swapchain formats found Referenced by issue #77348, Blender LTS: Maintenance Task 2.83
|
@ -56,7 +56,8 @@ class GHOST_IXrGraphicsBinding {
|
|||
std::string *r_requirement_info) const = 0;
|
||||
virtual void initFromGhostContext(class GHOST_Context *ghost_ctx) = 0;
|
||||
virtual bool chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
|
||||
int64_t *r_result) const = 0;
|
||||
int64_t &r_result,
|
||||
bool &r_is_rgb_format) const = 0;
|
||||
virtual std::vector<XrSwapchainImageBaseHeader *> createSwapchainImages(
|
||||
uint32_t image_count) = 0;
|
||||
virtual void submitToSwapchainImage(XrSwapchainImageBaseHeader *swapchain_image,
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
static bool choose_swapchain_format_from_candidates(std::vector<int64_t> gpu_binding_formats,
|
||||
std::vector<int64_t> runtime_formats,
|
||||
int64_t *r_result)
|
||||
int64_t &r_result)
|
||||
{
|
||||
if (gpu_binding_formats.empty()) {
|
||||
return false;
|
||||
|
@ -50,7 +50,7 @@ static bool choose_swapchain_format_from_candidates(std::vector<int64_t> gpu_bin
|
|||
return false;
|
||||
}
|
||||
|
||||
*r_result = *res;
|
||||
r_result = *res;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -132,10 +132,20 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
|
|||
}
|
||||
|
||||
bool chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
|
||||
int64_t *r_result) const override
|
||||
int64_t &r_result,
|
||||
bool &r_is_srgb_format) const override
|
||||
{
|
||||
std::vector<int64_t> gpu_binding_formats = {GL_RGBA8};
|
||||
return choose_swapchain_format_from_candidates(gpu_binding_formats, runtime_formats, r_result);
|
||||
std::vector<int64_t> gpu_binding_formats = {
|
||||
GL_RGBA8,
|
||||
GL_SRGB8_ALPHA8,
|
||||
};
|
||||
|
||||
if (choose_swapchain_format_from_candidates(gpu_binding_formats, runtime_formats, r_result)) {
|
||||
r_is_srgb_format = (r_result == GL_SRGB8_ALPHA8);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<XrSwapchainImageBaseHeader *> createSwapchainImages(uint32_t image_count) override
|
||||
|
@ -248,10 +258,19 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
|
|||
}
|
||||
|
||||
bool chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
|
||||
int64_t *r_result) const override
|
||||
int64_t &r_result,
|
||||
bool &r_is_srgb_format) const override
|
||||
{
|
||||
std::vector<int64_t> gpu_binding_formats = {DXGI_FORMAT_R8G8B8A8_UNORM};
|
||||
return choose_swapchain_format_from_candidates(gpu_binding_formats, runtime_formats, r_result);
|
||||
std::vector<int64_t> gpu_binding_formats = {
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
|
||||
};
|
||||
|
||||
if (choose_swapchain_format_from_candidates(gpu_binding_formats, runtime_formats, r_result)) {
|
||||
r_is_srgb_format = (r_result == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<XrSwapchainImageBaseHeader *> createSwapchainImages(uint32_t image_count) override
|
||||
|
|
|
@ -375,15 +375,6 @@ static void ghost_xr_draw_view_info_from_view(const XrView &view, GHOST_XrDrawVi
|
|||
r_info.fov.angle_down = view.fov.angleDown;
|
||||
}
|
||||
|
||||
static bool ghost_xr_draw_view_expects_srgb_buffer(const GHOST_XrContext *context)
|
||||
{
|
||||
/* Monado seems to be faulty and doesn't do OETF transform correctly. So expect a SRGB buffer to
|
||||
* compensate. You get way too dark rendering without this, it's pretty obvious (even in the
|
||||
* default startup scene). */
|
||||
GHOST_TXrOpenXRRuntimeID runtime_id = context->getOpenXRRuntimeID();
|
||||
return (runtime_id == OPENXR_RUNTIME_MONADO) || (runtime_id == OPENXR_RUNTIME_STEAMVR);
|
||||
}
|
||||
|
||||
void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
|
||||
XrCompositionLayerProjectionView &r_proj_layer_view,
|
||||
XrSpaceLocation &view_location,
|
||||
|
@ -398,7 +389,7 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
|
|||
r_proj_layer_view.fov = view.fov;
|
||||
swapchain.updateCompositionLayerProjectViewSubImage(r_proj_layer_view.subImage);
|
||||
|
||||
draw_view_info.expects_srgb_buffer = ghost_xr_draw_view_expects_srgb_buffer(m_context);
|
||||
draw_view_info.expects_srgb_buffer = swapchain.isBufferSRGB();
|
||||
draw_view_info.ofsx = r_proj_layer_view.subImage.imageRect.offset.x;
|
||||
draw_view_info.ofsy = r_proj_layer_view.subImage.imageRect.offset.y;
|
||||
draw_view_info.width = r_proj_layer_view.subImage.imageRect.extent.width;
|
||||
|
|
|
@ -68,7 +68,7 @@ GHOST_XrSwapchain::GHOST_XrSwapchain(GHOST_IXrGraphicsBinding &gpu_binding,
|
|||
"Failed to get swapchain image formats.");
|
||||
assert(swapchain_formats.size() == format_count);
|
||||
|
||||
if (!gpu_binding.chooseSwapchainFormat(swapchain_formats, &chosen_format)) {
|
||||
if (!gpu_binding.chooseSwapchainFormat(swapchain_formats, chosen_format, m_is_srgb_buffer)) {
|
||||
throw GHOST_XrException(
|
||||
"Error: No format matching OpenXR runtime supported swapchain formats found.");
|
||||
}
|
||||
|
@ -132,6 +132,11 @@ void GHOST_XrSwapchain::updateCompositionLayerProjectViewSubImage(XrSwapchainSub
|
|||
r_sub_image.imageRect.extent = {m_image_width, m_image_height};
|
||||
}
|
||||
|
||||
bool GHOST_XrSwapchain::isBufferSRGB()
|
||||
{
|
||||
return m_is_srgb_buffer;
|
||||
}
|
||||
|
||||
void GHOST_XrSwapchain::releaseImage()
|
||||
{
|
||||
XrSwapchainImageReleaseInfo release_info = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO};
|
||||
|
|
|
@ -38,9 +38,12 @@ class GHOST_XrSwapchain {
|
|||
|
||||
void updateCompositionLayerProjectViewSubImage(XrSwapchainSubImage &r_sub_image);
|
||||
|
||||
bool isBufferSRGB();
|
||||
|
||||
private:
|
||||
std::unique_ptr<OpenXRSwapchainData> m_oxr; /* Could use stack, but PImpl is preferable. */
|
||||
int32_t m_image_width, m_image_height;
|
||||
bool m_is_srgb_buffer = false;
|
||||
};
|
||||
|
||||
#endif // GHOST_XRSWAPCHAIN_H
|
||||
|
|
Loading…
Reference in New Issue