add a drm_dumb allocator

This commit is contained in:
Vaxry 2024-11-09 17:56:49 +00:00
parent f5ed91d122
commit abd58530c3
12 changed files with 363 additions and 101 deletions

View file

@ -16,6 +16,7 @@ namespace Aquamarine {
enum eAllocatorType {
AQ_ALLOCATOR_TYPE_GBM = 0,
AQ_ALLOCATOR_TYPE_DRM_DUMB,
};
class IAllocator {

View file

@ -0,0 +1,69 @@
#pragma once
#include "Allocator.hpp"
namespace Aquamarine {
class CDRMDumbAllocator;
class CBackend;
class CSwapchain;
class CDRMDumbBuffer : public IBuffer {
public:
virtual ~CDRMDumbBuffer();
virtual eBufferCapability caps();
virtual eBufferType type();
virtual void update(const Hyprutils::Math::CRegion& damage);
virtual bool isSynchronous();
virtual bool good();
virtual SSHMAttrs shm();
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
virtual void endDataPtr();
virtual uint32_t drmHandle();
private:
CDRMDumbBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer<CDRMDumbAllocator> allocator_,
Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain);
Hyprutils::Memory::CWeakPointer<CDRMDumbAllocator> allocator;
//
uint32_t drmID = 0;
Hyprutils::Math::Vector2D pixelSize;
uint32_t stride = 0, handle = 0;
uint64_t size = 0;
uint8_t* data = nullptr;
//
SSHMAttrs attrs{.success = false};
friend class CDRMDumbAllocator;
};
class CDRMDumbAllocator : public IAllocator {
public:
~CDRMDumbAllocator();
static Hyprutils::Memory::CSharedPointer<CDRMDumbAllocator> create(int drmfd_, Hyprutils::Memory::CWeakPointer<CBackend> backend_);
virtual Hyprutils::Memory::CSharedPointer<IBuffer> acquire(const SAllocatorBufferParams& params, Hyprutils::Memory::CSharedPointer<CSwapchain> swapchain_);
virtual Hyprutils::Memory::CSharedPointer<CBackend> getBackend();
virtual int drmFD();
virtual eAllocatorType type();
//
Hyprutils::Memory::CWeakPointer<CDRMDumbAllocator> self;
private:
CDRMDumbAllocator(int fd_, Hyprutils::Memory::CWeakPointer<CBackend> backend_);
// a vector purely for tracking (debugging) the buffers and nothing more
std::vector<Hyprutils::Memory::CWeakPointer<CDRMDumbBuffer>> buffers;
Hyprutils::Memory::CWeakPointer<CBackend> backend;
int drmfd = -1;
friend class CDRMDumbBuffer;
friend class CDRMRenderer;
};
};

View file

@ -66,18 +66,19 @@ namespace Aquamarine {
AQ_BACKEND_CAPABILITY_POINTER = (1 << 0),
};
virtual eBackendType type() = 0;
virtual bool start() = 0;
virtual std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> pollFDs() = 0;
virtual int drmFD() = 0;
virtual bool dispatchEvents() = 0;
virtual uint32_t capabilities() = 0;
virtual void onReady() = 0;
virtual std::vector<SDRMFormat> getRenderFormats() = 0;
virtual std::vector<SDRMFormat> getCursorFormats() = 0;
virtual bool createOutput(const std::string& name = "") = 0; // "" means auto
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator() = 0;
virtual std::vector<SDRMFormat> getRenderableFormats(); // empty = use getRenderFormats
virtual eBackendType type() = 0;
virtual bool start() = 0;
virtual std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> pollFDs() = 0;
virtual int drmFD() = 0;
virtual bool dispatchEvents() = 0;
virtual uint32_t capabilities() = 0;
virtual void onReady() = 0;
virtual std::vector<SDRMFormat> getRenderFormats() = 0;
virtual std::vector<SDRMFormat> getCursorFormats() = 0;
virtual bool createOutput(const std::string& name = "") = 0; // "" means auto
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator() = 0;
virtual std::vector<SDRMFormat> getRenderableFormats(); // empty = use getRenderFormats
virtual std::vector<Hyprutils::Memory::CSharedPointer<IAllocator>> getAllocators() = 0;
};
class CBackend {

View file

@ -15,6 +15,7 @@ namespace Aquamarine {
class CDRMOutput;
struct SDRMConnector;
class CDRMRenderer;
class CDRMDumbAllocator;
typedef std::function<void(void)> FIdleCallback;
@ -340,28 +341,29 @@ namespace Aquamarine {
class CDRMBackend : public IBackendImplementation {
public:
virtual ~CDRMBackend();
virtual eBackendType type();
virtual bool start();
virtual std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> pollFDs();
virtual int drmFD();
virtual bool dispatchEvents();
virtual uint32_t capabilities();
virtual bool setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot);
virtual void onReady();
virtual std::vector<SDRMFormat> getRenderFormats();
virtual std::vector<SDRMFormat> getCursorFormats();
virtual bool createOutput(const std::string& name = "");
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator();
virtual std::vector<SDRMFormat> getRenderableFormats();
virtual eBackendType type();
virtual bool start();
virtual std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> pollFDs();
virtual int drmFD();
virtual bool dispatchEvents();
virtual uint32_t capabilities();
virtual bool setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot);
virtual void onReady();
virtual std::vector<SDRMFormat> getRenderFormats();
virtual std::vector<SDRMFormat> getCursorFormats();
virtual bool createOutput(const std::string& name = "");
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator();
virtual std::vector<SDRMFormat> getRenderableFormats();
virtual std::vector<Hyprutils::Memory::CSharedPointer<IAllocator>> getAllocators();
Hyprutils::Memory::CWeakPointer<CDRMBackend> self;
Hyprutils::Memory::CWeakPointer<CDRMBackend> self;
void log(eBackendLogLevel, const std::string&);
bool sessionActive();
int getNonMasterFD();
void log(eBackendLogLevel, const std::string&);
bool sessionActive();
int getNonMasterFD();
std::vector<FIdleCallback> idleCallbacks;
std::string gpuName;
std::vector<FIdleCallback> idleCallbacks;
std::string gpuName;
private:
CDRMBackend(Hyprutils::Memory::CSharedPointer<CBackend> backend);
@ -396,6 +398,8 @@ namespace Aquamarine {
std::vector<SDRMFormat> formats;
std::vector<SDRMFormat> glFormats;
Hyprutils::Memory::CSharedPointer<CDRMDumbAllocator> dumbAllocator;
bool atomic = false;
struct {

View file

@ -8,6 +8,7 @@
namespace Aquamarine {
class CBackend;
class CHeadlessBackend;
class IAllocator;
class CHeadlessOutput : public IOutput {
public:
@ -35,20 +36,21 @@ namespace Aquamarine {
class CHeadlessBackend : public IBackendImplementation {
public:
virtual ~CHeadlessBackend();
virtual eBackendType type();
virtual bool start();
virtual std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> pollFDs();
virtual int drmFD();
virtual bool dispatchEvents();
virtual uint32_t capabilities();
virtual bool setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot);
virtual void onReady();
virtual std::vector<SDRMFormat> getRenderFormats();
virtual std::vector<SDRMFormat> getCursorFormats();
virtual bool createOutput(const std::string& name = "");
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator();
virtual eBackendType type();
virtual bool start();
virtual std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> pollFDs();
virtual int drmFD();
virtual bool dispatchEvents();
virtual uint32_t capabilities();
virtual bool setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot);
virtual void onReady();
virtual std::vector<SDRMFormat> getRenderFormats();
virtual std::vector<SDRMFormat> getCursorFormats();
virtual bool createOutput(const std::string& name = "");
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator();
virtual std::vector<Hyprutils::Memory::CSharedPointer<IAllocator>> getAllocators();
Hyprutils::Memory::CWeakPointer<CHeadlessBackend> self;
Hyprutils::Memory::CWeakPointer<CHeadlessBackend> self;
private:
CHeadlessBackend(Hyprutils::Memory::CSharedPointer<CBackend> backend_);

View file

@ -123,20 +123,21 @@ namespace Aquamarine {
class CWaylandBackend : public IBackendImplementation {
public:
virtual ~CWaylandBackend();
virtual eBackendType type();
virtual bool start();
virtual std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> pollFDs();
virtual int drmFD();
virtual bool dispatchEvents();
virtual uint32_t capabilities();
virtual bool setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot);
virtual void onReady();
virtual std::vector<SDRMFormat> getRenderFormats();
virtual std::vector<SDRMFormat> getCursorFormats();
virtual bool createOutput(const std::string& name = "");
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator();
virtual eBackendType type();
virtual bool start();
virtual std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> pollFDs();
virtual int drmFD();
virtual bool dispatchEvents();
virtual uint32_t capabilities();
virtual bool setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot);
virtual void onReady();
virtual std::vector<SDRMFormat> getRenderFormats();
virtual std::vector<SDRMFormat> getCursorFormats();
virtual bool createOutput(const std::string& name = "");
virtual Hyprutils::Memory::CSharedPointer<IAllocator> preferredAllocator();
virtual std::vector<Hyprutils::Memory::CSharedPointer<IAllocator>> getAllocators();
Hyprutils::Memory::CWeakPointer<CWaylandBackend> self;
Hyprutils::Memory::CWeakPointer<CWaylandBackend> self;
private:
CWaylandBackend(Hyprutils::Memory::CSharedPointer<CBackend> backend);

View file

@ -60,6 +60,7 @@ namespace Aquamarine {
virtual void lock();
virtual void unlock();
virtual bool locked();
virtual uint32_t drmHandle();
Hyprutils::Math::Vector2D size;
bool opaque = false;

142
src/allocator/DRMDumb.cpp Normal file
View file

@ -0,0 +1,142 @@
#include <aquamarine/allocator/DRMDumb.hpp>
#include <aquamarine/backend/Backend.hpp>
#include <aquamarine/backend/DRM.hpp>
#include <aquamarine/allocator/Swapchain.hpp>
#include "FormatUtils.hpp"
#include "Shared.hpp"
#include <xf86drm.h>
#include <unistd.h>
#include <cstring>
#include <sys/mman.h>
#include "../backend/drm/Renderer.hpp"
using namespace Aquamarine;
using namespace Hyprutils::Memory;
#define SP CSharedPointer
#define WP CWeakPointer
Aquamarine::CDRMDumbBuffer::CDRMDumbBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer<CDRMDumbAllocator> allocator_,
Hyprutils::Memory::CSharedPointer<CSwapchain> 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) {
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};
attrs.size = pixelSize;
attrs.fd = request.handle;
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)));
return;
}
data = (uint8_t*)mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, allocator->drmFD(), request2.offset);
if (!data) {
allocator->backend->log(AQ_LOG_ERROR, "failed to mmmap a drm_dumb buffer");
return;
}
// null the entire buffer so we dont get garbage
memset(data, 0x00, size);
attrs.success = true;
}
Aquamarine::CDRMDumbBuffer::~CDRMDumbBuffer() {
events.destroy.emit();
if (handle == 0)
return;
if (data)
munmap(data, size);
drm_mode_destroy_dumb request = {
.handle = handle,
};
drmIoctl(allocator->drmFD(), DRM_IOCTL_MODE_DESTROY_DUMB, &request);
}
eBufferCapability Aquamarine::CDRMDumbBuffer::caps() {
return eBufferCapability::BUFFER_CAPABILITY_DATAPTR;
}
eBufferType Aquamarine::CDRMDumbBuffer::type() {
return eBufferType::BUFFER_TYPE_SHM;
}
void Aquamarine::CDRMDumbBuffer::update(const Hyprutils::Math::CRegion& damage) {
; // nothing to do
}
bool Aquamarine::CDRMDumbBuffer::isSynchronous() {
return true;
}
bool Aquamarine::CDRMDumbBuffer::good() {
return attrs.success && data;
}
SSHMAttrs Aquamarine::CDRMDumbBuffer::shm() {
return attrs;
}
std::tuple<uint8_t*, uint32_t, size_t> Aquamarine::CDRMDumbBuffer::beginDataPtr(uint32_t flags) {
return {data, attrs.format, size};
}
void Aquamarine::CDRMDumbBuffer::endDataPtr() {
; // nothing to do
}
uint32_t Aquamarine::CDRMDumbBuffer::drmHandle() {
return handle;
}
Aquamarine::CDRMDumbAllocator::~CDRMDumbAllocator() {
; // nothing to do
}
SP<CDRMDumbAllocator> Aquamarine::CDRMDumbAllocator::create(int drmfd_, Hyprutils::Memory::CWeakPointer<CBackend> backend_) {
return SP<CDRMDumbAllocator>(new CDRMDumbAllocator(drmfd_, backend_));
}
SP<IBuffer> Aquamarine::CDRMDumbAllocator::acquire(const SAllocatorBufferParams& params, SP<CSwapchain> swapchain_) {
auto buf = SP<IBuffer>(new CDRMDumbBuffer(params, self, swapchain_));
if (!buf->good())
return nullptr;
return buf;
}
SP<CBackend> Aquamarine::CDRMDumbAllocator::getBackend() {
return backend.lock();
}
int Aquamarine::CDRMDumbAllocator::drmFD() {
return drmfd;
}
eAllocatorType Aquamarine::CDRMDumbAllocator::type() {
return eAllocatorType::AQ_ALLOCATOR_TYPE_DRM_DUMB;
}
Aquamarine::CDRMDumbAllocator::CDRMDumbAllocator(int fd_, Hyprutils::Memory::CWeakPointer<CBackend> backend_) : drmfd(fd_), backend(backend_) {
; // nothing to do
}

