drm: add support for explicit sync

This commit is contained in:
Vaxry 2024-07-06 17:38:13 +02:00
parent bb8743d9be
commit 330c089cd8
6 changed files with 66 additions and 25 deletions

View file

@ -134,8 +134,9 @@ namespace Aquamarine {
uint32_t fb_damage_clips; uint32_t fb_damage_clips;
uint32_t hotspot_x; uint32_t hotspot_x;
uint32_t hotspot_y; uint32_t hotspot_y;
uint32_t in_fence_fd;
}; };
uint32_t props[16] = {0}; uint32_t props[17] = {0};
}; };
UDRMPlaneProps props; UDRMPlaneProps props;
}; };
@ -171,8 +172,9 @@ namespace Aquamarine {
uint32_t active; uint32_t active;
uint32_t mode_id; uint32_t mode_id;
uint32_t out_fence_ptr;
}; };
uint32_t props[6] = {0}; uint32_t props[7] = {0};
}; };
UDRMCRTCProps props; UDRMCRTCProps props;
}; };

View file

@ -40,14 +40,16 @@ namespace Aquamarine {
class COutputState { class COutputState {
public: public:
enum eOutputStateProperties : uint32_t { enum eOutputStateProperties : uint32_t {
AQ_OUTPUT_STATE_DAMAGE = (1 << 0), AQ_OUTPUT_STATE_DAMAGE = (1 << 0),
AQ_OUTPUT_STATE_ENABLED = (1 << 1), AQ_OUTPUT_STATE_ENABLED = (1 << 1),
AQ_OUTPUT_STATE_ADAPTIVE_SYNC = (1 << 2), AQ_OUTPUT_STATE_ADAPTIVE_SYNC = (1 << 2),
AQ_OUTPUT_STATE_PRESENTATION_MODE = (1 << 3), AQ_OUTPUT_STATE_PRESENTATION_MODE = (1 << 3),
AQ_OUTPUT_STATE_GAMMA_LUT = (1 << 4), AQ_OUTPUT_STATE_GAMMA_LUT = (1 << 4),
AQ_OUTPUT_STATE_MODE = (1 << 5), AQ_OUTPUT_STATE_MODE = (1 << 5),
AQ_OUTPUT_STATE_FORMAT = (1 << 6), AQ_OUTPUT_STATE_FORMAT = (1 << 6),
AQ_OUTPUT_STATE_BUFFER = (1 << 7), AQ_OUTPUT_STATE_BUFFER = (1 << 7),
AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE = (1 << 8),
AQ_OUTPUT_STATE_EXPLICIT_OUT_FENCE = (1 << 9),
}; };
struct SInternalState { struct SInternalState {
@ -63,6 +65,7 @@ namespace Aquamarine {
Hyprutils::Memory::CSharedPointer<SOutputMode> customMode; Hyprutils::Memory::CSharedPointer<SOutputMode> customMode;
uint32_t drmFormat = DRM_FORMAT_INVALID; uint32_t drmFormat = DRM_FORMAT_INVALID;
Hyprutils::Memory::CSharedPointer<IBuffer> buffer; Hyprutils::Memory::CSharedPointer<IBuffer> buffer;
int64_t explicitInFence = -1, explicitOutFence = -1;
}; };
const SInternalState& state(); const SInternalState& state();
@ -77,6 +80,8 @@ namespace Aquamarine {
void setCustomMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode); void setCustomMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode);
void setFormat(uint32_t drmFormat); void setFormat(uint32_t drmFormat);
void setBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer); void setBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer);
void setExplicitInFence(int64_t fenceFD); // -1 removes
void setExplicitOutFence(int64_t fenceFD); // -1 removes
private: private:
SInternalState internalState; SInternalState internalState;
@ -113,7 +118,8 @@ namespace Aquamarine {
bool nonDesktop = false; bool nonDesktop = false;
eSubpixelMode subpixel = AQ_SUBPIXEL_NONE; eSubpixelMode subpixel = AQ_SUBPIXEL_NONE;
bool vrrCapable = false, vrrActive = false; bool vrrCapable = false, vrrActive = false;
bool needsFrame = false; bool needsFrame = false;
bool supportsExplicit = false;
// //
std::vector<Hyprutils::Memory::CSharedPointer<SOutputMode>> modes; std::vector<Hyprutils::Memory::CSharedPointer<SOutputMode>> modes;

View file

@ -1045,11 +1045,14 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
// TODO: subconnectors // TODO: subconnectors
output->make = make; output->make = make;
output->model = model; output->model = model;
output->serial = serial; output->serial = serial;
output->description = std::format("{} {} {} ({})", make, model, serial, szName); output->description = std::format("{} {} {} ({})", make, model, serial, szName);
output->needsFrame = true; output->needsFrame = true;
output->supportsExplicit = 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: Description {}", output->description)); backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Description {}", output->description));

View file

