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
969214c6
Commit
969214c6
authored
Nov 25, 2018
by
Laszlo Agocs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Start getting the readback api into shape
parent
75bda640
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
100 additions
and
25 deletions
+100
-25
examples/rhi/offscreen_vulkan/main.cpp
examples/rhi/offscreen_vulkan/main.cpp
+7
-0
src/rhi/qrhi.cpp
src/rhi/qrhi.cpp
+2
-2
src/rhi/qrhi.h
src/rhi/qrhi.h
+19
-7
src/rhi/qrhi_p.h
src/rhi/qrhi_p.h
+1
-1
src/rhi/qrhid3d11.cpp
src/rhi/qrhid3d11.cpp
+2
-1
src/rhi/qrhid3d11_p.h
src/rhi/qrhid3d11_p.h
+1
-1
src/rhi/qrhigles2.cpp
src/rhi/qrhigles2.cpp
+2
-1
src/rhi/qrhigles2_p.h
src/rhi/qrhigles2_p.h
+1
-1
src/rhi/qrhimetal.mm
src/rhi/qrhimetal.mm
+2
-1
src/rhi/qrhimetal_p.h
src/rhi/qrhimetal_p.h
+1
-1
src/rhi/qrhivulkan.cpp
src/rhi/qrhivulkan.cpp
+51
-7
src/rhi/qrhivulkan_p.h
src/rhi/qrhivulkan_p.h
+10
-2
todo.txt
todo.txt
+1
-0
No files found.
examples/rhi/offscreen_vulkan/main.cpp
View file @
969214c6
...
...
@@ -103,8 +103,15 @@ int main(int argc, char **argv)
r
->
beginPass
(
rt
,
cb
,
{
0
,
1
,
0
,
1
},
{
1
,
0
},
nullptr
);
r
->
endPass
(
cb
);
QRhiReadbackDescription
rb
(
tex
);
QRhiReadbackResult
rbResult
;
r
->
readback
(
cb
,
rb
,
&
rbResult
);
qDebug
(
"Submit and wait"
);
r
->
endAndWaitOffscreenFrame
();
// here it's simple, no need to bother with the completed callback of rbResult
qDebug
()
<<
rbResult
.
data
.
size
();
}
rt
->
releaseAndDestroy
();
...
...
src/rhi/qrhi.cpp
View file @
969214c6
...
...
@@ -487,9 +487,9 @@ void QRhi::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
d
->
drawIndexed
(
cb
,
indexCount
,
instanceCount
,
firstIndex
,
vertexOffset
,
firstInstance
);
}
void
QRhi
::
readback
(
QRhiCommandBuffer
*
cb
,
QRhiReadback
*
rb
)
void
QRhi
::
readback
(
QRhiCommandBuffer
*
cb
,
const
QRhiReadback
Description
&
rb
,
QRhiReadbackResult
*
result
)
{
d
->
readback
(
cb
,
rb
);
d
->
readback
(
cb
,
rb
,
result
);
}
QVector
<
int
>
QRhi
::
supportedSampleCounts
()
const
...
...
src/rhi/qrhi.h
View file @
969214c6
...
...
@@ -45,6 +45,7 @@
#include <QVector>
#include <QImage>
#include <QtShaderTools/QBakedShader>
#include <functional>
QT_BEGIN_NAMESPACE
...
...
@@ -280,12 +281,22 @@ Q_DECLARE_TYPEINFO(QRhiTextureUploadDescription::Layer::MipLevel, Q_MOVABLE_TYPE
Q_DECLARE_TYPEINFO
(
QRhiTextureUploadDescription
::
Layer
,
Q_MOVABLE_TYPE
);
Q_DECLARE_TYPEINFO
(
QRhiTextureUploadDescription
,
Q_MOVABLE_TYPE
);
struct
Q_RHI_EXPORT
QRhiReadback
struct
Q_RHI_EXPORT
QRhiReadback
Description
{
// ###
QRhiReadbackDescription
()
{
}
QRhiReadbackDescription
(
QRhiTexture
*
texture_
)
:
texture
(
texture_
)
{
}
QRhiTexture
*
texture
=
nullptr
;
int
layer
=
0
;
int
level
=
0
;
};
Q_DECLARE_TYPEINFO
(
QRhiReadback
,
Q_MOVABLE_TYPE
);
Q_DECLARE_TYPEINFO
(
QRhiReadbackDescription
,
Q_MOVABLE_TYPE
);
struct
Q_RHI_EXPORT
QRhiReadbackResult
{
std
::
function
<
void
()
>
completed
=
nullptr
;
QByteArray
data
;
};
// non-movable due to the std::function
class
Q_RHI_EXPORT
QRhiResource
{
...
...
@@ -980,12 +991,13 @@ public:
The typical use case is to use it in completely offscreen applications,
e.g. to generate image sequences by rendering and reading back without
ever showing a window.
QRhiReadbackResult rbResult;
QRhiCommandBuffer *cb; // not owned
beginOffscreenFrame(&cb);
// ... the usual, set up a QRhiTextureRenderTarget, beginPass-endPass, etc.
readback(cb,
someTexture
, rb);
readback(cb,
rb
,
&
rb
Result
);
endAndWaitOffscreenFrame();
//
the results are
available in rb
//
image data
available in rb
Result
*/
FrameOpResult
beginOffscreenFrame
(
QRhiCommandBuffer
**
cb
);
FrameOpResult
endAndWaitOffscreenFrame
();
...
...
@@ -1037,8 +1049,8 @@ public:
quint32
instanceCount
=
1
,
quint32
firstIndex
=
0
,
qint32
vertexOffset
=
0
,
quint32
firstInstance
=
0
);
//
Must only be called outside a
begin-endPass
section
.
void
readback
(
QRhiCommandBuffer
*
cb
,
QRhiReadback
*
rb
);
//
Cannot be mixed with
begin
Pass
-endPass.
void
readback
(
QRhiCommandBuffer
*
cb
,
const
QRhiReadback
Description
&
rb
,
QRhiReadbackResult
*
result
);
QVector
<
int
>
supportedSampleCounts
()
const
;
...
...
src/rhi/qrhi_p.h
View file @
969214c6
...
...
@@ -113,7 +113,7 @@ public:
quint32
instanceCount
,
quint32
firstIndex
,
qint32
vertexOffset
,
quint32
firstInstance
)
=
0
;
virtual
void
readback
(
QRhiCommandBuffer
*
cb
,
QRhiReadback
*
rb
)
=
0
;
virtual
void
readback
(
QRhiCommandBuffer
*
cb
,
const
QRhiReadback
Description
&
rb
,
QRhiReadbackResult
*
result
)
=
0
;
virtual
QVector
<
int
>
supportedSampleCounts
()
const
=
0
;
virtual
int
ubufAlignment
()
const
=
0
;
...
...
src/rhi/qrhid3d11.cpp
View file @
969214c6
...
...
@@ -453,10 +453,11 @@ void QRhiD3D11::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
cbD
->
commands
.
append
(
cmd
);
}
void
QRhiD3D11
::
readback
(
QRhiCommandBuffer
*
cb
,
QRhiReadback
*
rb
)
void
QRhiD3D11
::
readback
(
QRhiCommandBuffer
*
cb
,
const
QRhiReadback
Description
&
rb
,
QRhiReadbackResult
*
result
)
{
Q_UNUSED
(
cb
);
Q_UNUSED
(
rb
);
Q_UNUSED
(
result
);
}
QRhi
::
FrameOpResult
QRhiD3D11
::
beginFrame
(
QRhiSwapChain
*
swapChain
)
...
...
src/rhi/qrhid3d11_p.h
View file @
969214c6
...
...
@@ -405,7 +405,7 @@ public:
quint32
instanceCount
,
quint32
firstIndex
,
qint32
vertexOffset
,
quint32
firstInstance
)
override
;
void
readback
(
QRhiCommandBuffer
*
cb
,
QRhiReadback
*
rb
)
override
;
void
readback
(
QRhiCommandBuffer
*
cb
,
const
QRhiReadback
Description
&
rb
,
QRhiReadbackResult
*
result
)
override
;
QVector
<
int
>
supportedSampleCounts
()
const
override
;
int
ubufAlignment
()
const
override
;
...
...
src/rhi/qrhigles2.cpp
View file @
969214c6
...
...
@@ -366,10 +366,11 @@ void QRhiGles2::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
cbD
->
commands
.
append
(
cmd
);
}
void
QRhiGles2
::
readback
(
QRhiCommandBuffer
*
cb
,
QRhiReadback
*
rb
)
void
QRhiGles2
::
readback
(
QRhiCommandBuffer
*
cb
,
const
QRhiReadback
Description
&
rb
,
QRhiReadbackResult
*
result
)
{
Q_UNUSED
(
cb
);
Q_UNUSED
(
rb
);
Q_UNUSED
(
result
);
}
QRhi
::
FrameOpResult
QRhiGles2
::
beginFrame
(
QRhiSwapChain
*
swapChain
)
...
...
src/rhi/qrhigles2_p.h
View file @
969214c6
...
...
@@ -363,7 +363,7 @@ public:
quint32
instanceCount
,
quint32
firstIndex
,
qint32
vertexOffset
,
quint32
firstInstance
)
override
;
void
readback
(
QRhiCommandBuffer
*
cb
,
QRhiReadback
*
rb
)
override
;
void
readback
(
QRhiCommandBuffer
*
cb
,
const
QRhiReadback
Description
&
rb
,
QRhiReadbackResult
*
result
)
override
;
QVector
<
int
>
supportedSampleCounts
()
const
override
;
int
ubufAlignment
()
const
override
;
...
...
src/rhi/qrhimetal.mm
View file @
969214c6
...
...
@@ -496,10 +496,11 @@ void QRhiMetal::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
baseInstance:
firstInstance
];
}
void
QRhiMetal
::
readback
(
QRhiCommandBuffer
*
cb
,
QRhiReadback
*
rb
)
void
QRhiMetal
::
readback
(
QRhiCommandBuffer
*
cb
,
const
QRhiReadback
Description
&
rb
,
QRhiReadbackResult
*
result
)
{
Q_UNUSED
(
cb
);
Q_UNUSED
(
rb
);
Q_UNUSED
(
result
);
}
QRhi
::
FrameOpResult
QRhiMetal
::
beginFrame
(
QRhiSwapChain
*
swapChain
)
...
...
src/rhi/qrhimetal_p.h
View file @
969214c6
...
...
@@ -294,7 +294,7 @@ public:
quint32
instanceCount
,
quint32
firstIndex
,
qint32
vertexOffset
,
quint32
firstInstance
)
override
;
void
readback
(
QRhiCommandBuffer
*
cb
,
QRhiReadback
*
rb
)
override
;
void
readback
(
QRhiCommandBuffer
*
cb
,
const
QRhiReadback
Description
&
rb
,
QRhiReadbackResult
*
result
)
override
;
QVector
<
int
>
supportedSampleCounts
()
const
override
;
int
ubufAlignment
()
const
override
;
...
...
src/rhi/qrhivulkan.cpp
View file @
969214c6
...
...
@@ -1384,11 +1384,7 @@ QRhi::FrameOpResult QRhiVulkan::endAndWaitOffscreenFrame()
submitInfo
.
pWaitDstStageMask
=
&
psf
;
err
=
df
->
vkQueueSubmit
(
gfxQueue
,
1
,
&
submitInfo
,
ofr
.
cmdFence
);
if
(
err
==
VK_SUCCESS
)
{
// wait for completion
df
->
vkWaitForFences
(
dev
,
1
,
&
ofr
.
cmdFence
,
VK_TRUE
,
UINT64_MAX
);
df
->
vkResetFences
(
dev
,
1
,
&
ofr
.
cmdFence
);
}
else
{
if
(
err
!=
VK_SUCCESS
)
{
if
(
checkDeviceLost
(
err
))
return
QRhi
::
FrameOpDeviceLost
;
else
...
...
@@ -1396,6 +1392,14 @@ QRhi::FrameOpResult QRhiVulkan::endAndWaitOffscreenFrame()
return
QRhi
::
FrameOpError
;
}
// wait for completion
df
->
vkWaitForFences
(
dev
,
1
,
&
ofr
.
cmdFence
,
VK_TRUE
,
UINT64_MAX
);
df
->
vkResetFences
(
dev
,
1
,
&
ofr
.
cmdFence
);
// Here we know that executing the host-side reads for this (or any
// previous) frame is safe since we waited for completion above.
finishActiveReadbacks
(
true
);
return
QRhi
::
FrameOpSuccess
;
}
...
...
@@ -1426,6 +1430,15 @@ void QRhiVulkan::prepareNewFrame(QRhiCommandBuffer *cb)
Q_ASSERT
(
!
inFrame
);
inFrame
=
true
;
// Now is the time to do things for frame N-F, where N is the current one,
// F is QVK_FRAMES_IN_FLIGHT, because only here it is guaranteed that that
// frame has completed on the GPU (due to the fence wait in beginFrame). To
// decide if something is safe to handle now a simple "lastActiveFrameSlot
// == currentFrameSlot" is sufficient (remember that e.g. with F==2
// currentFrameSlot goes 0, 1, 0, 1, 0, ...)
finishActiveReadbacks
();
executeDeferredReleases
();
QRHI_RES
(
QVkCommandBuffer
,
cb
)
->
resetState
();
...
...
@@ -1972,6 +1985,27 @@ void QRhiVulkan::executeDeferredReleases(bool forced)
}
}
void
QRhiVulkan
::
finishActiveReadbacks
(
bool
forced
)
{
QVarLengthArray
<
std
::
function
<
void
()
>
,
4
>
completedCallbacks
;
for
(
int
i
=
activeReadbacks
.
count
()
-
1
;
i
>=
0
;
--
i
)
{
const
QRhiVulkan
::
ActiveReadback
&
aRb
(
activeReadbacks
[
i
]);
if
(
forced
||
currentFrameSlot
==
aRb
.
activeFrameSlot
||
aRb
.
activeFrameSlot
<
0
)
{
// map and memcpy
// destroy temp buffer
if
(
aRb
.
result
->
completed
)
completedCallbacks
.
append
(
aRb
.
result
->
completed
);
activeReadbacks
.
removeAt
(
i
);
}
}
for
(
auto
f
:
completedCallbacks
)
f
();
}
static
struct
{
VkSampleCountFlagBits
mask
;
int
count
;
...
...
@@ -2315,10 +2349,20 @@ void QRhiVulkan::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
df
->
vkCmdDrawIndexed
(
QRHI_RES
(
QVkCommandBuffer
,
cb
)
->
cb
,
indexCount
,
instanceCount
,
firstIndex
,
vertexOffset
,
firstInstance
);
}
void
QRhiVulkan
::
readback
(
QRhiCommandBuffer
*
cb
,
QRhiReadback
*
rb
)
void
QRhiVulkan
::
readback
(
QRhiCommandBuffer
*
cb
,
const
QRhiReadback
Description
&
rb
,
QRhiReadbackResult
*
result
)
{
Q_UNUSED
(
cb
);
Q_UNUSED
(
rb
);
Q_ASSERT
(
inFrame
&&
!
inPass
);
// create a host visible buffer
// add a vkCmdCopyImageToBuffer
ActiveReadback
aRb
;
aRb
.
activeFrameSlot
=
currentFrameSlot
;
aRb
.
desc
=
rb
;
aRb
.
result
=
result
;
activeReadbacks
.
append
(
aRb
);
}
static
inline
VkBufferUsageFlagBits
toVkBufferUsage
(
QRhiBuffer
::
UsageFlags
usage
)
...
...
src/rhi/qrhivulkan_p.h
View file @
969214c6
...
...
@@ -356,7 +356,7 @@ public:
quint32
instanceCount
,
quint32
firstIndex
,
qint32
vertexOffset
,
quint32
firstInstance
)
override
;
void
readback
(
QRhiCommandBuffer
*
cb
,
QRhiReadback
*
rb
)
override
;
void
readback
(
QRhiCommandBuffer
*
cb
,
const
QRhiReadback
Description
&
rb
,
QRhiReadbackResult
*
result
)
override
;
QVector
<
int
>
supportedSampleCounts
()
const
override
;
int
ubufAlignment
()
const
override
;
...
...
@@ -403,6 +403,7 @@ public:
void
activateTextureRenderTarget
(
QRhiCommandBuffer
*
cb
,
QRhiTextureRenderTarget
*
rt
);
void
deactivateTextureRenderTarget
(
QRhiCommandBuffer
*
cb
,
QRhiTextureRenderTarget
*
rt
);
void
executeDeferredReleases
(
bool
forced
=
false
);
void
finishActiveReadbacks
(
bool
forced
=
false
);
void
bufferBarrier
(
QRhiCommandBuffer
*
cb
,
QRhiBuffer
*
buf
);
void
imageBarrier
(
QRhiCommandBuffer
*
cb
,
QRhiTexture
*
tex
,
...
...
@@ -415,7 +416,6 @@ public:
// in case they changed in the meantime.
void
updateShaderResourceBindings
(
QRhiShaderResourceBindings
*
srb
,
int
descSetIdx
=
-
1
);
QRhi
*
q
;
QVulkanInstance
*
inst
=
nullptr
;
QWindow
*
maybeWindow
=
nullptr
;
bool
importedDevPoolQueue
=
false
;
...
...
@@ -464,6 +464,13 @@ public:
VkFence
cmdFence
=
VK_NULL_HANDLE
;
}
ofr
;
struct
ActiveReadback
{
int
activeFrameSlot
=
-
1
;
QRhiReadbackDescription
desc
;
QRhiReadbackResult
*
result
;
};
QVector
<
ActiveReadback
>
activeReadbacks
;
struct
DeferredReleaseEntry
{
enum
Type
{
Pipeline
,
...
...
@@ -526,6 +533,7 @@ public:
Q_DECLARE_TYPEINFO
(
QRhiVulkan
::
DescriptorPoolData
,
Q_MOVABLE_TYPE
);
Q_DECLARE_TYPEINFO
(
QRhiVulkan
::
DeferredReleaseEntry
,
Q_MOVABLE_TYPE
);
Q_DECLARE_TYPEINFO
(
QRhiVulkan
::
ActiveReadback
,
Q_MOVABLE_TYPE
);
QT_END_NAMESPACE
...
...
todo.txt
View file @
969214c6
...
...
@@ -2,6 +2,7 @@ gl, mtl: compressed textures
gl, mtl: srgb (tex, swapchain buf)
rhi without a window, fully offscreen
readbacks
some wait-gpu stuff for waiting for readback results inside a begin-endFrame f.ex.?
multi window? (multi swapchain) -> trouble
vk: rendering hangs sometimes when minimize and back on some systems?
mtl: cubemaps
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment