mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 07:53:51 +00:00
Improved swapchain format handling.
This commit is contained in:
parent
24d90ec54d
commit
8671611ed5
8 changed files with 89 additions and 28 deletions
|
@ -148,6 +148,11 @@ namespace MWVR
|
|||
return impl().selectDepthFormat();
|
||||
}
|
||||
|
||||
void OpenXRManager::eraseFormat(int64_t format)
|
||||
{
|
||||
return impl().eraseFormat(format);
|
||||
}
|
||||
|
||||
void
|
||||
OpenXRManager::CleanupOperation::operator()(
|
||||
osg::GraphicsContext* gc)
|
||||
|
|
|
@ -106,6 +106,9 @@ namespace MWVR
|
|||
//! Returns 0 if no format is supported.
|
||||
int64_t selectDepthFormat();
|
||||
|
||||
//! Erase format from list of format candidates
|
||||
void eraseFormat(int64_t format);
|
||||
|
||||
OpenXRManagerImpl& impl() { return *mPrivate; }
|
||||
const OpenXRManagerImpl& impl() const { return *mPrivate; }
|
||||
|
||||
|
|
|
@ -646,6 +646,11 @@ namespace MWVR
|
|||
return mPlatform.selectDepthFormat();
|
||||
}
|
||||
|
||||
void OpenXRManagerImpl::eraseFormat(int64_t format)
|
||||
{
|
||||
mPlatform.eraseFormat(format);
|
||||
}
|
||||
|
||||
void OpenXRManagerImpl::enablePredictions()
|
||||
{
|
||||
mPredictionsEnabled = true;
|
||||
|
|
|
@ -66,6 +66,7 @@ namespace MWVR
|
|||
PFN_xrVoidFunction xrGetFunction(const std::string& name);
|
||||
int64_t selectColorFormat();
|
||||
int64_t selectDepthFormat();
|
||||
void eraseFormat(int64_t format);
|
||||
OpenXRPlatform& platform() { return mPlatform; };
|
||||
|
||||
protected:
|
||||
|
|
|
@ -625,6 +625,18 @@ namespace MWVR
|
|||
}
|
||||
}
|
||||
|
||||
void OpenXRPlatform::eraseFormat(int64_t format)
|
||||
{
|
||||
for (auto it = mSwapchainFormats.begin(); it != mSwapchainFormats.end(); it++)
|
||||
{
|
||||
if (*it == format)
|
||||
{
|
||||
mSwapchainFormats.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int64_t OpenXRPlatform::selectFormat(const std::vector<int64_t>& requestedFormats)
|
||||
{
|
||||
auto it =
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace MWVR
|
|||
int64_t selectColorFormat();
|
||||
int64_t selectDepthFormat();
|
||||
int64_t selectFormat(const std::vector<int64_t>& requestedFormats);
|
||||
void eraseFormat(int64_t format);
|
||||
std::vector<int64_t> mSwapchainFormats{};
|
||||
|
||||
/// Registers an object for sharing as if calling wglDXRegisterObjectNV requesting write access.
|
||||
|
|
|
@ -113,23 +113,6 @@ namespace MWVR {
|
|||
{
|
||||
auto* xr = Environment::get().getManager();
|
||||
|
||||
// Select a swapchain format.
|
||||
if (use == Use::COLOR)
|
||||
mFormat = xr->selectColorFormat();
|
||||
else
|
||||
mFormat = xr->selectDepthFormat();
|
||||
std::string typeString = use == Use::COLOR ? "color" : "depth";
|
||||
|
||||
if (mFormat == 0) {
|
||||
throw std::runtime_error(std::string("Swapchain ") + typeString + " format not supported");
|
||||
}
|
||||
Log(Debug::Verbose) << "Selected " << typeString << " format: " << std::dec << mFormat << " (" << std::hex << mFormat << ")" << std::dec;
|
||||
|
||||
if (xr->xrExtensionIsEnabled(XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME))
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
XrSwapchainCreateInfo swapchainCreateInfo{ XR_TYPE_SWAPCHAIN_CREATE_INFO };
|
||||
swapchainCreateInfo.arraySize = 1;
|
||||
swapchainCreateInfo.width = mWidth;
|
||||
|
@ -137,18 +120,40 @@ namespace MWVR {
|
|||
swapchainCreateInfo.mipCount = 1;
|
||||
swapchainCreateInfo.faceCount = 1;
|
||||
|
||||
while (mSamples > 0 && mSwapchain == XR_NULL_HANDLE)
|
||||
while (mSamples > 0 && mSwapchain == XR_NULL_HANDLE && mFormat == 0)
|
||||
{
|
||||
// Select a swapchain format.
|
||||
if (use == Use::COLOR)
|
||||
mFormat = xr->selectColorFormat();
|
||||
else
|
||||
mFormat = xr->selectDepthFormat();
|
||||
std::string typeString = use == Use::COLOR ? "color" : "depth";
|
||||
if (mFormat == 0) {
|
||||
throw std::runtime_error(std::string("Swapchain ") + typeString + " format not supported");
|
||||
}
|
||||
Log(Debug::Verbose) << "Selected " << typeString << " format: " << std::dec << mFormat << " (" << std::hex << mFormat << ")" << std::dec;
|
||||
|
||||
// Now create the swapchain
|
||||
Log(Debug::Verbose) << "Creating swapchain with dimensions Width=" << mWidth << " Heigh=" << mHeight << " SampleCount=" << mSamples;
|
||||
// First create the swapchain of color buffers.
|
||||
swapchainCreateInfo.format = mFormat;
|
||||
swapchainCreateInfo.sampleCount = mSamples;
|
||||
if(use == Use::COLOR)
|
||||
swapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
if(mUsage == Use::COLOR)
|
||||
swapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
else
|
||||
swapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
swapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
auto res = xrCreateSwapchain(xr->impl().xrSession(), &swapchainCreateInfo, &mSwapchain);
|
||||
if (!XR_SUCCEEDED(res))
|
||||
|
||||
// Check errors and try again if possible
|
||||
if (res == XR_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED)
|
||||
{
|
||||
// We only try swapchain formats enumerated by the runtime itself.
|
||||
// This does not guarantee that that swapchain format is going to be supported for this specific usage.
|
||||
Log(Debug::Verbose) << "Failed to create swapchain with Format=" << mFormat<< ": " << XrResultString(res);
|
||||
xr->eraseFormat(mFormat);
|
||||
mFormat = 0;
|
||||
continue;
|
||||
}
|
||||
else if (!XR_SUCCEEDED(res))
|
||||
{
|
||||
Log(Debug::Verbose) << "Failed to create swapchain with SampleCount=" << mSamples << ": " << XrResultString(res);
|
||||
mSamples /= 2;
|
||||
|
@ -216,9 +221,38 @@ namespace MWVR {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRSwapchainImpl::SwapchainPrivate::checkAcquired() const
|
||||
{
|
||||
if (!isAcquired())
|
||||
throw std::logic_error("Swapchain must be acquired before use. Call between OpenXRSwapchain::beginFrame() and OpenXRSwapchain::endFrame()");
|
||||
}
|
||||
|
||||
XrSwapchain OpenXRSwapchainImpl::xrSwapchain(void) const
|
||||
{
|
||||
if(mSwapchain)
|
||||
return mSwapchain->xrSwapchain();
|
||||
return XR_NULL_HANDLE;
|
||||
}
|
||||
|
||||
XrSwapchain OpenXRSwapchainImpl::xrSwapchainDepth(void) const
|
||||
{
|
||||
if (mSwapchainDepth)
|
||||
return mSwapchainDepth->xrSwapchain();
|
||||
return XR_NULL_HANDLE;
|
||||
}
|
||||
|
||||
XrSwapchainSubImage OpenXRSwapchainImpl::xrSubImage(void) const
|
||||
{
|
||||
if (mSwapchain)
|
||||
return mSwapchain->xrSubImage();
|
||||
return XrSwapchainSubImage{ XR_NULL_HANDLE };
|
||||
}
|
||||
|
||||
XrSwapchainSubImage OpenXRSwapchainImpl::xrSubImageDepth(void) const
|
||||
{
|
||||
if (mSwapchainDepth)
|
||||
return mSwapchainDepth->xrSubImage();
|
||||
return XrSwapchainSubImage{ XR_NULL_HANDLE };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace MWVR
|
|||
int32_t mWidth = -1;
|
||||
int32_t mHeight = -1;
|
||||
int32_t mSamples = -1;
|
||||
int64_t mFormat = -1;
|
||||
int64_t mFormat = 0;
|
||||
uint32_t mAcquiredIndex{ 0 };
|
||||
Use mUsage;
|
||||
bool mIsIndexAcquired{ false };
|
||||
|
@ -62,10 +62,10 @@ namespace MWVR
|
|||
void endFrame(osg::GraphicsContext* gc, VRFramebuffer& readBuffer);
|
||||
|
||||
bool isAcquired() const;
|
||||
XrSwapchain xrSwapchain(void) const { return mSwapchain->xrSwapchain(); };
|
||||
XrSwapchain xrSwapchainDepth(void) const { return mSwapchainDepth->xrSwapchain(); };
|
||||
XrSwapchainSubImage xrSubImage(void) const { return mSwapchain->xrSubImage(); };
|
||||
XrSwapchainSubImage xrSubImageDepth(void) const { return mSwapchainDepth->xrSubImage(); };
|
||||
XrSwapchain xrSwapchain(void) const;
|
||||
XrSwapchain xrSwapchainDepth(void) const;
|
||||
XrSwapchainSubImage xrSubImage(void) const;
|
||||
XrSwapchainSubImage xrSubImageDepth(void) const;
|
||||
int width() const { return mConfig.selectedWidth; };
|
||||
int height() const { return mConfig.selectedHeight; };
|
||||
int samples() const { return mConfig.selectedSamples; };
|
||||
|
|
Loading…
Reference in a new issue