diff --git a/include/aquamarine/allocator/DRMDumb.hpp b/include/aquamarine/allocator/DRMDumb.hpp index 8006fed..1ca37bc 100644 --- a/include/aquamarine/allocator/DRMDumb.hpp +++ b/include/aquamarine/allocator/DRMDumb.hpp @@ -16,10 +16,9 @@ namespace Aquamarine { virtual void update(const Hyprutils::Math::CRegion& damage); virtual bool isSynchronous(); virtual bool good(); - virtual SSHMAttrs shm(); + virtual SDMABUFAttrs dmabuf(); virtual std::tuple beginDataPtr(uint32_t flags); virtual void endDataPtr(); - virtual uint32_t drmID(); private: CDRMDumbBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer allocator_, @@ -28,14 +27,14 @@ namespace Aquamarine { Hyprutils::Memory::CWeakPointer allocator; // - uint32_t idrmID = 0; Hyprutils::Math::Vector2D pixelSize; uint32_t stride = 0, handle = 0; - uint64_t size = 0; - uint8_t* data = nullptr; + uint64_t size = 0; + uint8_t* data = nullptr; + int primeFD = -1; // - SSHMAttrs attrs{.success = false}; + SDMABUFAttrs attrs{.success = false}; friend class CDRMDumbAllocator; }; diff --git a/include/aquamarine/buffer/Buffer.hpp b/include/aquamarine/buffer/Buffer.hpp index eba2558..99c21bf 100644 --- a/include/aquamarine/buffer/Buffer.hpp +++ b/include/aquamarine/buffer/Buffer.hpp @@ -60,7 +60,6 @@ namespace Aquamarine { virtual void lock(); virtual void unlock(); virtual bool locked(); - virtual uint32_t drmID(); Hyprutils::Math::Vector2D size; bool opaque = false; diff --git a/src/allocator/DRMDumb.cpp b/src/allocator/DRMDumb.cpp index 4d812f8..09cb37a 100644 --- a/src/allocator/DRMDumb.cpp +++ b/src/allocator/DRMDumb.cpp @@ -4,7 +4,9 @@ #include #include "FormatUtils.hpp" #include "Shared.hpp" +#include #include +#include #include #include #include @@ -19,47 +21,24 @@ Aquamarine::CDRMDumbBuffer::CDRMDumbBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CSharedPointer swapchain) : allocator(allocator_) { attrs.format = params.format; - drm_mode_create_dumb request = { - .height = (uint32_t)params.size.y, - .width = (uint32_t)params.size.x, - .bpp = 32, - }; - - if (int ret = drmIoctl(allocator->drmFD(), DRM_IOCTL_MODE_CREATE_DUMB, &request); ret < 0) { + if (int ret = drmModeCreateDumbBuffer(allocator->drmFD(), params.size.x, params.size.y, 32, 0, &handle, &stride, &size); ret < 0) { allocator->backend->log(AQ_LOG_ERROR, std::format("failed to create a drm_dumb buffer: {}", strerror(-ret))); return; } - stride = request.pitch; - handle = request.handle; - size = request.size; - pixelSize = {(double)request.width, (double)request.height}; + pixelSize = {(double)params.size.x, (double)params.size.y}; - attrs.size = pixelSize; - attrs.fd = request.handle; - attrs.stride = stride; + attrs.size = pixelSize; + attrs.strides.at(0) = stride; - uint32_t handles[4] = {handle, 0, 0, 0}; - uint32_t strides[4] = {stride, 0, 0, 0}; - uint32_t offsets[4] = {0, 0, 0, 0}; - - // these buffers are tied to drm... we need to import them here. CDRMFB will not be clean anymore... weeee... - if (int ret = drmModeAddFB2(allocator->drmFD(), params.size.x, params.size.y, params.format, handles, strides, offsets, &idrmID, 0); ret < 0) { - allocator->backend->log(AQ_LOG_ERROR, std::format("failed to drmModeAddFB2 a drm_dumb buffer: {}", strerror(-ret))); - return; - } - - drm_mode_map_dumb request2 = { - .handle = handle, - }; - - if (int ret = drmIoctl(allocator->drmFD(), DRM_IOCTL_MODE_MAP_DUMB, &request2); ret < 0) { + uint64_t offset = 0; + if (int ret = drmModeMapDumbBuffer(allocator->drmFD(), handle, &offset); ret < 0) { allocator->backend->log(AQ_LOG_ERROR, std::format("failed to map a drm_dumb buffer: {}", strerror(-ret))); return; } - data = (uint8_t*)mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, allocator->drmFD(), request2.offset); - if (!data) { + data = (uint8_t*)mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, allocator->drmFD(), offset); + if (data == MAP_FAILED) { allocator->backend->log(AQ_LOG_ERROR, "failed to mmap a drm_dumb buffer"); return; } @@ -67,15 +46,22 @@ Aquamarine::CDRMDumbBuffer::CDRMDumbBuffer(const SAllocatorBufferParams& params, // set the entire buffer so we dont get garbage memset(data, 0xFF, size); + if (int ret = drmPrimeHandleToFD(allocator->drmFD(), handle, DRM_CLOEXEC, &primeFD); ret < 0) { + allocator->backend->log(AQ_LOG_ERROR, std::format("failed to map a drm_dumb buffer: {}", strerror(-ret))); + return; + } + + attrs.fds.at(0) = primeFD; + attrs.success = true; - allocator->backend->log(AQ_LOG_DEBUG, std::format("DRM Dumb: Allocated a new buffer with drm id {}, size {} and format {}", idrmID, attrs.size, fourccToName(attrs.format))); + allocator->backend->log(AQ_LOG_DEBUG, std::format("DRM Dumb: Allocated a new buffer with primeFD {}, size {} and format {}", primeFD, attrs.size, fourccToName(attrs.format))); } Aquamarine::CDRMDumbBuffer::~CDRMDumbBuffer() { events.destroy.emit(); - TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("DRM Dumb: dropping buffer {}", idrmID))); + TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("DRM Dumb: dropping buffer {}", primeFD))); if (handle == 0) return; @@ -83,9 +69,6 @@ Aquamarine::CDRMDumbBuffer::~CDRMDumbBuffer() { if (data) munmap(data, size); - if (idrmID) - drmModeRmFB(allocator->drmFD(), idrmID); - drm_mode_destroy_dumb request = { .handle = handle, }; @@ -97,7 +80,7 @@ eBufferCapability Aquamarine::CDRMDumbBuffer::caps() { } eBufferType Aquamarine::CDRMDumbBuffer::type() { - return eBufferType::BUFFER_TYPE_SHM; + return eBufferType::BUFFER_TYPE_DMABUF; } void Aquamarine::CDRMDumbBuffer::update(const Hyprutils::Math::CRegion& damage) { @@ -112,7 +95,7 @@ bool Aquamarine::CDRMDumbBuffer::good() { return attrs.success && data; } -SSHMAttrs Aquamarine::CDRMDumbBuffer::shm() { +SDMABUFAttrs Aquamarine::CDRMDumbBuffer::dmabuf() { return attrs; } @@ -124,10 +107,6 @@ void Aquamarine::CDRMDumbBuffer::endDataPtr() { ; // nothing to do } -uint32_t Aquamarine::CDRMDumbBuffer::drmID() { - return idrmID; -} - Aquamarine::CDRMDumbAllocator::~CDRMDumbAllocator() { ; // nothing to do } diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index 1a0916a..592f6f0 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -1826,7 +1826,7 @@ Aquamarine::CDRMFB::CDRMFB(SP buffer_, Hyprutils::Memory::CWeakPointer< void Aquamarine::CDRMFB::import() { auto attrs = buffer->dmabuf(); - if (!attrs.success && !buffer->drmID()) { + if (!attrs.success) { backend->backend->log(AQ_LOG_ERROR, "drm: Buffer submitted has no dmabuf or a drm handle"); return; } @@ -1837,22 +1837,18 @@ void Aquamarine::CDRMFB::import() { } // TODO: check format - - if (!buffer->drmID()) { - for (int i = 0; i < attrs.planes; ++i) { - int ret = drmPrimeFDToHandle(backend->gpu->fd, attrs.fds.at(i), &boHandles[i]); - if (ret) { - backend->backend->log(AQ_LOG_ERROR, "drm: drmPrimeFDToHandle failed"); - drop(); - return; - } - - TRACE(backend->backend->log(AQ_LOG_TRACE, std::format("drm: CDRMFB: plane {} has fd {}, got handle {}", i, attrs.fds.at(i), boHandles.at(i)))); + for (int i = 0; i < attrs.planes; ++i) { + int ret = drmPrimeFDToHandle(backend->gpu->fd, attrs.fds.at(i), &boHandles[i]); + if (ret) { + backend->backend->log(AQ_LOG_ERROR, "drm: drmPrimeFDToHandle failed"); + drop(); + return; } - id = submitBuffer(); - } else - id = buffer->drmID(); + TRACE(backend->backend->log(AQ_LOG_TRACE, std::format("drm: CDRMFB: plane {} has fd {}, got handle {}", i, attrs.fds.at(i), boHandles.at(i)))); + } + + id = submitBuffer(); if (!id) { backend->backend->log(AQ_LOG_ERROR, "drm: Failed to submit a buffer to KMS"); @@ -1921,7 +1917,7 @@ void Aquamarine::CDRMFB::drop() { dropped = true; - if (!id || buffer->drmID() /* drmID means the buffer manages itself */) + if (!id) return; closeHandles(); diff --git a/src/buffer/Buffer.cpp b/src/buffer/Buffer.cpp index 2ef5b41..8197742 100644 --- a/src/buffer/Buffer.cpp +++ b/src/buffer/Buffer.cpp @@ -39,7 +39,3 @@ void Aquamarine::IBuffer::unlock() { bool Aquamarine::IBuffer::locked() { return locks; } - -uint32_t Aquamarine::IBuffer::drmID() { - return 0; -}