mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-10-27 14:30:25 +00:00
Fix assert on exit using KMSDRM on AMDGPU
AMDGPU disallows commits that would leave a CRTC active without the primary plane enabled. Instead of disabling the primary plane, simply restore the original state of the plane to avoid this.
This commit is contained in:
1 parent
5d813ed3df
commit
51f86caac3
2 files changed
+51
-7
No files matched your search
@@ -403,10 +403,10 @@ void DrmRenderer::cleanupRenderContext()
|
|||||||
// Ensure we're out of HDR mode
|
// Ensure we're out of HDR mode
|
||||||
setHdrMode(false);
|
setHdrMode(false);
|
||||||
|
|
||||||
// Deactivate all planes
|
// Restore active planes that we took over
|
||||||
m_PropSetter.disablePlane(m_VideoPlane);
|
m_PropSetter.restorePlane(m_VideoPlane);
|
||||||
for (int i = 0; i < Overlay::OverlayMax; i++) {
|
for (int i = 0; i < Overlay::OverlayMax; i++) {
|
||||||
m_PropSetter.disablePlane(m_OverlayPlanes[i]);
|
m_PropSetter.restorePlane(m_OverlayPlanes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Revert our changes from prepareToRender()
|
// Revert our changes from prepareToRender()
|
||||||
@@ -428,10 +428,7 @@ void DrmRenderer::cleanupRenderContext()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto &plane : m_UnusedActivePlanes) {
|
for (auto &plane : m_UnusedActivePlanes) {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
m_PropSetter.restorePlane(plane.second);
|
||||||
"Restoring previously active plane: %u",
|
|
||||||
plane.second.objectId());
|
|
||||||
m_PropSetter.restoreToInitial(plane.second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_PropSetter.apply();
|
m_PropSetter.apply();
|
||||||
|
|||||||
@@ -466,6 +466,53 @@ class DrmRenderer : public IFFmpegRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void restorePlane(const DrmPropertyMap& plane) {
|
||||||
|
if (!plane.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAtomic() && plane.property("FB_ID")->initialValue() != 0) {
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Restoring previously active plane: %u",
|
||||||
|
plane.objectId());
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard lg { m_Lock };
|
||||||
|
auto &pb = m_PlaneBuffers[plane.objectId()];
|
||||||
|
|
||||||
|
// Free any pending buffers first
|
||||||
|
if (pb.pendingFbId) {
|
||||||
|
drmModeRmFB(m_Fd, pb.pendingFbId);
|
||||||
|
pb.pendingFbId = 0;
|
||||||
|
}
|
||||||
|
if (pb.pendingDumbBuffer) {
|
||||||
|
struct drm_mode_destroy_dumb destroyBuf = {};
|
||||||
|
destroyBuf.handle = pb.pendingDumbBuffer;
|
||||||
|
drmIoctl(m_Fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroyBuf);
|
||||||
|
pb.pendingDumbBuffer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since we restore the FB_ID, remember that we need to swap
|
||||||
|
// pending buffers to current after committing in apply().
|
||||||
|
// This would normally be done in flipPlane(), but we can't
|
||||||
|
// use that here as it takes ownership of the FB.
|
||||||
|
//
|
||||||
|
// Since we cleared our pending buffers, the result is that
|
||||||
|
// apply() will free the current buffers and believe that no
|
||||||
|
// buffers are currently set. This will ensure it doesn't
|
||||||
|
// later free the restored FB_ID (which would happen if we
|
||||||
|
// used flipPlane() normally).
|
||||||
|
pb.modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore the old plane properties and FB_ID
|
||||||
|
restoreToInitial(plane);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
disablePlane(plane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The damage rect is relative to the FB
|
// The damage rect is relative to the FB
|
||||||
void damagePlane(const DrmPropertyMap& plane, const SDL_Rect& rect) {
|
void damagePlane(const DrmPropertyMap& plane, const SDL_Rect& rect) {
|
||||||
SDL_assert(m_Atomic);
|
SDL_assert(m_Atomic);
|
||||||
|
|||||||
Reference in new issue
Block a user