initial impl of ctm

This commit is contained in:
Vaxry 2024-10-07 19:04:00 +01:00
parent b82fdaff91
commit 62031d59bb
6 changed files with 44 additions and 0 deletions

View file

@ -7,6 +7,7 @@
#include <hyprutils/memory/WeakPtr.hpp>
#include <wayland-client.h>
#include <xf86drmMode.h>
#include <optional>
namespace Aquamarine {
class CDRMBackend;
@ -162,6 +163,7 @@ namespace Aquamarine {
bool ownModeID = false;
uint32_t modeID = 0;
uint32_t gammaLut = 0;
uint32_t ctm = 0;
} atomic;
Hyprutils::Memory::CSharedPointer<SDRMPlane> primary;
@ -175,6 +177,7 @@ namespace Aquamarine {
uint32_t vrr_enabled;
uint32_t gamma_lut;
uint32_t gamma_lut_size;
uint32_t ctm;
// atomic-modesetting only
@ -242,13 +245,16 @@ namespace Aquamarine {
uint32_t flags = 0;
bool test = false;
drmModeModeInfo modeInfo;
std::optional<Hyprutils::Math::Mat3x3> ctm;
struct {
uint32_t gammaLut = 0;
uint32_t fbDamage = 0;
uint32_t modeBlob = 0;
uint32_t ctmBlob = 0;
bool blobbed = false;
bool gammad = false;
bool ctmd = false;
} atomic;
void calculateMode(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);

View file

@ -5,6 +5,7 @@
#include <hyprutils/signal/Signal.hpp>
#include <hyprutils/memory/SharedPtr.hpp>
#include <hyprutils/math/Region.hpp>
#include <hyprutils/math/Mat3x3.hpp>
#include <drm_fourcc.h>
#include <xf86drmMode.h>
#include "../allocator/Swapchain.hpp"
@ -51,6 +52,7 @@ namespace Aquamarine {
AQ_OUTPUT_STATE_BUFFER = (1 << 7),
AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE = (1 << 8),
AQ_OUTPUT_STATE_EXPLICIT_OUT_FENCE = (1 << 9),
AQ_OUTPUT_STATE_CTM = (1 << 10),
};
struct SInternalState {
@ -67,6 +69,7 @@ namespace Aquamarine {
uint32_t drmFormat = DRM_FORMAT_INVALID;
Hyprutils::Memory::CSharedPointer<IBuffer> buffer;
int64_t explicitInFence = -1, explicitOutFence = -1;
Hyprutils::Math::Mat3x3 ctm;
};
const SInternalState& state();
@ -84,6 +87,7 @@ namespace Aquamarine {
void setExplicitInFence(int64_t fenceFD); // -1 removes
void setExplicitOutFence(int64_t fenceFD); // -1 removes
void resetExplicitFences();
void setCTM(const Hyprutils::Math::Mat3x3& ctm);
private:
SInternalState internalState;

View file

@ -1183,6 +1183,8 @@ void Aquamarine::SDRMConnector::recheckCRTCProps() {
output->supportsExplicit = backend->drmProps.supportsTimelines && crtc->props.out_fence_ptr && crtc->primary->props.in_fence_fd;
backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Explicit sync {}", output->supportsExplicit ? "supported" : "unsupported"));
backend->backend->log(AQ_LOG_DEBUG, std::format("drm: connector {} crtc {} CTM", szName, (crtc->props.ctm ? "supports" : "doesn't support")));
}
void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
@ -1577,6 +1579,9 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) {
}
}
if (COMMITTED & COutputState::eOutputStateProperties::AQ_OUTPUT_STATE_CTM)
data.ctm = STATE.ctm;
data.blocking = BLOCKING || formatMismatch;
data.modeset = NEEDS_RECONFIG || lastCommitNoBuffer || formatMismatch;
data.flags = flags;

View file

@ -38,6 +38,7 @@ static const struct prop_info crtc_info[] = {
#define INDEX(name) (offsetof(SDRMCRTC::UDRMCRTCProps, name) / sizeof(uint32_t))
{"ACTIVE", INDEX(active)}, {"GAMMA_LUT", INDEX(gamma_lut)}, {"GAMMA_LUT_SIZE", INDEX(gamma_lut_size)},
{"MODE_ID", INDEX(mode_id)}, {"OUT_FENCE_PTR", INDEX(out_fence_ptr)}, {"VRR_ENABLED", INDEX(vrr_enabled)},
{"CTM", INDEX(ctm)},
#undef INDEX
};

View file

@ -100,6 +100,9 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint
if (data.modeset && enable && connector->props.max_bpc && connector->maxBpcBounds.at(1))
add(connector->id, connector->props.max_bpc, 8); // FIXME: this isnt always 8
if (data.ctm.has_value() && connector->crtc->props.ctm && data.atomic.ctmBlob && data.atomic.ctmd)
add(connector->crtc->id, connector->crtc->props.ctm, data.atomic.ctmBlob);
add(connector->crtc->id, connector->crtc->props.active, enable);
if (enable) {
@ -197,6 +200,7 @@ void Aquamarine::CDRMAtomicRequest::rollback(SDRMConnectorCommitData& data) {
if (data.atomic.blobbed)
rollbackBlob(&conn->crtc->atomic.modeID, data.atomic.modeBlob);
rollbackBlob(&conn->crtc->atomic.gammaLut, data.atomic.gammaLut);
rollbackBlob(&conn->crtc->atomic.ctm, data.atomic.ctmBlob);
destroyBlob(data.atomic.fbDamage);
}
@ -211,6 +215,7 @@ void Aquamarine::CDRMAtomicRequest::apply(SDRMConnectorCommitData& data) {
if (data.atomic.blobbed)
commitBlob(&conn->crtc->atomic.modeID, data.atomic.modeBlob);
commitBlob(&conn->crtc->atomic.gammaLut, data.atomic.gammaLut);
commitBlob(&conn->crtc->atomic.ctm, data.atomic.ctmBlob);
destroyBlob(data.atomic.fbDamage);
}
@ -263,6 +268,24 @@ bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPoin
}
}
if ((STATE.committed & COutputState::AQ_OUTPUT_STATE_CTM) && data.ctm.has_value()) {
if (!connector->crtc->props.ctm)
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to commit ctm: no ctm prop support");
else {
drm_color_ctm ctm = {0};
for (size_t i = 0; i < 9; ++i) {
const double val = data.ctm->getMatrix()[i];
ctm.matrix[i] = static_cast<uint64_t>(val * std::pow(2, 32));
}
if (drmModeCreatePropertyBlob(connector->backend->gpu->fd, &ctm, sizeof(drm_color_ctm), &data.atomic.ctmBlob)) {
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to create a ctm blob");
data.atomic.ctmBlob = 0;
} else
data.atomic.ctmd = true;
}
}
if ((STATE.committed & COutputState::AQ_OUTPUT_STATE_DAMAGE) && connector->crtc->primary->props.fb_damage_clips && MODE) {
if (STATE.damage.empty())
data.atomic.fbDamage = 0;

View file

@ -115,6 +115,11 @@ void Aquamarine::COutputState::resetExplicitFences() {
internalState.explicitOutFence = -1;
}
void Aquamarine::COutputState::setCTM(const Hyprutils::Math::Mat3x3& ctm) {
internalState.ctm = ctm;
internalState.committed |= AQ_OUTPUT_STATE_CTM;
}
void Aquamarine::COutputState::onCommit() {
internalState.committed = 0;
internalState.damage.clear();