mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-12-22 11:39:49 +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,11 +45,14 @@ namespace Aquamarine {
|
|||
public:
|
||||
~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();
|
||||
// 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;
|
||||
Hyprutils::Memory::CWeakPointer<IBuffer> buffer;
|
||||
|
@ -59,6 +62,7 @@ namespace Aquamarine {
|
|||
private:
|
||||
CDRMFB(Hyprutils::Memory::CSharedPointer<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_);
|
||||
uint32_t submitBuffer();
|
||||
void import();
|
||||
|
||||
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()));
|
||||
|
||||
std::vector<SP<CDRMBackend>> backends;
|
||||
SP<CDRMBackend> primary;
|
||||
SP<CDRMBackend> newPrimary;
|
||||
|
||||
for (auto& gpu : gpus) {
|
||||
auto drmBackend = SP<CDRMBackend>(new CDRMBackend(backend));
|
||||
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));
|
||||
continue;
|
||||
} else
|
||||
|
@ -225,9 +223,9 @@ std::vector<SP<CDRMBackend>> Aquamarine::CDRMBackend::attempt(SP<CBackend> backe
|
|||
|
||||
drmBackend->scanConnectors();
|
||||
|
||||
if (!primary) {
|
||||
if (!newPrimary) {
|
||||
backend->log(AQ_LOG_DEBUG, std::format("drm: gpu {} becomes primary drm", gpu->path));
|
||||
primary = drmBackend;
|
||||
newPrimary = drmBackend;
|
||||
}
|
||||
|
||||
backends.emplace_back(drmBackend);
|
||||
|
@ -441,7 +439,9 @@ bool Aquamarine::CDRMBackend::registerGPU(SP<CSessionDevice> gpu_, SP<CDRMBacken
|
|||
|
||||
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);
|
||||
|
||||
|
@ -1111,15 +1111,23 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) {
|
|||
backend->backend->log(AQ_LOG_TRACE, "drm: Committed a buffer, updating state");
|
||||
|
||||
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) {
|
||||
backend->backend->log(AQ_LOG_ERROR, "drm: Buffer failed to import to KMS");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1197,18 +1205,24 @@ Aquamarine::CDRMOutput::CDRMOutput(const std::string& name_, Hyprutils::Memory::
|
|||
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;
|
||||
|
||||
if (isNew)
|
||||
*isNew = true;
|
||||
|
||||
if (buffer_->attachments.has(AQ_ATTACHMENT_DRM_BUFFER)) {
|
||||
auto at = (CDRMBufferAttachment*)buffer_->attachments.get(AQ_ATTACHMENT_DRM_BUFFER).get();
|
||||
fb = at->fb;
|
||||
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;
|
||||
}
|
||||
|
||||
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_) {
|
||||
import();
|
||||
}
|
||||
|
||||
void Aquamarine::CDRMFB::import() {
|
||||
auto attrs = buffer->dmabuf();
|
||||
if (!attrs.success) {
|
||||
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();
|
||||
}
|
||||
|
||||
void Aquamarine::CDRMFB::reimport() {
|
||||
drop();
|
||||
dropped = false;
|
||||
handlesClosed = false;
|
||||
boHandles = {0, 0, 0, 0};
|
||||
|
||||
import();
|
||||
}
|
||||
|
||||
Aquamarine::CDRMFB::~CDRMFB() {
|
||||
drop();
|
||||
}
|
||||
|
@ -1299,6 +1326,8 @@ void Aquamarine::CDRMFB::drop() {
|
|||
if (!id)
|
||||
return;
|
||||
|
||||
closeHandles();
|
||||
|
||||
backend->backend->log(AQ_LOG_TRACE, std::format("drm: dropping buffer {}", id));
|
||||
|
||||
int ret = drmModeCloseFB(backend->gpu->fd, id);
|
||||
|
|
Loading…
Reference in a new issue