@ -36,20 +36,30 @@ static const struct prop_info connector_info[] = {
static const struct prop_info crtc_info[] = { static const struct prop_info crtc_info[] = {
#define INDEX(name) (offsetof(SDRMCRTC::UDRMCRTCProps, name) / sizeof(uint32_t)) #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)}, {"VRR_ENABLED", INDEX(vrr_enabled)}, {"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)},
#undef INDEX #undef INDEX
}; };
static const struct prop_info plane_info[] = { static const struct prop_info plane_info[] = {
#define INDEX(name) (offsetof(SDRMPlane::UDRMPlaneProps, name) / sizeof(uint32_t)) #define INDEX(name) (offsetof(SDRMPlane::UDRMPlaneProps, name) / sizeof(uint32_t))
{"CRTC_H", INDEX(crtc_h)}, {"CRTC_ID", INDEX(crtc_id)}, {"CRTC_H", INDEX(crtc_h)},
{"CRTC_W", INDEX(crtc_w)}, {"CRTC_X", INDEX(crtc_x)}, {"CRTC_ID", INDEX(crtc_id)},
{"CRTC_Y", INDEX(crtc_y)}, {"FB_DAMAGE_CLIPS", INDEX(fb_damage_clips)}, {"CRTC_W", INDEX(crtc_w)},
{"FB_ID", INDEX(fb_id)}, {"HOTSPOT_X", INDEX(hotspot_x)}, {"CRTC_X", INDEX(crtc_x)},
{"HOTSPOT_Y", INDEX(hotspot_y)}, {"IN_FORMATS", INDEX(in_formats)}, {"CRTC_Y", INDEX(crtc_y)},
{"SRC_H", INDEX(src_h)}, {"SRC_W", INDEX(src_w)}, {"FB_DAMAGE_CLIPS", INDEX(fb_damage_clips)},
{"SRC_X", INDEX(src_x)}, {"SRC_Y", INDEX(src_y)}, {"FB_ID", INDEX(fb_id)},
{"rotation", INDEX(rotation)}, {"type", INDEX(type)}, {"HOTSPOT_X", INDEX(hotspot_x)},
{"HOTSPOT_Y", INDEX(hotspot_y)},
{"IN_FENCE_FD", INDEX(in_fence_fd)},
{"IN_FORMATS", INDEX(in_formats)},
{"SRC_H", INDEX(src_h)},
{"SRC_W", INDEX(src_w)},
{"SRC_X", INDEX(src_x)},
{"SRC_Y", INDEX(src_y)},
{"rotation", INDEX(rotation)},
{"type", INDEX(type)},
#undef INDEX #undef INDEX
}; };

View file

@ -100,6 +100,9 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint
add(connector->crtc->id, connector->crtc->props.active, enable); add(connector->crtc->id, connector->crtc->props.active, enable);
if (enable) { if (enable) {
if (connector->output->supportsExplicit && STATE.explicitOutFence >= 0)
add(connector->crtc->id, connector->crtc->props.out_fence_ptr, STATE.explicitOutFence);
if (connector->crtc->props.gamma_lut && data.atomic.gammad) if (connector->crtc->props.gamma_lut && data.atomic.gammad)
add(connector->crtc->id, connector->crtc->props.gamma_lut, data.atomic.gammaLut); add(connector->crtc->id, connector->crtc->props.gamma_lut, data.atomic.gammaLut);
@ -108,6 +111,9 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint
planeProps(connector->crtc->primary, data.mainFB, connector->crtc->id, {}); planeProps(connector->crtc->primary, data.mainFB, connector->crtc->id, {});
if (connector->output->supportsExplicit && STATE.explicitInFence >= 0)
add(connector->crtc->primary->id, connector->crtc->primary->props.in_fence_fd, STATE.explicitInFence);
if (connector->crtc->primary->props.fb_damage_clips) if (connector->crtc->primary->props.fb_damage_clips)
add(connector->crtc->primary->id, connector->crtc->primary->props.fb_damage_clips, data.atomic.fbDamage); add(connector->crtc->primary->id, connector->crtc->primary->props.fb_damage_clips, data.atomic.fbDamage);

View file

@ -95,7 +95,21 @@ void Aquamarine::COutputState::setBuffer(Hyprutils::Memory::CSharedPointer<IBuff
internalState.committed |= AQ_OUTPUT_STATE_BUFFER; internalState.committed |= AQ_OUTPUT_STATE_BUFFER;
} }
void Aquamarine::COutputState::setExplicitInFence(int64_t fenceFD) {
internalState.explicitInFence = fenceFD;
internalState.committed |= AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE;
}
void Aquamarine::COutputState::setExplicitOutFence(int64_t fenceFD) {
internalState.explicitOutFence = fenceFD;
internalState.committed |= AQ_OUTPUT_STATE_EXPLICIT_OUT_FENCE;
}
void Aquamarine::COutputState::onCommit() { void Aquamarine::COutputState::onCommit() {
internalState.committed = 0; internalState.committed = 0;
internalState.damage.clear(); internalState.damage.clear();
// fences are now used, let's reset them to not confuse ourselves later.
internalState.explicitInFence = -1;
internalState.explicitOutFence = -1;
} }