Add stereo support for DirectX12 and Vulkan backends
Change-Id: Id12723d6c392e25935ccb265c58af91aff968984 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
parent
91dcc76fc1
commit
1eb15adee3
@ -7228,10 +7228,9 @@ QRhiResource::Type QRhiSwapChain::resourceType() const
|
||||
is backed by two color buffers, one for each eye, instead of just one.
|
||||
|
||||
When stereoscopic rendering is not supported, the return value will be
|
||||
the default target. For the time being the only backends and 3D API where traditional
|
||||
stereoscopic rendering is supported are OpenGL (excluding OpenGL ES) and Direct3D 11, in
|
||||
the default target. It is supported by all hardware backends except for Metal, in
|
||||
combination with \l QSurfaceFormat::StereoBuffers, assuming it is supported
|
||||
by the graphics and display driver stack at run time. All other backends
|
||||
by the graphics and display driver stack at run time. Metal and Null backends
|
||||
are going to return the default render target from this overload.
|
||||
|
||||
\note the value must not be cached and reused between frames
|
||||
|
@ -1497,6 +1497,16 @@ QRhi::FrameOpResult QRhiD3D12::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginF
|
||||
swapChainD->rtWrapper.d.dsv = swapChainD->ds ? swapChainD->ds->dsv.cpuHandle
|
||||
: D3D12_CPU_DESCRIPTOR_HANDLE { 0 };
|
||||
|
||||
if (swapChainD->stereo) {
|
||||
swapChainD->rtWrapperRight.d.rtv[0] = swapChainD->sampleDesc.Count > 1
|
||||
? swapChainD->msaaRtvs[swapChainD->currentBackBufferIndex].cpuHandle
|
||||
: swapChainD->rtvsRight[swapChainD->currentBackBufferIndex].cpuHandle;
|
||||
|
||||
swapChainD->rtWrapperRight.d.dsv =
|
||||
swapChainD->ds ? swapChainD->ds->dsv.cpuHandle : D3D12_CPU_DESCRIPTOR_HANDLE{ 0 };
|
||||
}
|
||||
|
||||
|
||||
// Time to release things that are marked for currentFrameSlot since due to
|
||||
// the wait above we know that the previous commands on the GPU for this
|
||||
// slot must have finished already.
|
||||
@ -5970,6 +5980,7 @@ int QD3D12SwapChainRenderTarget::sampleCount() const
|
||||
QD3D12SwapChain::QD3D12SwapChain(QRhiImplementation *rhi)
|
||||
: QRhiSwapChain(rhi),
|
||||
rtWrapper(rhi, this),
|
||||
rtWrapperRight(rhi, this),
|
||||
cbWrapper(rhi)
|
||||
{
|
||||
}
|
||||
@ -6026,6 +6037,8 @@ void QD3D12SwapChain::releaseBuffers()
|
||||
for (UINT i = 0; i < BUFFER_COUNT; ++i) {
|
||||
rhiD->resourcePool.remove(colorBuffers[i]);
|
||||
rhiD->rtvPool.release(rtvs[i], 1);
|
||||
if (stereo)
|
||||
rhiD->rtvPool.release(rtvsRight[i], 1);
|
||||
if (!msaaBuffers[i].isNull())
|
||||
rhiD->resourcePool.remove(msaaBuffers[i]);
|
||||
if (msaaRtvs[i].isValid())
|
||||
@ -6060,6 +6073,11 @@ QRhiRenderTarget *QD3D12SwapChain::currentFrameRenderTarget()
|
||||
return &rtWrapper;
|
||||
}
|
||||
|
||||
QRhiRenderTarget *QD3D12SwapChain::currentFrameRenderTarget(StereoTargetBuffer targetBuffer)
|
||||
{
|
||||
return !stereo || targetBuffer == StereoTargetBuffer::LeftBuffer ? &rtWrapper : &rtWrapperRight;
|
||||
}
|
||||
|
||||
QSize QD3D12SwapChain::surfacePixelSize()
|
||||
{
|
||||
Q_ASSERT(m_window);
|
||||
@ -6191,6 +6209,7 @@ bool QD3D12SwapChain::createOrResize()
|
||||
HWND hwnd = reinterpret_cast<HWND>(window->winId());
|
||||
HRESULT hr;
|
||||
QRHI_RES_RHI(QRhiD3D12);
|
||||
stereo = m_window->format().stereo() && rhiD->dxgiFactory->IsWindowedStereoEnabled();
|
||||
|
||||
if (m_flags.testFlag(SurfaceHasPreMulAlpha) || m_flags.testFlag(SurfaceHasNonPreMulAlpha)) {
|
||||
if (rhiD->ensureDirectCompositionDevice()) {
|
||||
@ -6233,6 +6252,7 @@ bool QD3D12SwapChain::createOrResize()
|
||||
desc.Flags = swapChainFlags;
|
||||
desc.Scaling = DXGI_SCALING_NONE;
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
desc.Stereo = stereo;
|
||||
|
||||
if (dcompVisual) {
|
||||
// With DirectComposition setting AlphaMode to STRAIGHT fails the
|
||||
@ -6342,6 +6362,16 @@ bool QD3D12SwapChain::createOrResize()
|
||||
rtvDesc.Format = srgbAdjustedColorFormat;
|
||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||
rhiD->dev->CreateRenderTargetView(colorBuffer, &rtvDesc, rtvs[i].cpuHandle);
|
||||
|
||||
if (stereo) {
|
||||
rtvsRight[i] = rhiD->rtvPool.allocate(1);
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {};
|
||||
rtvDesc.Format = srgbAdjustedColorFormat;
|
||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
|
||||
rtvDesc.Texture2DArray.ArraySize = 1;
|
||||
rtvDesc.Texture2DArray.FirstArraySlice = 1;
|
||||
rhiD->dev->CreateRenderTargetView(colorBuffer, &rtvDesc, rtvsRight[i].cpuHandle);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_depthStencil && m_depthStencil->sampleCount() != m_sampleCount) {
|
||||
@ -6414,6 +6444,15 @@ bool QD3D12SwapChain::createOrResize()
|
||||
rtD->d.colorAttCount = 1;
|
||||
rtD->d.dsAttCount = m_depthStencil ? 1 : 0;
|
||||
|
||||
rtWrapperRight.setRenderPassDescriptor(m_renderPassDesc);
|
||||
QD3D12SwapChainRenderTarget *rtDr = QRHI_RES(QD3D12SwapChainRenderTarget, &rtWrapperRight);
|
||||
rtDr->d.rp = QRHI_RES(QD3D12RenderPassDescriptor, m_renderPassDesc);
|
||||
rtDr->d.pixelSize = pixelSize;
|
||||
rtDr->d.dpr = float(window->devicePixelRatio());
|
||||
rtDr->d.sampleCount = int(sampleDesc.Count);
|
||||
rtDr->d.colorAttCount = 1;
|
||||
rtDr->d.dsAttCount = m_depthStencil ? 1 : 0;
|
||||
|
||||
if (needsRegistration) {
|
||||
rhiD->swapchains.insert(this);
|
||||
rhiD->registerResource(this);
|
||||
|
@ -972,6 +972,7 @@ struct QD3D12SwapChain : public QRhiSwapChain
|
||||
|
||||
QRhiCommandBuffer *currentFrameCommandBuffer() override;
|
||||
QRhiRenderTarget *currentFrameRenderTarget() override;
|
||||
QRhiRenderTarget *currentFrameRenderTarget(StereoTargetBuffer targetBuffer) override;
|
||||
|
||||
QSize surfacePixelSize() override;
|
||||
bool isFormatSupported(Format f) override;
|
||||
@ -991,6 +992,7 @@ struct QD3D12SwapChain : public QRhiSwapChain
|
||||
QSize pixelSize;
|
||||
UINT swapInterval = 1;
|
||||
UINT swapChainFlags = 0;
|
||||
BOOL stereo = false;
|
||||
DXGI_FORMAT colorFormat;
|
||||
DXGI_FORMAT srgbAdjustedColorFormat;
|
||||
DXGI_COLOR_SPACE_TYPE hdrColorSpace;
|
||||
@ -999,12 +1001,14 @@ struct QD3D12SwapChain : public QRhiSwapChain
|
||||
static const UINT BUFFER_COUNT = 3;
|
||||
QD3D12ObjectHandle colorBuffers[BUFFER_COUNT];
|
||||
QD3D12Descriptor rtvs[BUFFER_COUNT];
|
||||
QD3D12Descriptor rtvsRight[BUFFER_COUNT];
|
||||
DXGI_SAMPLE_DESC sampleDesc;
|
||||
QD3D12ObjectHandle msaaBuffers[BUFFER_COUNT];
|
||||
QD3D12Descriptor msaaRtvs[BUFFER_COUNT];
|
||||
QD3D12RenderBuffer *ds = nullptr;
|
||||
UINT currentBackBufferIndex = 0;
|
||||
QD3D12SwapChainRenderTarget rtWrapper;
|
||||
QD3D12SwapChainRenderTarget rtWrapperRight;
|
||||
QD3D12CommandBuffer cbWrapper;
|
||||
|
||||
struct FrameResources {
|
||||
|
@ -1592,9 +1592,16 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
|
||||
if (swapChainD->supportsReadback && swapChainD->m_flags.testFlag(QRhiSwapChain::UsedAsTransferSource))
|
||||
usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
|
||||
const bool stereo = bool(swapChainD->m_window) && (swapChainD->m_window->format().stereo())
|
||||
&& surfaceCaps.maxImageArrayLayers > 1;
|
||||
swapChainD->stereo = stereo;
|
||||
|
||||
VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
if (swapChainD->m_flags.testFlag(QRhiSwapChain::NoVSync)) {
|
||||
if (swapChainD->supportedPresentationModes.contains(VK_PRESENT_MODE_MAILBOX_KHR))
|
||||
// Stereo has a weird bug, when using VK_PRESENT_MODE_MAILBOX_KHR,
|
||||
// black screen is shown, but there is no validation error.
|
||||
// Detected on Windows, with NVidia RTX A series (at least 4000 and 6000) driver 535.98
|
||||
if (swapChainD->supportedPresentationModes.contains(VK_PRESENT_MODE_MAILBOX_KHR) && !stereo)
|
||||
presentMode = VK_PRESENT_MODE_MAILBOX_KHR;
|
||||
else if (swapChainD->supportedPresentationModes.contains(VK_PRESENT_MODE_IMMEDIATE_KHR))
|
||||
presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||
@ -1618,7 +1625,7 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
|
||||
swapChainInfo.imageFormat = swapChainD->colorFormat;
|
||||
swapChainInfo.imageColorSpace = swapChainD->colorSpace;
|
||||
swapChainInfo.imageExtent = VkExtent2D { uint32_t(swapChainD->pixelSize.width()), uint32_t(swapChainD->pixelSize.height()) };
|
||||
swapChainInfo.imageArrayLayers = 1;
|
||||
swapChainInfo.imageArrayLayers = stereo ? 2u : 1u;
|
||||
swapChainInfo.imageUsage = usage;
|
||||
swapChainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
swapChainInfo.preTransform = preTransform;
|
||||
@ -1680,7 +1687,9 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
|
||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
|
||||
swapChainD->imageRes.resize(swapChainD->bufferCount);
|
||||
// Double up for stereo
|
||||
swapChainD->imageRes.resize(swapChainD->bufferCount * (stereo ? 2u : 1u));
|
||||
|
||||
for (int i = 0; i < swapChainD->bufferCount; ++i) {
|
||||
QVkSwapChain::ImageResources &image(swapChainD->imageRes[i]);
|
||||
image.image = swapChainImages[i];
|
||||
@ -1708,6 +1717,36 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
|
||||
|
||||
image.lastUse = QVkSwapChain::ImageResources::ScImageUseNone;
|
||||
}
|
||||
if (stereo) {
|
||||
for (int i = 0; i < swapChainD->bufferCount; ++i) {
|
||||
QVkSwapChain::ImageResources &image(swapChainD->imageRes[i + swapChainD->bufferCount]);
|
||||
image.image = swapChainImages[i];
|
||||
if (swapChainD->samples > VK_SAMPLE_COUNT_1_BIT) {
|
||||
image.msaaImage = msaaImages[i];
|
||||
image.msaaImageView = msaaViews[i];
|
||||
}
|
||||
|
||||
VkImageViewCreateInfo imgViewInfo = {};
|
||||
imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
imgViewInfo.image = swapChainImages[i];
|
||||
imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
imgViewInfo.format = swapChainD->colorFormat;
|
||||
imgViewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
|
||||
imgViewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||
imgViewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
|
||||
imgViewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
|
||||
imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
imgViewInfo.subresourceRange.baseArrayLayer = 1;
|
||||
imgViewInfo.subresourceRange.levelCount = imgViewInfo.subresourceRange.layerCount = 1;
|
||||
err = df->vkCreateImageView(dev, &imgViewInfo, nullptr, &image.imageView);
|
||||
if (err != VK_SUCCESS) {
|
||||
qWarning("Failed to create swapchain image view %d: %d", i, err);
|
||||
return false;
|
||||
}
|
||||
|
||||
image.lastUse = QVkSwapChain::ImageResources::ScImageUseNone;
|
||||
}
|
||||
}
|
||||
|
||||
swapChainD->currentImageIndex = 0;
|
||||
|
||||
@ -1775,7 +1814,7 @@ void QRhiVulkan::releaseSwapChainResources(QRhiSwapChain *swapChain)
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < swapChainD->bufferCount; ++i) {
|
||||
for (int i = 0; i < swapChainD->bufferCount * (swapChainD->stereo ? 2 : 1); ++i) {
|
||||
QVkSwapChain::ImageResources &image(swapChainD->imageRes[i]);
|
||||
if (image.fb) {
|
||||
df->vkDestroyFramebuffer(dev, image.fb, nullptr);
|
||||
@ -1907,6 +1946,12 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin
|
||||
QVkSwapChain::ImageResources &image(swapChainD->imageRes[swapChainD->currentImageIndex]);
|
||||
swapChainD->rtWrapper.d.fb = image.fb;
|
||||
|
||||
if (swapChainD->stereo) {
|
||||
QVkSwapChain::ImageResources &image(
|
||||
swapChainD->imageRes[swapChainD->currentImageIndex + swapChainD->bufferCount]);
|
||||
swapChainD->rtWrapperRight.d.fb = image.fb;
|
||||
}
|
||||
|
||||
prepareNewFrame(&swapChainD->cbWrapper);
|
||||
|
||||
// Read the timestamps for the previous frame for this slot.
|
||||
@ -7443,6 +7488,7 @@ const QRhiNativeHandles *QVkCommandBuffer::nativeHandles()
|
||||
QVkSwapChain::QVkSwapChain(QRhiImplementation *rhi)
|
||||
: QRhiSwapChain(rhi),
|
||||
rtWrapper(rhi, this),
|
||||
rtWrapperRight(rhi, this),
|
||||
cbWrapper(rhi)
|
||||
{
|
||||
}
|
||||
@ -7485,6 +7531,11 @@ QRhiRenderTarget *QVkSwapChain::currentFrameRenderTarget()
|
||||
return &rtWrapper;
|
||||
}
|
||||
|
||||
QRhiRenderTarget *QVkSwapChain::currentFrameRenderTarget(StereoTargetBuffer targetBuffer)
|
||||
{
|
||||
return !stereo || targetBuffer == StereoTargetBuffer::LeftBuffer ? &rtWrapper : &rtWrapperRight;
|
||||
}
|
||||
|
||||
QSize QVkSwapChain::surfacePixelSize()
|
||||
{
|
||||
if (!ensureSurface())
|
||||
@ -7735,6 +7786,55 @@ bool QVkSwapChain::createOrResize()
|
||||
}
|
||||
}
|
||||
|
||||
if (stereo) {
|
||||
rtWrapperRight.setRenderPassDescriptor(
|
||||
m_renderPassDesc); // for the public getter in QRhiRenderTarget
|
||||
rtWrapperRight.d.rp = QRHI_RES(QVkRenderPassDescriptor, m_renderPassDesc);
|
||||
Q_ASSERT(rtWrapperRight.d.rp && rtWrapperRight.d.rp->rp);
|
||||
|
||||
rtWrapperRight.d.pixelSize = pixelSize;
|
||||
rtWrapperRight.d.dpr = float(window->devicePixelRatio());
|
||||
rtWrapperRight.d.sampleCount = samples;
|
||||
rtWrapperRight.d.colorAttCount = 1;
|
||||
if (m_depthStencil) {
|
||||
rtWrapperRight.d.dsAttCount = 1;
|
||||
ds = QRHI_RES(QVkRenderBuffer, m_depthStencil);
|
||||
} else {
|
||||
rtWrapperRight.d.dsAttCount = 0;
|
||||
ds = nullptr;
|
||||
}
|
||||
if (samples > VK_SAMPLE_COUNT_1_BIT)
|
||||
rtWrapperRight.d.resolveAttCount = 1;
|
||||
else
|
||||
rtWrapperRight.d.resolveAttCount = 0;
|
||||
|
||||
for (int i = 0; i < bufferCount; ++i) {
|
||||
QVkSwapChain::ImageResources &image(imageRes[i + bufferCount]);
|
||||
VkImageView views[3] = {
|
||||
// color, ds, resolve
|
||||
samples > VK_SAMPLE_COUNT_1_BIT ? image.msaaImageView : image.imageView,
|
||||
ds ? ds->imageView : VK_NULL_HANDLE,
|
||||
samples > VK_SAMPLE_COUNT_1_BIT ? image.imageView : VK_NULL_HANDLE
|
||||
};
|
||||
|
||||
VkFramebufferCreateInfo fbInfo = {};
|
||||
fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
fbInfo.renderPass = rtWrapperRight.d.rp->rp;
|
||||
fbInfo.attachmentCount = uint32_t(rtWrapperRight.d.colorAttCount + rtWrapperRight.d.dsAttCount
|
||||
+ rtWrapperRight.d.resolveAttCount);
|
||||
fbInfo.pAttachments = views;
|
||||
fbInfo.width = uint32_t(pixelSize.width());
|
||||
fbInfo.height = uint32_t(pixelSize.height());
|
||||
fbInfo.layers = 1;
|
||||
|
||||
VkResult err = rhiD->df->vkCreateFramebuffer(rhiD->dev, &fbInfo, nullptr, &image.fb);
|
||||
if (err != VK_SUCCESS) {
|
||||
qWarning("Failed to create framebuffer: %d", err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frameCount = 0;
|
||||
|
||||
if (needsRegistration)
|
||||
|
@ -572,6 +572,7 @@ struct QVkSwapChain : public QRhiSwapChain
|
||||
|
||||
QRhiCommandBuffer *currentFrameCommandBuffer() override;
|
||||
QRhiRenderTarget *currentFrameRenderTarget() override;
|
||||
QRhiRenderTarget *currentFrameRenderTarget(StereoTargetBuffer targetBuffer) override;
|
||||
|
||||
QSize surfacePixelSize() override;
|
||||
bool isFormatSupported(Format f) override;
|
||||
@ -586,6 +587,7 @@ struct QVkSwapChain : public QRhiSwapChain
|
||||
QWindow *window = nullptr;
|
||||
QSize pixelSize;
|
||||
bool supportsReadback = false;
|
||||
bool stereo = false;
|
||||
VkSwapchainKHR sc = VK_NULL_HANDLE;
|
||||
int bufferCount = 0;
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
@ -597,6 +599,7 @@ struct QVkSwapChain : public QRhiSwapChain
|
||||
QVarLengthArray<VkPresentModeKHR, 8> supportedPresentationModes;
|
||||
VkDeviceMemory msaaImageMem = VK_NULL_HANDLE;
|
||||
QVkSwapChainRenderTarget rtWrapper;
|
||||
QVkSwapChainRenderTarget rtWrapperRight;
|
||||
QVkCommandBuffer cbWrapper;
|
||||
|
||||
struct ImageResources {
|
||||
|
@ -22,7 +22,7 @@ int main(int argc, char **argv)
|
||||
|
||||
QSurfaceFormat::setDefaultFormat(fmt);
|
||||
|
||||
Window w;
|
||||
Window w{QRhi::Vulkan};
|
||||
w.resize(1280, 720);
|
||||
w.setTitle(QCoreApplication::applicationName());
|
||||
w.show();
|
||||
|
@ -8,9 +8,25 @@
|
||||
#include <rhi/qshader.h>
|
||||
#include "../shared/cube.h"
|
||||
|
||||
Window::Window()
|
||||
Window::Window(QRhi::Implementation graphicsApi)
|
||||
:m_graphicsApi(graphicsApi)
|
||||
{
|
||||
setSurfaceType(OpenGLSurface);
|
||||
switch (graphicsApi) {
|
||||
default:
|
||||
case QRhi::OpenGLES2:
|
||||
setSurfaceType(OpenGLSurface);
|
||||
break;
|
||||
case QRhi::Vulkan:
|
||||
instance.setLayers({ "VK_LAYER_KHRONOS_validation" });
|
||||
instance.create();
|
||||
setVulkanInstance(&instance);
|
||||
setSurfaceType(VulkanSurface);
|
||||
break;
|
||||
case QRhi::D3D11:
|
||||
case QRhi::D3D12:
|
||||
setSurfaceType(Direct3DSurface);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Window::exposeEvent(QExposeEvent *)
|
||||
@ -57,11 +73,42 @@ void Window::init()
|
||||
{
|
||||
QRhi::Flags rhiFlags = QRhi::EnableDebugMarkers;
|
||||
|
||||
m_fallbackSurface.reset(QRhiGles2InitParams::newFallbackSurface());
|
||||
QRhiGles2InitParams params;
|
||||
params.fallbackSurface = m_fallbackSurface.get();
|
||||
params.window = this;
|
||||
m_rhi.reset(QRhi::create(QRhi::OpenGLES2, ¶ms, rhiFlags));
|
||||
switch (m_graphicsApi) {
|
||||
case QRhi::Vulkan:
|
||||
{
|
||||
QRhiVulkanInitParams params;
|
||||
params.window = this;
|
||||
params.inst = vulkanInstance();
|
||||
m_rhi.reset(QRhi::create(QRhi::Vulkan, ¶ms, rhiFlags));
|
||||
break;
|
||||
}
|
||||
case QRhi::Null:
|
||||
case QRhi::Metal:
|
||||
case QRhi::OpenGLES2:
|
||||
{
|
||||
m_fallbackSurface.reset(QRhiGles2InitParams::newFallbackSurface());
|
||||
QRhiGles2InitParams params;
|
||||
params.fallbackSurface = m_fallbackSurface.get();
|
||||
params.window = this;
|
||||
m_rhi.reset(QRhi::create(QRhi::OpenGLES2, ¶ms, rhiFlags));
|
||||
break;
|
||||
}
|
||||
case QRhi::D3D11:
|
||||
{
|
||||
QRhiD3D11InitParams params;
|
||||
m_rhi.reset(QRhi::create(QRhi::D3D11, ¶ms, rhiFlags));
|
||||
break;
|
||||
}
|
||||
case QRhi::D3D12:
|
||||
{
|
||||
QRhiD3D12InitParams params;
|
||||
params.enableDebugLayer = true;
|
||||
m_rhi.reset(QRhi::create(QRhi::D3D12, ¶ms, rhiFlags));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_sc.reset(m_rhi->newSwapChain());
|
||||
m_ds.reset(m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil,
|
||||
|
@ -11,17 +11,19 @@
|
||||
class Window : public QWindow
|
||||
{
|
||||
public:
|
||||
Window();
|
||||
Window(QRhi::Implementation graphicsApi);
|
||||
|
||||
void releaseSwapChain();
|
||||
|
||||
protected:
|
||||
QVulkanInstance instance;
|
||||
std::unique_ptr<QOffscreenSurface> m_fallbackSurface;
|
||||
std::unique_ptr<QRhi> m_rhi;
|
||||
std::unique_ptr<QRhiSwapChain> m_sc;
|
||||
std::unique_ptr<QRhiRenderBuffer> m_ds;
|
||||
std::unique_ptr<QRhiRenderPassDescriptor> m_rp;
|
||||
|
||||
QRhi::Implementation m_graphicsApi;
|
||||
bool m_hasSwapChain = false;
|
||||
QMatrix4x4 m_proj;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user