View file

@ -187,6 +187,10 @@ SP<IAllocator> Aquamarine::CHeadlessBackend::preferredAllocator() {
return backend->primaryAllocator;
}
std::vector<SP<IAllocator>> Aquamarine::CHeadlessBackend::getAllocators() {
return {backend->primaryAllocator};
}
bool Aquamarine::CHeadlessBackend::CTimer::expired() {
return std::chrono::steady_clock::now() > when;
}

View file

@ -442,6 +442,10 @@ SP<IAllocator> Aquamarine::CWaylandBackend::preferredAllocator() {
return backend->primaryAllocator;
}
std::vector<SP<IAllocator>> Aquamarine::CWaylandBackend::getAllocators() {
return {backend->primaryAllocator};
}
Aquamarine::CWaylandOutput::CWaylandOutput(const std::string& name_, Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend_) : backend(backend_) {
name = name_;

View file

@ -3,6 +3,7 @@
#include <aquamarine/backend/drm/Legacy.hpp>
#include <aquamarine/backend/drm/Atomic.hpp>
#include <aquamarine/allocator/GBM.hpp>
#include <aquamarine/allocator/DRMDumb.hpp>
#include <hyprutils/string/VarList.hpp>
#include <chrono>
#include <thread>
@ -961,6 +962,10 @@ SP<IAllocator> Aquamarine::CDRMBackend::preferredAllocator() {
return backend->primaryAllocator;
}
std::vector<SP<IAllocator>> Aquamarine::CDRMBackend::getAllocators() {
return {backend->primaryAllocator, dumbAllocator};
}
bool Aquamarine::SDRMPlane::init(drmModePlane* plane) {
id = plane->plane_id;
@ -1647,8 +1652,10 @@ SP<IBackendImplementation> Aquamarine::CDRMOutput::getBackend() {
}
bool Aquamarine::CDRMOutput::setCursor(SP<IBuffer> buffer, const Vector2D& hotspot) {
if (buffer && !buffer->dmabuf().success) {
backend->backend->log(AQ_LOG_ERROR, "drm: Cursor buffer has to be a dmabuf");
auto bufferType = buffer->type();
if ((bufferType == eBufferType::BUFFER_TYPE_SHM && !buffer->shm().success) || (bufferType == eBufferType::BUFFER_TYPE_DMABUF && !buffer->dmabuf().success)) {
backend->backend->log(AQ_LOG_ERROR, "drm: Invalid buffer passed to setCursor");
return false;
}
@ -1663,18 +1670,23 @@ bool Aquamarine::CDRMOutput::setCursor(SP<IBuffer> buffer, const Vector2D& hotsp
if (backend->primary) {
TRACE(backend->backend->log(AQ_LOG_TRACE, "drm: Backend requires cursor blit, blitting"));
// TODO: will this not implode on drm_dumb?!
if (!mgpu.cursorSwapchain) {
TRACE(backend->backend->log(AQ_LOG_TRACE, "drm: No cursorSwapchain for blit, creating"));
mgpu.cursorSwapchain = CSwapchain::create(backend->rendererState.allocator, backend.lock());
}
auto OPTIONS = mgpu.cursorSwapchain->currentOptions();
OPTIONS.multigpu = false;
OPTIONS.scanout = true;
OPTIONS.cursor = true;
OPTIONS.format = buffer->dmabuf().format;
OPTIONS.size = buffer->dmabuf().size;
OPTIONS.length = 2;
const auto FORMAT = bufferType == eBufferType::BUFFER_TYPE_SHM ? buffer->shm().format : buffer->dmabuf().format;
const auto SIZE = bufferType == eBufferType::BUFFER_TYPE_SHM ? buffer->shm().size : buffer->dmabuf().size;
auto OPTIONS = mgpu.cursorSwapchain->currentOptions();
OPTIONS.multigpu = false;
OPTIONS.scanout = true;
OPTIONS.cursor = true;
OPTIONS.format = FORMAT;
OPTIONS.size = SIZE;
OPTIONS.length = 2;
if (!mgpu.cursorSwapchain->reconfigure(OPTIONS)) {
backend->backend->log(AQ_LOG_ERROR, "drm: Backend requires blit, but the mgpu cursorSwapchain failed reconfiguring");
@ -1807,8 +1819,8 @@ Aquamarine::CDRMFB::CDRMFB(SP<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<
void Aquamarine::CDRMFB::import() {
auto attrs = buffer->dmabuf();
if (!attrs.success) {
backend->backend->log(AQ_LOG_ERROR, "drm: Buffer submitted has no dmabuf");
if (!attrs.success && !buffer->drmHandle()) {
backend->backend->log(AQ_LOG_ERROR, "drm: Buffer submitted has no dmabuf or a drm handle");
return;
}
@ -1819,16 +1831,19 @@ void Aquamarine::CDRMFB::import() {
// TODO: check format
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;
}
if (!buffer->drmHandle()) {
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))));
}
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
boHandles = {buffer->drmHandle(), 0, 0, 0};
id = submitBuffer();
if (!id) {
@ -1915,34 +1930,48 @@ void Aquamarine::CDRMFB::drop() {
}
uint32_t Aquamarine::CDRMFB::submitBuffer() {
auto attrs = buffer->dmabuf();
uint32_t newID = 0;
std::array<uint64_t, 4> mods = {0, 0, 0, 0};
for (size_t i = 0; i < attrs.planes; ++i) {
mods[i] = attrs.modifier;
}
uint32_t newID = 0;
if (backend->drmProps.supportsAddFb2Modifiers && attrs.modifier != DRM_FORMAT_MOD_INVALID) {
TRACE(backend->backend->log(AQ_LOG_TRACE,
std::format("drm: Using drmModeAddFB2WithModifiers to import buffer into KMS: Size {} with format {} and mod {}", attrs.size,
fourccToName(attrs.format), attrs.modifier)));
if (drmModeAddFB2WithModifiers(backend->gpu->fd, attrs.size.x, attrs.size.y, attrs.format, boHandles.data(), attrs.strides.data(), attrs.offsets.data(), mods.data(),
&newID, DRM_MODE_FB_MODIFIERS)) {
backend->backend->log(AQ_LOG_ERROR, "drm: Failed to submit a buffer with drmModeAddFB2WithModifiers");
return 0;
if (buffer->type() == eBufferType::BUFFER_TYPE_DMABUF) {
auto attrs = buffer->dmabuf();
std::array<uint64_t, 4> mods = {0, 0, 0, 0};
for (size_t i = 0; i < attrs.planes; ++i) {
mods[i] = attrs.modifier;
}
if (backend->drmProps.supportsAddFb2Modifiers && attrs.modifier != DRM_FORMAT_MOD_INVALID) {
TRACE(backend->backend->log(AQ_LOG_TRACE,
std::format("drm: Using drmModeAddFB2WithModifiers to import buffer into KMS: Size {} with format {} and mod {}", attrs.size,
fourccToName(attrs.format), attrs.modifier)));
if (drmModeAddFB2WithModifiers(backend->gpu->fd, attrs.size.x, attrs.size.y, attrs.format, boHandles.data(), attrs.strides.data(), attrs.offsets.data(), mods.data(),
&newID, DRM_MODE_FB_MODIFIERS)) {
backend->backend->log(AQ_LOG_ERROR, "drm: Failed to submit a buffer with drmModeAddFB2WithModifiers");
return 0;
}
} else {
if (attrs.modifier != DRM_FORMAT_MOD_INVALID && attrs.modifier != DRM_FORMAT_MOD_LINEAR) {
backend->backend->log(AQ_LOG_ERROR, "drm: drmModeAddFB2WithModifiers unsupported and buffer has explicit modifiers");
return 0;
}
TRACE(backend->backend->log(
AQ_LOG_TRACE,
std::format("drm: Using drmModeAddFB2 to import buffer into KMS: Size {} with format {} and mod {}", attrs.size, fourccToName(attrs.format), attrs.modifier)));
if (drmModeAddFB2(backend->gpu->fd, attrs.size.x, attrs.size.y, attrs.format, boHandles.data(), attrs.strides.data(), attrs.offsets.data(), &newID, 0)) {
backend->backend->log(AQ_LOG_ERROR, "drm: Failed to submit a buffer with drmModeAddFB2");
return 0;
}
}
} else {
if (attrs.modifier != DRM_FORMAT_MOD_INVALID && attrs.modifier != DRM_FORMAT_MOD_LINEAR) {
backend->backend->log(AQ_LOG_ERROR, "drm: drmModeAddFB2WithModifiers unsupported and buffer has explicit modifiers");
return 0;
}
auto attrs = buffer->shm();
const uint32_t strides[4] = {(uint32_t)attrs.stride, 0, 0, 0};
const uint32_t offsets[4] = {0, 0, 0, 0};
TRACE(backend->backend->log(
AQ_LOG_TRACE,
std::format("drm: Using drmModeAddFB2 to import buffer into KMS: Size {} with format {} and mod {}", attrs.size, fourccToName(attrs.format), attrs.modifier)));
if (drmModeAddFB2(backend->gpu->fd, attrs.size.x, attrs.size.y, attrs.format, boHandles.data(), attrs.strides.data(), attrs.offsets.data(), &newID, 0)) {
backend->backend->log(AQ_LOG_ERROR, "drm: Failed to submit a buffer with drmModeAddFB2");
if (drmModeAddFB2(backend->gpu->fd, attrs.size.x, attrs.size.y, attrs.format, boHandles.data(), strides, offsets, &newID, 0)) {
backend->backend->log(AQ_LOG_ERROR, "drm: Failed to submit a shm buffer with drmModeAddFB2");
return 0;
}
}

View file

@ -39,3 +39,7 @@ void Aquamarine::IBuffer::unlock() {
bool Aquamarine::IBuffer::locked() {
return locks;
}
uint32_t Aquamarine::IBuffer::drmHandle() {
return 0;
}