mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-11-17 08:26:00 +01:00
life is a piece of shit
This commit is contained in:
parent
1cdd74c967
commit
d3b58683cc
5 changed files with 38 additions and 69 deletions
|
@ -16,10 +16,9 @@ namespace Aquamarine {
|
||||||
virtual void update(const Hyprutils::Math::CRegion& damage);
|
virtual void update(const Hyprutils::Math::CRegion& damage);
|
||||||
virtual bool isSynchronous();
|
virtual bool isSynchronous();
|
||||||
virtual bool good();
|
virtual bool good();
|
||||||
virtual SSHMAttrs shm();
|
virtual SDMABUFAttrs dmabuf();
|
||||||
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
|
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
|
||||||
virtual void endDataPtr();
|
virtual void endDataPtr();
|
||||||
virtual uint32_t drmID();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CDRMDumbBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer<CDRMDumbAllocator> allocator_,
|
CDRMDumbBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer<CDRMDumbAllocator> allocator_,
|
||||||
|
@ -28,14 +27,14 @@ namespace Aquamarine {
|
||||||
Hyprutils::Memory::CWeakPointer<CDRMDumbAllocator> allocator;
|
Hyprutils::Memory::CWeakPointer<CDRMDumbAllocator> allocator;
|
||||||
|
|
||||||
//
|
//
|
||||||
uint32_t idrmID = 0;
|
|
||||||
Hyprutils::Math::Vector2D pixelSize;
|
Hyprutils::Math::Vector2D pixelSize;
|
||||||
uint32_t stride = 0, handle = 0;
|
uint32_t stride = 0, handle = 0;
|
||||||
uint64_t size = 0;
|
uint64_t size = 0;
|
||||||
uint8_t* data = nullptr;
|
uint8_t* data = nullptr;
|
||||||
|
int primeFD = -1;
|
||||||
|
|
||||||
//
|
//
|
||||||
SSHMAttrs attrs{.success = false};
|
SDMABUFAttrs attrs{.success = false};
|
||||||
|
|
||||||
friend class CDRMDumbAllocator;
|
friend class CDRMDumbAllocator;
|
||||||
};
|
};
|
||||||
|
|
|
@ -60,7 +60,6 @@ namespace Aquamarine {
|
||||||
virtual void lock();
|
virtual void lock();
|
||||||
virtual void unlock();
|
virtual void unlock();
|
||||||
virtual bool locked();
|
virtual bool locked();
|
||||||
virtual uint32_t drmID();
|
|
||||||
|
|
||||||
Hyprutils::Math::Vector2D size;
|
Hyprutils::Math::Vector2D size;
|
||||||
bool opaque = false;
|
bool opaque = false;
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
#include <aquamarine/allocator/Swapchain.hpp>
|
#include <aquamarine/allocator/Swapchain.hpp>
|
||||||
#include "FormatUtils.hpp"
|
#include "FormatUtils.hpp"
|
||||||
#include "Shared.hpp"
|
#include "Shared.hpp"
|
||||||
|
#include <fcntl.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
|
#include <xf86drmMode.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
@ -19,47 +21,24 @@ Aquamarine::CDRMDumbBuffer::CDRMDumbBuffer(const SAllocatorBufferParams& params,
|
||||||
Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain) : allocator(allocator_) {
|
Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain) : allocator(allocator_) {
|
||||||
attrs.format = params.format;
|
attrs.format = params.format;
|
||||||
|
|
||||||
drm_mode_create_dumb request = {
|
if (int ret = drmModeCreateDumbBuffer(allocator->drmFD(), params.size.x, params.size.y, 32, 0, &handle, &stride, &size); ret < 0) {
|
||||||
.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) {
|
|
||||||
allocator->backend->log(AQ_LOG_ERROR, std::format("failed to create a drm_dumb buffer: {}", strerror(-ret)));
|
allocator->backend->log(AQ_LOG_ERROR, std::format("failed to create a drm_dumb buffer: {}", strerror(-ret)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stride = request.pitch;
|
pixelSize = {(double)params.size.x, (double)params.size.y};
|
||||||
handle = request.handle;
|
|
||||||
size = request.size;
|
|
||||||
pixelSize = {(double)request.width, (double)request.height};
|
|
||||||
|
|
||||||
attrs.size = pixelSize;
|
attrs.size = pixelSize;
|
||||||
attrs.fd = request.handle;
|
attrs.strides.at(0) = stride;
|
||||||
attrs.stride = stride;
|
|
||||||
|
|
||||||
uint32_t handles[4] = {handle, 0, 0, 0};
|
uint64_t offset = 0;
|
||||||
uint32_t strides[4] = {stride, 0, 0, 0};
|
if (int ret = drmModeMapDumbBuffer(allocator->drmFD(), handle, &offset); ret < 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) {
|
|
||||||
allocator->backend->log(AQ_LOG_ERROR, std::format("failed to map a drm_dumb buffer: {}", strerror(-ret)));
|
allocator->backend->log(AQ_LOG_ERROR, std::format("failed to map a drm_dumb buffer: {}", strerror(-ret)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (uint8_t*)mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, allocator->drmFD(), request2.offset);
|
data = (uint8_t*)mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, allocator->drmFD(), offset);
|
||||||
if (!data) {
|
if (data == MAP_FAILED) {
|
||||||
allocator->backend->log(AQ_LOG_ERROR, "failed to mmap a drm_dumb buffer");
|
allocator->backend->log(AQ_LOG_ERROR, "failed to mmap a drm_dumb buffer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -67,15 +46,22 @@ Aquamarine::CDRMDumbBuffer::CDRMDumbBuffer(const SAllocatorBufferParams& params,
|
||||||
// set the entire buffer so we dont get garbage
|
// set the entire buffer so we dont get garbage
|
||||||
memset(data, 0xFF, size);
|
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;
|
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() {
|
Aquamarine::CDRMDumbBuffer::~CDRMDumbBuffer() {
|
||||||
events.destroy.emit();
|
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)
|
if (handle == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -83,9 +69,6 @@ Aquamarine::CDRMDumbBuffer::~CDRMDumbBuffer() {
|
||||||
if (data)
|
if (data)
|
||||||
munmap(data, size);
|
munmap(data, size);
|
||||||
|
|
||||||
if (idrmID)
|
|
||||||
drmModeRmFB(allocator->drmFD(), idrmID);
|
|
||||||
|
|
||||||
drm_mode_destroy_dumb request = {
|
drm_mode_destroy_dumb request = {
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
};
|
};
|
||||||
|
@ -97,7 +80,7 @@ eBufferCapability Aquamarine::CDRMDumbBuffer::caps() {
|
||||||
}
|
}
|
||||||
|
|
||||||
eBufferType Aquamarine::CDRMDumbBuffer::type() {
|
eBufferType Aquamarine::CDRMDumbBuffer::type() {
|
||||||
return eBufferType::BUFFER_TYPE_SHM;
|
return eBufferType::BUFFER_TYPE_DMABUF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aquamarine::CDRMDumbBuffer::update(const Hyprutils::Math::CRegion& damage) {
|
void Aquamarine::CDRMDumbBuffer::update(const Hyprutils::Math::CRegion& damage) {
|
||||||
|
@ -112,7 +95,7 @@ bool Aquamarine::CDRMDumbBuffer::good() {
|
||||||
return attrs.success && data;
|
return attrs.success && data;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSHMAttrs Aquamarine::CDRMDumbBuffer::shm() {
|
SDMABUFAttrs Aquamarine::CDRMDumbBuffer::dmabuf() {
|
||||||
return attrs;
|
return attrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,10 +107,6 @@ void Aquamarine::CDRMDumbBuffer::endDataPtr() {
|
||||||
; // nothing to do
|
; // nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Aquamarine::CDRMDumbBuffer::drmID() {
|
|
||||||
return idrmID;
|
|
||||||
}
|
|
||||||
|
|
||||||
Aquamarine::CDRMDumbAllocator::~CDRMDumbAllocator() {
|
Aquamarine::CDRMDumbAllocator::~CDRMDumbAllocator() {
|
||||||
; // nothing to do
|
; // nothing to do
|
||||||
}
|
}
|
||||||
|
|
|
@ -1826,7 +1826,7 @@ Aquamarine::CDRMFB::CDRMFB(SP<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<
|
||||||
|
|
||||||
void Aquamarine::CDRMFB::import() {
|
void Aquamarine::CDRMFB::import() {
|
||||||
auto attrs = buffer->dmabuf();
|
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");
|
backend->backend->log(AQ_LOG_ERROR, "drm: Buffer submitted has no dmabuf or a drm handle");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1837,22 +1837,18 @@ void Aquamarine::CDRMFB::import() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check format
|
// TODO: check format
|
||||||
|
for (int i = 0; i < attrs.planes; ++i) {
|
||||||
if (!buffer->drmID()) {
|
int ret = drmPrimeFDToHandle(backend->gpu->fd, attrs.fds.at(i), &boHandles[i]);
|
||||||
for (int i = 0; i < attrs.planes; ++i) {
|
if (ret) {
|
||||||
int ret = drmPrimeFDToHandle(backend->gpu->fd, attrs.fds.at(i), &boHandles[i]);
|
backend->backend->log(AQ_LOG_ERROR, "drm: drmPrimeFDToHandle failed");
|
||||||
if (ret) {
|
drop();
|
||||||
backend->backend->log(AQ_LOG_ERROR, "drm: drmPrimeFDToHandle failed");
|
return;
|
||||||
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))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
id = submitBuffer();
|
TRACE(backend->backend->log(AQ_LOG_TRACE, std::format("drm: CDRMFB: plane {} has fd {}, got handle {}", i, attrs.fds.at(i), boHandles.at(i))));
|
||||||
} else
|
}
|
||||||
id = buffer->drmID();
|
|
||||||
|
id = submitBuffer();
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
backend->backend->log(AQ_LOG_ERROR, "drm: Failed to submit a buffer to KMS");
|
backend->backend->log(AQ_LOG_ERROR, "drm: Failed to submit a buffer to KMS");
|
||||||
|
@ -1921,7 +1917,7 @@ void Aquamarine::CDRMFB::drop() {
|
||||||
|
|
||||||
dropped = true;
|
dropped = true;
|
||||||
|
|
||||||
if (!id || buffer->drmID() /* drmID means the buffer manages itself */)
|
if (!id)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
closeHandles();
|
closeHandles();
|
||||||
|
|
|
@ -39,7 +39,3 @@ void Aquamarine::IBuffer::unlock() {
|
||||||
bool Aquamarine::IBuffer::locked() {
|
bool Aquamarine::IBuffer::locked() {
|
||||||
return locks;
|
return locks;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Aquamarine::IBuffer::drmID() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue