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 hotspot_x;
uint32_t hotspot_y;
uint32_t in_fence_fd;
};
uint32_t props[16] = {0};
uint32_t props[17] = {0};
};
UDRMPlaneProps props;
};
@ -171,8 +172,9 @@ namespace Aquamarine {
uint32_t active;
uint32_t mode_id;
uint32_t out_fence_ptr;
};
uint32_t props[6] = {0};
uint32_t props[7] = {0};
};
UDRMCRTCProps props;
};

View File

@ -48,6 +48,8 @@ namespace Aquamarine {
AQ_OUTPUT_STATE_MODE = (1 << 5),
AQ_OUTPUT_STATE_FORMAT = (1 << 6),
AQ_OUTPUT_STATE_BUFFER = (1 << 7),
AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE = (1 << 8),
AQ_OUTPUT_STATE_EXPLICIT_OUT_FENCE = (1 << 9),
};
struct SInternalState {
@ -63,6 +65,7 @@ namespace Aquamarine {
Hyprutils::Memory::CSharedPointer<SOutputMode> customMode;
uint32_t drmFormat = DRM_FORMAT_INVALID;
Hyprutils::Memory::CSharedPointer<IBuffer> buffer;
int64_t explicitInFence = -1, explicitOutFence = -1;
};
const SInternalState& state();
@ -77,6 +80,8 @@ namespace Aquamarine {
void setCustomMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode);
void setFormat(uint32_t drmFormat);
void setBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer);
void setExplicitInFence(int64_t fenceFD); // -1 removes
void setExplicitOutFence(int64_t fenceFD); // -1 removes
private:
SInternalState internalState;
@ -114,6 +119,7 @@ namespace Aquamarine {
eSubpixelMode subpixel = AQ_SUBPIXEL_NONE;
bool vrrCapable = false, vrrActive = false;
bool needsFrame = false;
bool supportsExplicit = false;
//
std::vector<Hyprutils::Memory::CSharedPointer<SOutputMode>> modes;

View File

@ -1050,6 +1050,9 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
output->serial = serial;
output->description = std::format("{} {} {} ({})", make, model, serial, szName);
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));

View File

@ -36,20 +36,30 @@ static const struct prop_info connector_info[] = {
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)}, {"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
};
static const struct prop_info plane_info[] = {
#define INDEX(name) (offsetof(SDRMPlane::UDRMPlaneProps, name) / sizeof(uint32_t))
{"CRTC_H", INDEX(crtc_h)}, {"CRTC_ID", INDEX(crtc_id)},
{"CRTC_W", INDEX(crtc_w)}, {"CRTC_X", INDEX(crtc_x)},
{"CRTC_Y", INDEX(crtc_y)}, {"FB_DAMAGE_CLIPS", INDEX(fb_damage_clips)},
{"FB_ID", INDEX(fb_id)}, {"HOTSPOT_X", INDEX(hotspot_x)},
{"HOTSPOT_Y", INDEX(hotspot_y)}, {"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)},
{"CRTC_H", INDEX(crtc_h)},
{"CRTC_ID", INDEX(crtc_id)},
{"CRTC_W", INDEX(crtc_w)},
{"CRTC_X", INDEX(crtc_x)},
{"CRTC_Y", INDEX(crtc_y)},
{"FB_DAMAGE_CLIPS", INDEX(fb_damage_clips)},
{"FB_ID", INDEX(fb_id)},
{"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
};

View File

@ -100,6 +100,9 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint
add(connector->crtc->id, connector->crtc->props.active, 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)
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, {});
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)
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;
}
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() {
internalState.committed = 0;
internalState.damage.clear();
// fences are now used, let's reset them to not confuse ourselves later.
internalState.explicitInFence = -1;
internalState.explicitOutFence = -1;
}