Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Laszlo Agocs
qtrhi
Commits
728c8fa9
Commit
728c8fa9
authored
Oct 29, 2018
by
Laszlo Agocs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revamp swapchain api
...and add the - for now - unused buildCompatibleRenderPass functions.
parent
2ee3c17d
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
176 additions
and
109 deletions
+176
-109
examples/rhi/hellominimalcrossgfxtriangle/hellominimalcrossgfxtriangle.cpp
...ominimalcrossgfxtriangle/hellominimalcrossgfxtriangle.cpp
+7
-2
examples/rhi/shared/examplewindow.cpp
examples/rhi/shared/examplewindow.cpp
+8
-2
examples/rhi/vulkanwindow/renderer.cpp
examples/rhi/vulkanwindow/renderer.cpp
+2
-1
src/rhi/qrhi.h
src/rhi/qrhi.h
+32
-6
src/rhi/qrhid3d11.cpp
src/rhi/qrhid3d11.cpp
+17
-20
src/rhi/qrhid3d11_p.h
src/rhi/qrhid3d11_p.h
+6
-6
src/rhi/qrhigles2.cpp
src/rhi/qrhigles2.cpp
+13
-18
src/rhi/qrhigles2_p.h
src/rhi/qrhigles2_p.h
+6
-6
src/rhi/qrhimetal.mm
src/rhi/qrhimetal.mm
+7
-0
src/rhi/qrhimetal_p.h
src/rhi/qrhimetal_p.h
+6
-1
src/rhi/qrhivulkan.cpp
src/rhi/qrhivulkan.cpp
+60
-40
src/rhi/qrhivulkan_p.h
src/rhi/qrhivulkan_p.h
+10
-7
todo.txt
todo.txt
+2
-0
No files found.
examples/rhi/hellominimalcrossgfxtriangle/hellominimalcrossgfxtriangle.cpp
View file @
728c8fa9
...
...
@@ -354,7 +354,12 @@ void Window::recreateSwapChain()
}
m_ds
->
build
();
m_hasSwapChain
=
m_sc
->
build
(
this
,
outputSize
,
0
,
m_ds
,
1
);
m_sc
->
setWindow
(
this
);
m_sc
->
setRequestedPixelSize
(
outputSize
);
m_sc
->
setDepthStencil
(
m_ds
);
m_hasSwapChain
=
m_sc
->
buildOrResize
();
m_swapChainChanged
=
true
;
m_elapsedMs
=
0
;
...
...
@@ -423,7 +428,7 @@ void Window::render()
// If the window got resized or got newly exposed, recreate the swapchain.
// (the newly-exposed case is not actually required by some
// platforms/backends, but f.ex. Vulkan on Windows seems to need it)
if
(
m_sc
->
requested
SizeIn
Pixel
s
()
!=
size
()
*
devicePixelRatio
()
||
m_newlyExposed
)
{
if
(
m_sc
->
requestedPixel
Size
()
!=
size
()
*
devicePixelRatio
()
||
m_newlyExposed
)
{
recreateSwapChain
();
if
(
!
m_hasSwapChain
)
return
;
...
...
examples/rhi/shared/examplewindow.cpp
View file @
728c8fa9
...
...
@@ -174,7 +174,13 @@ void ExampleWindow::recreateSwapChain()
m_ds
->
build
();
m_hasSwapChain
=
m_sc
->
build
(
this
,
outputSize
,
0
,
m_ds
,
m_triRenderer
.
sampleCount
());
m_sc
->
setWindow
(
this
);
m_sc
->
setRequestedPixelSize
(
outputSize
);
m_sc
->
setDepthStencil
(
m_ds
);
m_sc
->
setSampleCount
(
m_triRenderer
.
sampleCount
());
m_hasSwapChain
=
m_sc
->
buildOrResize
();
m_swapChainChanged
=
true
;
}
...
...
@@ -195,7 +201,7 @@ void ExampleWindow::render()
if
(
!
m_hasSwapChain
||
m_notExposed
)
return
;
if
(
m_sc
->
requested
SizeIn
Pixel
s
()
!=
size
()
*
devicePixelRatio
()
||
m_newlyExposed
)
{
if
(
m_sc
->
requestedPixel
Size
()
!=
size
()
*
devicePixelRatio
()
||
m_newlyExposed
)
{
recreateSwapChain
();
if
(
!
m_hasSwapChain
)
return
;
...
...
examples/rhi/vulkanwindow/renderer.cpp
View file @
728c8fa9
...
...
@@ -80,7 +80,8 @@ void Renderer::initResources()
void
Renderer
::
initSwapChainResources
()
{
m_sc
->
build
(
m_window
);
// this just wraps the window's swapchain
m_sc
->
setTarget
(
m_window
);
// note: very different from setWindow(m_window)
m_sc
->
buildOrResize
();
// this just wraps the qvulkanwindow's swapchain
m_triRenderer
.
initOutputDependentResources
(
m_sc
->
defaultRenderPass
(),
m_sc
->
effectiveSizeInPixels
());
}
...
...
src/rhi/qrhi.h
View file @
728c8fa9
...
...
@@ -479,6 +479,9 @@ public:
Flags
flags
()
const
{
return
m_flags
;
}
void
setFlags
(
Flags
f
)
{
m_flags
=
f
;
}
// to be called before build() with description and flags set
virtual
QRhiRenderPass
*
buildCompatibleRenderPass
()
=
0
;
// as usual, textures in desc must be built before calling build() on the rt
virtual
bool
build
()
=
0
;
...
...
@@ -710,6 +713,26 @@ public:
};
Q_DECLARE_FLAGS
(
SurfaceImportFlags
,
SurfaceImportFlag
)
QWindow
*
window
()
const
{
return
m_window
;
}
void
setWindow
(
QWindow
*
window
)
{
m_window
=
window
;
}
QSize
requestedPixelSize
()
const
{
return
m_requestedPixelSize
;
}
void
setRequestedPixelSize
(
const
QSize
&
size
)
{
m_requestedPixelSize
=
size
;
}
SurfaceImportFlags
flags
()
const
{
return
m_flags
;
}
void
setFlags
(
SurfaceImportFlags
f
)
{
m_flags
=
f
;
}
QRhiRenderBuffer
*
depthStencil
()
const
{
return
m_depthStencil
;
}
void
setDepthStencil
(
QRhiRenderBuffer
*
ds
)
{
m_depthStencil
=
ds
;
}
int
sampleCount
()
const
{
return
m_sampleCount
;
}
void
setSampleCount
(
int
samples
)
{
m_sampleCount
=
samples
;
}
// Alternatively, integrate with an existing swapchain, f.ex.
// QVulkanWindow. Other settings have no effect when this is set.
QObject
*
target
()
const
{
return
m_target
;
}
void
setTarget
(
QObject
*
obj
)
{
m_target
=
obj
;
}
virtual
QRhiCommandBuffer
*
currentFrameCommandBuffer
()
=
0
;
virtual
QRhiRenderTarget
*
currentFrameRenderTarget
()
=
0
;
virtual
const
QRhiRenderPass
*
defaultRenderPass
()
const
=
0
;
...
...
@@ -717,18 +740,21 @@ public:
// Some backends use the requested size, others ignore it and get the actual
// size on their own. Keep track of both - application logic will need the
// requested size (to do their "if qwindow->size() * dpr != req.size then
// re
build
_swapchain" logic) and the actual size as well (for all graphics
// re
size
_swapchain" logic) and the actual size as well (for all graphics
// calculations like viewport).
virtual
QSize
requestedSizeInPixels
()
const
=
0
;
virtual
QSize
effectiveSizeInPixels
()
const
=
0
;
virtual
bool
build
(
QWindow
*
window
,
const
QSize
&
requestedPixelSize
,
SurfaceImportFlags
flags
,
QRhiRenderBuffer
*
depthStencil
,
int
sampleCount
)
=
0
;
virtual
bool
build
(
QObject
*
target
)
=
0
;
// integrate with an existing swapchain, f.ex. QVulkanWindow
virtual
QRhiRenderPass
*
buildCompatibleRenderPass
()
=
0
;
virtual
bool
buildOrResize
()
=
0
;
protected:
QRhiSwapChain
(
QRhiImplementation
*
rhi
);
QWindow
*
m_window
=
nullptr
;
QSize
m_requestedPixelSize
;
SurfaceImportFlags
m_flags
;
QRhiRenderBuffer
*
m_depthStencil
=
nullptr
;
int
m_sampleCount
=
1
;
QObject
*
m_target
=
nullptr
;
void
*
m_reserved
;
};
...
...
src/rhi/qrhid3d11.cpp
View file @
728c8fa9
...
...
@@ -1170,6 +1170,7 @@ bool QD3D11Sampler::build()
return
true
;
}
// dummy, no Vulkan-style RenderPass+Framebuffer concept here
QD3D11RenderPass
::
QD3D11RenderPass
(
QRhiImplementation
*
rhi
)
:
QRhiRenderPass
(
rhi
)
{
...
...
@@ -1235,6 +1236,11 @@ void QD3D11TextureRenderTarget::release()
}
}
QRhiRenderPass
*
QD3D11TextureRenderTarget
::
buildCompatibleRenderPass
()
{
return
new
QD3D11RenderPass
(
rhi
);
}
bool
QD3D11TextureRenderTarget
::
build
()
{
if
(
rtv
[
0
]
||
dsv
)
...
...
@@ -1821,29 +1827,26 @@ const QRhiRenderPass *QD3D11SwapChain::defaultRenderPass() const
return
rt
.
renderPass
();
}
QSize
QD3D11SwapChain
::
requested
SizeInPixels
()
const
QSize
QD3D11SwapChain
::
effective
SizeInPixels
()
const
{
return
pixelSize
;
}
Q
Size
QD3D11SwapChain
::
effectiveSizeInPixels
()
const
Q
RhiRenderPass
*
QD3D11SwapChain
::
buildCompatibleRenderPass
()
{
return
pixelSize
;
return
new
QD3D11RenderPass
(
rhi
)
;
}
bool
QD3D11SwapChain
::
build
(
QWindow
*
window_
,
const
QSize
&
requestedPixelSize
,
SurfaceImportFlags
flags
,
QRhiRenderBuffer
*
depthStencil
,
int
sampleCount
)
bool
QD3D11SwapChain
::
buildOrResize
()
{
// Can be called multiple times due to window resizes - that is not the
// same as a simple release+build (as with other resources). Just need to
// resize the buffers then.
Q_ASSERT
(
!
swapChain
||
window
==
window
_
);
Q_ASSERT
(
!
swapChain
||
window
==
m_
window
);
Q_UNUSED
(
sampleCount
);
// ### MSAA
window
=
window_
;
pixelSize
=
requestedPixelSize
;
window
=
m_window
;
pixelSize
=
m_requestedPixelSize
;
QRHI_RES_RHI
(
QRhiD3D11
);
...
...
@@ -1868,9 +1871,9 @@ bool QD3D11SwapChain::build(QWindow *window_, const QSize &requestedPixelSize, S
desc
.
BufferCount
=
BUFFER_COUNT
;
desc
.
Scaling
=
DXGI_SCALING_STRETCH
;
desc
.
SwapEffect
=
DXGI_SWAP_EFFECT_FLIP_DISCARD
;
if
(
flags
.
testFlag
(
SurfaceHasPreMulAlpha
))
if
(
m_
flags
.
testFlag
(
SurfaceHasPreMulAlpha
))
desc
.
AlphaMode
=
DXGI_ALPHA_MODE_PREMULTIPLIED
;
else
if
(
flags
.
testFlag
(
SurfaceHasNonPreMulAlpha
))
else
if
(
m_
flags
.
testFlag
(
SurfaceHasNonPreMulAlpha
))
desc
.
AlphaMode
=
DXGI_ALPHA_MODE_STRAIGHT
;
desc
.
Flags
=
swapChainFlags
;
...
...
@@ -1911,20 +1914,14 @@ bool QD3D11SwapChain::build(QWindow *window_, const QSize &requestedPixelSize, S
}
currentFrame
=
0
;
ds
=
depthStencil
?
QRHI_RES
(
QD3D11RenderBuffer
,
depthStencil
)
:
nullptr
;
ds
=
m_
depthStencil
?
QRHI_RES
(
QD3D11RenderBuffer
,
m_
depthStencil
)
:
nullptr
;
QD3D11ReferenceRenderTarget
*
rtD
=
QRHI_RES
(
QD3D11ReferenceRenderTarget
,
&
rt
);
rtD
->
d
.
pixelSize
=
pixelSize
;
rtD
->
d
.
colorAttCount
=
1
;
rtD
->
d
.
dsAttCount
=
depthStencil
?
1
:
0
;
rtD
->
d
.
dsAttCount
=
m_
depthStencil
?
1
:
0
;
return
true
;
}
bool
QD3D11SwapChain
::
build
(
QObject
*
target
)
{
Q_UNUSED
(
target
);
return
false
;
}
QT_END_NAMESPACE
src/rhi/qrhid3d11_p.h
View file @
728c8fa9
...
...
@@ -140,11 +140,14 @@ struct QD3D11TextureRenderTarget : public QRhiTextureRenderTarget
{
QD3D11TextureRenderTarget
(
QRhiImplementation
*
rhi
,
const
QRhiTextureRenderTargetDescription
&
desc
,
Flags
flags
);
void
release
()
override
;
Type
type
()
const
override
;
bool
build
()
override
;
QSize
sizeInPixels
()
const
override
;
const
QRhiRenderPass
*
renderPass
()
const
override
;
QRhiRenderPass
*
buildCompatibleRenderPass
()
override
;
bool
build
()
override
;
QD3D11BasicRenderTargetData
d
;
ID3D11RenderTargetView
*
rtv
[
QD3D11BasicRenderTargetData
::
MAX_COLOR_ATTACHMENTS
];
bool
ownsDsv
=
false
;
...
...
@@ -360,13 +363,10 @@ struct QD3D11SwapChain : public QRhiSwapChain
QRhiCommandBuffer
*
currentFrameCommandBuffer
()
override
;
QRhiRenderTarget
*
currentFrameRenderTarget
()
override
;
const
QRhiRenderPass
*
defaultRenderPass
()
const
override
;
QSize
requestedSizeInPixels
()
const
override
;
QSize
effectiveSizeInPixels
()
const
override
;
bool
build
(
QWindow
*
window
,
const
QSize
&
requestedPixelSize
,
SurfaceImportFlags
flags
,
QRhiRenderBuffer
*
depthStencil
,
int
sampleCount
)
override
;
bool
build
(
QObject
*
target
)
override
;
QRhiRenderPass
*
buildCompatibleRenderPass
()
override
;
bool
buildOrResize
();
QWindow
*
window
=
nullptr
;
QSize
pixelSize
;
...
...
src/rhi/qrhigles2.cpp
View file @
728c8fa9
...
...
@@ -1225,6 +1225,7 @@ bool QGles2Sampler::build()
return
true
;
}
// dummy, no Vulkan-style RenderPass+Framebuffer concept here
QGles2RenderPass
::
QGles2RenderPass
(
QRhiImplementation
*
rhi
)
:
QRhiRenderPass
(
rhi
)
{
...
...
@@ -1285,6 +1286,11 @@ void QGles2TextureRenderTarget::release()
rhiD
->
releaseQueue
.
append
(
e
);
}
QRhiRenderPass
*
QGles2TextureRenderTarget
::
buildCompatibleRenderPass
()
{
return
new
QGles2RenderPass
(
rhi
);
}
bool
QGles2TextureRenderTarget
::
build
()
{
QRHI_RES_RHI
(
QRhiGles2
);
...
...
@@ -1544,36 +1550,25 @@ const QRhiRenderPass *QGles2SwapChain::defaultRenderPass() const
return
rt
.
renderPass
();
}
QSize
QGles2SwapChain
::
requested
SizeInPixels
()
const
QSize
QGles2SwapChain
::
effective
SizeInPixels
()
const
{
return
pixelSize
;
}
Q
Size
QGles2SwapChain
::
effectiveSizeInPixels
()
const
Q
RhiRenderPass
*
QGles2SwapChain
::
buildCompatibleRenderPass
()
{
return
pixelSize
;
return
new
QGles2RenderPass
(
rhi
)
;
}
bool
QGles2SwapChain
::
build
(
QWindow
*
window
,
const
QSize
&
requestedPixelSize
,
SurfaceImportFlags
flags
,
QRhiRenderBuffer
*
depthStencil
,
int
sampleCount
)
bool
QGles2SwapChain
::
buildOrResize
()
{
Q_UNUSED
(
flags
);
Q_UNUSED
(
sampleCount
);
surface
=
window
;
pixelSize
=
requestedPixelSize
;
surface
=
m_window
;
pixelSize
=
m_requestedPixelSize
;
rt
.
d
.
pixelSize
=
pixelSize
;
rt
.
d
.
attCount
=
depthStencil
?
2
:
1
;
rt
.
d
.
attCount
=
m_
depthStencil
?
2
:
1
;
return
true
;
}
bool
QGles2SwapChain
::
build
(
QObject
*
target
)
{
// ### some day this could support QOpenGLWindow, OpenGLWidget, ...
Q_UNUSED
(
target
);
return
false
;
}
QT_END_NAMESPACE
src/rhi/qrhigles2_p.h
View file @
728c8fa9
...
...
@@ -139,11 +139,14 @@ struct QGles2TextureRenderTarget : public QRhiTextureRenderTarget
{
QGles2TextureRenderTarget
(
QRhiImplementation
*
rhi
,
const
QRhiTextureRenderTargetDescription
&
desc
,
Flags
flags
);
void
release
()
override
;
Type
type
()
const
override
;
bool
build
()
override
;
QSize
sizeInPixels
()
const
override
;
const
QRhiRenderPass
*
renderPass
()
const
override
;
QRhiRenderPass
*
buildCompatibleRenderPass
()
override
;
bool
build
()
override
;
QGles2BasicRenderTargetData
d
;
GLuint
framebuffer
=
0
;
friend
class
QRhiGles2
;
...
...
@@ -292,13 +295,10 @@ struct QGles2SwapChain : public QRhiSwapChain
QRhiCommandBuffer
*
currentFrameCommandBuffer
()
override
;
QRhiRenderTarget
*
currentFrameRenderTarget
()
override
;
const
QRhiRenderPass
*
defaultRenderPass
()
const
override
;
QSize
requestedSizeInPixels
()
const
override
;
QSize
effectiveSizeInPixels
()
const
override
;
bool
build
(
QWindow
*
window
,
const
QSize
&
requestedPixelSize
,
SurfaceImportFlags
flags
,
QRhiRenderBuffer
*
depthStencil
,
int
sampleCount
)
override
;
bool
build
(
QObject
*
target
)
override
;
QRhiRenderPass
*
buildCompatibleRenderPass
()
override
;
bool
buildOrResize
()
override
;
QSurface
*
surface
=
nullptr
;
QSize
pixelSize
;
...
...
src/rhi/qrhimetal.mm
View file @
728c8fa9
...
...
@@ -682,6 +682,8 @@ bool QMetalSampler::build()
return
true
;
}
// dummy, no Vulkan-style RenderPass+Framebuffer concept here.
// We do have MTLRenderPassDescriptor of course, but it will be created on the fly for each pass.
QMetalRenderPass
::
QMetalRenderPass
(
QRhiImplementation
*
rhi
)
:
QRhiRenderPass
(
rhi
)
{
...
...
@@ -730,6 +732,11 @@ void QMetalTextureRenderTarget::release()
{
}
QRhiRenderPass
*
QMetalTextureRenderTarget
::
buildCompatibleRenderPass
()
{
return
new
QMetalRenderPass
(
rhi
);
}
bool
QMetalTextureRenderTarget
::
build
()
{
return
true
;
...
...
src/rhi/qrhimetal_p.h
View file @
728c8fa9
...
...
@@ -131,11 +131,14 @@ struct QMetalTextureRenderTarget : public QRhiTextureRenderTarget
{
QMetalTextureRenderTarget
(
QRhiImplementation
*
rhi
,
const
QRhiTextureRenderTargetDescription
&
desc
,
Flags
flags
);
void
release
()
override
;
Type
type
()
const
override
;
bool
build
()
override
;
QSize
sizeInPixels
()
const
override
;
const
QRhiRenderPass
*
renderPass
()
const
override
;
QRhiRenderPass
*
buildCompatibleRenderPass
()
override
;
bool
build
()
override
;
QMetalBasicRenderTargetData
d
;
friend
class
QRhiMetal
;
};
...
...
@@ -209,6 +212,8 @@ struct QMetalSwapChain : public QRhiSwapChain
QSize
requestedSizeInPixels
()
const
override
;
QSize
effectiveSizeInPixels
()
const
override
;
QRhiRenderPass
*
buildCompatibleRenderPass
()
override
;
bool
build
(
QWindow
*
window
,
const
QSize
&
requestedPixelSize
,
SurfaceImportFlags
flags
,
QRhiRenderBuffer
*
depthStencil
,
int
sampleCount
)
override
;
...
...
src/rhi/qrhivulkan.cpp
View file @
728c8fa9
...
...
@@ -764,9 +764,6 @@ bool QRhiVulkan::recreateSwapChain(VkSurfaceKHR surface, const QSize &pixelSize,
df
->
vkDeviceWaitIdle
(
dev
);
QVkSwapChain
*
swapChainD
=
QRHI_RES
(
QVkSwapChain
,
swapChain
);
swapChainD
->
requestedPixelSize
=
pixelSize
;
if
(
!
vkCreateSwapchainKHR
)
{
vkCreateSwapchainKHR
=
reinterpret_cast
<
PFN_vkCreateSwapchainKHR
>
(
f
->
vkGetDeviceProcAddr
(
dev
,
"vkCreateSwapchainKHR"
));
vkDestroySwapchainKHR
=
reinterpret_cast
<
PFN_vkDestroySwapchainKHR
>
(
f
->
vkGetDeviceProcAddr
(
dev
,
"vkDestroySwapchainKHR"
));
...
...
@@ -779,17 +776,19 @@ bool QRhiVulkan::recreateSwapChain(VkSurfaceKHR surface, const QSize &pixelSize,
}
}
VkSurfaceCapabilitiesKHR
surfaceCaps
;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR
(
physDev
,
surface
,
&
surfaceCaps
);
quint32
reqBufferCount
=
QVkSwapChain
::
DEFAULT_BUFFER_COUNT
;
if
(
surfaceCaps
.
maxImageCount
)
reqBufferCount
=
qBound
(
surfaceCaps
.
minImageCount
,
reqBufferCount
,
surfaceCaps
.
maxImageCount
);
QVkSwapChain
*
swapChainD
=
QRHI_RES
(
QVkSwapChain
,
swapChain
);
VkExtent2D
bufferSize
=
surfaceCaps
.
currentExtent
;
if
(
bufferSize
.
width
==
quint32
(
-
1
))
{
Q_ASSERT
(
bufferSize
.
height
==
quint32
(
-
1
));
bufferSize
.
width
=
swapChainD
->
requestedPixelSize
.
width
();
bufferSize
.
height
=
swapChainD
->
requestedPixelSize
.
height
();
bufferSize
.
width
=
swapChainD
->
m_
requestedPixelSize
.
width
();
bufferSize
.
height
=
swapChainD
->
m_
requestedPixelSize
.
height
();
}
swapChainD
->
effectivePixelSize
=
QSize
(
bufferSize
.
width
,
bufferSize
.
height
);
...
...
@@ -1061,7 +1060,7 @@ QRhi::FrameOpResult QRhiVulkan::beginWrapperFrame(QRhiSwapChain *swapChain)
swapChainD
->
cbWrapper
.
cb
=
w
->
currentCommandBuffer
();
swapChainD
->
rtWrapper
.
d
.
fb
=
w
->
currentFramebuffer
();
swapChainD
->
requestedPixelSize
=
swapChainD
->
effectivePixelSize
=
swapChainD
->
rtWrapper
.
d
.
pixelSize
=
w
->
swapChainImageSize
();
swapChainD
->
m_
requestedPixelSize
=
swapChainD
->
effectivePixelSize
=
swapChainD
->
rtWrapper
.
d
.
pixelSize
=
w
->
swapChainImageSize
();
currentFrameSlot
=
w
->
currentFrame
();
...
...
@@ -2809,6 +2808,25 @@ void QVkTextureRenderTarget::release()
rhiD
->
releaseQueue
.
append
(
e
);
}
QRhiRenderPass
*
QVkTextureRenderTarget
::
buildCompatibleRenderPass
()
{
QRHI_RES_RHI
(
QRhiVulkan
);
QVkRenderPass
*
rp
=
new
QVkRenderPass
(
rhi
);
const
VkFormat
dsFormat
=
m_desc
.
depthTexture
?
toVkTextureFormat
(
m_desc
.
depthTexture
->
format
())
:
rhiD
->
optimalDepthStencilFormat
();
if
(
!
rhiD
->
createOffscreenRenderPass
(
&
rp
->
rp
,
m_desc
.
colorAttachments
,
m_flags
.
testFlag
(
QRhiTextureRenderTarget
::
PreserveColorContents
),
d
.
dsAttCount
>
0
,
dsFormat
,
m_desc
.
depthTexture
!=
nullptr
))
{
delete
rp
;
return
nullptr
;
}
return
rp
;
}
bool
QVkTextureRenderTarget
::
build
()
{
if
(
d
.
fb
)
...
...
@@ -3239,24 +3257,45 @@ const QRhiRenderPass *QVkSwapChain::defaultRenderPass() const
return
rtWrapper
.
renderPass
();
}
QSize
QVkSwapChain
::
requestedSizeInPixels
()
const
{
return
requestedPixelSize
;
}
QSize
QVkSwapChain
::
effectiveSizeInPixels
()
const
{
return
effectivePixelSize
;
}
bool
QVkSwapChain
::
build
(
QWindow
*
window
,
const
QSize
&
requestedPixelSize_
,
SurfaceImportFlags
flags
,
QRhiRenderBuffer
*
depthStencil
,
int
sampleCount_
)
QRhiRenderPass
*
QVkSwapChain
::
buildCompatibleRenderPass
()
{
QRHI_RES_RHI
(
QRhiVulkan
);
QVkRenderPass
*
rp
=
new
QVkRenderPass
(
rhi
);
if
(
!
rhiD
->
createDefaultRenderPass
(
&
rp
->
rp
,
m_depthStencil
!=
nullptr
,
sampleCount
,
colorFormat
))
{
delete
rp
;
return
nullptr
;
}
return
rp
;
}
bool
QVkSwapChain
::
buildOrResize
()
{
if
(
m_target
)
{
if
(
sc
)
release
();
QVulkanWindow
*
vkw
=
qobject_cast
<
QVulkanWindow
*>
(
m_target
);
if
(
vkw
)
{
rtWrapper
.
d
.
rp
.
rp
=
vkw
->
defaultRenderPass
();
m_requestedPixelSize
=
effectivePixelSize
=
rtWrapper
.
d
.
pixelSize
=
vkw
->
swapChainImageSize
();
rtWrapper
.
d
.
colorAttCount
=
1
;
rtWrapper
.
d
.
dsAttCount
=
1
;
rtWrapper
.
d
.
msaaAttCount
=
vkw
->
sampleCountFlagBits
()
>
VK_SAMPLE_COUNT_1_BIT
?
1
:
0
;
wrapWindow
=
vkw
;
return
true
;
}
return
false
;
}
// Can be called multiple times due to window resizes - that is not the
// same as a simple release+build (as with other resources). Thus no
// release() here. See recreateSwapChain() below.
VkSurfaceKHR
surface
=
QVulkanInstance
::
surfaceForWindow
(
window
);
VkSurfaceKHR
surface
=
QVulkanInstance
::
surfaceForWindow
(
m_
window
);
if
(
!
surface
)
{
qWarning
(
"Failed to get surface for window"
);
return
false
;
...
...
@@ -3286,24 +3325,24 @@ bool QVkSwapChain::build(QWindow *window, const QSize &requestedPixelSize_, Surf
colorSpace
=
formats
[
0
].
colorSpace
;
}
sampleCount
=
rhiD
->
effectiveSampleCount
(
sampleCount
_
);
if
(
depthStencil
&&
depthStencil
->
sampleCount
()
!=
sampleCount
)
{
sampleCount
=
rhiD
->
effectiveSampleCount
(
m_
sampleCount
);
if
(
m_
depthStencil
&&
m_
depthStencil
->
sampleCount
()
!=
m_
sampleCount
)
{
qWarning
(
"Depth-stencil buffer's sampleCount (%d) does not match color buffers' sample count (%d). Expect problems."
,
depthStencil
->
sampleCount
(),
sampleCount
);
m_
depthStencil
->
sampleCount
(),
m_
sampleCount
);
}
if
(
!
rhiD
->
recreateSwapChain
(
surface
,
requestedPixelSize
_
,
flags
,
this
))
if
(
!
rhiD
->
recreateSwapChain
(
surface
,
m_
requestedPixelSize
,
m_
flags
,
this
))
return
false
;
if
(
!
rhiD
->
createDefaultRenderPass
(
&
rp
,
depthStencil
!=
nullptr
,
sampleCount
,
colorFormat
))
if
(
!
rhiD
->
createDefaultRenderPass
(
&
rp
,
m_
depthStencil
!=
nullptr
,
sampleCount
,
colorFormat
))
return
false
;
rtWrapper
.
d
.
rp
.
rp
=
rp
;
rtWrapper
.
d
.
pixelSize
=
effectivePixelSize
;
rtWrapper
.
d
.
colorAttCount
=
1
;
if
(
depthStencil
)
{
if
(
m_
depthStencil
)
{
rtWrapper
.
d
.
dsAttCount
=
1
;
ds
=
QRHI_RES
(
QVkRenderBuffer
,
depthStencil
);
ds
=
QRHI_RES
(
QVkRenderBuffer
,
m_
depthStencil
);
}
else
{
rtWrapper
.
d
.
dsAttCount
=
0
;
ds
=
nullptr
;
...
...
@@ -3341,23 +3380,4 @@ bool QVkSwapChain::build(QWindow *window, const QSize &requestedPixelSize_, Surf
return
true
;
}
bool
QVkSwapChain
::
build
(
QObject
*
target
)
{
if
(
sc
)
release
();
QVulkanWindow
*
vkw
=
qobject_cast
<
QVulkanWindow
*>
(
target
);
if
(
vkw
)
{
rtWrapper
.
d
.
rp
.
rp
=
vkw
->
defaultRenderPass
();
requestedPixelSize
=
effectivePixelSize
=
rtWrapper
.
d
.
pixelSize
=
vkw
->
swapChainImageSize
();
rtWrapper
.
d
.
colorAttCount
=
1
;
rtWrapper
.
d
.
dsAttCount
=
1
;
rtWrapper
.
d
.
msaaAttCount
=
vkw
->
sampleCountFlagBits
()
>
VK_SAMPLE_COUNT_1_BIT
?
1
:
0
;
wrapWindow
=
vkw
;
return
true
;
}
return
false
;
}
QT_END_NAMESPACE
src/rhi/qrhivulkan_p.h
View file @
728c8fa9
...
...
@@ -158,11 +158,14 @@ struct QVkTextureRenderTarget : public QRhiTextureRenderTarget
{
QVkTextureRenderTarget
(
QRhiImplementation
*
rhi
,
const
QRhiTextureRenderTargetDescription
&
desc
,
Flags
flags
);
void
release
()
override
;
Type
type
()
const
override
;
bool
build
()
override
;
QSize
sizeInPixels
()
const
override
;
const
QRhiRenderPass
*
renderPass
()
const
override
;
QRhiRenderPass
*
buildCompatibleRenderPass
()
override
;
bool
build
()
override
;
QVkBasicRenderTargetData
d
;
VkImageView
cubeFaceView
[
6
];
int
lastActiveFrameSlot
=
-
1
;
...
...
@@ -236,6 +239,8 @@ struct QVkCommandBuffer : public QRhiCommandBuffer
uint
currentPipelineGeneration
;
QRhiShaderResourceBindings
*
currentSrb
;
uint
currentSrbGeneration
;
friend
class
QRhiVulkan
;
};
struct
QVkSwapChain
:
public
QRhiSwapChain
...
...
@@ -246,19 +251,15 @@ struct QVkSwapChain : public QRhiSwapChain
QRhiCommandBuffer
*
currentFrameCommandBuffer
()
override
;
QRhiRenderTarget
*
currentFrameRenderTarget
()
override
;
const
QRhiRenderPass
*
defaultRenderPass
()
const
override
;
QSize
requestedSizeInPixels
()
const
override
;
QSize
effectiveSizeInPixels
()
const
override
;
bool
build
(
QWindow
*
window
,
const
QSize
&
requestedPixelSize
,
SurfaceImportFlags
flags
,
QRhiRenderBuffer
*
depthStencil
,
int
sampleCount
)
override
;
bool
build
(
QObject
*
target
)
override
;
QRhiRenderPass
*
buildCompatibleRenderPass
()
override
;
bool
buildOrResize
()
override
;
static
const
int
DEFAULT_BUFFER_COUNT
=
2
;
static
const
int
MAX_BUFFER_COUNT
=
3
;
QVulkanWindow
*
wrapWindow
=
nullptr
;
QSize
requestedPixelSize
;
QSize
effectivePixelSize
;
bool
supportsReadback
=
false
;
VkSwapchainKHR
sc
=
VK_NULL_HANDLE
;
...
...
@@ -294,6 +295,8 @@ struct QVkSwapChain : public QRhiSwapChain
quint32
currentImage
=
0
;
// index in imageRes
quint32
currentFrame
=
0
;
// index in frameRes
friend
class
QRhiVulkan
;
};
class
QRhiVulkan
:
public
QRhiImplementation
...
...