backend/drm: remove primary swapchain
We can't nuke it completely, we still need it for multi-GPU.
This commit is contained in:
		
							parent
							
								
									85d7ad2eef
								
							
						
					
					
						commit
						f5900c1f00
					
				|  | @ -329,21 +329,6 @@ static struct wlr_drm_connector *get_drm_connector_from_output( | |||
| 	return (struct wlr_drm_connector *)wlr_output; | ||||
| } | ||||
| 
 | ||||
| static bool drm_connector_attach_render(struct wlr_output *output, | ||||
| 		int *buffer_age) { | ||||
| 	struct wlr_drm_connector *conn = get_drm_connector_from_output(output); | ||||
| 	return drm_surface_make_current(&conn->crtc->primary->surf, buffer_age); | ||||
| } | ||||
| 
 | ||||
| static void drm_plane_set_committed(struct wlr_drm_plane *plane) { | ||||
| 	drm_fb_move(&plane->queued_fb, &plane->pending_fb); | ||||
| 
 | ||||
| 	if (plane->queued_fb && plane->surf.swapchain) { | ||||
| 		wlr_swapchain_set_buffer_submitted(plane->surf.swapchain, | ||||
| 			plane->queued_fb->wlr_buf); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static bool drm_crtc_commit(struct wlr_drm_connector *conn, | ||||
| 		const struct wlr_output_state *state, uint32_t flags, bool test_only) { | ||||
| 	// Disallow atomic-only flags
 | ||||
|  | @ -353,9 +338,9 @@ static bool drm_crtc_commit(struct wlr_drm_connector *conn, | |||
| 	struct wlr_drm_crtc *crtc = conn->crtc; | ||||
| 	bool ok = drm->iface->crtc_commit(conn, state, flags, test_only); | ||||
| 	if (ok && !test_only) { | ||||
| 		drm_plane_set_committed(crtc->primary); | ||||
| 		drm_fb_move(&crtc->primary->queued_fb, &crtc->primary->pending_fb); | ||||
| 		if (crtc->cursor != NULL) { | ||||
| 			drm_plane_set_committed(crtc->cursor); | ||||
| 			drm_fb_move(&crtc->cursor->queued_fb, &crtc->cursor->pending_fb); | ||||
| 		} | ||||
| 	} else { | ||||
| 		drm_fb_clear(&crtc->primary->pending_fb); | ||||
|  | @ -411,21 +396,37 @@ static bool drm_connector_set_pending_fb(struct wlr_drm_connector *conn, | |||
| 	struct wlr_drm_plane *plane = crtc->primary; | ||||
| 
 | ||||
| 	assert(state->committed & WLR_OUTPUT_STATE_BUFFER); | ||||
| 	switch (state->buffer_type) { | ||||
| 	case WLR_OUTPUT_STATE_BUFFER_RENDER: | ||||
| 		if (!drm_plane_lock_surface(plane, drm)) { | ||||
| 			wlr_drm_conn_log(conn, WLR_ERROR, "drm_plane_lock_surface failed"); | ||||
| 	assert(state->buffer_type == WLR_OUTPUT_STATE_BUFFER_SCANOUT); | ||||
| 
 | ||||
| 	struct wlr_buffer *local_buf; | ||||
| 	if (drm->parent) { | ||||
| 		struct wlr_drm_format *format = | ||||
| 			drm_plane_pick_render_format(plane, &drm->renderer); | ||||
| 		if (format == NULL) { | ||||
| 			wlr_log(WLR_ERROR, "Failed to pick primary plane format"); | ||||
| 			return false; | ||||
| 		} | ||||
| 		break; | ||||
| 	case WLR_OUTPUT_STATE_BUFFER_SCANOUT:; | ||||
| 		if (!drm_fb_import(&plane->pending_fb, drm, state->buffer, | ||||
| 				&crtc->primary->formats)) { | ||||
| 			wlr_drm_conn_log(conn, WLR_DEBUG, | ||||
| 				"Failed to import buffer for scan-out"); | ||||
| 
 | ||||
| 		// TODO: fallback to modifier-less buffer allocation
 | ||||
| 		bool ok = init_drm_surface(&plane->mgpu_surf, &drm->renderer, | ||||
| 			state->buffer->width, state->buffer->height, format); | ||||
| 		free(format); | ||||
| 		if (!ok) { | ||||
| 			return false; | ||||
| 		} | ||||
| 		break; | ||||
| 
 | ||||
| 		local_buf = drm_surface_blit(&plane->mgpu_surf, state->buffer); | ||||
| 	} else { | ||||
| 		local_buf = wlr_buffer_lock(state->buffer); | ||||
| 	} | ||||
| 
 | ||||
| 	bool ok = drm_fb_import(&plane->pending_fb, drm, local_buf, | ||||
| 		&crtc->primary->formats); | ||||
| 	wlr_buffer_unlock(local_buf); | ||||
| 	if (!ok) { | ||||
| 		wlr_drm_conn_log(conn, WLR_DEBUG, | ||||
| 			"Failed to import buffer for scan-out"); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
|  | @ -572,11 +573,6 @@ static bool drm_connector_commit(struct wlr_output *output) { | |||
| 	return drm_connector_commit_state(conn, &output->pending); | ||||
| } | ||||
| 
 | ||||
| static void drm_connector_rollback_render(struct wlr_output *output) { | ||||
| 	struct wlr_drm_connector *conn = get_drm_connector_from_output(output); | ||||
| 	return drm_surface_unset_current(&conn->crtc->primary->surf); | ||||
| } | ||||
| 
 | ||||
| size_t drm_crtc_get_gamma_lut_size(struct wlr_drm_backend *drm, | ||||
| 		struct wlr_drm_crtc *crtc) { | ||||
| 	if (crtc->props.gamma_lut_size == 0 || drm->iface == &legacy_iface) { | ||||
|  | @ -615,34 +611,6 @@ struct wlr_drm_fb *plane_get_next_fb(struct wlr_drm_plane *plane) { | |||
| 	return plane->current_fb; | ||||
| } | ||||
| 
 | ||||
| static bool drm_connector_test_renderer(struct wlr_drm_connector *conn, | ||||
| 		const struct wlr_output_state *state) { | ||||
| 	struct wlr_drm_backend *drm = conn->backend; | ||||
| 
 | ||||
| 	if (drm->iface == &legacy_iface) { | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wlr_drm_plane *plane = conn->crtc->primary; | ||||
| 
 | ||||
| 	struct wlr_drm_fb *prev_fb = NULL; | ||||
| 	drm_fb_move(&prev_fb, &plane->pending_fb); | ||||
| 
 | ||||
| 	bool ok = false; | ||||
| 	if (!drm_surface_render_black_frame(&plane->surf)) { | ||||
| 		goto out; | ||||
| 	} | ||||
| 	if (!drm_plane_lock_surface(plane, drm)) { | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	ok = drm_crtc_commit(conn, state, 0, true); | ||||
| 
 | ||||
| out: | ||||
| 	drm_fb_move(&plane->pending_fb, &prev_fb); | ||||
| 	return ok; | ||||
| } | ||||
| 
 | ||||
| static bool drm_connector_init_renderer(struct wlr_drm_connector *conn, | ||||
| 		const struct wlr_output_state *state) { | ||||
| 	struct wlr_drm_backend *drm = conn->backend; | ||||
|  | @ -654,37 +622,33 @@ static bool drm_connector_init_renderer(struct wlr_drm_connector *conn, | |||
| 
 | ||||
| 	assert(conn->crtc != NULL); | ||||
| 
 | ||||
| 	wlr_drm_conn_log(conn, WLR_DEBUG, "Initializing renderer"); | ||||
| 	if (drm->parent) { | ||||
| 		wlr_drm_conn_log(conn, WLR_DEBUG, "Initializing multi-GPU renderer"); | ||||
| 
 | ||||
| 	drmModeModeInfo mode = {0}; | ||||
| 	drm_connector_state_mode(conn, state, &mode); | ||||
| 		drmModeModeInfo mode = {0}; | ||||
| 		drm_connector_state_mode(conn, state, &mode); | ||||
| 
 | ||||
| 	struct wlr_drm_plane *plane = conn->crtc->primary; | ||||
| 	int width = mode.hdisplay; | ||||
| 	int height = mode.vdisplay; | ||||
| 		struct wlr_drm_plane *plane = conn->crtc->primary; | ||||
| 		int width = mode.hdisplay; | ||||
| 		int height = mode.vdisplay; | ||||
| 
 | ||||
| 	if (drm->addfb2_modifiers) { | ||||
| 		// Modifiers are supported, try to use them
 | ||||
| 		if (drm_plane_init_surface(plane, drm, width, height, true) && | ||||
| 				drm_connector_test_renderer(conn, state)) { | ||||
| 			return true; | ||||
| 		struct wlr_drm_format *format = | ||||
| 			drm_plane_pick_render_format(plane, &drm->renderer); | ||||
| 		if (format == NULL) { | ||||
| 			wlr_log(WLR_ERROR, "Failed to pick primary plane format"); | ||||
| 			return false; | ||||
| 		} | ||||
| 
 | ||||
| 		// If page-flipping with modifiers enabled doesn't work, retry without
 | ||||
| 		// modifiers
 | ||||
| 		wlr_drm_conn_log(conn, WLR_INFO, | ||||
| 			"Page-flip failed with primary FB modifiers enabled, " | ||||
| 			"retrying without modifiers"); | ||||
| 		// TODO: fallback to modifier-less buffer allocation
 | ||||
| 		bool ok = init_drm_surface(&plane->mgpu_surf, &drm->renderer, | ||||
| 			width, height, format); | ||||
| 		free(format); | ||||
| 		if (!ok) { | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (drm_plane_init_surface(plane, drm, width, height, false) && | ||||
| 			drm_connector_test_renderer(conn, state)) { | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	wlr_drm_conn_log(conn, WLR_ERROR, "Failed to initialize renderer: " | ||||
| 		"initial page-flip failed"); | ||||
| 	return false; | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| static void realloc_crtcs(struct wlr_drm_backend *drm); | ||||
|  | @ -778,12 +742,8 @@ static bool drm_connector_set_mode(struct wlr_drm_connector *conn, | |||
| 	// drm_crtc_page_flip expects a FB to be available
 | ||||
| 	struct wlr_drm_plane *plane = conn->crtc->primary; | ||||
| 	if (!plane_get_next_fb(plane)) { | ||||
| 		if (!drm_surface_render_black_frame(&plane->surf)) { | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (!drm_plane_lock_surface(plane, drm)) { | ||||
| 			return false; | ||||
| 		} | ||||
| 		wlr_drm_conn_log(conn, WLR_ERROR, "Missing FB in modeset"); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!drm_crtc_page_flip(conn, state)) { | ||||
|  | @ -1023,10 +983,8 @@ static const struct wlr_output_impl output_impl = { | |||
| 	.set_cursor = drm_connector_set_cursor, | ||||
| 	.move_cursor = drm_connector_move_cursor, | ||||
| 	.destroy = drm_connector_destroy_output, | ||||
| 	.attach_render = drm_connector_attach_render, | ||||
| 	.test = drm_connector_test, | ||||
| 	.commit = drm_connector_commit, | ||||
| 	.rollback_render = drm_connector_rollback_render, | ||||
| 	.get_gamma_size = drm_connector_get_gamma_size, | ||||
| 	.get_cursor_formats = drm_connector_get_cursor_formats, | ||||
| 	.get_cursor_size = drm_connector_get_cursor_size, | ||||
|  |  | |||
|  | @ -176,22 +176,9 @@ void drm_plane_finish_surface(struct wlr_drm_plane *plane) { | |||
| 	drm_fb_clear(&plane->queued_fb); | ||||
| 	drm_fb_clear(&plane->current_fb); | ||||
| 
 | ||||
| 	finish_drm_surface(&plane->surf); | ||||
| 	finish_drm_surface(&plane->mgpu_surf); | ||||
| } | ||||
| 
 | ||||
| static struct wlr_drm_format *create_linear_format(uint32_t format) { | ||||
| 	struct wlr_drm_format *fmt = wlr_drm_format_create(format); | ||||
| 	if (fmt == NULL) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	if (!wlr_drm_format_add(&fmt, DRM_FORMAT_MOD_LINEAR)) { | ||||
| 		free(fmt); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	return fmt; | ||||
| } | ||||
| 
 | ||||
| struct wlr_drm_format *drm_plane_pick_render_format( | ||||
| 		struct wlr_drm_plane *plane, struct wlr_drm_renderer *renderer) { | ||||
| 	const struct wlr_drm_format_set *render_formats = | ||||
|  | @ -238,53 +225,6 @@ struct wlr_drm_format *drm_plane_pick_render_format( | |||
| 	return format; | ||||
| } | ||||
| 
 | ||||
| bool drm_plane_init_surface(struct wlr_drm_plane *plane, | ||||
| 		struct wlr_drm_backend *drm, int32_t width, uint32_t height, | ||||
| 		bool with_modifiers) { | ||||
| 	struct wlr_drm_format *format = | ||||
| 		drm_plane_pick_render_format(plane, &drm->renderer); | ||||
| 	if (format == NULL) { | ||||
| 		wlr_log(WLR_ERROR, "Failed to pick render format for plane %"PRIu32, | ||||
| 			plane->id); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!with_modifiers) { | ||||
| 		struct wlr_drm_format *format_implicit_modifier = | ||||
| 			wlr_drm_format_create(format->format); | ||||
| 		free(format); | ||||
| 		format = format_implicit_modifier; | ||||
| 	} | ||||
| 
 | ||||
| 	drm_plane_finish_surface(plane); | ||||
| 
 | ||||
| 	bool ok = true; | ||||
| 	if (!drm->parent) { | ||||
| 		ok = init_drm_surface(&plane->surf, &drm->renderer, | ||||
| 			width, height, format); | ||||
| 	} else { | ||||
| 		struct wlr_drm_format *format_linear = create_linear_format(format->format); | ||||
| 		if (format_linear == NULL) { | ||||
| 			free(format); | ||||
| 			return false; | ||||
| 		} | ||||
| 
 | ||||
| 		ok = init_drm_surface(&plane->surf, &drm->parent->renderer, | ||||
| 			width, height, format_linear); | ||||
| 		free(format_linear); | ||||
| 
 | ||||
| 		if (ok && !init_drm_surface(&plane->mgpu_surf, &drm->renderer, | ||||
| 				width, height, format)) { | ||||
| 			finish_drm_surface(&plane->surf); | ||||
| 			ok = false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	free(format); | ||||
| 
 | ||||
| 	return ok; | ||||
| } | ||||
| 
 | ||||
| void drm_fb_clear(struct wlr_drm_fb **fb_ptr) { | ||||
| 	if (*fb_ptr == NULL) { | ||||
| 		return; | ||||
|  | @ -296,36 +236,6 @@ void drm_fb_clear(struct wlr_drm_fb **fb_ptr) { | |||
| 	*fb_ptr = NULL; | ||||
| } | ||||
| 
 | ||||
| bool drm_plane_lock_surface(struct wlr_drm_plane *plane, | ||||
| 		struct wlr_drm_backend *drm) { | ||||
| 	assert(plane->surf.back_buffer != NULL); | ||||
| 	struct wlr_buffer *buf = wlr_buffer_lock(plane->surf.back_buffer); | ||||
| 
 | ||||
| 	// Unset the current EGL context ASAP, because other operations may require
 | ||||
| 	// making another context current.
 | ||||
| 	drm_surface_unset_current(&plane->surf); | ||||
| 
 | ||||
| 	struct wlr_buffer *local_buf; | ||||
| 	if (drm->parent) { | ||||
| 		// Perform a copy across GPUs
 | ||||
| 		local_buf = drm_surface_blit(&plane->mgpu_surf, buf); | ||||
| 		if (!local_buf) { | ||||
| 			wlr_log(WLR_ERROR, "Failed to blit buffer across GPUs"); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} else { | ||||
| 		local_buf = wlr_buffer_lock(buf); | ||||
| 	} | ||||
| 	wlr_buffer_unlock(buf); | ||||
| 
 | ||||
| 	bool ok = drm_fb_import(&plane->pending_fb, drm, local_buf, NULL); | ||||
| 	if (!ok) { | ||||
| 		wlr_log(WLR_ERROR, "Failed to import buffer"); | ||||
| 	} | ||||
| 	wlr_buffer_unlock(local_buf); | ||||
| 	return ok; | ||||
| } | ||||
| 
 | ||||
| static struct gbm_bo *get_bo_for_dmabuf(struct gbm_device *gbm, | ||||
| 		struct wlr_dmabuf_attributes *attribs) { | ||||
| 	if (attribs->modifier != DRM_FORMAT_MOD_INVALID || | ||||
|  | @ -478,16 +388,3 @@ void drm_fb_move(struct wlr_drm_fb **new, struct wlr_drm_fb **old) { | |||
| 	*new = *old; | ||||
| 	*old = NULL; | ||||
| } | ||||
| 
 | ||||
| bool drm_surface_render_black_frame(struct wlr_drm_surface *surf) { | ||||
| 	if (!drm_surface_make_current(surf, NULL)) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wlr_renderer *renderer = surf->renderer->wlr_rend; | ||||
| 	wlr_renderer_begin(renderer, surf->width, surf->height); | ||||
| 	wlr_renderer_clear(renderer, (float[]){ 0.0, 0.0, 0.0, 1.0 }); | ||||
| 	wlr_renderer_end(renderer); | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
|  |  | |||
|  | @ -20,9 +20,7 @@ struct wlr_drm_plane { | |||
| 	uint32_t type; | ||||
| 	uint32_t id; | ||||
| 
 | ||||
| 	/* Local if this isn't a multi-GPU setup, on the parent otherwise. */ | ||||
| 	struct wlr_drm_surface surf; | ||||
| 	/* Local, only initialized on multi-GPU setups. */ | ||||
| 	/* Only initialized on multi-GPU setups */ | ||||
| 	struct wlr_drm_surface mgpu_surf; | ||||
| 
 | ||||
| 	/* Buffer to be submitted to the kernel on the next page-flip */ | ||||
|  |  | |||
|  | @ -58,15 +58,9 @@ void drm_fb_move(struct wlr_drm_fb **new, struct wlr_drm_fb **old); | |||
| 
 | ||||
| struct wlr_buffer *drm_surface_blit(struct wlr_drm_surface *surf, | ||||
| 	struct wlr_buffer *buffer); | ||||
| bool drm_surface_render_black_frame(struct wlr_drm_surface *surf); | ||||
| 
 | ||||
| struct wlr_drm_format *drm_plane_pick_render_format( | ||||
| 		struct wlr_drm_plane *plane, struct wlr_drm_renderer *renderer); | ||||
| bool drm_plane_init_surface(struct wlr_drm_plane *plane, | ||||
| 		struct wlr_drm_backend *drm, int32_t width, uint32_t height, | ||||
| 		bool with_modifiers); | ||||
| void drm_plane_finish_surface(struct wlr_drm_plane *plane); | ||||
| bool drm_plane_lock_surface(struct wlr_drm_plane *plane, | ||||
| 		struct wlr_drm_backend *drm); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue