protocols/dmabuf: fix DMA-BUF checks and events (#12965)
This commit is contained in:
parent
9f9dbb0dc5
commit
60f1c61323
3 changed files with 55 additions and 12 deletions
|
|
@ -2047,5 +2047,11 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{.value = 0, .min = 0, .max = 2},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "quirks:skip_non_kms_dmabuf_formats",
|
||||
.description = "Do not report dmabuf formats which cannot be imported into KMS",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -791,6 +791,7 @@ CConfigManager::CConfigManager() {
|
|||
registerConfigVar("ecosystem:enforce_permissions", Hyprlang::INT{0});
|
||||
|
||||
registerConfigVar("quirks:prefer_hdr", Hyprlang::INT{0});
|
||||
registerConfigVar("quirks:skip_non_kms_dmabuf_formats", Hyprlang::INT{0});
|
||||
|
||||
// devices
|
||||
m_config->addSpecialCategory("device", {"name"});
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ static std::optional<dev_t> devIDFromFD(int fd) {
|
|||
CDMABUFFormatTable::CDMABUFFormatTable(SDMABUFTranche _rendererTranche, std::vector<std::pair<PHLMONITORREF, SDMABUFTranche>> tranches_) :
|
||||
m_rendererTranche(_rendererTranche), m_monitorTranches(tranches_) {
|
||||
|
||||
static const auto PSKIP_NON_KMS = CConfigValue<Hyprlang::INT>("quirks:skip_non_kms_dmabuf_formats");
|
||||
|
||||
std::vector<SDMABUFFormatTableEntry> formatsVec;
|
||||
std::set<std::pair<uint32_t, uint64_t>> formats;
|
||||
|
||||
|
|
@ -35,6 +37,17 @@ CDMABUFFormatTable::CDMABUFFormatTable(SDMABUFTranche _rendererTranche, std::vec
|
|||
m_rendererTranche.indices.clear();
|
||||
for (auto const& fmt : m_rendererTranche.formats) {
|
||||
for (auto const& mod : fmt.modifiers) {
|
||||
LOGM(Log::TRACE, "Render format 0x{:x} ({}) with mod 0x{:x} ({})", fmt.drmFormat, NFormatUtils::drmFormatName(fmt.drmFormat), mod, NFormatUtils::drmModifierName(mod));
|
||||
if (*PSKIP_NON_KMS && !m_monitorTranches.empty()) {
|
||||
if (std::ranges::none_of(m_monitorTranches, [fmt, mod](const std::pair<PHLMONITORREF, SDMABUFTranche>& pair) {
|
||||
return std::ranges::any_of(pair.second.formats, [fmt, mod](const SDRMFormat& format) {
|
||||
return format.drmFormat == fmt.drmFormat && std::ranges::any_of(format.modifiers, [mod](uint64_t modifier) { return mod == modifier; });
|
||||
});
|
||||
})) {
|
||||
LOGM(Log::TRACE, " skipped");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
auto format = std::make_pair<>(fmt.drmFormat, mod);
|
||||
auto [_, inserted] = formats.insert(format);
|
||||
if (inserted) {
|
||||
|
|
@ -56,6 +69,9 @@ CDMABUFFormatTable::CDMABUFFormatTable(SDMABUFTranche _rendererTranche, std::vec
|
|||
tranche.indices.clear();
|
||||
for (auto const& fmt : tranche.formats) {
|
||||
for (auto const& mod : fmt.modifiers) {
|
||||
LOGM(Log::TRACE, "[DMA] Monitor format 0x{:x} ({}) with mod 0x{:x} ({})", fmt.drmFormat, NFormatUtils::drmFormatName(fmt.drmFormat), mod,
|
||||
NFormatUtils::drmModifierName(mod));
|
||||
// FIXME: recheck this. DRM_FORMAT_MOD_INVALID is allowed by the proto "For legacy support". DRM_FORMAT_MOD_LINEAR should be the most compatible mod
|
||||
// apparently these can implode on planes, so don't use them
|
||||
if (mod == DRM_FORMAT_MOD_INVALID || mod == DRM_FORMAT_MOD_LINEAR)
|
||||
continue;
|
||||
|
|
@ -147,10 +163,17 @@ CLinuxDMABUFParamsResource::CLinuxDMABUFParamsResource(UP<CZwpLinuxBufferParamsV
|
|||
return;
|
||||
}
|
||||
|
||||
const uint64_t modifier = (sc<uint64_t>(modHi) << 32) | modLo;
|
||||
|
||||
if (m_resource->version() >= 5 && m_attrs->modifier && m_attrs->modifier != modifier) {
|
||||
r->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_FORMAT, "planes have different modifiers");
|
||||
return;
|
||||
}
|
||||
|
||||
m_attrs->fds[plane] = fd;
|
||||
m_attrs->strides[plane] = stride;
|
||||
m_attrs->offsets[plane] = offset;
|
||||
m_attrs->modifier = (sc<uint64_t>(modHi) << 32) | modLo;
|
||||
m_attrs->modifier = modifier;
|
||||
});
|
||||
|
||||
m_resource->setCreate([this](CZwpLinuxBufferParamsV1* r, int32_t w, int32_t h, uint32_t fmt, zwpLinuxBufferParamsV1Flags flags) {
|
||||
|
|
@ -165,6 +188,13 @@ CLinuxDMABUFParamsResource::CLinuxDMABUFParamsResource(UP<CZwpLinuxBufferParamsV
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_resource->version() >= 4 && std::ranges::none_of(PROTO::linuxDma->m_formatTable->m_rendererTranche.formats, [this, fmt](const auto format) {
|
||||
return format.drmFormat == fmt && std::ranges::any_of(format.modifiers, [this](const auto mod) { return !mod || mod == m_attrs->modifier; });
|
||||
})) {
|
||||
r->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_FORMAT, "format + modifier pair is not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
m_attrs->size = {w, h};
|
||||
m_attrs->format = fmt;
|
||||
m_attrs->planes = 4 - std::ranges::count(m_attrs->fds, -1);
|
||||
|
|
@ -382,8 +412,7 @@ CLinuxDMABUFResource::CLinuxDMABUFResource(UP<CZwpLinuxDmabufV1>&& resource_) :
|
|||
}
|
||||
});
|
||||
|
||||
if (m_resource->version() < 4)
|
||||
sendMods();
|
||||
sendMods();
|
||||
}
|
||||
|
||||
bool CLinuxDMABUFResource::good() {
|
||||
|
|
@ -392,16 +421,14 @@ bool CLinuxDMABUFResource::good() {
|
|||
|
||||
void CLinuxDMABUFResource::sendMods() {
|
||||
for (auto const& fmt : PROTO::linuxDma->m_formatTable->m_rendererTranche.formats) {
|
||||
for (auto const& mod : fmt.modifiers) {
|
||||
if (m_resource->version() < 3) {
|
||||
if (mod == DRM_FORMAT_MOD_INVALID || mod == DRM_FORMAT_MOD_LINEAR)
|
||||
m_resource->sendFormat(fmt.drmFormat);
|
||||
continue;
|
||||
m_resource->sendFormat(fmt.drmFormat);
|
||||
|
||||
if (m_resource->version() == 3) {
|
||||
for (auto const& mod : fmt.modifiers) {
|
||||
// TODO: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1166
|
||||
|
||||
m_resource->sendModifier(fmt.drmFormat, mod >> 32, mod & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// TODO: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1166
|
||||
|
||||
m_resource->sendModifier(fmt.drmFormat, mod >> 32, mod & 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -456,6 +483,15 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const
|
|||
std::erase_if(m_formatTable->m_monitorTranches, [pMonitor](std::pair<PHLMONITORREF, SDMABUFTranche> pair) { return pair.first == pMonitor; });
|
||||
resetFormatTable();
|
||||
});
|
||||
|
||||
static auto configReloaded = g_pHookSystem->hookDynamic("configReloaded", [this](void* self, SCallbackInfo& info, std::any param) {
|
||||
static const auto PSKIP_NON_KMS = CConfigValue<Hyprlang::INT>("quirks:skip_non_kms_dmabuf_formats");
|
||||
static auto prev = *PSKIP_NON_KMS;
|
||||
if (prev != *PSKIP_NON_KMS) {
|
||||
prev = *PSKIP_NON_KMS;
|
||||
resetFormatTable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
m_formatTable = makeUnique<CDMABUFFormatTable>(eglTranche, tches);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue