mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-11-17 04:56:00 +01:00
drm: reimport buffers when on a secondary gpu
This commit is contained in:
parent
8ecf8773db
commit
320a6d40a7
2 changed files with 46 additions and 13 deletions
|
@ -45,12 +45,15 @@ namespace Aquamarine {
|
||||||
public:
|
public:
|
||||||
~CDRMFB();
|
~CDRMFB();
|
||||||
|
|
||||||
static Hyprutils::Memory::CSharedPointer<CDRMFB> create(Hyprutils::Memory::CSharedPointer<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_);
|
static Hyprutils::Memory::CSharedPointer<CDRMFB> create(Hyprutils::Memory::CSharedPointer<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_, bool* isNew = nullptr);
|
||||||
|
|
||||||
void closeHandles();
|
void closeHandles();
|
||||||
// drops the buffer from KMS
|
// drops the buffer from KMS
|
||||||
void drop();
|
void drop();
|
||||||
|
|
||||||
|
// re-imports the buffer into KMS. Essentially drop and import.
|
||||||
|
void reimport();
|
||||||
|
|
||||||
uint32_t id = 0;
|
uint32_t id = 0;
|
||||||
Hyprutils::Memory::CWeakPointer<IBuffer> buffer;
|
Hyprutils::Memory::CWeakPointer<IBuffer> buffer;
|
||||||
Hyprutils::Memory::CWeakPointer<CDRMBackend> backend;
|
Hyprutils::Memory::CWeakPointer<CDRMBackend> backend;
|
||||||
|
@ -59,6 +62,7 @@ namespace Aquamarine {
|
||||||
private:
|
private:
|
||||||
CDRMFB(Hyprutils::Memory::CSharedPointer<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_);
|
CDRMFB(Hyprutils::Memory::CSharedPointer<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_);
|
||||||
uint32_t submitBuffer();
|
uint32_t submitBuffer();
|
||||||
|
void import();
|
||||||
|
|
||||||
bool dropped = false, handlesClosed = false;
|
bool dropped = false, handlesClosed = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -192,15 +192,13 @@ std::vector<SP<CDRMBackend>> Aquamarine::CDRMBackend::attempt(SP<CBackend> backe
|
||||||
backend->log(AQ_LOG_DEBUG, std::format("drm: Found {} GPUs", gpus.size()));
|
backend->log(AQ_LOG_DEBUG, std::format("drm: Found {} GPUs", gpus.size()));
|
||||||
|
|
||||||
std::vector<SP<CDRMBackend>> backends;
|
std::vector<SP<CDRMBackend>> backends;
|
||||||
SP<CDRMBackend> primary;
|
SP<CDRMBackend> newPrimary;
|
||||||
|
|
||||||
for (auto& gpu : gpus) {
|
for (auto& gpu : gpus) {
|
||||||
auto drmBackend = SP<CDRMBackend>(new CDRMBackend(backend));
|
auto drmBackend = SP<CDRMBackend>(new CDRMBackend(backend));
|
||||||
drmBackend->self = drmBackend;
|
drmBackend->self = drmBackend;
|
||||||
if (primary)
|
|
||||||
drmBackend->primary = primary;
|
|
||||||
|
|
||||||
if (!drmBackend->registerGPU(gpu)) {
|
if (!drmBackend->registerGPU(gpu, newPrimary)) {
|
||||||
backend->log(AQ_LOG_ERROR, std::format("drm: Failed to register gpu {}", gpu->path));
|
backend->log(AQ_LOG_ERROR, std::format("drm: Failed to register gpu {}", gpu->path));
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else
|
||||||
|
@ -225,9 +223,9 @@ std::vector<SP<CDRMBackend>> Aquamarine::CDRMBackend::attempt(SP<CBackend> backe
|
||||||
|
|
||||||
drmBackend->scanConnectors();
|
drmBackend->scanConnectors();
|
||||||
|
|
||||||
if (!primary) {
|
if (!newPrimary) {
|
||||||
backend->log(AQ_LOG_DEBUG, std::format("drm: gpu {} becomes primary drm", gpu->path));
|
backend->log(AQ_LOG_DEBUG, std::format("drm: gpu {} becomes primary drm", gpu->path));
|
||||||
primary = drmBackend;
|
newPrimary = drmBackend;
|
||||||
}
|
}
|
||||||
|
|
||||||
backends.emplace_back(drmBackend);
|
backends.emplace_back(drmBackend);
|
||||||
|
@ -441,7 +439,9 @@ bool Aquamarine::CDRMBackend::registerGPU(SP<CSessionDevice> gpu_, SP<CDRMBacken
|
||||||
|
|
||||||
gpuName = drmName;
|
gpuName = drmName;
|
||||||
|
|
||||||
backend->log(AQ_LOG_DEBUG, std::format("drm: Starting backend for {}, with driver {}", drmName ? drmName : "unknown", drmVer->name ? drmVer->name : "unknown"));
|
backend->log(AQ_LOG_DEBUG,
|
||||||
|
std::format("drm: Starting backend for {}, with driver {}{}", drmName ? drmName : "unknown", drmVer->name ? drmVer->name : "unknown",
|
||||||
|
(primary ? std::format(" with primary {}", primary->gpu->path) : "")));
|
||||||
|
|
||||||
drmFreeVersion(drmVer);
|
drmFreeVersion(drmVer);
|
||||||
|
|
||||||
|
@ -1112,14 +1112,22 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) {
|
||||||
|
|
||||||
SP<CDRMFB> drmFB;
|
SP<CDRMFB> drmFB;
|
||||||
auto buf = STATE.buffer;
|
auto buf = STATE.buffer;
|
||||||
|
bool isNew = false;
|
||||||
|
|
||||||
drmFB = CDRMFB::create(buf, backend); // will return attachment if present
|
drmFB = CDRMFB::create(buf, backend, &isNew); // will return attachment if present
|
||||||
|
|
||||||
if (!drmFB) {
|
if (!drmFB) {
|
||||||
backend->backend->log(AQ_LOG_ERROR, "drm: Buffer failed to import to KMS");
|
backend->backend->log(AQ_LOG_ERROR, "drm: Buffer failed to import to KMS");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isNew && backend->primary) {
|
||||||
|
// this is not a new buffer, and we are not on a primary GPU, which means
|
||||||
|
// this buffer lives on the primary. We need to re-import it to update
|
||||||
|
// the contents that have possibly (probably) changed
|
||||||
|
drmFB->reimport();
|
||||||
|
}
|
||||||
|
|
||||||
data.mainFB = drmFB;
|
data.mainFB = drmFB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1197,18 +1205,24 @@ Aquamarine::CDRMOutput::CDRMOutput(const std::string& name_, Hyprutils::Memory::
|
||||||
name = name_;
|
name = name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
SP<CDRMFB> Aquamarine::CDRMFB::create(SP<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_) {
|
SP<CDRMFB> Aquamarine::CDRMFB::create(SP<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_, bool* isNew) {
|
||||||
|
|
||||||
SP<CDRMFB> fb;
|
SP<CDRMFB> fb;
|
||||||
|
|
||||||
|
if (isNew)
|
||||||
|
*isNew = true;
|
||||||
|
|
||||||
if (buffer_->attachments.has(AQ_ATTACHMENT_DRM_BUFFER)) {
|
if (buffer_->attachments.has(AQ_ATTACHMENT_DRM_BUFFER)) {
|
||||||
auto at = (CDRMBufferAttachment*)buffer_->attachments.get(AQ_ATTACHMENT_DRM_BUFFER).get();
|
auto at = (CDRMBufferAttachment*)buffer_->attachments.get(AQ_ATTACHMENT_DRM_BUFFER).get();
|
||||||
fb = at->fb;
|
fb = at->fb;
|
||||||
backend_->log(AQ_LOG_TRACE, std::format("drm: CDRMFB: buffer has drmfb attachment with fb {:x}", (uintptr_t)fb.get()));
|
backend_->log(AQ_LOG_TRACE, std::format("drm: CDRMFB: buffer has drmfb attachment with fb {:x}", (uintptr_t)fb.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fb)
|
if (fb) {
|
||||||
|
if (isNew)
|
||||||
|
*isNew = false;
|
||||||
return fb;
|
return fb;
|
||||||
|
}
|
||||||
|
|
||||||
fb = SP<CDRMFB>(new CDRMFB(buffer_, backend_));
|
fb = SP<CDRMFB>(new CDRMFB(buffer_, backend_));
|
||||||
|
|
||||||
|
@ -1221,6 +1235,10 @@ SP<CDRMFB> Aquamarine::CDRMFB::create(SP<IBuffer> buffer_, Hyprutils::Memory::CW
|
||||||
}
|
}
|
||||||
|
|
||||||
Aquamarine::CDRMFB::CDRMFB(SP<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_) : buffer(buffer_), backend(backend_) {
|
Aquamarine::CDRMFB::CDRMFB(SP<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_) : buffer(buffer_), backend(backend_) {
|
||||||
|
import();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aquamarine::CDRMFB::import() {
|
||||||
auto attrs = buffer->dmabuf();
|
auto attrs = buffer->dmabuf();
|
||||||
if (!attrs.success) {
|
if (!attrs.success) {
|
||||||
backend->backend->log(AQ_LOG_ERROR, "drm: Buffer submitted has no dmabuf");
|
backend->backend->log(AQ_LOG_ERROR, "drm: Buffer submitted has no dmabuf");
|
||||||
|
@ -1259,6 +1277,15 @@ Aquamarine::CDRMFB::CDRMFB(SP<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<
|
||||||
// closeHandles();
|
// closeHandles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Aquamarine::CDRMFB::reimport() {
|
||||||
|
drop();
|
||||||
|
dropped = false;
|
||||||
|
handlesClosed = false;
|
||||||
|
boHandles = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
import();
|
||||||
|
}
|
||||||
|
|
||||||
Aquamarine::CDRMFB::~CDRMFB() {
|
Aquamarine::CDRMFB::~CDRMFB() {
|
||||||
drop();
|
drop();
|
||||||
}
|
}
|
||||||
|
@ -1299,6 +1326,8 @@ void Aquamarine::CDRMFB::drop() {
|
||||||
if (!id)
|
if (!id)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
closeHandles();
|
||||||
|
|
||||||
backend->backend->log(AQ_LOG_TRACE, std::format("drm: dropping buffer {}", id));
|
backend->backend->log(AQ_LOG_TRACE, std::format("drm: dropping buffer {}", id));
|
||||||
|
|
||||||
int ret = drmModeCloseFB(backend->gpu->fd, id);
|
int ret = drmModeCloseFB(backend->gpu->fd, id);
|
||||||
|
|
Loading…
Reference in a new issue