platforms/drm: multi-gpu buffer import with modifiers
This commit is contained in:
parent
35ec9b87a7
commit
e6cab81b53
3 changed files with 53 additions and 23 deletions
|
@ -41,11 +41,15 @@ public:
|
||||||
Q_UNUSED(stride)
|
Q_UNUSED(stride)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
virtual int exportFramebufferAsDmabuf(DrmAbstractOutput *output, uint32_t *format, uint32_t *stride) {
|
virtual bool exportFramebufferAsDmabuf(DrmAbstractOutput *output, int *fds, int *strides, int *offsets, uint32_t *num_fds, uint32_t *format, uint64_t *modifier) {
|
||||||
Q_UNUSED(output)
|
Q_UNUSED(output)
|
||||||
|
Q_UNUSED(fds)
|
||||||
|
Q_UNUSED(strides)
|
||||||
|
Q_UNUSED(offsets)
|
||||||
|
Q_UNUSED(num_fds)
|
||||||
Q_UNUSED(format)
|
Q_UNUSED(format)
|
||||||
Q_UNUSED(stride)
|
Q_UNUSED(modifier)
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
virtual QRegion beginFrameForSecondaryGpu(DrmAbstractOutput *output) {
|
virtual QRegion beginFrameForSecondaryGpu(DrmAbstractOutput *output) {
|
||||||
Q_UNUSED(output)
|
Q_UNUSED(output)
|
||||||
|
|
|
@ -270,7 +270,7 @@ bool EglGbmBackend::exportFramebuffer(DrmAbstractOutput *drmOutput, void *data,
|
||||||
return memcpy(data, bo->mappedData(), size.height() * stride);
|
return memcpy(data, bo->mappedData(), size.height() * stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
int EglGbmBackend::exportFramebufferAsDmabuf(DrmAbstractOutput *drmOutput, uint32_t *format, uint32_t *stride)
|
bool EglGbmBackend::exportFramebufferAsDmabuf(DrmAbstractOutput *drmOutput, int *fds, int *strides, int *offsets, uint32_t *num_fds, uint32_t *format, uint64_t *modifier)
|
||||||
{
|
{
|
||||||
auto it = std::find_if(m_secondaryGpuOutputs.begin(), m_secondaryGpuOutputs.end(),
|
auto it = std::find_if(m_secondaryGpuOutputs.begin(), m_secondaryGpuOutputs.end(),
|
||||||
[drmOutput] (const Output &output) {
|
[drmOutput] (const Output &output) {
|
||||||
|
@ -281,14 +281,33 @@ int EglGbmBackend::exportFramebufferAsDmabuf(DrmAbstractOutput *drmOutput, uint3
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
auto bo = it->current.gbmSurface->currentBuffer()->getBo();
|
auto bo = it->current.gbmSurface->currentBuffer()->getBo();
|
||||||
int fd = gbm_bo_get_fd(bo);
|
if (gbm_bo_get_handle_for_plane(bo, 0).s32 != -1) {
|
||||||
if (fd == -1) {
|
*num_fds = gbm_bo_get_plane_count(bo);
|
||||||
qCWarning(KWIN_DRM) << "failed to export gbm_bo as dma-buf:" << strerror(errno);
|
for (uint32_t i = 0; i < *num_fds; i++) {
|
||||||
return -1;
|
fds[i] = gbm_bo_get_fd_for_plane(bo, i);
|
||||||
|
if (fds[i] < 0) {
|
||||||
|
qCWarning(KWIN_DRM) << "failed to export gbm_bo as dma-buf:" << strerror(errno);
|
||||||
|
for (uint32_t f = 0; f < i; f++) {
|
||||||
|
close(fds[f]);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
strides[i] = gbm_bo_get_stride_for_plane(bo, i);
|
||||||
|
offsets[i] = gbm_bo_get_offset(bo, i);
|
||||||
|
}
|
||||||
|
*modifier = gbm_bo_get_modifier(bo);
|
||||||
|
} else {
|
||||||
|
fds[0] = gbm_bo_get_fd(bo);
|
||||||
|
if (fds[0] < 0) {
|
||||||
|
qCWarning(KWIN_DRM) << "failed to export gbm_bo as dma-buf:" << strerror(errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*num_fds = 1;
|
||||||
|
strides[0] = gbm_bo_get_stride(bo);
|
||||||
|
*modifier = DRM_FORMAT_MOD_INVALID;
|
||||||
}
|
}
|
||||||
*format = gbm_bo_get_format(bo);
|
*format = gbm_bo_get_format(bo);
|
||||||
*stride = gbm_bo_get_stride(bo);
|
return true;
|
||||||
return fd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QRegion EglGbmBackend::beginFrameForSecondaryGpu(DrmAbstractOutput *drmOutput)
|
QRegion EglGbmBackend::beginFrameForSecondaryGpu(DrmAbstractOutput *drmOutput)
|
||||||
|
@ -312,18 +331,25 @@ QSharedPointer<DrmBuffer> EglGbmBackend::importFramebuffer(Output &output, const
|
||||||
}
|
}
|
||||||
const auto size = output.output->modeSize();
|
const auto size = output.output->modeSize();
|
||||||
if (output.current.importMode == ImportMode::Dmabuf) {
|
if (output.current.importMode == ImportMode::Dmabuf) {
|
||||||
uint32_t stride = 0;
|
struct gbm_import_fd_modifier_data data;
|
||||||
uint32_t format = 0;
|
data.width = size.width();
|
||||||
int fd = renderingBackend()->exportFramebufferAsDmabuf(output.output, &format, &stride);
|
data.height = size.height();
|
||||||
if (fd != -1) {
|
if (renderingBackend()->exportFramebufferAsDmabuf(output.output, data.fds, data.strides, data.offsets, &data.num_fds, &data.format, &data.modifier)) {
|
||||||
struct gbm_import_fd_data data = {};
|
gbm_bo *importedBuffer = nullptr;
|
||||||
data.fd = fd;
|
if (data.modifier == DRM_FORMAT_MOD_INVALID) {
|
||||||
data.width = (uint32_t) size.width();
|
struct gbm_import_fd_data data1;
|
||||||
data.height = (uint32_t) size.height();
|
data1.fd = data.fds[0];
|
||||||
data.stride = stride;
|
data1.width = size.width();
|
||||||
data.format = format;
|
data1.height = size.height();
|
||||||
gbm_bo *importedBuffer = gbm_bo_import(m_gpu->gbmDevice(), GBM_BO_IMPORT_FD, &data, GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR);
|
data1.stride = data.strides[0];
|
||||||
close(fd);
|
data1.format = data.format;
|
||||||
|
importedBuffer = gbm_bo_import(m_gpu->gbmDevice(), GBM_BO_IMPORT_FD, &data1, GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR);
|
||||||
|
} else {
|
||||||
|
importedBuffer = gbm_bo_import(m_gpu->gbmDevice(), GBM_BO_IMPORT_FD_MODIFIER, &data, 0);
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < data.num_fds; i++) {
|
||||||
|
close(data.fds[i]);
|
||||||
|
}
|
||||||
if (importedBuffer) {
|
if (importedBuffer) {
|
||||||
auto buffer = QSharedPointer<DrmGbmBuffer>::create(m_gpu, importedBuffer, nullptr);
|
auto buffer = QSharedPointer<DrmGbmBuffer>::create(m_gpu, importedBuffer, nullptr);
|
||||||
if (buffer->bufferId() > 0) {
|
if (buffer->bufferId() > 0) {
|
||||||
|
|
|
@ -62,7 +62,7 @@ public:
|
||||||
void removeOutput(DrmAbstractOutput *output) override;
|
void removeOutput(DrmAbstractOutput *output) override;
|
||||||
bool swapBuffers(DrmAbstractOutput *output, const QRegion &dirty) override;
|
bool swapBuffers(DrmAbstractOutput *output, const QRegion &dirty) override;
|
||||||
bool exportFramebuffer(DrmAbstractOutput *output, void *data, const QSize &size, uint32_t stride) override;
|
bool exportFramebuffer(DrmAbstractOutput *output, void *data, const QSize &size, uint32_t stride) override;
|
||||||
int exportFramebufferAsDmabuf(DrmAbstractOutput *output, uint32_t *format, uint32_t *stride) override;
|
bool exportFramebufferAsDmabuf(DrmAbstractOutput *output, int *fds, int *strides, int *offsets, uint32_t *num_fds, uint32_t *format, uint64_t *modifier) override;
|
||||||
QRegion beginFrameForSecondaryGpu(DrmAbstractOutput *output) override;
|
QRegion beginFrameForSecondaryGpu(DrmAbstractOutput *output) override;
|
||||||
|
|
||||||
bool directScanoutAllowed(int screen) const override;
|
bool directScanoutAllowed(int screen) const override;
|
||||||
|
|
Loading…
Reference in a new issue