All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V6 i-g-t 0/6] igt: Add support for testing writeback connectors
@ 2019-06-13  2:14 ` Rodrigo Siqueira
  0 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-06-13  2:14 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 1441 bytes --]

DRM already have writeback connectors support, which is a way to expose
in DRM the hardware functionality from display engines that allows
writing back into memory the result of the DE's composition of supported
planes.

These days, I'm working to add the writeback support into the vkms[1],
and I used the kms_writeback to validate my implementation. As a result,
I had to rebase the v5 version of Liviu's series, and I also fixed a
small issue in the first path (lib/igt_kms: Add writeback support).

Patches have been originally implemented by Brian, Liviu has done the v3
and v4 updates to them. I’m just sending a v6.

1. https://patchwork.freedesktop.org/series/61738/

Brian Starkey (6):
  lib/igt_kms: Add writeback support
  kms_writeback: Add initial writeback tests
  lib: Add function to hash a framebuffer
  kms_writeback: Add writeback-check-output
  lib/igt_kms: Add igt_output_clone_pipe for cloning
  kms_writeback: Add tests using a cloned output

 lib/igt_fb.c           |  66 ++++++
 lib/igt_fb.h           |   3 +
 lib/igt_kms.c          | 157 +++++++++----
 lib/igt_kms.h          |  10 +
 tests/Makefile.sources |   1 +
 tests/kms_writeback.c  | 492 +++++++++++++++++++++++++++++++++++++++++
 tests/meson.build      |   1 +
 7 files changed, 692 insertions(+), 38 deletions(-)
 create mode 100644 tests/kms_writeback.c

-- 
2.21.0


-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* [igt-dev] [PATCH V6 i-g-t 0/6] igt: Add support for testing writeback connectors
@ 2019-06-13  2:14 ` Rodrigo Siqueira
  0 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-06-13  2:14 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 1441 bytes --]

DRM already have writeback connectors support, which is a way to expose
in DRM the hardware functionality from display engines that allows
writing back into memory the result of the DE's composition of supported
planes.

These days, I'm working to add the writeback support into the vkms[1],
and I used the kms_writeback to validate my implementation. As a result,
I had to rebase the v5 version of Liviu's series, and I also fixed a
small issue in the first path (lib/igt_kms: Add writeback support).

Patches have been originally implemented by Brian, Liviu has done the v3
and v4 updates to them. I’m just sending a v6.

1. https://patchwork.freedesktop.org/series/61738/

Brian Starkey (6):
  lib/igt_kms: Add writeback support
  kms_writeback: Add initial writeback tests
  lib: Add function to hash a framebuffer
  kms_writeback: Add writeback-check-output
  lib/igt_kms: Add igt_output_clone_pipe for cloning
  kms_writeback: Add tests using a cloned output

 lib/igt_fb.c           |  66 ++++++
 lib/igt_fb.h           |   3 +
 lib/igt_kms.c          | 157 +++++++++----
 lib/igt_kms.h          |  10 +
 tests/Makefile.sources |   1 +
 tests/kms_writeback.c  | 492 +++++++++++++++++++++++++++++++++++++++++
 tests/meson.build      |   1 +
 7 files changed, 692 insertions(+), 38 deletions(-)
 create mode 100644 tests/kms_writeback.c

-- 
2.21.0


-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
  2019-06-13  2:14 ` [igt-dev] " Rodrigo Siqueira
@ 2019-06-13  2:16   ` Brian Starkey
  -1 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:16 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 6251 bytes --]

Add support in igt_kms for writeback connectors, with the ability
to attach framebuffers.

v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
drmModeGetResources()

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
[rebased and updated to the latest igt style]
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
---
 lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_kms.h |  6 ++++++
 2 files changed, 63 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index da188a39..140db346 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
 	[IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
 	[IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
 	[IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
+	[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
+	[IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
+	[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
 };
 
 /*
@@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
 	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
 	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
 	{ DRM_MODE_CONNECTOR_DPI, "DPI" },
+	{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
 	{}
 };
 
@@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
 	if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
 		igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
 					  BROADCAST_RGB_FULL);
+	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
+		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
+	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
+		igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
+		output->writeback_out_fence_fd = -1;
+	}
 }
 
 /**
@@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
  * For outputs:
  * - %IGT_CONNECTOR_CRTC_ID
  * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
+ * - %IGT_CONNECTOR_WRITEBACK_FB_ID
+ * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
  * - igt_output_override_mode() to default.
  *
  * For pipes:
@@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
 
 	display->drm_fd = drm_fd;
 
+	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
+
 	resources = drmModeGetResources(display->drm_fd);
 	if (!resources)
 		goto out;
@@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
 	kmstest_free_connector_config(&output->config);
 	free(output->name);
 	output->name = NULL;
+
+	if (output->writeback_out_fence_fd != -1) {
+		close(output->writeback_out_fence_fd);
+		output->writeback_out_fence_fd = -1;
+	}
 }
 
 /**
@@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
 					  output->props[i],
 					  output->values[i]));
 	}
+
+	if (output->writeback_out_fence_fd != -1) {
+		close(output->writeback_out_fence_fd);
+		output->writeback_out_fence_fd = -1;
+	}
 }
 
 /*
@@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
 		else
 			/* no modeset in universal commit, no change to crtc. */
 			output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
+
+		if (s == COMMIT_ATOMIC) {
+			if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
+				igt_assert(output->writeback_out_fence_fd >= 0);
+
+			output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
+			output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
+			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
+			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
+		}
 	}
 
 	if (display->first_commit) {
@@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
 	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
 }
 
+/**
+ * igt_output_set_writeback_fb:
+ * @output: Target output
+ * @fb: Target framebuffer
+ *
+ * This function sets the given @fb to be used as the target framebuffer for the
+ * writeback engine at the next atomic commit. It will also request a writeback
+ * out fence that will contain the fd number of the out fence created by KMS if
+ * the given @fb is valid.
+ */
+void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
+{
+	igt_display_t *display = output->display;
+
+	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
+
+	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
+	/* only request a writeback out fence if the framebuffer is valid */
+	if (fb)
+		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
+					  (ptrdiff_t)&output->writeback_out_fence_fd);
+}
+
 /**
  * igt_wait_for_vblank_count:
  * @drm_fd: A drm file descriptor
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index a448a003..cacc6b90 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
        IGT_CONNECTOR_BROADCAST_RGB,
        IGT_CONNECTOR_CONTENT_PROTECTION,
        IGT_CONNECTOR_VRR_CAPABLE,
+       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
+       IGT_CONNECTOR_WRITEBACK_FB_ID,
+       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
        IGT_NUM_CONNECTOR_PROPS
 };
 
@@ -364,6 +367,8 @@ typedef struct {
 	bool use_override_mode;
 	drmModeModeInfo override_mode;
 
+	int32_t writeback_out_fence_fd;
+
 	/* bitmask of changed properties */
 	uint64_t changed;
 
@@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
 igt_output_t *igt_output_from_connector(igt_display_t *display,
     drmModeConnector *connector);
 const drmModeModeInfo *igt_std_1024_mode_get(void);
+void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
 
 igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
 int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
-- 
2.21.0


-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [Intel-gfx] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
@ 2019-06-13  2:16   ` Brian Starkey
  0 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:16 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 6251 bytes --]

Add support in igt_kms for writeback connectors, with the ability
to attach framebuffers.

v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
drmModeGetResources()

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
[rebased and updated to the latest igt style]
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
---
 lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_kms.h |  6 ++++++
 2 files changed, 63 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index da188a39..140db346 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
 	[IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
 	[IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
 	[IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
+	[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
+	[IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
+	[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
 };
 
 /*
@@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
 	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
 	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
 	{ DRM_MODE_CONNECTOR_DPI, "DPI" },
+	{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
 	{}
 };
 
@@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
 	if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
 		igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
 					  BROADCAST_RGB_FULL);
+	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
+		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
+	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
+		igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
+		output->writeback_out_fence_fd = -1;
+	}
 }
 
 /**
@@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
  * For outputs:
  * - %IGT_CONNECTOR_CRTC_ID
  * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
+ * - %IGT_CONNECTOR_WRITEBACK_FB_ID
+ * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
  * - igt_output_override_mode() to default.
  *
  * For pipes:
@@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
 
 	display->drm_fd = drm_fd;
 
+	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
+
 	resources = drmModeGetResources(display->drm_fd);
 	if (!resources)
 		goto out;
@@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
 	kmstest_free_connector_config(&output->config);
 	free(output->name);
 	output->name = NULL;
+
+	if (output->writeback_out_fence_fd != -1) {
+		close(output->writeback_out_fence_fd);
+		output->writeback_out_fence_fd = -1;
+	}
 }
 
 /**
@@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
 					  output->props[i],
 					  output->values[i]));
 	}
+
+	if (output->writeback_out_fence_fd != -1) {
+		close(output->writeback_out_fence_fd);
+		output->writeback_out_fence_fd = -1;
+	}
 }
 
 /*
@@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
 		else
 			/* no modeset in universal commit, no change to crtc. */
 			output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
+
+		if (s == COMMIT_ATOMIC) {
+			if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
+				igt_assert(output->writeback_out_fence_fd >= 0);
+
+			output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
+			output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
+			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
+			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
+		}
 	}
 
 	if (display->first_commit) {
@@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
 	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
 }
 
+/**
+ * igt_output_set_writeback_fb:
+ * @output: Target output
+ * @fb: Target framebuffer
+ *
+ * This function sets the given @fb to be used as the target framebuffer for the
+ * writeback engine at the next atomic commit. It will also request a writeback
+ * out fence that will contain the fd number of the out fence created by KMS if
+ * the given @fb is valid.
+ */
+void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
+{
+	igt_display_t *display = output->display;
+
+	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
+
+	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
+	/* only request a writeback out fence if the framebuffer is valid */
+	if (fb)
+		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
+					  (ptrdiff_t)&output->writeback_out_fence_fd);
+}
+
 /**
  * igt_wait_for_vblank_count:
  * @drm_fd: A drm file descriptor
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index a448a003..cacc6b90 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
        IGT_CONNECTOR_BROADCAST_RGB,
        IGT_CONNECTOR_CONTENT_PROTECTION,
        IGT_CONNECTOR_VRR_CAPABLE,
+       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
+       IGT_CONNECTOR_WRITEBACK_FB_ID,
+       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
        IGT_NUM_CONNECTOR_PROPS
 };
 
@@ -364,6 +367,8 @@ typedef struct {
 	bool use_override_mode;
 	drmModeModeInfo override_mode;
 
+	int32_t writeback_out_fence_fd;
+
 	/* bitmask of changed properties */
 	uint64_t changed;
 
@@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
 igt_output_t *igt_output_from_connector(igt_display_t *display,
     drmModeConnector *connector);
 const drmModeModeInfo *igt_std_1024_mode_get(void);
+void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
 
 igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
 int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
-- 
2.21.0


-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-06-13  2:14 ` [igt-dev] " Rodrigo Siqueira
@ 2019-06-13  2:16   ` Brian Starkey
  -1 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:16 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 10763 bytes --]

Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
WRITEBACK_FB_ID properties on writeback connectors, ensuring their
behaviour is correct.

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
[rebased and updated do_writeback_test() function to address feedback]
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
---
 tests/Makefile.sources |   1 +
 tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
 tests/meson.build      |   1 +
 3 files changed, 316 insertions(+)
 create mode 100644 tests/kms_writeback.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 027ed82f..03cc8efa 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -77,6 +77,7 @@ TESTS_progs = \
 	kms_universal_plane \
 	kms_vblank \
 	kms_vrr \
+	kms_writeback \
 	meta_test \
 	perf \
 	perf_pmu \
diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
new file mode 100644
index 00000000..66ef48a6
--- /dev/null
+++ b/tests/kms_writeback.c
@@ -0,0 +1,314 @@
+/*
+ * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "igt.h"
+#include "igt_core.h"
+#include "igt_fb.h"
+
+static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
+{
+	drmModePropertyBlobRes *blob = NULL;
+	uint64_t blob_id;
+	int ret;
+
+	ret = kmstest_get_property(output->display->drm_fd,
+				   output->config.connector->connector_id,
+				   DRM_MODE_OBJECT_CONNECTOR,
+				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
+				   NULL, &blob_id, NULL);
+	if (ret)
+		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
+
+	igt_assert(blob);
+
+	return blob;
+}
+
+static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
+{
+	igt_fb_t input_fb, output_fb;
+	igt_plane_t *plane;
+	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
+	uint64_t tiling = igt_fb_mod_to_tiling(0);
+	int width, height, ret;
+	drmModeModeInfo override_mode = {
+		.clock = 25175,
+		.hdisplay = 640,
+		.hsync_start = 656,
+		.hsync_end = 752,
+		.htotal = 800,
+		.hskew = 0,
+		.vdisplay = 480,
+		.vsync_start = 490,
+		.vsync_end = 492,
+		.vtotal = 525,
+		.vscan = 0,
+		.vrefresh = 60,
+		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+		.name = {"640x480-60"},
+	};
+	igt_output_override_mode(output, &override_mode);
+
+	width = override_mode.hdisplay;
+	height = override_mode.vdisplay;
+
+	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
+	igt_assert(ret >= 0);
+
+	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
+	igt_assert(ret >= 0);
+
+	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+	igt_plane_set_fb(plane, &input_fb);
+	igt_output_set_writeback_fb(output, &output_fb);
+
+	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
+					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+	igt_plane_set_fb(plane, NULL);
+	igt_remove_fb(display->drm_fd, &input_fb);
+	igt_remove_fb(display->drm_fd, &output_fb);
+
+	return !ret;
+}
+
+static igt_output_t *kms_writeback_get_output(igt_display_t *display)
+{
+	int i;
+
+	for (i = 0; i < display->n_outputs; i++) {
+		igt_output_t *output = &display->outputs[i];
+		int j;
+
+		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
+		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
+
+		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
+			igt_output_set_pipe(output, j);
+
+			if (check_writeback_config(display, output)) {
+				igt_debug("Using connector %u:%s on pipe %d\n",
+					  output->config.connector->connector_id,
+					  output->name, j);
+				return output;
+			}
+		}
+
+		/* Restore any connectors we don't use, so we don't trip on them later */
+		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
+	}
+
+	return NULL;
+}
+
+static void check_writeback_fb_id(igt_output_t *output)
+{
+	uint64_t check_fb_id;
+
+	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
+	igt_assert(check_fb_id == 0);
+}
+
+static int do_writeback_test(igt_output_t *output, uint32_t flags,
+			      uint32_t fb_id, int32_t *out_fence_ptr,
+			      bool ptr_valid)
+{
+	int ret;
+	igt_display_t *display = output->display;
+	struct kmstest_connector_config *config = &output->config;
+
+	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
+	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
+	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
+
+	if (ptr_valid)
+		*out_fence_ptr = 0;
+
+	ret = igt_display_try_commit_atomic(display, flags, NULL);
+
+	if (ptr_valid)
+		igt_assert(*out_fence_ptr == -1);
+
+	/* WRITEBACK_FB_ID must always read as zero */
+	check_writeback_fb_id(output);
+
+	return ret;
+}
+
+static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
+{
+	int i, ret;
+	int32_t out_fence;
+	struct {
+		uint32_t fb_id;
+		bool ptr_valid;
+		int32_t *out_fence_ptr;
+	} invalid_tests[] = {
+		{
+			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
+			.fb_id = 0,
+			.ptr_valid = true,
+			.out_fence_ptr = &out_fence,
+		},
+		{
+			/* Invalid output buffer. */
+			.fb_id = invalid_fb->fb_id,
+			.ptr_valid = true,
+			.out_fence_ptr = &out_fence,
+		},
+		{
+			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
+			.fb_id = valid_fb->fb_id,
+			.ptr_valid = false,
+			.out_fence_ptr = (int32_t *)0x8,
+		},
+	};
+
+	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
+		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
+					invalid_tests[i].fb_id,
+					invalid_tests[i].out_fence_ptr,
+					invalid_tests[i].ptr_valid);
+		igt_assert(ret != 0);
+	}
+}
+
+static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
+{
+
+	int ret;
+
+	/* Valid output buffer */
+	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
+				valid_fb->fb_id, NULL, false);
+	igt_assert(ret == 0);
+
+	/* Invalid object for WRITEBACK_FB_ID */
+	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
+				output->id, NULL, false);
+	igt_assert(ret == -EINVAL);
+
+	/* Zero WRITEBACK_FB_ID */
+	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
+				0, NULL, false);
+	igt_assert(ret == 0);
+}
+
+igt_main
+{
+	igt_display_t display;
+	igt_output_t *output;
+	igt_plane_t *plane;
+	igt_fb_t input_fb;
+	drmModeModeInfo mode;
+	int ret;
+
+	memset(&display, 0, sizeof(display));
+
+	igt_fixture {
+		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
+		igt_display_require(&display, display.drm_fd);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_display_require(&display, display.drm_fd);
+
+		igt_require(display.is_atomic);
+
+		output = kms_writeback_get_output(&display);
+		igt_require(output);
+
+		if (output->use_override_mode)
+			memcpy(&mode, &output->override_mode, sizeof(mode));
+		else
+			memcpy(&mode, &output->config.default_mode, sizeof(mode));
+
+		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+		igt_require(plane);
+
+		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
+				    mode.vdisplay,
+				    DRM_FORMAT_XRGB8888,
+				    igt_fb_mod_to_tiling(0),
+				    &input_fb);
+		igt_assert(ret >= 0);
+		igt_plane_set_fb(plane, &input_fb);
+	}
+
+	igt_subtest("writeback-pixel-formats") {
+		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
+		const char *valid_chars = "0123456 ABCGNRUVXY";
+		unsigned int i;
+		char *c;
+
+		/*
+		 * We don't have a comprehensive list of formats, so just check
+		 * that the blob length is sensible and that it doesn't contain
+		 * any outlandish characters
+		 */
+		igt_assert(!(formats_blob->length % 4));
+		c = formats_blob->data;
+		for (i = 0; i < formats_blob->length; i++)
+			igt_assert_f(strchr(valid_chars, c[i]),
+				     "Unexpected character %c\n", c[i]);
+	}
+
+	igt_subtest("writeback-invalid-out-fence") {
+		igt_fb_t invalid_fb;
+		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
+				    mode.vdisplay / 2,
+				    DRM_FORMAT_XRGB8888,
+				    igt_fb_mod_to_tiling(0),
+				    &invalid_fb);
+		igt_require(ret > 0);
+
+		invalid_out_fence(output, &input_fb, &invalid_fb);
+
+		igt_remove_fb(display.drm_fd, &invalid_fb);
+	}
+
+	igt_subtest("writeback-fb-id") {
+		igt_fb_t output_fb;
+		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
+				    DRM_FORMAT_XRGB8888,
+				    igt_fb_mod_to_tiling(0),
+				    &output_fb);
+		igt_require(ret > 0);
+
+		writeback_fb_id(output, &input_fb, &output_fb);
+
+		igt_remove_fb(display.drm_fd, &output_fb);
+	}
+
+	igt_fixture {
+		igt_remove_fb(display.drm_fd, &input_fb);
+		igt_display_fini(&display);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index f168fbba..9c77cfcd 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -63,6 +63,7 @@ test_progs = [
 	'kms_universal_plane',
 	'kms_vblank',
 	'kms_vrr',
+	'kms_writeback',
 	'meta_test',
 	'panfrost_get_param',
 	'panfrost_gem_new',
-- 
2.21.0

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-06-13  2:16   ` Brian Starkey
  0 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:16 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 10763 bytes --]

Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
WRITEBACK_FB_ID properties on writeback connectors, ensuring their
behaviour is correct.

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
[rebased and updated do_writeback_test() function to address feedback]
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
---
 tests/Makefile.sources |   1 +
 tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
 tests/meson.build      |   1 +
 3 files changed, 316 insertions(+)
 create mode 100644 tests/kms_writeback.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 027ed82f..03cc8efa 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -77,6 +77,7 @@ TESTS_progs = \
 	kms_universal_plane \
 	kms_vblank \
 	kms_vrr \
+	kms_writeback \
 	meta_test \
 	perf \
 	perf_pmu \
diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
new file mode 100644
index 00000000..66ef48a6
--- /dev/null
+++ b/tests/kms_writeback.c
@@ -0,0 +1,314 @@
+/*
+ * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "igt.h"
+#include "igt_core.h"
+#include "igt_fb.h"
+
+static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
+{
+	drmModePropertyBlobRes *blob = NULL;
+	uint64_t blob_id;
+	int ret;
+
+	ret = kmstest_get_property(output->display->drm_fd,
+				   output->config.connector->connector_id,
+				   DRM_MODE_OBJECT_CONNECTOR,
+				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
+				   NULL, &blob_id, NULL);
+	if (ret)
+		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
+
+	igt_assert(blob);
+
+	return blob;
+}
+
+static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
+{
+	igt_fb_t input_fb, output_fb;
+	igt_plane_t *plane;
+	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
+	uint64_t tiling = igt_fb_mod_to_tiling(0);
+	int width, height, ret;
+	drmModeModeInfo override_mode = {
+		.clock = 25175,
+		.hdisplay = 640,
+		.hsync_start = 656,
+		.hsync_end = 752,
+		.htotal = 800,
+		.hskew = 0,
+		.vdisplay = 480,
+		.vsync_start = 490,
+		.vsync_end = 492,
+		.vtotal = 525,
+		.vscan = 0,
+		.vrefresh = 60,
+		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+		.name = {"640x480-60"},
+	};
+	igt_output_override_mode(output, &override_mode);
+
+	width = override_mode.hdisplay;
+	height = override_mode.vdisplay;
+
+	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
+	igt_assert(ret >= 0);
+
+	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
+	igt_assert(ret >= 0);
+
+	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+	igt_plane_set_fb(plane, &input_fb);
+	igt_output_set_writeback_fb(output, &output_fb);
+
+	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
+					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+	igt_plane_set_fb(plane, NULL);
+	igt_remove_fb(display->drm_fd, &input_fb);
+	igt_remove_fb(display->drm_fd, &output_fb);
+
+	return !ret;
+}
+
+static igt_output_t *kms_writeback_get_output(igt_display_t *display)
+{
+	int i;
+
+	for (i = 0; i < display->n_outputs; i++) {
+		igt_output_t *output = &display->outputs[i];
+		int j;
+
+		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
+		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
+
+		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
+			igt_output_set_pipe(output, j);
+
+			if (check_writeback_config(display, output)) {
+				igt_debug("Using connector %u:%s on pipe %d\n",
+					  output->config.connector->connector_id,
+					  output->name, j);
+				return output;
+			}
+		}
+
+		/* Restore any connectors we don't use, so we don't trip on them later */
+		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
+	}
+
+	return NULL;
+}
+
+static void check_writeback_fb_id(igt_output_t *output)
+{
+	uint64_t check_fb_id;
+
+	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
+	igt_assert(check_fb_id == 0);
+}
+
+static int do_writeback_test(igt_output_t *output, uint32_t flags,
+			      uint32_t fb_id, int32_t *out_fence_ptr,
+			      bool ptr_valid)
+{
+	int ret;
+	igt_display_t *display = output->display;
+	struct kmstest_connector_config *config = &output->config;
+
+	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
+	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
+	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
+
+	if (ptr_valid)
+		*out_fence_ptr = 0;
+
+	ret = igt_display_try_commit_atomic(display, flags, NULL);
+
+	if (ptr_valid)
+		igt_assert(*out_fence_ptr == -1);
+
+	/* WRITEBACK_FB_ID must always read as zero */
+	check_writeback_fb_id(output);
+
+	return ret;
+}
+
+static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
+{
+	int i, ret;
+	int32_t out_fence;
+	struct {
+		uint32_t fb_id;
+		bool ptr_valid;
+		int32_t *out_fence_ptr;
+	} invalid_tests[] = {
+		{
+			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
+			.fb_id = 0,
+			.ptr_valid = true,
+			.out_fence_ptr = &out_fence,
+		},
+		{
+			/* Invalid output buffer. */
+			.fb_id = invalid_fb->fb_id,
+			.ptr_valid = true,
+			.out_fence_ptr = &out_fence,
+		},
+		{
+			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
+			.fb_id = valid_fb->fb_id,
+			.ptr_valid = false,
+			.out_fence_ptr = (int32_t *)0x8,
+		},
+	};
+
+	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
+		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
+					invalid_tests[i].fb_id,
+					invalid_tests[i].out_fence_ptr,
+					invalid_tests[i].ptr_valid);
+		igt_assert(ret != 0);
+	}
+}
+
+static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
+{
+
+	int ret;
+
+	/* Valid output buffer */
+	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
+				valid_fb->fb_id, NULL, false);
+	igt_assert(ret == 0);
+
+	/* Invalid object for WRITEBACK_FB_ID */
+	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
+				output->id, NULL, false);
+	igt_assert(ret == -EINVAL);
+
+	/* Zero WRITEBACK_FB_ID */
+	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
+				0, NULL, false);
+	igt_assert(ret == 0);
+}
+
+igt_main
+{
+	igt_display_t display;
+	igt_output_t *output;
+	igt_plane_t *plane;
+	igt_fb_t input_fb;
+	drmModeModeInfo mode;
+	int ret;
+
+	memset(&display, 0, sizeof(display));
+
+	igt_fixture {
+		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
+		igt_display_require(&display, display.drm_fd);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_display_require(&display, display.drm_fd);
+
+		igt_require(display.is_atomic);
+
+		output = kms_writeback_get_output(&display);
+		igt_require(output);
+
+		if (output->use_override_mode)
+			memcpy(&mode, &output->override_mode, sizeof(mode));
+		else
+			memcpy(&mode, &output->config.default_mode, sizeof(mode));
+
+		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+		igt_require(plane);
+
+		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
+				    mode.vdisplay,
+				    DRM_FORMAT_XRGB8888,
+				    igt_fb_mod_to_tiling(0),
+				    &input_fb);
+		igt_assert(ret >= 0);
+		igt_plane_set_fb(plane, &input_fb);
+	}
+
+	igt_subtest("writeback-pixel-formats") {
+		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
+		const char *valid_chars = "0123456 ABCGNRUVXY";
+		unsigned int i;
+		char *c;
+
+		/*
+		 * We don't have a comprehensive list of formats, so just check
+		 * that the blob length is sensible and that it doesn't contain
+		 * any outlandish characters
+		 */
+		igt_assert(!(formats_blob->length % 4));
+		c = formats_blob->data;
+		for (i = 0; i < formats_blob->length; i++)
+			igt_assert_f(strchr(valid_chars, c[i]),
+				     "Unexpected character %c\n", c[i]);
+	}
+
+	igt_subtest("writeback-invalid-out-fence") {
+		igt_fb_t invalid_fb;
+		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
+				    mode.vdisplay / 2,
+				    DRM_FORMAT_XRGB8888,
+				    igt_fb_mod_to_tiling(0),
+				    &invalid_fb);
+		igt_require(ret > 0);
+
+		invalid_out_fence(output, &input_fb, &invalid_fb);
+
+		igt_remove_fb(display.drm_fd, &invalid_fb);
+	}
+
+	igt_subtest("writeback-fb-id") {
+		igt_fb_t output_fb;
+		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
+				    DRM_FORMAT_XRGB8888,
+				    igt_fb_mod_to_tiling(0),
+				    &output_fb);
+		igt_require(ret > 0);
+
+		writeback_fb_id(output, &input_fb, &output_fb);
+
+		igt_remove_fb(display.drm_fd, &output_fb);
+	}
+
+	igt_fixture {
+		igt_remove_fb(display.drm_fd, &input_fb);
+		igt_display_fini(&display);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index f168fbba..9c77cfcd 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -63,6 +63,7 @@ test_progs = [
 	'kms_universal_plane',
 	'kms_vblank',
 	'kms_vrr',
+	'kms_writeback',
 	'meta_test',
 	'panfrost_get_param',
 	'panfrost_gem_new',
-- 
2.21.0

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
  2019-06-13  2:14 ` [igt-dev] " Rodrigo Siqueira
@ 2019-06-13  2:17   ` Brian Starkey
  -1 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:17 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 3275 bytes --]

To use writeback buffers as a CRC source, we need to be able to hash
them. Implement a simple FVA-1a hashing routine for this purpose.

Doing a bytewise hash on the framebuffer directly can be very slow if
the memory is noncached. By making a copy of each line in the FB first
(which can take advantage of word-access speedup), we can do the hash
on a cached copy, which is much faster (10x speedup on my platform).

v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
    Chris Wilson

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
[rebased and updated to the most recent API]
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
---
 lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_fb.h |  3 +++
 2 files changed, 69 insertions(+)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 9d4f905e..d07dae39 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
 	return false;
 }
 
+/*
+ * This implements the FNV-1a hashing algorithm instead of CRC, for
+ * simplicity
+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html
+ *
+ * hash = offset_basis
+ * for each octet_of_data to be hashed
+ *         hash = hash xor octet_of_data
+ *         hash = hash * FNV_prime
+ * return hash
+ *
+ * 32 bit offset_basis = 2166136261
+ * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
+ */
+int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
+{
+#define FNV1a_OFFSET_BIAS 2166136261
+#define FNV1a_PRIME 16777619
+	uint32_t hash;
+	void *map;
+	char *ptr, *line = NULL;
+	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
+	uint32_t stride = calc_plane_stride(fb, 0);
+
+	if (fb->is_dumb)
+		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
+					      PROT_READ);
+	else
+		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
+				    PROT_READ);
+	ptr = map;
+
+	/*
+	 * Framebuffers are often uncached, which can make byte-wise accesses
+	 * very slow. We copy each line of the FB into a local buffer to speed
+	 * up the hashing.
+	 */
+	line = malloc(stride);
+	if (!line) {
+		munmap(map, fb->size);
+		return -ENOMEM;
+	}
+
+	hash = FNV1a_OFFSET_BIAS;
+
+	for (y = 0; y < fb->height; y++, ptr += stride) {
+
+		igt_memcpy_from_wc(line, ptr, stride);
+
+		for (x = 0; x < fb->width * cpp; x++) {
+			hash ^= line[x];
+			hash *= FNV1a_PRIME;
+		}
+	}
+
+	crc->n_words = 1;
+	crc->crc[0] = hash;
+
+	free(line);
+	munmap(map, fb->size);
+
+	return 0;
+#undef FNV1a_OFFSET_BIAS
+#undef FNV1a_PRIME
+}
+
 /**
  * igt_format_is_yuv:
  * @drm_format: drm fourcc
diff --git a/lib/igt_fb.h b/lib/igt_fb.h
index adefebe1..a2741c05 100644
--- a/lib/igt_fb.h
+++ b/lib/igt_fb.h
@@ -37,6 +37,7 @@
 #include <i915_drm.h>
 
 #include "igt_color_encoding.h"
+#include "igt_debugfs.h"
 
 /*
  * Internal format to denote a buffer compatible with pixman's
@@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
 void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
 			   bool allow_yuv);
 
+int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
+
 #endif /* __IGT_FB_H__ */
 
-- 
2.21.0

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [Intel-gfx] [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
@ 2019-06-13  2:17   ` Brian Starkey
  0 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:17 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 3275 bytes --]

To use writeback buffers as a CRC source, we need to be able to hash
them. Implement a simple FVA-1a hashing routine for this purpose.

Doing a bytewise hash on the framebuffer directly can be very slow if
the memory is noncached. By making a copy of each line in the FB first
(which can take advantage of word-access speedup), we can do the hash
on a cached copy, which is much faster (10x speedup on my platform).

v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
    Chris Wilson

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
[rebased and updated to the most recent API]
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
---
 lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_fb.h |  3 +++
 2 files changed, 69 insertions(+)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 9d4f905e..d07dae39 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
 	return false;
 }
 
+/*
+ * This implements the FNV-1a hashing algorithm instead of CRC, for
+ * simplicity
+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html
+ *
+ * hash = offset_basis
+ * for each octet_of_data to be hashed
+ *         hash = hash xor octet_of_data
+ *         hash = hash * FNV_prime
+ * return hash
+ *
+ * 32 bit offset_basis = 2166136261
+ * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
+ */
+int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
+{
+#define FNV1a_OFFSET_BIAS 2166136261
+#define FNV1a_PRIME 16777619
+	uint32_t hash;
+	void *map;
+	char *ptr, *line = NULL;
+	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
+	uint32_t stride = calc_plane_stride(fb, 0);
+
+	if (fb->is_dumb)
+		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
+					      PROT_READ);
+	else
+		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
+				    PROT_READ);
+	ptr = map;
+
+	/*
+	 * Framebuffers are often uncached, which can make byte-wise accesses
+	 * very slow. We copy each line of the FB into a local buffer to speed
+	 * up the hashing.
+	 */
+	line = malloc(stride);
+	if (!line) {
+		munmap(map, fb->size);
+		return -ENOMEM;
+	}
+
+	hash = FNV1a_OFFSET_BIAS;
+
+	for (y = 0; y < fb->height; y++, ptr += stride) {
+
+		igt_memcpy_from_wc(line, ptr, stride);
+
+		for (x = 0; x < fb->width * cpp; x++) {
+			hash ^= line[x];
+			hash *= FNV1a_PRIME;
+		}
+	}
+
+	crc->n_words = 1;
+	crc->crc[0] = hash;
+
+	free(line);
+	munmap(map, fb->size);
+
+	return 0;
+#undef FNV1a_OFFSET_BIAS
+#undef FNV1a_PRIME
+}
+
 /**
  * igt_format_is_yuv:
  * @drm_format: drm fourcc
diff --git a/lib/igt_fb.h b/lib/igt_fb.h
index adefebe1..a2741c05 100644
--- a/lib/igt_fb.h
+++ b/lib/igt_fb.h
@@ -37,6 +37,7 @@
 #include <i915_drm.h>
 
 #include "igt_color_encoding.h"
+#include "igt_debugfs.h"
 
 /*
  * Internal format to denote a buffer compatible with pixman's
@@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
 void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
 			   bool allow_yuv);
 
+int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
+
 #endif /* __IGT_FB_H__ */
 
-- 
2.21.0

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH V6 i-g-t 4/6] kms_writeback: Add writeback-check-output
  2019-06-13  2:14 ` [igt-dev] " Rodrigo Siqueira
@ 2019-06-13  2:17   ` Brian Starkey
  -1 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:17 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 4650 bytes --]

Add a test which makes commits using the writeback connector, and
checks the output buffer hash to make sure it is/isn't written as
appropriate.

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
---
 tests/kms_writeback.c | 124 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
index 66ef48a6..0f20dadd 100644
--- a/tests/kms_writeback.c
+++ b/tests/kms_writeback.c
@@ -30,6 +30,7 @@
 #include "igt.h"
 #include "igt_core.h"
 #include "igt_fb.h"
+#include "sw_sync.h"
 
 static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
 {
@@ -221,6 +222,116 @@ static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *
 	igt_assert(ret == 0);
 }
 
+static void fill_fb(igt_fb_t *fb, double color[3])
+{
+	cairo_t *cr = igt_get_cairo_ctx(fb->fd, fb);
+	igt_assert(cr);
+
+	igt_paint_color(cr, 0, 0, fb->width, fb->height,
+			color[0], color[1], color[2]);
+}
+
+static void get_and_wait_out_fence(igt_output_t *output)
+{
+	int ret;
+
+	igt_assert(output->writeback_out_fence_fd >= 0);
+
+	ret = sync_fence_wait(output->writeback_out_fence_fd, 1000);
+	igt_assert(ret == 0);
+	close(output->writeback_out_fence_fd);
+	output->writeback_out_fence_fd = -1;
+}
+
+static void writeback_sequence(igt_output_t *output, igt_plane_t *plane,
+				igt_fb_t *in_fb, igt_fb_t *out_fbs[], int n_commits)
+{
+	int i, color_idx = 0;
+	double in_fb_colors[2][3] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+	};
+	double clear_color[3] = { 1.0, 1.0, 1.0 };
+	igt_crc_t cleared_crc, out_expected;
+
+	for (i = 0; i < n_commits; i++, color_idx++) {
+		/* Change the input color each time */
+		fill_fb(in_fb, in_fb_colors[color_idx % 2]);
+
+		if (out_fbs[i]) {
+			igt_crc_t out_before;
+
+			/* Get the expected CRC */
+			fill_fb(out_fbs[i], in_fb_colors[color_idx % 2]);
+			igt_fb_get_crc(out_fbs[i], &out_expected);
+
+			fill_fb(out_fbs[i], clear_color);
+			if (i == 0)
+				igt_fb_get_crc(out_fbs[i], &cleared_crc);
+			igt_fb_get_crc(out_fbs[i], &out_before);
+			igt_assert_crc_equal(&cleared_crc, &out_before);
+		}
+
+		/* Commit */
+		igt_plane_set_fb(plane, in_fb);
+		igt_output_set_writeback_fb(output, out_fbs[i]);
+
+		igt_display_commit_atomic(output->display,
+					  DRM_MODE_ATOMIC_ALLOW_MODESET,
+					  NULL);
+		if (out_fbs[i])
+			get_and_wait_out_fence(output);
+
+		/* Make sure the old output buffer is untouched */
+		if (i > 0 && out_fbs[i - 1] && (out_fbs[i] != out_fbs[i - 1])) {
+			igt_crc_t out_prev;
+			igt_fb_get_crc(out_fbs[i - 1], &out_prev);
+			igt_assert_crc_equal(&cleared_crc, &out_prev);
+		}
+
+		/* Make sure this output buffer is written */
+		if (out_fbs[i]) {
+			igt_crc_t out_after;
+			igt_fb_get_crc(out_fbs[i], &out_after);
+			igt_assert_crc_equal(&out_expected, &out_after);
+
+			/* And clear it, for the next time */
+			fill_fb(out_fbs[i], clear_color);
+		}
+	}
+}
+
+static void writeback_check_output(igt_output_t *output, igt_plane_t *plane,
+				   igt_fb_t *input_fb, igt_fb_t *output_fb)
+{
+	igt_fb_t *out_fbs[2] = { 0 };
+	igt_fb_t second_out_fb;
+	int ret;
+
+	/* One commit, with a writeback. */
+	writeback_sequence(output, plane, input_fb, &output_fb, 1);
+
+	/* Two commits, the second with no writeback */
+	out_fbs[0] = output_fb;
+	writeback_sequence(output, plane, input_fb, out_fbs, 2);
+
+	/* Two commits, both with writeback */
+	out_fbs[1] = output_fb;
+	writeback_sequence(output, plane, input_fb, out_fbs, 2);
+
+	ret = igt_create_fb(output_fb->fd, output_fb->width, output_fb->height,
+			    DRM_FORMAT_XRGB8888,
+			    igt_fb_mod_to_tiling(0),
+			    &second_out_fb);
+	igt_require(ret > 0);
+
+	/* Two commits, with different writeback buffers */
+	out_fbs[1] = &second_out_fb;
+	writeback_sequence(output, plane, input_fb, out_fbs, 2);
+
+	igt_remove_fb(output_fb->fd, &second_out_fb);
+}
+
 igt_main
 {
 	igt_display_t display;
@@ -307,6 +418,19 @@ igt_main
 		igt_remove_fb(display.drm_fd, &output_fb);
 	}
 
+	igt_subtest("writeback-check-output") {
+		igt_fb_t output_fb;
+		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
+				    DRM_FORMAT_XRGB8888,
+				    igt_fb_mod_to_tiling(0),
+				    &output_fb);
+		igt_require(ret > 0);
+
+		writeback_check_output(output, plane, &input_fb, &output_fb);
+
+		igt_remove_fb(display.drm_fd, &output_fb);
+	}
+
 	igt_fixture {
 		igt_remove_fb(display.drm_fd, &input_fb);
 		igt_display_fini(&display);
-- 
2.21.0

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [igt-dev] [PATCH V6 i-g-t 4/6] kms_writeback: Add writeback-check-output
@ 2019-06-13  2:17   ` Brian Starkey
  0 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:17 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 4650 bytes --]

Add a test which makes commits using the writeback connector, and
checks the output buffer hash to make sure it is/isn't written as
appropriate.

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
---
 tests/kms_writeback.c | 124 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
index 66ef48a6..0f20dadd 100644
--- a/tests/kms_writeback.c
+++ b/tests/kms_writeback.c
@@ -30,6 +30,7 @@
 #include "igt.h"
 #include "igt_core.h"
 #include "igt_fb.h"
+#include "sw_sync.h"
 
 static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
 {
@@ -221,6 +222,116 @@ static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *
 	igt_assert(ret == 0);
 }
 
+static void fill_fb(igt_fb_t *fb, double color[3])
+{
+	cairo_t *cr = igt_get_cairo_ctx(fb->fd, fb);
+	igt_assert(cr);
+
+	igt_paint_color(cr, 0, 0, fb->width, fb->height,
+			color[0], color[1], color[2]);
+}
+
+static void get_and_wait_out_fence(igt_output_t *output)
+{
+	int ret;
+
+	igt_assert(output->writeback_out_fence_fd >= 0);
+
+	ret = sync_fence_wait(output->writeback_out_fence_fd, 1000);
+	igt_assert(ret == 0);
+	close(output->writeback_out_fence_fd);
+	output->writeback_out_fence_fd = -1;
+}
+
+static void writeback_sequence(igt_output_t *output, igt_plane_t *plane,
+				igt_fb_t *in_fb, igt_fb_t *out_fbs[], int n_commits)
+{
+	int i, color_idx = 0;
+	double in_fb_colors[2][3] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+	};
+	double clear_color[3] = { 1.0, 1.0, 1.0 };
+	igt_crc_t cleared_crc, out_expected;
+
+	for (i = 0; i < n_commits; i++, color_idx++) {
+		/* Change the input color each time */
+		fill_fb(in_fb, in_fb_colors[color_idx % 2]);
+
+		if (out_fbs[i]) {
+			igt_crc_t out_before;
+
+			/* Get the expected CRC */
+			fill_fb(out_fbs[i], in_fb_colors[color_idx % 2]);
+			igt_fb_get_crc(out_fbs[i], &out_expected);
+
+			fill_fb(out_fbs[i], clear_color);
+			if (i == 0)
+				igt_fb_get_crc(out_fbs[i], &cleared_crc);
+			igt_fb_get_crc(out_fbs[i], &out_before);
+			igt_assert_crc_equal(&cleared_crc, &out_before);
+		}
+
+		/* Commit */
+		igt_plane_set_fb(plane, in_fb);
+		igt_output_set_writeback_fb(output, out_fbs[i]);
+
+		igt_display_commit_atomic(output->display,
+					  DRM_MODE_ATOMIC_ALLOW_MODESET,
+					  NULL);
+		if (out_fbs[i])
+			get_and_wait_out_fence(output);
+
+		/* Make sure the old output buffer is untouched */
+		if (i > 0 && out_fbs[i - 1] && (out_fbs[i] != out_fbs[i - 1])) {
+			igt_crc_t out_prev;
+			igt_fb_get_crc(out_fbs[i - 1], &out_prev);
+			igt_assert_crc_equal(&cleared_crc, &out_prev);
+		}
+
+		/* Make sure this output buffer is written */
+		if (out_fbs[i]) {
+			igt_crc_t out_after;
+			igt_fb_get_crc(out_fbs[i], &out_after);
+			igt_assert_crc_equal(&out_expected, &out_after);
+
+			/* And clear it, for the next time */
+			fill_fb(out_fbs[i], clear_color);
+		}
+	}
+}
+
+static void writeback_check_output(igt_output_t *output, igt_plane_t *plane,
+				   igt_fb_t *input_fb, igt_fb_t *output_fb)
+{
+	igt_fb_t *out_fbs[2] = { 0 };
+	igt_fb_t second_out_fb;
+	int ret;
+
+	/* One commit, with a writeback. */
+	writeback_sequence(output, plane, input_fb, &output_fb, 1);
+
+	/* Two commits, the second with no writeback */
+	out_fbs[0] = output_fb;
+	writeback_sequence(output, plane, input_fb, out_fbs, 2);
+
+	/* Two commits, both with writeback */
+	out_fbs[1] = output_fb;
+	writeback_sequence(output, plane, input_fb, out_fbs, 2);
+
+	ret = igt_create_fb(output_fb->fd, output_fb->width, output_fb->height,
+			    DRM_FORMAT_XRGB8888,
+			    igt_fb_mod_to_tiling(0),
+			    &second_out_fb);
+	igt_require(ret > 0);
+
+	/* Two commits, with different writeback buffers */
+	out_fbs[1] = &second_out_fb;
+	writeback_sequence(output, plane, input_fb, out_fbs, 2);
+
+	igt_remove_fb(output_fb->fd, &second_out_fb);
+}
+
 igt_main
 {
 	igt_display_t display;
@@ -307,6 +418,19 @@ igt_main
 		igt_remove_fb(display.drm_fd, &output_fb);
 	}
 
+	igt_subtest("writeback-check-output") {
+		igt_fb_t output_fb;
+		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
+				    DRM_FORMAT_XRGB8888,
+				    igt_fb_mod_to_tiling(0),
+				    &output_fb);
+		igt_require(ret > 0);
+
+		writeback_check_output(output, plane, &input_fb, &output_fb);
+
+		igt_remove_fb(display.drm_fd, &output_fb);
+	}
+
 	igt_fixture {
 		igt_remove_fb(display.drm_fd, &input_fb);
 		igt_display_fini(&display);
-- 
2.21.0

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH V6 i-g-t 5/6] lib/igt_kms: Add igt_output_clone_pipe for cloning
  2019-06-13  2:14 ` [igt-dev] " Rodrigo Siqueira
@ 2019-06-13  2:18   ` Brian Starkey
  -1 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:18 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 5657 bytes --]

An output can be added as a clone of any other output(s) attached to a
pipe using igt_output_clone_pipe()

v5: Drop field out_fence_requested from struct igt_pipe (Brian Starkey)

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
---
 lib/igt_kms.c | 100 +++++++++++++++++++++++++++++++-------------------
 lib/igt_kms.h |   4 ++
 2 files changed, 66 insertions(+), 38 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 140db346..b85a0404 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -1765,6 +1765,17 @@ static void igt_display_log_shift(igt_display_t *display, int shift)
 	igt_assert(display->log_shift >= 0);
 }
 
+static int igt_output_idx(igt_output_t *output)
+{
+	int i;
+
+	for (i = 0; i < output->display->n_outputs; i++)
+		if (&output->display->outputs[i] == output)
+			return i;
+
+	return -1;
+}
+
 static void igt_output_refresh(igt_output_t *output)
 {
 	igt_display_t *display = output->display;
@@ -2317,42 +2328,6 @@ void igt_display_fini(igt_display_t *display)
 	display->planes = NULL;
 }
 
-static void igt_display_refresh(igt_display_t *display)
-{
-	igt_output_t *output;
-	int i;
-
-	unsigned long pipes_in_use = 0;
-
-       /* Check that two outputs aren't trying to use the same pipe */
-	for (i = 0; i < display->n_outputs; i++) {
-		output = &display->outputs[i];
-
-		if (output->pending_pipe != PIPE_NONE) {
-			if (pipes_in_use & (1 << output->pending_pipe))
-				goto report_dup;
-
-			pipes_in_use |= 1 << output->pending_pipe;
-		}
-
-		if (output->force_reprobe)
-			igt_output_refresh(output);
-	}
-
-	return;
-
-report_dup:
-	for (; i > 0; i--) {
-		igt_output_t *b = &display->outputs[i - 1];
-
-		igt_assert_f(output->pending_pipe !=
-			     b->pending_pipe,
-			     "%s and %s are both trying to use pipe %s\n",
-			     igt_output_name(output), igt_output_name(b),
-			     kmstest_pipe_name(output->pending_pipe));
-	}
-}
-
 static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
 {
 	igt_display_t *display = output->display;
@@ -2376,6 +2351,40 @@ static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
 	return &display->pipes[pipe];
 }
 
+static void igt_display_refresh(igt_display_t *display)
+{
+	igt_output_t *output;
+	igt_pipe_t *pipe;
+	int i;
+
+	unsigned long pipes_in_use = 0;
+	unsigned long pending_crtc_idx_mask;
+
+	/* Check that outputs and pipes agree wrt. cloning */
+	for (i = 0; i < display->n_outputs; i++) {
+		output = &display->outputs[i];
+		pending_crtc_idx_mask = 1 << output->pending_pipe;
+
+		pipe = igt_output_get_driving_pipe(output);
+		if (pipe) {
+			igt_assert_f(pipe->outputs & (1 << igt_output_idx(output)),
+				     "Output %s not expected to be using pipe %s\n",
+				     igt_output_name(output),
+				     kmstest_pipe_name(pipe->pipe));
+
+			if (pipes_in_use & pending_crtc_idx_mask)
+				LOG(display, "Output %s clones pipe %s\n",
+				    igt_output_name(output),
+				    kmstest_pipe_name(pipe->pipe));
+		}
+
+		pipes_in_use |= pending_crtc_idx_mask;
+
+		if (output->force_reprobe)
+			igt_output_refresh(output);
+	}
+}
+
 static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, int plane_idx)
 {
 	igt_require_f(plane_idx >= 0 && plane_idx < pipe->n_planes,
@@ -3766,6 +3775,7 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
 	output->use_override_mode = !!mode;
 
 	if (pipe) {
+		igt_debug("overriding pipe mode in %s way\n", output->display->is_atomic ? "atomic" : "legacy");
 		if (output->display->is_atomic)
 			igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
 		else
@@ -3773,6 +3783,16 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
 	}
 }
 
+void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe)
+{
+	igt_display_t *display = output->display;
+	uint32_t current_clones = display->pipes[pipe].outputs;
+
+	igt_output_set_pipe(output, pipe);
+
+	display->pipes[pipe].outputs |= current_clones;
+}
+
 /*
  * igt_output_set_pipe:
  * @output: Target output for which the pipe is being set to
@@ -3789,11 +3809,15 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
 
 	igt_assert(output->name);
 
-	if (output->pending_pipe != PIPE_NONE)
+	if (output->pending_pipe != PIPE_NONE) {
 		old_pipe = igt_output_get_driving_pipe(output);
+		old_pipe->outputs &= ~(1 << igt_output_idx(output));
+	}
 
-	if (pipe != PIPE_NONE)
+	if (pipe != PIPE_NONE) {
 		pipe_obj = &display->pipes[pipe];
+		pipe_obj->outputs = (1 << igt_output_idx(output));
+	}
 
 	LOG(display, "%s: set_pipe(%s)\n", igt_output_name(output),
 	    kmstest_pipe_name(pipe));
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index cacc6b90..676839bb 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -354,6 +354,8 @@ struct igt_pipe {
 	uint32_t crtc_id;
 
 	int32_t out_fence_fd;
+
+	uint32_t outputs;
 };
 
 typedef struct {
@@ -411,6 +413,8 @@ const char *igt_output_name(igt_output_t *output);
 drmModeModeInfo *igt_output_get_mode(igt_output_t *output);
 void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode);
 void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
+void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe);
+
 igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
 igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
 int igt_output_count_plane_type(igt_output_t *output, int plane_type);
-- 
2.21.0

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [igt-dev] [PATCH V6 i-g-t 5/6] lib/igt_kms: Add igt_output_clone_pipe for cloning
@ 2019-06-13  2:18   ` Brian Starkey
  0 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:18 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 5657 bytes --]

An output can be added as a clone of any other output(s) attached to a
pipe using igt_output_clone_pipe()

v5: Drop field out_fence_requested from struct igt_pipe (Brian Starkey)

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
---
 lib/igt_kms.c | 100 +++++++++++++++++++++++++++++++-------------------
 lib/igt_kms.h |   4 ++
 2 files changed, 66 insertions(+), 38 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 140db346..b85a0404 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -1765,6 +1765,17 @@ static void igt_display_log_shift(igt_display_t *display, int shift)
 	igt_assert(display->log_shift >= 0);
 }
 
+static int igt_output_idx(igt_output_t *output)
+{
+	int i;
+
+	for (i = 0; i < output->display->n_outputs; i++)
+		if (&output->display->outputs[i] == output)
+			return i;
+
+	return -1;
+}
+
 static void igt_output_refresh(igt_output_t *output)
 {
 	igt_display_t *display = output->display;
@@ -2317,42 +2328,6 @@ void igt_display_fini(igt_display_t *display)
 	display->planes = NULL;
 }
 
-static void igt_display_refresh(igt_display_t *display)
-{
-	igt_output_t *output;
-	int i;
-
-	unsigned long pipes_in_use = 0;
-
-       /* Check that two outputs aren't trying to use the same pipe */
-	for (i = 0; i < display->n_outputs; i++) {
-		output = &display->outputs[i];
-
-		if (output->pending_pipe != PIPE_NONE) {
-			if (pipes_in_use & (1 << output->pending_pipe))
-				goto report_dup;
-
-			pipes_in_use |= 1 << output->pending_pipe;
-		}
-
-		if (output->force_reprobe)
-			igt_output_refresh(output);
-	}
-
-	return;
-
-report_dup:
-	for (; i > 0; i--) {
-		igt_output_t *b = &display->outputs[i - 1];
-
-		igt_assert_f(output->pending_pipe !=
-			     b->pending_pipe,
-			     "%s and %s are both trying to use pipe %s\n",
-			     igt_output_name(output), igt_output_name(b),
-			     kmstest_pipe_name(output->pending_pipe));
-	}
-}
-
 static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
 {
 	igt_display_t *display = output->display;
@@ -2376,6 +2351,40 @@ static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
 	return &display->pipes[pipe];
 }
 
+static void igt_display_refresh(igt_display_t *display)
+{
+	igt_output_t *output;
+	igt_pipe_t *pipe;
+	int i;
+
+	unsigned long pipes_in_use = 0;
+	unsigned long pending_crtc_idx_mask;
+
+	/* Check that outputs and pipes agree wrt. cloning */
+	for (i = 0; i < display->n_outputs; i++) {
+		output = &display->outputs[i];
+		pending_crtc_idx_mask = 1 << output->pending_pipe;
+
+		pipe = igt_output_get_driving_pipe(output);
+		if (pipe) {
+			igt_assert_f(pipe->outputs & (1 << igt_output_idx(output)),
+				     "Output %s not expected to be using pipe %s\n",
+				     igt_output_name(output),
+				     kmstest_pipe_name(pipe->pipe));
+
+			if (pipes_in_use & pending_crtc_idx_mask)
+				LOG(display, "Output %s clones pipe %s\n",
+				    igt_output_name(output),
+				    kmstest_pipe_name(pipe->pipe));
+		}
+
+		pipes_in_use |= pending_crtc_idx_mask;
+
+		if (output->force_reprobe)
+			igt_output_refresh(output);
+	}
+}
+
 static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, int plane_idx)
 {
 	igt_require_f(plane_idx >= 0 && plane_idx < pipe->n_planes,
@@ -3766,6 +3775,7 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
 	output->use_override_mode = !!mode;
 
 	if (pipe) {
+		igt_debug("overriding pipe mode in %s way\n", output->display->is_atomic ? "atomic" : "legacy");
 		if (output->display->is_atomic)
 			igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
 		else
@@ -3773,6 +3783,16 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
 	}
 }
 
+void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe)
+{
+	igt_display_t *display = output->display;
+	uint32_t current_clones = display->pipes[pipe].outputs;
+
+	igt_output_set_pipe(output, pipe);
+
+	display->pipes[pipe].outputs |= current_clones;
+}
+
 /*
  * igt_output_set_pipe:
  * @output: Target output for which the pipe is being set to
@@ -3789,11 +3809,15 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
 
 	igt_assert(output->name);
 
-	if (output->pending_pipe != PIPE_NONE)
+	if (output->pending_pipe != PIPE_NONE) {
 		old_pipe = igt_output_get_driving_pipe(output);
+		old_pipe->outputs &= ~(1 << igt_output_idx(output));
+	}
 
-	if (pipe != PIPE_NONE)
+	if (pipe != PIPE_NONE) {
 		pipe_obj = &display->pipes[pipe];
+		pipe_obj->outputs = (1 << igt_output_idx(output));
+	}
 
 	LOG(display, "%s: set_pipe(%s)\n", igt_output_name(output),
 	    kmstest_pipe_name(pipe));
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index cacc6b90..676839bb 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -354,6 +354,8 @@ struct igt_pipe {
 	uint32_t crtc_id;
 
 	int32_t out_fence_fd;
+
+	uint32_t outputs;
 };
 
 typedef struct {
@@ -411,6 +413,8 @@ const char *igt_output_name(igt_output_t *output);
 drmModeModeInfo *igt_output_get_mode(igt_output_t *output);
 void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode);
 void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
+void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe);
+
 igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
 igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
 int igt_output_count_plane_type(igt_output_t *output, int plane_type);
-- 
2.21.0

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH V6 i-g-t 6/6] kms_writeback: Add tests using a cloned output
  2019-06-13  2:14 ` [igt-dev] " Rodrigo Siqueira
@ 2019-06-13  2:19   ` Brian Starkey
  -1 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:19 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 4528 bytes --]

Update the connector search to also optionally attempt to find a
non-writeback connector to clone to.

Add a subtest which is the same as writeback-check-output, but also
clones to the second connector.

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
[rebased and addressed comments by Maarten]
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
---
 tests/kms_writeback.c | 64 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 59 insertions(+), 5 deletions(-)

diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
index 0f20dadd..ae536bbf 100644
--- a/tests/kms_writeback.c
+++ b/tests/kms_writeback.c
@@ -51,7 +51,8 @@ static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
 	return blob;
 }
 
-static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
+static bool check_writeback_config(igt_display_t *display, igt_output_t *output,
+				   int pipe, igt_output_t **clone)
 {
 	igt_fb_t input_fb, output_fb;
 	igt_plane_t *plane;
@@ -91,6 +92,30 @@ static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
 
 	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
 					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+	if (!ret && clone) {
+		/* Try and find a clone */
+		int i, newret;
+		*clone = NULL;
+
+		for (i = 0; i < display->n_outputs; i++) {
+			igt_output_t *second_output = &display->outputs[i];
+			if (output != second_output &&
+			    igt_pipe_connector_valid(pipe, second_output)) {
+
+				igt_output_clone_pipe(second_output, pipe);
+				igt_output_override_mode(output, &override_mode);
+				newret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
+								       DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+				igt_output_set_pipe(second_output, PIPE_NONE);
+				igt_debug("try_commit_atomic clone returned %d\n", newret);
+				if (!newret) {
+					*clone = second_output;
+					igt_debug("Selected clone %s\n", (*clone)->name);
+					break;
+				}
+			}
+		}
+	}
 	igt_plane_set_fb(plane, NULL);
 	igt_remove_fb(display->drm_fd, &input_fb);
 	igt_remove_fb(display->drm_fd, &output_fb);
@@ -98,7 +123,8 @@ static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
 	return !ret;
 }
 
-static igt_output_t *kms_writeback_get_output(igt_display_t *display)
+static igt_output_t *kms_writeback_get_output(igt_display_t *display, enum pipe *pipe,
+					      igt_output_t **clone)
 {
 	int i;
 
@@ -114,10 +140,16 @@ static igt_output_t *kms_writeback_get_output(igt_display_t *display)
 		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
 			igt_output_set_pipe(output, j);
 
-			if (check_writeback_config(display, output)) {
+			if (check_writeback_config(display, output, j, clone)) {
 				igt_debug("Using connector %u:%s on pipe %d\n",
 					  output->config.connector->connector_id,
 					  output->name, j);
+				if (clone && *clone)
+					igt_debug("Cloning to connector %u:%s\n",
+						  (*clone)->config.connector->connector_id,
+						  (*clone)->name);
+				if (pipe)
+					*pipe = j;
 				return output;
 			}
 		}
@@ -335,10 +367,11 @@ static void writeback_check_output(igt_output_t *output, igt_plane_t *plane,
 igt_main
 {
 	igt_display_t display;
-	igt_output_t *output;
+	igt_output_t *output, *clone;
 	igt_plane_t *plane;
 	igt_fb_t input_fb;
 	drmModeModeInfo mode;
+	enum pipe pipe;
 	int ret;
 
 	memset(&display, 0, sizeof(display));
@@ -353,7 +386,7 @@ igt_main
 
 		igt_require(display.is_atomic);
 
-		output = kms_writeback_get_output(&display);
+		output = kms_writeback_get_output(&display, &pipe, &clone);
 		igt_require(output);
 
 		if (output->use_override_mode)
@@ -431,6 +464,27 @@ igt_main
 		igt_remove_fb(display.drm_fd, &output_fb);
 	}
 
+	igt_subtest("writeback-check-output-clone") {
+		igt_fb_t output_fb;
+
+		igt_require(clone);
+
+		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
+				    DRM_FORMAT_XRGB8888,
+				    igt_fb_mod_to_tiling(0),
+				    &output_fb);
+		igt_require(ret > 0);
+
+		igt_output_clone_pipe(clone, pipe);
+		igt_output_override_mode(clone, &mode);
+
+		writeback_check_output(output, plane, &input_fb, &output_fb);
+
+		igt_output_set_pipe(clone, PIPE_NONE);
+
+		igt_remove_fb(display.drm_fd, &output_fb);
+	}
+
 	igt_fixture {
 		igt_remove_fb(display.drm_fd, &input_fb);
 		igt_display_fini(&display);
-- 
2.21.0


[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [igt-dev] [PATCH V6 i-g-t 6/6] kms_writeback: Add tests using a cloned output
@ 2019-06-13  2:19   ` Brian Starkey
  0 siblings, 0 replies; 71+ messages in thread
From: Brian Starkey @ 2019-06-13  2:19 UTC (permalink / raw)
  To: Brian Starkey, Liviu Dudau, Petri Latvala, Arkadiusz Hiler,
	Daniel Vetter
  Cc: igt-dev, intel-gfx, nd


[-- Attachment #1.1: Type: text/plain, Size: 4528 bytes --]

Update the connector search to also optionally attempt to find a
non-writeback connector to clone to.

Add a subtest which is the same as writeback-check-output, but also
clones to the second connector.

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
[rebased and addressed comments by Maarten]
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
---
 tests/kms_writeback.c | 64 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 59 insertions(+), 5 deletions(-)

diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
index 0f20dadd..ae536bbf 100644
--- a/tests/kms_writeback.c
+++ b/tests/kms_writeback.c
@@ -51,7 +51,8 @@ static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
 	return blob;
 }
 
-static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
+static bool check_writeback_config(igt_display_t *display, igt_output_t *output,
+				   int pipe, igt_output_t **clone)
 {
 	igt_fb_t input_fb, output_fb;
 	igt_plane_t *plane;
@@ -91,6 +92,30 @@ static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
 
 	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
 					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+	if (!ret && clone) {
+		/* Try and find a clone */
+		int i, newret;
+		*clone = NULL;
+
+		for (i = 0; i < display->n_outputs; i++) {
+			igt_output_t *second_output = &display->outputs[i];
+			if (output != second_output &&
+			    igt_pipe_connector_valid(pipe, second_output)) {
+
+				igt_output_clone_pipe(second_output, pipe);
+				igt_output_override_mode(output, &override_mode);
+				newret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
+								       DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+				igt_output_set_pipe(second_output, PIPE_NONE);
+				igt_debug("try_commit_atomic clone returned %d\n", newret);
+				if (!newret) {
+					*clone = second_output;
+					igt_debug("Selected clone %s\n", (*clone)->name);
+					break;
+				}
+			}
+		}
+	}
 	igt_plane_set_fb(plane, NULL);
 	igt_remove_fb(display->drm_fd, &input_fb);
 	igt_remove_fb(display->drm_fd, &output_fb);
@@ -98,7 +123,8 @@ static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
 	return !ret;
 }
 
-static igt_output_t *kms_writeback_get_output(igt_display_t *display)
+static igt_output_t *kms_writeback_get_output(igt_display_t *display, enum pipe *pipe,
+					      igt_output_t **clone)
 {
 	int i;
 
@@ -114,10 +140,16 @@ static igt_output_t *kms_writeback_get_output(igt_display_t *display)
 		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
 			igt_output_set_pipe(output, j);
 
-			if (check_writeback_config(display, output)) {
+			if (check_writeback_config(display, output, j, clone)) {
 				igt_debug("Using connector %u:%s on pipe %d\n",
 					  output->config.connector->connector_id,
 					  output->name, j);
+				if (clone && *clone)
+					igt_debug("Cloning to connector %u:%s\n",
+						  (*clone)->config.connector->connector_id,
+						  (*clone)->name);
+				if (pipe)
+					*pipe = j;
 				return output;
 			}
 		}
@@ -335,10 +367,11 @@ static void writeback_check_output(igt_output_t *output, igt_plane_t *plane,
 igt_main
 {
 	igt_display_t display;
-	igt_output_t *output;
+	igt_output_t *output, *clone;
 	igt_plane_t *plane;
 	igt_fb_t input_fb;
 	drmModeModeInfo mode;
+	enum pipe pipe;
 	int ret;
 
 	memset(&display, 0, sizeof(display));
@@ -353,7 +386,7 @@ igt_main
 
 		igt_require(display.is_atomic);
 
-		output = kms_writeback_get_output(&display);
+		output = kms_writeback_get_output(&display, &pipe, &clone);
 		igt_require(output);
 
 		if (output->use_override_mode)
@@ -431,6 +464,27 @@ igt_main
 		igt_remove_fb(display.drm_fd, &output_fb);
 	}
 
+	igt_subtest("writeback-check-output-clone") {
+		igt_fb_t output_fb;
+
+		igt_require(clone);
+
+		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
+				    DRM_FORMAT_XRGB8888,
+				    igt_fb_mod_to_tiling(0),
+				    &output_fb);
+		igt_require(ret > 0);
+
+		igt_output_clone_pipe(clone, pipe);
+		igt_output_override_mode(clone, &mode);
+
+		writeback_check_output(output, plane, &input_fb, &output_fb);
+
+		igt_output_set_pipe(clone, PIPE_NONE);
+
+		igt_remove_fb(display.drm_fd, &output_fb);
+	}
+
 	igt_fixture {
 		igt_remove_fb(display.drm_fd, &input_fb);
 		igt_display_fini(&display);
-- 
2.21.0


[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [igt-dev] ✗ Fi.CI.BAT: failure for igt: Add support for testing writeback connectors (rev6)
  2019-06-13  2:14 ` [igt-dev] " Rodrigo Siqueira
                   ` (6 preceding siblings ...)
  (?)
@ 2019-06-13  3:38 ` Patchwork
  -1 siblings, 0 replies; 71+ messages in thread
From: Patchwork @ 2019-06-13  3:38 UTC (permalink / raw)
  To: Brian Starkey; +Cc: igt-dev

== Series Details ==

Series: igt: Add support for testing writeback connectors (rev6)
URL   : https://patchwork.freedesktop.org/series/39229/
State : failure

== Summary ==

CI Bug Log - changes from IGT_5055 -> IGTPW_3143
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_3143 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_3143, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/39229/revisions/6/mbox/

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_3143:

### IGT changes ###

#### Possible regressions ####

  * igt@kms_chamelium@vga-hpd-fast:
    - fi-cml-u2:          NOTRUN -> [SKIP][1] +1 similar issue
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/fi-cml-u2/igt@kms_chamelium@vga-hpd-fast.html

  
#### Warnings ####

  * igt@kms_chamelium@vga-hpd-fast:
    - fi-icl-u2:          [SKIP][2] ([fdo#109309]) -> [SKIP][3] +1 similar issue
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5055/fi-icl-u2/igt@kms_chamelium@vga-hpd-fast.html
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/fi-icl-u2/igt@kms_chamelium@vga-hpd-fast.html

  
Known issues
------------

  Here are the changes found in IGTPW_3143 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_create@basic-files:
    - fi-icl-dsi:         [PASS][4] -> [INCOMPLETE][5] ([fdo#107713] / [fdo#109100])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5055/fi-icl-dsi/igt@gem_ctx_create@basic-files.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/fi-icl-dsi/igt@gem_ctx_create@basic-files.html

  * igt@kms_busy@basic-flip-c:
    - fi-skl-6770hq:      [PASS][6] -> [SKIP][7] ([fdo#109271] / [fdo#109278]) +2 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5055/fi-skl-6770hq/igt@kms_busy@basic-flip-c.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/fi-skl-6770hq/igt@kms_busy@basic-flip-c.html

  * igt@kms_flip@basic-flip-vs-dpms:
    - fi-skl-6770hq:      [PASS][8] -> [SKIP][9] ([fdo#109271]) +23 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5055/fi-skl-6770hq/igt@kms_flip@basic-flip-vs-dpms.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/fi-skl-6770hq/igt@kms_flip@basic-flip-vs-dpms.html
    - fi-bxt-dsi:         [PASS][10] -> [INCOMPLETE][11] ([fdo#103927])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5055/fi-bxt-dsi/igt@kms_flip@basic-flip-vs-dpms.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/fi-bxt-dsi/igt@kms_flip@basic-flip-vs-dpms.html

  
#### Possible fixes ####

  * igt@gem_ctx_create@basic-files:
    - fi-icl-y:           [INCOMPLETE][12] ([fdo#107713] / [fdo#109100]) -> [PASS][13]
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5055/fi-icl-y/igt@gem_ctx_create@basic-files.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/fi-icl-y/igt@gem_ctx_create@basic-files.html

  * igt@gem_ctx_switch@basic-default:
    - fi-icl-guc:         [INCOMPLETE][14] ([fdo#107713] / [fdo#108569]) -> [PASS][15]
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5055/fi-icl-guc/igt@gem_ctx_switch@basic-default.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/fi-icl-guc/igt@gem_ctx_switch@basic-default.html

  * igt@gem_exec_basic@basic-all:
    - fi-cml-u2:          [INCOMPLETE][16] ([fdo#110566]) -> [PASS][17]
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5055/fi-cml-u2/igt@gem_exec_basic@basic-all.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/fi-cml-u2/igt@gem_exec_basic@basic-all.html

  * igt@kms_frontbuffer_tracking@basic:
    - fi-hsw-peppy:       [DMESG-WARN][18] ([fdo#102614]) -> [PASS][19]
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5055/fi-hsw-peppy/igt@kms_frontbuffer_tracking@basic.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/fi-hsw-peppy/igt@kms_frontbuffer_tracking@basic.html

  
  [fdo#102614]: https://bugs.freedesktop.org/show_bug.cgi?id=102614
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
  [fdo#108569]: https://bugs.freedesktop.org/show_bug.cgi?id=108569
  [fdo#109100]: https://bugs.freedesktop.org/show_bug.cgi?id=109100
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109309]: https://bugs.freedesktop.org/show_bug.cgi?id=109309
  [fdo#110566]: https://bugs.freedesktop.org/show_bug.cgi?id=110566


Participating hosts (53 -> 47)
------------------------------

  Additional (1): fi-skl-6600u 
  Missing    (7): fi-kbl-soraka fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * IGT: IGT_5055 -> IGTPW_3143

  CI_DRM_6253: 83fdc69645c5c6b511e36e171f1c75a6132f007c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_3143: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/
  IGT_5055: 495287320225e7f180d384cad7b207b77154438f @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools



== Testlist changes ==

+igt@kms_writeback@writeback-check-output
+igt@kms_writeback@writeback-check-output-clone
+igt@kms_writeback@writeback-fb-id
+igt@kms_writeback@writeback-invalid-out-fence
+igt@kms_writeback@writeback-pixel-formats

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3143/
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
  2019-06-13  2:16   ` [Intel-gfx] " Brian Starkey
@ 2019-06-13 14:54     ` Liviu Dudau
  -1 siblings, 0 replies; 71+ messages in thread
From: Liviu Dudau @ 2019-06-13 14:54 UTC (permalink / raw)
  To: Brian Starkey; +Cc: intel-gfx, igt-dev, nd

On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> Add support in igt_kms for writeback connectors, with the ability
> to attach framebuffers.
> 
> v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> drmModeGetResources()

Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>

Thanks for updating this! Given that I have done the last changes and this is
mostly a refresh, not sure if I should add more Reviewed-by's to the other
patches.

Best regards,
Liviu

> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> [rebased and updated to the latest igt style]
> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> ---
>  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_kms.h |  6 ++++++
>  2 files changed, 63 insertions(+)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index da188a39..140db346 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
>  	[IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
>  	[IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
>  	[IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> +	[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> +	[IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> +	[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
>  };
>  
>  /*
> @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
>  	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
>  	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
>  	{ DRM_MODE_CONNECTOR_DPI, "DPI" },
> +	{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
>  	{}
>  };
>  
> @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
>  	if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
>  		igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
>  					  BROADCAST_RGB_FULL);
> +	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> +	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> +		igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /**
> @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
>   * For outputs:
>   * - %IGT_CONNECTOR_CRTC_ID
>   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
>   * - igt_output_override_mode() to default.
>   *
>   * For pipes:
> @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
>  
>  	display->drm_fd = drm_fd;
>  
> +	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> +
>  	resources = drmModeGetResources(display->drm_fd);
>  	if (!resources)
>  		goto out;
> @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
>  	kmstest_free_connector_config(&output->config);
>  	free(output->name);
>  	output->name = NULL;
> +
> +	if (output->writeback_out_fence_fd != -1) {
> +		close(output->writeback_out_fence_fd);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /**
> @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
>  					  output->props[i],
>  					  output->values[i]));
>  	}
> +
> +	if (output->writeback_out_fence_fd != -1) {
> +		close(output->writeback_out_fence_fd);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /*
> @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
>  		else
>  			/* no modeset in universal commit, no change to crtc. */
>  			output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> +
> +		if (s == COMMIT_ATOMIC) {
> +			if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> +				igt_assert(output->writeback_out_fence_fd >= 0);
> +
> +			output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> +			output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> +			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> +			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> +		}
>  	}
>  
>  	if (display->first_commit) {
> @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
>  	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
>  }
>  
> +/**
> + * igt_output_set_writeback_fb:
> + * @output: Target output
> + * @fb: Target framebuffer
> + *
> + * This function sets the given @fb to be used as the target framebuffer for the
> + * writeback engine at the next atomic commit. It will also request a writeback
> + * out fence that will contain the fd number of the out fence created by KMS if
> + * the given @fb is valid.
> + */
> +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> +{
> +	igt_display_t *display = output->display;
> +
> +	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> +
> +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> +	/* only request a writeback out fence if the framebuffer is valid */
> +	if (fb)
> +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> +					  (ptrdiff_t)&output->writeback_out_fence_fd);
> +}
> +
>  /**
>   * igt_wait_for_vblank_count:
>   * @drm_fd: A drm file descriptor
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index a448a003..cacc6b90 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
>         IGT_CONNECTOR_BROADCAST_RGB,
>         IGT_CONNECTOR_CONTENT_PROTECTION,
>         IGT_CONNECTOR_VRR_CAPABLE,
> +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
>         IGT_NUM_CONNECTOR_PROPS
>  };
>  
> @@ -364,6 +367,8 @@ typedef struct {
>  	bool use_override_mode;
>  	drmModeModeInfo override_mode;
>  
> +	int32_t writeback_out_fence_fd;
> +
>  	/* bitmask of changed properties */
>  	uint64_t changed;
>  
> @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
>  igt_output_t *igt_output_from_connector(igt_display_t *display,
>      drmModeConnector *connector);
>  const drmModeModeInfo *igt_std_1024_mode_get(void);
> +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
>  
>  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
>  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> -- 
> 2.21.0
> 
> 
> -- 
> Rodrigo Siqueira
> https://siqueira.tech



-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
@ 2019-06-13 14:54     ` Liviu Dudau
  0 siblings, 0 replies; 71+ messages in thread
From: Liviu Dudau @ 2019-06-13 14:54 UTC (permalink / raw)
  To: Brian Starkey
  Cc: Petri Latvala, intel-gfx, igt-dev, Daniel Vetter, nd, Brian Starkey

On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> Add support in igt_kms for writeback connectors, with the ability
> to attach framebuffers.
> 
> v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> drmModeGetResources()

Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>

Thanks for updating this! Given that I have done the last changes and this is
mostly a refresh, not sure if I should add more Reviewed-by's to the other
patches.

Best regards,
Liviu

> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> [rebased and updated to the latest igt style]
> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> ---
>  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_kms.h |  6 ++++++
>  2 files changed, 63 insertions(+)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index da188a39..140db346 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
>  	[IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
>  	[IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
>  	[IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> +	[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> +	[IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> +	[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
>  };
>  
>  /*
> @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
>  	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
>  	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
>  	{ DRM_MODE_CONNECTOR_DPI, "DPI" },
> +	{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
>  	{}
>  };
>  
> @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
>  	if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
>  		igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
>  					  BROADCAST_RGB_FULL);
> +	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> +	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> +		igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /**
> @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
>   * For outputs:
>   * - %IGT_CONNECTOR_CRTC_ID
>   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
>   * - igt_output_override_mode() to default.
>   *
>   * For pipes:
> @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
>  
>  	display->drm_fd = drm_fd;
>  
> +	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> +
>  	resources = drmModeGetResources(display->drm_fd);
>  	if (!resources)
>  		goto out;
> @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
>  	kmstest_free_connector_config(&output->config);
>  	free(output->name);
>  	output->name = NULL;
> +
> +	if (output->writeback_out_fence_fd != -1) {
> +		close(output->writeback_out_fence_fd);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /**
> @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
>  					  output->props[i],
>  					  output->values[i]));
>  	}
> +
> +	if (output->writeback_out_fence_fd != -1) {
> +		close(output->writeback_out_fence_fd);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /*
> @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
>  		else
>  			/* no modeset in universal commit, no change to crtc. */
>  			output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> +
> +		if (s == COMMIT_ATOMIC) {
> +			if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> +				igt_assert(output->writeback_out_fence_fd >= 0);
> +
> +			output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> +			output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> +			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> +			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> +		}
>  	}
>  
>  	if (display->first_commit) {
> @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
>  	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
>  }
>  
> +/**
> + * igt_output_set_writeback_fb:
> + * @output: Target output
> + * @fb: Target framebuffer
> + *
> + * This function sets the given @fb to be used as the target framebuffer for the
> + * writeback engine at the next atomic commit. It will also request a writeback
> + * out fence that will contain the fd number of the out fence created by KMS if
> + * the given @fb is valid.
> + */
> +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> +{
> +	igt_display_t *display = output->display;
> +
> +	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> +
> +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> +	/* only request a writeback out fence if the framebuffer is valid */
> +	if (fb)
> +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> +					  (ptrdiff_t)&output->writeback_out_fence_fd);
> +}
> +
>  /**
>   * igt_wait_for_vblank_count:
>   * @drm_fd: A drm file descriptor
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index a448a003..cacc6b90 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
>         IGT_CONNECTOR_BROADCAST_RGB,
>         IGT_CONNECTOR_CONTENT_PROTECTION,
>         IGT_CONNECTOR_VRR_CAPABLE,
> +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
>         IGT_NUM_CONNECTOR_PROPS
>  };
>  
> @@ -364,6 +367,8 @@ typedef struct {
>  	bool use_override_mode;
>  	drmModeModeInfo override_mode;
>  
> +	int32_t writeback_out_fence_fd;
> +
>  	/* bitmask of changed properties */
>  	uint64_t changed;
>  
> @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
>  igt_output_t *igt_output_from_connector(igt_display_t *display,
>      drmModeConnector *connector);
>  const drmModeModeInfo *igt_std_1024_mode_get(void);
> +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
>  
>  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
>  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> -- 
> 2.21.0
> 
> 
> -- 
> Rodrigo Siqueira
> https://siqueira.tech



-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
  2019-06-13 14:54     ` [igt-dev] " Liviu Dudau
@ 2019-06-18 21:56       ` Rodrigo Siqueira
  -1 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-06-18 21:56 UTC (permalink / raw)
  To: Liviu Dudau; +Cc: Intel GFX ML, IGT GPU Tools, nd

On Thu, Jun 13, 2019 at 11:54 AM Liviu Dudau <Liviu.Dudau@arm.com> wrote:
>
> On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> > Add support in igt_kms for writeback connectors, with the ability
> > to attach framebuffers.
> >
> > v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> > drmModeGetResources()
>
> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
>
> Thanks for updating this! Given that I have done the last changes and this is
> mostly a refresh, not sure if I should add more Reviewed-by's to the other
> patches.

Thanks Liviu!

I just forgot to add my SoB, and for some reason, gmail does not allow
me to send an email on someone behalf. Btw, I can fix it after
everybody agrees that the kms_writeback is ready for landing.


> Best regards,
> Liviu
>
> >
> > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > [rebased and updated to the latest igt style]
> > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > ---
> >  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
> >  lib/igt_kms.h |  6 ++++++
> >  2 files changed, 63 insertions(+)
> >
> > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > index da188a39..140db346 100644
> > --- a/lib/igt_kms.c
> > +++ b/lib/igt_kms.c
> > @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
> >       [IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
> >       [IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
> >       [IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> > +     [IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> > +     [IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> > +     [IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
> >  };
> >
> >  /*
> > @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
> >       { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
> >       { DRM_MODE_CONNECTOR_DSI, "DSI" },
> >       { DRM_MODE_CONNECTOR_DPI, "DPI" },
> > +     { DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
> >       {}
> >  };
> >
> > @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
> >       if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
> >               igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
> >                                         BROADCAST_RGB_FULL);
> > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> > +             igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > +             output->writeback_out_fence_fd = -1;
> > +     }
> >  }
> >
> >  /**
> > @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
> >   * For outputs:
> >   * - %IGT_CONNECTOR_CRTC_ID
> >   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> > + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> > + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
> >   * - igt_output_override_mode() to default.
> >   *
> >   * For pipes:
> > @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> >
> >       display->drm_fd = drm_fd;
> >
> > +     drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > +
> >       resources = drmModeGetResources(display->drm_fd);
> >       if (!resources)
> >               goto out;
> > @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
> >       kmstest_free_connector_config(&output->config);
> >       free(output->name);
> >       output->name = NULL;
> > +
> > +     if (output->writeback_out_fence_fd != -1) {
> > +             close(output->writeback_out_fence_fd);
> > +             output->writeback_out_fence_fd = -1;
> > +     }
> >  }
> >
> >  /**
> > @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
> >                                         output->props[i],
> >                                         output->values[i]));
> >       }
> > +
> > +     if (output->writeback_out_fence_fd != -1) {
> > +             close(output->writeback_out_fence_fd);
> > +             output->writeback_out_fence_fd = -1;
> > +     }
> >  }
> >
> >  /*
> > @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
> >               else
> >                       /* no modeset in universal commit, no change to crtc. */
> >                       output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> > +
> > +             if (s == COMMIT_ATOMIC) {
> > +                     if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> > +                             igt_assert(output->writeback_out_fence_fd >= 0);
> > +
> > +                     output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> > +                     output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > +             }
> >       }
> >
> >       if (display->first_commit) {
> > @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
> >       igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
> >  }
> >
> > +/**
> > + * igt_output_set_writeback_fb:
> > + * @output: Target output
> > + * @fb: Target framebuffer
> > + *
> > + * This function sets the given @fb to be used as the target framebuffer for the
> > + * writeback engine at the next atomic commit. It will also request a writeback
> > + * out fence that will contain the fd number of the out fence created by KMS if
> > + * the given @fb is valid.
> > + */
> > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > +{
> > +     igt_display_t *display = output->display;
> > +
> > +     LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > +
> > +     igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > +     /* only request a writeback out fence if the framebuffer is valid */
> > +     if (fb)
> > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > +                                       (ptrdiff_t)&output->writeback_out_fence_fd);
> > +}
> > +
> >  /**
> >   * igt_wait_for_vblank_count:
> >   * @drm_fd: A drm file descriptor
> > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > index a448a003..cacc6b90 100644
> > --- a/lib/igt_kms.h
> > +++ b/lib/igt_kms.h
> > @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
> >         IGT_CONNECTOR_BROADCAST_RGB,
> >         IGT_CONNECTOR_CONTENT_PROTECTION,
> >         IGT_CONNECTOR_VRR_CAPABLE,
> > +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> > +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> > +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> >         IGT_NUM_CONNECTOR_PROPS
> >  };
> >
> > @@ -364,6 +367,8 @@ typedef struct {
> >       bool use_override_mode;
> >       drmModeModeInfo override_mode;
> >
> > +     int32_t writeback_out_fence_fd;
> > +
> >       /* bitmask of changed properties */
> >       uint64_t changed;
> >
> > @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
> >  igt_output_t *igt_output_from_connector(igt_display_t *display,
> >      drmModeConnector *connector);
> >  const drmModeModeInfo *igt_std_1024_mode_get(void);
> > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
> >
> >  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
> >  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> > --
> > 2.21.0
> >
> >
> > --
> > Rodrigo Siqueira
> > https://siqueira.tech
>
>
>
> --
> ====================
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---------------
>     ¯\_(ツ)_/¯



-- 

Rodrigo Siqueira
https://siqueira.tech
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
@ 2019-06-18 21:56       ` Rodrigo Siqueira
  0 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-06-18 21:56 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Petri Latvala, Intel GFX ML, IGT GPU Tools, Daniel Vetter, nd,
	Brian Starkey

On Thu, Jun 13, 2019 at 11:54 AM Liviu Dudau <Liviu.Dudau@arm.com> wrote:
>
> On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> > Add support in igt_kms for writeback connectors, with the ability
> > to attach framebuffers.
> >
> > v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> > drmModeGetResources()
>
> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
>
> Thanks for updating this! Given that I have done the last changes and this is
> mostly a refresh, not sure if I should add more Reviewed-by's to the other
> patches.

Thanks Liviu!

I just forgot to add my SoB, and for some reason, gmail does not allow
me to send an email on someone behalf. Btw, I can fix it after
everybody agrees that the kms_writeback is ready for landing.


> Best regards,
> Liviu
>
> >
> > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > [rebased and updated to the latest igt style]
> > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > ---
> >  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
> >  lib/igt_kms.h |  6 ++++++
> >  2 files changed, 63 insertions(+)
> >
> > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > index da188a39..140db346 100644
> > --- a/lib/igt_kms.c
> > +++ b/lib/igt_kms.c
> > @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
> >       [IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
> >       [IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
> >       [IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> > +     [IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> > +     [IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> > +     [IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
> >  };
> >
> >  /*
> > @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
> >       { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
> >       { DRM_MODE_CONNECTOR_DSI, "DSI" },
> >       { DRM_MODE_CONNECTOR_DPI, "DPI" },
> > +     { DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
> >       {}
> >  };
> >
> > @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
> >       if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
> >               igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
> >                                         BROADCAST_RGB_FULL);
> > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> > +             igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > +             output->writeback_out_fence_fd = -1;
> > +     }
> >  }
> >
> >  /**
> > @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
> >   * For outputs:
> >   * - %IGT_CONNECTOR_CRTC_ID
> >   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> > + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> > + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
> >   * - igt_output_override_mode() to default.
> >   *
> >   * For pipes:
> > @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> >
> >       display->drm_fd = drm_fd;
> >
> > +     drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > +
> >       resources = drmModeGetResources(display->drm_fd);
> >       if (!resources)
> >               goto out;
> > @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
> >       kmstest_free_connector_config(&output->config);
> >       free(output->name);
> >       output->name = NULL;
> > +
> > +     if (output->writeback_out_fence_fd != -1) {
> > +             close(output->writeback_out_fence_fd);
> > +             output->writeback_out_fence_fd = -1;
> > +     }
> >  }
> >
> >  /**
> > @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
> >                                         output->props[i],
> >                                         output->values[i]));
> >       }
> > +
> > +     if (output->writeback_out_fence_fd != -1) {
> > +             close(output->writeback_out_fence_fd);
> > +             output->writeback_out_fence_fd = -1;
> > +     }
> >  }
> >
> >  /*
> > @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
> >               else
> >                       /* no modeset in universal commit, no change to crtc. */
> >                       output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> > +
> > +             if (s == COMMIT_ATOMIC) {
> > +                     if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> > +                             igt_assert(output->writeback_out_fence_fd >= 0);
> > +
> > +                     output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> > +                     output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > +             }
> >       }
> >
> >       if (display->first_commit) {
> > @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
> >       igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
> >  }
> >
> > +/**
> > + * igt_output_set_writeback_fb:
> > + * @output: Target output
> > + * @fb: Target framebuffer
> > + *
> > + * This function sets the given @fb to be used as the target framebuffer for the
> > + * writeback engine at the next atomic commit. It will also request a writeback
> > + * out fence that will contain the fd number of the out fence created by KMS if
> > + * the given @fb is valid.
> > + */
> > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > +{
> > +     igt_display_t *display = output->display;
> > +
> > +     LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > +
> > +     igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > +     /* only request a writeback out fence if the framebuffer is valid */
> > +     if (fb)
> > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > +                                       (ptrdiff_t)&output->writeback_out_fence_fd);
> > +}
> > +
> >  /**
> >   * igt_wait_for_vblank_count:
> >   * @drm_fd: A drm file descriptor
> > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > index a448a003..cacc6b90 100644
> > --- a/lib/igt_kms.h
> > +++ b/lib/igt_kms.h
> > @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
> >         IGT_CONNECTOR_BROADCAST_RGB,
> >         IGT_CONNECTOR_CONTENT_PROTECTION,
> >         IGT_CONNECTOR_VRR_CAPABLE,
> > +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> > +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> > +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> >         IGT_NUM_CONNECTOR_PROPS
> >  };
> >
> > @@ -364,6 +367,8 @@ typedef struct {
> >       bool use_override_mode;
> >       drmModeModeInfo override_mode;
> >
> > +     int32_t writeback_out_fence_fd;
> > +
> >       /* bitmask of changed properties */
> >       uint64_t changed;
> >
> > @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
> >  igt_output_t *igt_output_from_connector(igt_display_t *display,
> >      drmModeConnector *connector);
> >  const drmModeModeInfo *igt_std_1024_mode_get(void);
> > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
> >
> >  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
> >  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> > --
> > 2.21.0
> >
> >
> > --
> > Rodrigo Siqueira
> > https://siqueira.tech
>
>
>
> --
> ====================
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---------------
>     ¯\_(ツ)_/¯



-- 

Rodrigo Siqueira
https://siqueira.tech
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
  2019-06-18 21:56       ` [igt-dev] " Rodrigo Siqueira
@ 2019-07-03 12:15         ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-03 12:15 UTC (permalink / raw)
  To: Liviu.Dudau, rodrigosiqueiramelo; +Cc: intel-gfx, igt-dev, nd

On Tue, 2019-06-18 at 18:56 -0300, Rodrigo Siqueira wrote:
> On Thu, Jun 13, 2019 at 11:54 AM Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> > > Add support in igt_kms for writeback connectors, with the ability
> > > to attach framebuffers.
> > > 
> > > v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> > > drmModeGetResources()
> > 
> > Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
> > 
> > Thanks for updating this! Given that I have done the last changes and this is
> > mostly a refresh, not sure if I should add more Reviewed-by's to the other
> > patches.
> 
> Thanks Liviu!
> 
> I just forgot to add my SoB, and for some reason, gmail does not allow
> me to send an email on someone behalf.

FWIW, that's a good thing, and it's required to pass DMARC checks.

Instead, git-send-email should add a From line at the beginning of the
message when sending a patch on behalf of someone else. I wonder what
happened here.

> Btw, I can fix it after
> everybody agrees that the kms_writeback is ready for landing.
> 
> 
> > Best regards,
> > Liviu
> > 
> > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > [rebased and updated to the latest igt style]
> > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > ---
> > >  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  lib/igt_kms.h |  6 ++++++
> > >  2 files changed, 63 insertions(+)
> > > 
> > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > index da188a39..140db346 100644
> > > --- a/lib/igt_kms.c
> > > +++ b/lib/igt_kms.c
> > > @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
> > >       [IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
> > >       [IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
> > >       [IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> > > +     [IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> > > +     [IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> > > +     [IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
> > >  };
> > > 
> > >  /*
> > > @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
> > >       { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
> > >       { DRM_MODE_CONNECTOR_DSI, "DSI" },
> > >       { DRM_MODE_CONNECTOR_DPI, "DPI" },
> > > +     { DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
> > >       {}
> > >  };
> > > 
> > > @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
> > >       if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
> > >               igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
> > >                                         BROADCAST_RGB_FULL);
> > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> > > +             igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > +             output->writeback_out_fence_fd = -1;
> > > +     }
> > >  }
> > > 
> > >  /**
> > > @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
> > >   * For outputs:
> > >   * - %IGT_CONNECTOR_CRTC_ID
> > >   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> > > + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> > > + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
> > >   * - igt_output_override_mode() to default.
> > >   *
> > >   * For pipes:
> > > @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> > > 
> > >       display->drm_fd = drm_fd;
> > > 
> > > +     drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > > +
> > >       resources = drmModeGetResources(display->drm_fd);
> > >       if (!resources)
> > >               goto out;
> > > @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
> > >       kmstest_free_connector_config(&output->config);
> > >       free(output->name);
> > >       output->name = NULL;
> > > +
> > > +     if (output->writeback_out_fence_fd != -1) {
> > > +             close(output->writeback_out_fence_fd);
> > > +             output->writeback_out_fence_fd = -1;
> > > +     }
> > >  }
> > > 
> > >  /**
> > > @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
> > >                                         output->props[i],
> > >                                         output->values[i]));
> > >       }
> > > +
> > > +     if (output->writeback_out_fence_fd != -1) {
> > > +             close(output->writeback_out_fence_fd);
> > > +             output->writeback_out_fence_fd = -1;
> > > +     }
> > >  }
> > > 
> > >  /*
> > > @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
> > >               else
> > >                       /* no modeset in universal commit, no change to crtc. */
> > >                       output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> > > +
> > > +             if (s == COMMIT_ATOMIC) {
> > > +                     if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> > > +                             igt_assert(output->writeback_out_fence_fd >= 0);
> > > +
> > > +                     output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> > > +                     output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > +             }
> > >       }
> > > 
> > >       if (display->first_commit) {
> > > @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
> > >       igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
> > >  }
> > > 
> > > +/**
> > > + * igt_output_set_writeback_fb:
> > > + * @output: Target output
> > > + * @fb: Target framebuffer
> > > + *
> > > + * This function sets the given @fb to be used as the target framebuffer for the
> > > + * writeback engine at the next atomic commit. It will also request a writeback
> > > + * out fence that will contain the fd number of the out fence created by KMS if
> > > + * the given @fb is valid.
> > > + */
> > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > > +{
> > > +     igt_display_t *display = output->display;
> > > +
> > > +     LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > > +
> > > +     igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > > +     /* only request a writeback out fence if the framebuffer is valid */
> > > +     if (fb)
> > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > +                                       (ptrdiff_t)&output->writeback_out_fence_fd);
> > > +}
> > > +
> > >  /**
> > >   * igt_wait_for_vblank_count:
> > >   * @drm_fd: A drm file descriptor
> > > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > > index a448a003..cacc6b90 100644
> > > --- a/lib/igt_kms.h
> > > +++ b/lib/igt_kms.h
> > > @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
> > >         IGT_CONNECTOR_BROADCAST_RGB,
> > >         IGT_CONNECTOR_CONTENT_PROTECTION,
> > >         IGT_CONNECTOR_VRR_CAPABLE,
> > > +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> > > +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> > > +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > >         IGT_NUM_CONNECTOR_PROPS
> > >  };
> > > 
> > > @@ -364,6 +367,8 @@ typedef struct {
> > >       bool use_override_mode;
> > >       drmModeModeInfo override_mode;
> > > 
> > > +     int32_t writeback_out_fence_fd;
> > > +
> > >       /* bitmask of changed properties */
> > >       uint64_t changed;
> > > 
> > > @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
> > >  igt_output_t *igt_output_from_connector(igt_display_t *display,
> > >      drmModeConnector *connector);
> > >  const drmModeModeInfo *igt_std_1024_mode_get(void);
> > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
> > > 
> > >  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
> > >  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> > > --
> > > 2.21.0
> > > 
> > > 
> > > --
> > > Rodrigo Siqueira
> > > https://siqueira.tech
> > 
> > 
> > --
> > ====================
> > > I would like to |
> > > fix the world,  |
> > > but they're not |
> > > giving me the   |
> >  \ source code!  /
> >   ---------------
> >     ¯\_(ツ)_/¯
> 
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
@ 2019-07-03 12:15         ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-03 12:15 UTC (permalink / raw)
  To: Liviu.Dudau, rodrigosiqueiramelo
  Cc: Latvala, Petri, intel-gfx, igt-dev, daniel, nd, Brian.Starkey

On Tue, 2019-06-18 at 18:56 -0300, Rodrigo Siqueira wrote:
> On Thu, Jun 13, 2019 at 11:54 AM Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> > > Add support in igt_kms for writeback connectors, with the ability
> > > to attach framebuffers.
> > > 
> > > v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> > > drmModeGetResources()
> > 
> > Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
> > 
> > Thanks for updating this! Given that I have done the last changes and this is
> > mostly a refresh, not sure if I should add more Reviewed-by's to the other
> > patches.
> 
> Thanks Liviu!
> 
> I just forgot to add my SoB, and for some reason, gmail does not allow
> me to send an email on someone behalf.

FWIW, that's a good thing, and it's required to pass DMARC checks.

Instead, git-send-email should add a From line at the beginning of the
message when sending a patch on behalf of someone else. I wonder what
happened here.

> Btw, I can fix it after
> everybody agrees that the kms_writeback is ready for landing.
> 
> 
> > Best regards,
> > Liviu
> > 
> > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > [rebased and updated to the latest igt style]
> > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > ---
> > >  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  lib/igt_kms.h |  6 ++++++
> > >  2 files changed, 63 insertions(+)
> > > 
> > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > index da188a39..140db346 100644
> > > --- a/lib/igt_kms.c
> > > +++ b/lib/igt_kms.c
> > > @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
> > >       [IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
> > >       [IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
> > >       [IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> > > +     [IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> > > +     [IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> > > +     [IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
> > >  };
> > > 
> > >  /*
> > > @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
> > >       { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
> > >       { DRM_MODE_CONNECTOR_DSI, "DSI" },
> > >       { DRM_MODE_CONNECTOR_DPI, "DPI" },
> > > +     { DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
> > >       {}
> > >  };
> > > 
> > > @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
> > >       if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
> > >               igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
> > >                                         BROADCAST_RGB_FULL);
> > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> > > +             igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > +             output->writeback_out_fence_fd = -1;
> > > +     }
> > >  }
> > > 
> > >  /**
> > > @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
> > >   * For outputs:
> > >   * - %IGT_CONNECTOR_CRTC_ID
> > >   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> > > + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> > > + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
> > >   * - igt_output_override_mode() to default.
> > >   *
> > >   * For pipes:
> > > @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> > > 
> > >       display->drm_fd = drm_fd;
> > > 
> > > +     drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > > +
> > >       resources = drmModeGetResources(display->drm_fd);
> > >       if (!resources)
> > >               goto out;
> > > @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
> > >       kmstest_free_connector_config(&output->config);
> > >       free(output->name);
> > >       output->name = NULL;
> > > +
> > > +     if (output->writeback_out_fence_fd != -1) {
> > > +             close(output->writeback_out_fence_fd);
> > > +             output->writeback_out_fence_fd = -1;
> > > +     }
> > >  }
> > > 
> > >  /**
> > > @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
> > >                                         output->props[i],
> > >                                         output->values[i]));
> > >       }
> > > +
> > > +     if (output->writeback_out_fence_fd != -1) {
> > > +             close(output->writeback_out_fence_fd);
> > > +             output->writeback_out_fence_fd = -1;
> > > +     }
> > >  }
> > > 
> > >  /*
> > > @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
> > >               else
> > >                       /* no modeset in universal commit, no change to crtc. */
> > >                       output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> > > +
> > > +             if (s == COMMIT_ATOMIC) {
> > > +                     if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> > > +                             igt_assert(output->writeback_out_fence_fd >= 0);
> > > +
> > > +                     output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> > > +                     output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > +             }
> > >       }
> > > 
> > >       if (display->first_commit) {
> > > @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
> > >       igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
> > >  }
> > > 
> > > +/**
> > > + * igt_output_set_writeback_fb:
> > > + * @output: Target output
> > > + * @fb: Target framebuffer
> > > + *
> > > + * This function sets the given @fb to be used as the target framebuffer for the
> > > + * writeback engine at the next atomic commit. It will also request a writeback
> > > + * out fence that will contain the fd number of the out fence created by KMS if
> > > + * the given @fb is valid.
> > > + */
> > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > > +{
> > > +     igt_display_t *display = output->display;
> > > +
> > > +     LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > > +
> > > +     igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > > +     /* only request a writeback out fence if the framebuffer is valid */
> > > +     if (fb)
> > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > +                                       (ptrdiff_t)&output->writeback_out_fence_fd);
> > > +}
> > > +
> > >  /**
> > >   * igt_wait_for_vblank_count:
> > >   * @drm_fd: A drm file descriptor
> > > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > > index a448a003..cacc6b90 100644
> > > --- a/lib/igt_kms.h
> > > +++ b/lib/igt_kms.h
> > > @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
> > >         IGT_CONNECTOR_BROADCAST_RGB,
> > >         IGT_CONNECTOR_CONTENT_PROTECTION,
> > >         IGT_CONNECTOR_VRR_CAPABLE,
> > > +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> > > +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> > > +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > >         IGT_NUM_CONNECTOR_PROPS
> > >  };
> > > 
> > > @@ -364,6 +367,8 @@ typedef struct {
> > >       bool use_override_mode;
> > >       drmModeModeInfo override_mode;
> > > 
> > > +     int32_t writeback_out_fence_fd;
> > > +
> > >       /* bitmask of changed properties */
> > >       uint64_t changed;
> > > 
> > > @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
> > >  igt_output_t *igt_output_from_connector(igt_display_t *display,
> > >      drmModeConnector *connector);
> > >  const drmModeModeInfo *igt_std_1024_mode_get(void);
> > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
> > > 
> > >  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
> > >  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> > > --
> > > 2.21.0
> > > 
> > > 
> > > --
> > > Rodrigo Siqueira
> > > https://siqueira.tech
> > 
> > 
> > --
> > ====================
> > > I would like to |
> > > fix the world,  |
> > > but they're not |
> > > giving me the   |
> >  \ source code!  /
> >   ---------------
> >     ¯\_(ツ)_/¯
> 
> 
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
  2019-07-03 12:15         ` Ser, Simon
@ 2019-07-09 14:32           ` Rodrigo Siqueira
  -1 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-09 14:32 UTC (permalink / raw)
  To: Ser, Simon; +Cc: intel-gfx, igt-dev, nd

On Wed, Jul 3, 2019 at 9:15 AM Ser, Simon <simon.ser@intel.com> wrote:
>
> On Tue, 2019-06-18 at 18:56 -0300, Rodrigo Siqueira wrote:
> > On Thu, Jun 13, 2019 at 11:54 AM Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > > On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> > > > Add support in igt_kms for writeback connectors, with the ability
> > > > to attach framebuffers.
> > > >
> > > > v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> > > > drmModeGetResources()
> > >
> > > Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
> > >
> > > Thanks for updating this! Given that I have done the last changes and this is
> > > mostly a refresh, not sure if I should add more Reviewed-by's to the other
> > > patches.
> >
> > Thanks Liviu!
> >
> > I just forgot to add my SoB, and for some reason, gmail does not allow
> > me to send an email on someone behalf.
>
> FWIW, that's a good thing, and it's required to pass DMARC checks.
>
> Instead, git-send-email should add a From line at the beginning of the
> message when sending a patch on behalf of someone else. I wonder what
> happened here.

Thank you for your help.

I’m using neomutt for sending patches, and I’ll take a look at
git-send-email. Additionally, it looks like Gmail requires that I add
a new account in order to allow me to send patches on someone behalf.
I’ll take some time to read about this issue, and I will try to resend
the patchset again.

Btw, if you have time, could you take a look in this series?

Best regards

> > Btw, I can fix it after
> > everybody agrees that the kms_writeback is ready for landing.
> >
> >
> > > Best regards,
> > > Liviu
> > >
> > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > [rebased and updated to the latest igt style]
> > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > ---
> > > >  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > >  lib/igt_kms.h |  6 ++++++
> > > >  2 files changed, 63 insertions(+)
> > > >
> > > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > > index da188a39..140db346 100644
> > > > --- a/lib/igt_kms.c
> > > > +++ b/lib/igt_kms.c
> > > > @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
> > > >       [IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
> > > >       [IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
> > > >       [IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> > > > +     [IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> > > > +     [IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> > > > +     [IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
> > > >  };
> > > >
> > > >  /*
> > > > @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
> > > >       { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
> > > >       { DRM_MODE_CONNECTOR_DSI, "DSI" },
> > > >       { DRM_MODE_CONNECTOR_DPI, "DPI" },
> > > > +     { DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
> > > >       {}
> > > >  };
> > > >
> > > > @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
> > > >       if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
> > > >               igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
> > > >                                         BROADCAST_RGB_FULL);
> > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> > > > +             igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > +             output->writeback_out_fence_fd = -1;
> > > > +     }
> > > >  }
> > > >
> > > >  /**
> > > > @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
> > > >   * For outputs:
> > > >   * - %IGT_CONNECTOR_CRTC_ID
> > > >   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> > > > + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> > > > + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
> > > >   * - igt_output_override_mode() to default.
> > > >   *
> > > >   * For pipes:
> > > > @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> > > >
> > > >       display->drm_fd = drm_fd;
> > > >
> > > > +     drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > > > +
> > > >       resources = drmModeGetResources(display->drm_fd);
> > > >       if (!resources)
> > > >               goto out;
> > > > @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
> > > >       kmstest_free_connector_config(&output->config);
> > > >       free(output->name);
> > > >       output->name = NULL;
> > > > +
> > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > +             close(output->writeback_out_fence_fd);
> > > > +             output->writeback_out_fence_fd = -1;
> > > > +     }
> > > >  }
> > > >
> > > >  /**
> > > > @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
> > > >                                         output->props[i],
> > > >                                         output->values[i]));
> > > >       }
> > > > +
> > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > +             close(output->writeback_out_fence_fd);
> > > > +             output->writeback_out_fence_fd = -1;
> > > > +     }
> > > >  }
> > > >
> > > >  /*
> > > > @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
> > > >               else
> > > >                       /* no modeset in universal commit, no change to crtc. */
> > > >                       output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> > > > +
> > > > +             if (s == COMMIT_ATOMIC) {
> > > > +                     if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> > > > +                             igt_assert(output->writeback_out_fence_fd >= 0);
> > > > +
> > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > +             }
> > > >       }
> > > >
> > > >       if (display->first_commit) {
> > > > @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
> > > >       igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
> > > >  }
> > > >
> > > > +/**
> > > > + * igt_output_set_writeback_fb:
> > > > + * @output: Target output
> > > > + * @fb: Target framebuffer
> > > > + *
> > > > + * This function sets the given @fb to be used as the target framebuffer for the
> > > > + * writeback engine at the next atomic commit. It will also request a writeback
> > > > + * out fence that will contain the fd number of the out fence created by KMS if
> > > > + * the given @fb is valid.
> > > > + */
> > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > > > +{
> > > > +     igt_display_t *display = output->display;
> > > > +
> > > > +     LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > > > +
> > > > +     igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > > > +     /* only request a writeback out fence if the framebuffer is valid */
> > > > +     if (fb)
> > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > +                                       (ptrdiff_t)&output->writeback_out_fence_fd);
> > > > +}
> > > > +
> > > >  /**
> > > >   * igt_wait_for_vblank_count:
> > > >   * @drm_fd: A drm file descriptor
> > > > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > > > index a448a003..cacc6b90 100644
> > > > --- a/lib/igt_kms.h
> > > > +++ b/lib/igt_kms.h
> > > > @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
> > > >         IGT_CONNECTOR_BROADCAST_RGB,
> > > >         IGT_CONNECTOR_CONTENT_PROTECTION,
> > > >         IGT_CONNECTOR_VRR_CAPABLE,
> > > > +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> > > > +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> > > > +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > >         IGT_NUM_CONNECTOR_PROPS
> > > >  };
> > > >
> > > > @@ -364,6 +367,8 @@ typedef struct {
> > > >       bool use_override_mode;
> > > >       drmModeModeInfo override_mode;
> > > >
> > > > +     int32_t writeback_out_fence_fd;
> > > > +
> > > >       /* bitmask of changed properties */
> > > >       uint64_t changed;
> > > >
> > > > @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
> > > >  igt_output_t *igt_output_from_connector(igt_display_t *display,
> > > >      drmModeConnector *connector);
> > > >  const drmModeModeInfo *igt_std_1024_mode_get(void);
> > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
> > > >
> > > >  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
> > > >  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> > > > --
> > > > 2.21.0
> > > >
> > > >
> > > > --
> > > > Rodrigo Siqueira
> > > > https://siqueira.tech
> > >
> > >
> > > --
> > > ====================
> > > > I would like to |
> > > > fix the world,  |
> > > > but they're not |
> > > > giving me the   |
> > >  \ source code!  /
> > >   ---------------
> > >     ¯\_(ツ)_/¯
> >
> >



-- 

Rodrigo Siqueira
https://siqueira.tech
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
@ 2019-07-09 14:32           ` Rodrigo Siqueira
  0 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-09 14:32 UTC (permalink / raw)
  To: Ser, Simon
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey

On Wed, Jul 3, 2019 at 9:15 AM Ser, Simon <simon.ser@intel.com> wrote:
>
> On Tue, 2019-06-18 at 18:56 -0300, Rodrigo Siqueira wrote:
> > On Thu, Jun 13, 2019 at 11:54 AM Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > > On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> > > > Add support in igt_kms for writeback connectors, with the ability
> > > > to attach framebuffers.
> > > >
> > > > v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> > > > drmModeGetResources()
> > >
> > > Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
> > >
> > > Thanks for updating this! Given that I have done the last changes and this is
> > > mostly a refresh, not sure if I should add more Reviewed-by's to the other
> > > patches.
> >
> > Thanks Liviu!
> >
> > I just forgot to add my SoB, and for some reason, gmail does not allow
> > me to send an email on someone behalf.
>
> FWIW, that's a good thing, and it's required to pass DMARC checks.
>
> Instead, git-send-email should add a From line at the beginning of the
> message when sending a patch on behalf of someone else. I wonder what
> happened here.

Thank you for your help.

I’m using neomutt for sending patches, and I’ll take a look at
git-send-email. Additionally, it looks like Gmail requires that I add
a new account in order to allow me to send patches on someone behalf.
I’ll take some time to read about this issue, and I will try to resend
the patchset again.

Btw, if you have time, could you take a look in this series?

Best regards

> > Btw, I can fix it after
> > everybody agrees that the kms_writeback is ready for landing.
> >
> >
> > > Best regards,
> > > Liviu
> > >
> > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > [rebased and updated to the latest igt style]
> > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > ---
> > > >  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > >  lib/igt_kms.h |  6 ++++++
> > > >  2 files changed, 63 insertions(+)
> > > >
> > > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > > index da188a39..140db346 100644
> > > > --- a/lib/igt_kms.c
> > > > +++ b/lib/igt_kms.c
> > > > @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
> > > >       [IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
> > > >       [IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
> > > >       [IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> > > > +     [IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> > > > +     [IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> > > > +     [IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
> > > >  };
> > > >
> > > >  /*
> > > > @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
> > > >       { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
> > > >       { DRM_MODE_CONNECTOR_DSI, "DSI" },
> > > >       { DRM_MODE_CONNECTOR_DPI, "DPI" },
> > > > +     { DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
> > > >       {}
> > > >  };
> > > >
> > > > @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
> > > >       if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
> > > >               igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
> > > >                                         BROADCAST_RGB_FULL);
> > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> > > > +             igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > +             output->writeback_out_fence_fd = -1;
> > > > +     }
> > > >  }
> > > >
> > > >  /**
> > > > @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
> > > >   * For outputs:
> > > >   * - %IGT_CONNECTOR_CRTC_ID
> > > >   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> > > > + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> > > > + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
> > > >   * - igt_output_override_mode() to default.
> > > >   *
> > > >   * For pipes:
> > > > @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> > > >
> > > >       display->drm_fd = drm_fd;
> > > >
> > > > +     drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > > > +
> > > >       resources = drmModeGetResources(display->drm_fd);
> > > >       if (!resources)
> > > >               goto out;
> > > > @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
> > > >       kmstest_free_connector_config(&output->config);
> > > >       free(output->name);
> > > >       output->name = NULL;
> > > > +
> > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > +             close(output->writeback_out_fence_fd);
> > > > +             output->writeback_out_fence_fd = -1;
> > > > +     }
> > > >  }
> > > >
> > > >  /**
> > > > @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
> > > >                                         output->props[i],
> > > >                                         output->values[i]));
> > > >       }
> > > > +
> > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > +             close(output->writeback_out_fence_fd);
> > > > +             output->writeback_out_fence_fd = -1;
> > > > +     }
> > > >  }
> > > >
> > > >  /*
> > > > @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
> > > >               else
> > > >                       /* no modeset in universal commit, no change to crtc. */
> > > >                       output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> > > > +
> > > > +             if (s == COMMIT_ATOMIC) {
> > > > +                     if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> > > > +                             igt_assert(output->writeback_out_fence_fd >= 0);
> > > > +
> > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > +             }
> > > >       }
> > > >
> > > >       if (display->first_commit) {
> > > > @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
> > > >       igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
> > > >  }
> > > >
> > > > +/**
> > > > + * igt_output_set_writeback_fb:
> > > > + * @output: Target output
> > > > + * @fb: Target framebuffer
> > > > + *
> > > > + * This function sets the given @fb to be used as the target framebuffer for the
> > > > + * writeback engine at the next atomic commit. It will also request a writeback
> > > > + * out fence that will contain the fd number of the out fence created by KMS if
> > > > + * the given @fb is valid.
> > > > + */
> > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > > > +{
> > > > +     igt_display_t *display = output->display;
> > > > +
> > > > +     LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > > > +
> > > > +     igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > > > +     /* only request a writeback out fence if the framebuffer is valid */
> > > > +     if (fb)
> > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > +                                       (ptrdiff_t)&output->writeback_out_fence_fd);
> > > > +}
> > > > +
> > > >  /**
> > > >   * igt_wait_for_vblank_count:
> > > >   * @drm_fd: A drm file descriptor
> > > > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > > > index a448a003..cacc6b90 100644
> > > > --- a/lib/igt_kms.h
> > > > +++ b/lib/igt_kms.h
> > > > @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
> > > >         IGT_CONNECTOR_BROADCAST_RGB,
> > > >         IGT_CONNECTOR_CONTENT_PROTECTION,
> > > >         IGT_CONNECTOR_VRR_CAPABLE,
> > > > +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> > > > +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> > > > +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > >         IGT_NUM_CONNECTOR_PROPS
> > > >  };
> > > >
> > > > @@ -364,6 +367,8 @@ typedef struct {
> > > >       bool use_override_mode;
> > > >       drmModeModeInfo override_mode;
> > > >
> > > > +     int32_t writeback_out_fence_fd;
> > > > +
> > > >       /* bitmask of changed properties */
> > > >       uint64_t changed;
> > > >
> > > > @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
> > > >  igt_output_t *igt_output_from_connector(igt_display_t *display,
> > > >      drmModeConnector *connector);
> > > >  const drmModeModeInfo *igt_std_1024_mode_get(void);
> > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
> > > >
> > > >  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
> > > >  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> > > > --
> > > > 2.21.0
> > > >
> > > >
> > > > --
> > > > Rodrigo Siqueira
> > > > https://siqueira.tech
> > >
> > >
> > > --
> > > ====================
> > > > I would like to |
> > > > fix the world,  |
> > > > but they're not |
> > > > giving me the   |
> > >  \ source code!  /
> > >   ---------------
> > >     ¯\_(ツ)_/¯
> >
> >



-- 

Rodrigo Siqueira
https://siqueira.tech
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
  2019-07-09 14:32           ` Rodrigo Siqueira
@ 2019-07-09 14:42             ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-09 14:42 UTC (permalink / raw)
  To: rodrigosiqueiramelo; +Cc: intel-gfx, igt-dev, nd

On Tue, 2019-07-09 at 11:32 -0300, Rodrigo Siqueira wrote:
> On Wed, Jul 3, 2019 at 9:15 AM Ser, Simon <simon.ser@intel.com> wrote:
> > On Tue, 2019-06-18 at 18:56 -0300, Rodrigo Siqueira wrote:
> > > On Thu, Jun 13, 2019 at 11:54 AM Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > > > On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> > > > > Add support in igt_kms for writeback connectors, with the ability
> > > > > to attach framebuffers.
> > > > > 
> > > > > v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> > > > > drmModeGetResources()
> > > > 
> > > > Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > 
> > > > Thanks for updating this! Given that I have done the last changes and this is
> > > > mostly a refresh, not sure if I should add more Reviewed-by's to the other
> > > > patches.
> > > 
> > > Thanks Liviu!
> > > 
> > > I just forgot to add my SoB, and for some reason, gmail does not allow
> > > me to send an email on someone behalf.
> > 
> > FWIW, that's a good thing, and it's required to pass DMARC checks.
> > 
> > Instead, git-send-email should add a From line at the beginning of the
> > message when sending a patch on behalf of someone else. I wonder what
> > happened here.
> 
> Thank you for your help.
> 
> I’m using neomutt for sending patches, and I’ll take a look at
> git-send-email. Additionally, it looks like Gmail requires that I add
> a new account in order to allow me to send patches on someone behalf.
> I’ll take some time to read about this issue, and I will try to resend
> the patchset again.

When sending a patch on someone else's behalf, you shouldn't send the
e-mail with the sender (From header) set to someone else. You should
use your normal address. The From line in the body of the message will
make Git understand the author is someone else.

So no new account setup required.

I really recommend using git-send-email for patches. There are too many
ways to make a mistake if you try sending emails manually. Here is a
tutorial:
https://git-send-email.io/

> Btw, if you have time, could you take a look in this series?

Sure, I've already began looking at the series. I'll continue soon.

Thanks for your work!

> Best regards
> 
> > > Btw, I can fix it after
> > > everybody agrees that the kms_writeback is ready for landing.
> > > 
> > > 
> > > > Best regards,
> > > > Liviu
> > > > 
> > > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > > [rebased and updated to the latest igt style]
> > > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > > ---
> > > > >  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > >  lib/igt_kms.h |  6 ++++++
> > > > >  2 files changed, 63 insertions(+)
> > > > > 
> > > > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > > > index da188a39..140db346 100644
> > > > > --- a/lib/igt_kms.c
> > > > > +++ b/lib/igt_kms.c
> > > > > @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
> > > > >       [IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
> > > > >       [IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
> > > > >       [IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> > > > > +     [IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> > > > > +     [IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> > > > > +     [IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
> > > > >  };
> > > > > 
> > > > >  /*
> > > > > @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
> > > > >       { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
> > > > >       { DRM_MODE_CONNECTOR_DSI, "DSI" },
> > > > >       { DRM_MODE_CONNECTOR_DPI, "DPI" },
> > > > > +     { DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
> > > > >       {}
> > > > >  };
> > > > > 
> > > > > @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
> > > > >       if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
> > > > >               igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
> > > > >                                         BROADCAST_RGB_FULL);
> > > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> > > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> > > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> > > > > +             igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > > +             output->writeback_out_fence_fd = -1;
> > > > > +     }
> > > > >  }
> > > > > 
> > > > >  /**
> > > > > @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
> > > > >   * For outputs:
> > > > >   * - %IGT_CONNECTOR_CRTC_ID
> > > > >   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> > > > > + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> > > > > + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
> > > > >   * - igt_output_override_mode() to default.
> > > > >   *
> > > > >   * For pipes:
> > > > > @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> > > > > 
> > > > >       display->drm_fd = drm_fd;
> > > > > 
> > > > > +     drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > > > > +
> > > > >       resources = drmModeGetResources(display->drm_fd);
> > > > >       if (!resources)
> > > > >               goto out;
> > > > > @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
> > > > >       kmstest_free_connector_config(&output->config);
> > > > >       free(output->name);
> > > > >       output->name = NULL;
> > > > > +
> > > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > > +             close(output->writeback_out_fence_fd);
> > > > > +             output->writeback_out_fence_fd = -1;
> > > > > +     }
> > > > >  }
> > > > > 
> > > > >  /**
> > > > > @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
> > > > >                                         output->props[i],
> > > > >                                         output->values[i]));
> > > > >       }
> > > > > +
> > > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > > +             close(output->writeback_out_fence_fd);
> > > > > +             output->writeback_out_fence_fd = -1;
> > > > > +     }
> > > > >  }
> > > > > 
> > > > >  /*
> > > > > @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
> > > > >               else
> > > > >                       /* no modeset in universal commit, no change to crtc. */
> > > > >                       output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> > > > > +
> > > > > +             if (s == COMMIT_ATOMIC) {
> > > > > +                     if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> > > > > +                             igt_assert(output->writeback_out_fence_fd >= 0);
> > > > > +
> > > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> > > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> > > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > > +             }
> > > > >       }
> > > > > 
> > > > >       if (display->first_commit) {
> > > > > @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
> > > > >       igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
> > > > >  }
> > > > > 
> > > > > +/**
> > > > > + * igt_output_set_writeback_fb:
> > > > > + * @output: Target output
> > > > > + * @fb: Target framebuffer
> > > > > + *
> > > > > + * This function sets the given @fb to be used as the target framebuffer for the
> > > > > + * writeback engine at the next atomic commit. It will also request a writeback
> > > > > + * out fence that will contain the fd number of the out fence created by KMS if
> > > > > + * the given @fb is valid.
> > > > > + */
> > > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > > > > +{
> > > > > +     igt_display_t *display = output->display;
> > > > > +
> > > > > +     LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > > > > +
> > > > > +     igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > > > > +     /* only request a writeback out fence if the framebuffer is valid */
> > > > > +     if (fb)
> > > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > > +                                       (ptrdiff_t)&output->writeback_out_fence_fd);
> > > > > +}
> > > > > +
> > > > >  /**
> > > > >   * igt_wait_for_vblank_count:
> > > > >   * @drm_fd: A drm file descriptor
> > > > > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > > > > index a448a003..cacc6b90 100644
> > > > > --- a/lib/igt_kms.h
> > > > > +++ b/lib/igt_kms.h
> > > > > @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
> > > > >         IGT_CONNECTOR_BROADCAST_RGB,
> > > > >         IGT_CONNECTOR_CONTENT_PROTECTION,
> > > > >         IGT_CONNECTOR_VRR_CAPABLE,
> > > > > +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> > > > > +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> > > > > +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > >         IGT_NUM_CONNECTOR_PROPS
> > > > >  };
> > > > > 
> > > > > @@ -364,6 +367,8 @@ typedef struct {
> > > > >       bool use_override_mode;
> > > > >       drmModeModeInfo override_mode;
> > > > > 
> > > > > +     int32_t writeback_out_fence_fd;
> > > > > +
> > > > >       /* bitmask of changed properties */
> > > > >       uint64_t changed;
> > > > > 
> > > > > @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
> > > > >  igt_output_t *igt_output_from_connector(igt_display_t *display,
> > > > >      drmModeConnector *connector);
> > > > >  const drmModeModeInfo *igt_std_1024_mode_get(void);
> > > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
> > > > > 
> > > > >  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
> > > > >  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> > > > > --
> > > > > 2.21.0
> > > > > 
> > > > > 
> > > > > --
> > > > > Rodrigo Siqueira
> > > > > https://siqueira.tech
> > > > 
> > > > --
> > > > ====================
> > > > > I would like to |
> > > > > fix the world,  |
> > > > > but they're not |
> > > > > giving me the   |
> > > >  \ source code!  /
> > > >   ---------------
> > > >     ¯\_(ツ)_/¯
> 
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
@ 2019-07-09 14:42             ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-09 14:42 UTC (permalink / raw)
  To: rodrigosiqueiramelo
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey

On Tue, 2019-07-09 at 11:32 -0300, Rodrigo Siqueira wrote:
> On Wed, Jul 3, 2019 at 9:15 AM Ser, Simon <simon.ser@intel.com> wrote:
> > On Tue, 2019-06-18 at 18:56 -0300, Rodrigo Siqueira wrote:
> > > On Thu, Jun 13, 2019 at 11:54 AM Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > > > On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> > > > > Add support in igt_kms for writeback connectors, with the ability
> > > > > to attach framebuffers.
> > > > > 
> > > > > v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> > > > > drmModeGetResources()
> > > > 
> > > > Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > 
> > > > Thanks for updating this! Given that I have done the last changes and this is
> > > > mostly a refresh, not sure if I should add more Reviewed-by's to the other
> > > > patches.
> > > 
> > > Thanks Liviu!
> > > 
> > > I just forgot to add my SoB, and for some reason, gmail does not allow
> > > me to send an email on someone behalf.
> > 
> > FWIW, that's a good thing, and it's required to pass DMARC checks.
> > 
> > Instead, git-send-email should add a From line at the beginning of the
> > message when sending a patch on behalf of someone else. I wonder what
> > happened here.
> 
> Thank you for your help.
> 
> I’m using neomutt for sending patches, and I’ll take a look at
> git-send-email. Additionally, it looks like Gmail requires that I add
> a new account in order to allow me to send patches on someone behalf.
> I’ll take some time to read about this issue, and I will try to resend
> the patchset again.

When sending a patch on someone else's behalf, you shouldn't send the
e-mail with the sender (From header) set to someone else. You should
use your normal address. The From line in the body of the message will
make Git understand the author is someone else.

So no new account setup required.

I really recommend using git-send-email for patches. There are too many
ways to make a mistake if you try sending emails manually. Here is a
tutorial:
https://git-send-email.io/

> Btw, if you have time, could you take a look in this series?

Sure, I've already began looking at the series. I'll continue soon.

Thanks for your work!

> Best regards
> 
> > > Btw, I can fix it after
> > > everybody agrees that the kms_writeback is ready for landing.
> > > 
> > > 
> > > > Best regards,
> > > > Liviu
> > > > 
> > > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > > [rebased and updated to the latest igt style]
> > > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > > ---
> > > > >  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > >  lib/igt_kms.h |  6 ++++++
> > > > >  2 files changed, 63 insertions(+)
> > > > > 
> > > > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > > > index da188a39..140db346 100644
> > > > > --- a/lib/igt_kms.c
> > > > > +++ b/lib/igt_kms.c
> > > > > @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
> > > > >       [IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
> > > > >       [IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
> > > > >       [IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> > > > > +     [IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> > > > > +     [IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> > > > > +     [IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
> > > > >  };
> > > > > 
> > > > >  /*
> > > > > @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
> > > > >       { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
> > > > >       { DRM_MODE_CONNECTOR_DSI, "DSI" },
> > > > >       { DRM_MODE_CONNECTOR_DPI, "DPI" },
> > > > > +     { DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
> > > > >       {}
> > > > >  };
> > > > > 
> > > > > @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
> > > > >       if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
> > > > >               igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
> > > > >                                         BROADCAST_RGB_FULL);
> > > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> > > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> > > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> > > > > +             igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > > +             output->writeback_out_fence_fd = -1;
> > > > > +     }
> > > > >  }
> > > > > 
> > > > >  /**
> > > > > @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
> > > > >   * For outputs:
> > > > >   * - %IGT_CONNECTOR_CRTC_ID
> > > > >   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> > > > > + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> > > > > + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
> > > > >   * - igt_output_override_mode() to default.
> > > > >   *
> > > > >   * For pipes:
> > > > > @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> > > > > 
> > > > >       display->drm_fd = drm_fd;
> > > > > 
> > > > > +     drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > > > > +
> > > > >       resources = drmModeGetResources(display->drm_fd);
> > > > >       if (!resources)
> > > > >               goto out;
> > > > > @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
> > > > >       kmstest_free_connector_config(&output->config);
> > > > >       free(output->name);
> > > > >       output->name = NULL;
> > > > > +
> > > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > > +             close(output->writeback_out_fence_fd);
> > > > > +             output->writeback_out_fence_fd = -1;
> > > > > +     }
> > > > >  }
> > > > > 
> > > > >  /**
> > > > > @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
> > > > >                                         output->props[i],
> > > > >                                         output->values[i]));
> > > > >       }
> > > > > +
> > > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > > +             close(output->writeback_out_fence_fd);
> > > > > +             output->writeback_out_fence_fd = -1;
> > > > > +     }
> > > > >  }
> > > > > 
> > > > >  /*
> > > > > @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
> > > > >               else
> > > > >                       /* no modeset in universal commit, no change to crtc. */
> > > > >                       output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> > > > > +
> > > > > +             if (s == COMMIT_ATOMIC) {
> > > > > +                     if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> > > > > +                             igt_assert(output->writeback_out_fence_fd >= 0);
> > > > > +
> > > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> > > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> > > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > > +             }
> > > > >       }
> > > > > 
> > > > >       if (display->first_commit) {
> > > > > @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
> > > > >       igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
> > > > >  }
> > > > > 
> > > > > +/**
> > > > > + * igt_output_set_writeback_fb:
> > > > > + * @output: Target output
> > > > > + * @fb: Target framebuffer
> > > > > + *
> > > > > + * This function sets the given @fb to be used as the target framebuffer for the
> > > > > + * writeback engine at the next atomic commit. It will also request a writeback
> > > > > + * out fence that will contain the fd number of the out fence created by KMS if
> > > > > + * the given @fb is valid.
> > > > > + */
> > > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > > > > +{
> > > > > +     igt_display_t *display = output->display;
> > > > > +
> > > > > +     LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > > > > +
> > > > > +     igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > > > > +     /* only request a writeback out fence if the framebuffer is valid */
> > > > > +     if (fb)
> > > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > > +                                       (ptrdiff_t)&output->writeback_out_fence_fd);
> > > > > +}
> > > > > +
> > > > >  /**
> > > > >   * igt_wait_for_vblank_count:
> > > > >   * @drm_fd: A drm file descriptor
> > > > > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > > > > index a448a003..cacc6b90 100644
> > > > > --- a/lib/igt_kms.h
> > > > > +++ b/lib/igt_kms.h
> > > > > @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
> > > > >         IGT_CONNECTOR_BROADCAST_RGB,
> > > > >         IGT_CONNECTOR_CONTENT_PROTECTION,
> > > > >         IGT_CONNECTOR_VRR_CAPABLE,
> > > > > +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> > > > > +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> > > > > +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > >         IGT_NUM_CONNECTOR_PROPS
> > > > >  };
> > > > > 
> > > > > @@ -364,6 +367,8 @@ typedef struct {
> > > > >       bool use_override_mode;
> > > > >       drmModeModeInfo override_mode;
> > > > > 
> > > > > +     int32_t writeback_out_fence_fd;
> > > > > +
> > > > >       /* bitmask of changed properties */
> > > > >       uint64_t changed;
> > > > > 
> > > > > @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
> > > > >  igt_output_t *igt_output_from_connector(igt_display_t *display,
> > > > >      drmModeConnector *connector);
> > > > >  const drmModeModeInfo *igt_std_1024_mode_get(void);
> > > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
> > > > > 
> > > > >  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
> > > > >  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> > > > > --
> > > > > 2.21.0
> > > > > 
> > > > > 
> > > > > --
> > > > > Rodrigo Siqueira
> > > > > https://siqueira.tech
> > > > 
> > > > --
> > > > ====================
> > > > > I would like to |
> > > > > fix the world,  |
> > > > > but they're not |
> > > > > giving me the   |
> > > >  \ source code!  /
> > > >   ---------------
> > > >     ¯\_(ツ)_/¯
> 
> 
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
  2019-07-09 14:42             ` Ser, Simon
@ 2019-07-09 15:07               ` Rodrigo Siqueira
  -1 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-09 15:07 UTC (permalink / raw)
  To: Ser, Simon; +Cc: intel-gfx, igt-dev, nd

On Tue, Jul 9, 2019 at 11:42 AM Ser, Simon <simon.ser@intel.com> wrote:
>
> On Tue, 2019-07-09 at 11:32 -0300, Rodrigo Siqueira wrote:
> > On Wed, Jul 3, 2019 at 9:15 AM Ser, Simon <simon.ser@intel.com> wrote:
> > > On Tue, 2019-06-18 at 18:56 -0300, Rodrigo Siqueira wrote:
> > > > On Thu, Jun 13, 2019 at 11:54 AM Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > > > > On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> > > > > > Add support in igt_kms for writeback connectors, with the ability
> > > > > > to attach framebuffers.
> > > > > >
> > > > > > v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> > > > > > drmModeGetResources()
> > > > >
> > > > > Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > >
> > > > > Thanks for updating this! Given that I have done the last changes and this is
> > > > > mostly a refresh, not sure if I should add more Reviewed-by's to the other
> > > > > patches.
> > > >
> > > > Thanks Liviu!
> > > >
> > > > I just forgot to add my SoB, and for some reason, gmail does not allow
> > > > me to send an email on someone behalf.
> > >
> > > FWIW, that's a good thing, and it's required to pass DMARC checks.
> > >
> > > Instead, git-send-email should add a From line at the beginning of the
> > > message when sending a patch on behalf of someone else. I wonder what
> > > happened here.
> >
> > Thank you for your help.
> >
> > I’m using neomutt for sending patches, and I’ll take a look at
> > git-send-email. Additionally, it looks like Gmail requires that I add
> > a new account in order to allow me to send patches on someone behalf.
> > I’ll take some time to read about this issue, and I will try to resend
> > the patchset again.
>
> When sending a patch on someone else's behalf, you shouldn't send the
> e-mail with the sender (From header) set to someone else. You should
> use your normal address. The From line in the body of the message will
> make Git understand the author is someone else.
>
> So no new account setup required.
>
> I really recommend using git-send-email for patches. There are too many
> ways to make a mistake if you try sending emails manually. Here is a
> tutorial:
> https://git-send-email.io/

Thank you very much for the tutorial! I'll read it and prepare to
migrate from 'neomutt -H' to git-send-mail.

> > Btw, if you have time, could you take a look in this series?
>
> Sure, I've already began looking at the series. I'll continue soon.

Thank you again for your help.

> Thanks for your work!
>
> > Best regards
> >
> > > > Btw, I can fix it after
> > > > everybody agrees that the kms_writeback is ready for landing.
> > > >
> > > >
> > > > > Best regards,
> > > > > Liviu
> > > > >
> > > > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > > > [rebased and updated to the latest igt style]
> > > > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > > > ---
> > > > > >  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > >  lib/igt_kms.h |  6 ++++++
> > > > > >  2 files changed, 63 insertions(+)
> > > > > >
> > > > > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > > > > index da188a39..140db346 100644
> > > > > > --- a/lib/igt_kms.c
> > > > > > +++ b/lib/igt_kms.c
> > > > > > @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
> > > > > >       [IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
> > > > > >       [IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
> > > > > >       [IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> > > > > > +     [IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> > > > > > +     [IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> > > > > > +     [IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
> > > > > >  };
> > > > > >
> > > > > >  /*
> > > > > > @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
> > > > > >       { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
> > > > > >       { DRM_MODE_CONNECTOR_DSI, "DSI" },
> > > > > >       { DRM_MODE_CONNECTOR_DPI, "DPI" },
> > > > > > +     { DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
> > > > > >       {}
> > > > > >  };
> > > > > >
> > > > > > @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
> > > > > >       if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
> > > > > >               igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
> > > > > >                                         BROADCAST_RGB_FULL);
> > > > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> > > > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> > > > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> > > > > > +             igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > > > +             output->writeback_out_fence_fd = -1;
> > > > > > +     }
> > > > > >  }
> > > > > >
> > > > > >  /**
> > > > > > @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
> > > > > >   * For outputs:
> > > > > >   * - %IGT_CONNECTOR_CRTC_ID
> > > > > >   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> > > > > > + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> > > > > > + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
> > > > > >   * - igt_output_override_mode() to default.
> > > > > >   *
> > > > > >   * For pipes:
> > > > > > @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> > > > > >
> > > > > >       display->drm_fd = drm_fd;
> > > > > >
> > > > > > +     drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > > > > > +
> > > > > >       resources = drmModeGetResources(display->drm_fd);
> > > > > >       if (!resources)
> > > > > >               goto out;
> > > > > > @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
> > > > > >       kmstest_free_connector_config(&output->config);
> > > > > >       free(output->name);
> > > > > >       output->name = NULL;
> > > > > > +
> > > > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > > > +             close(output->writeback_out_fence_fd);
> > > > > > +             output->writeback_out_fence_fd = -1;
> > > > > > +     }
> > > > > >  }
> > > > > >
> > > > > >  /**
> > > > > > @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
> > > > > >                                         output->props[i],
> > > > > >                                         output->values[i]));
> > > > > >       }
> > > > > > +
> > > > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > > > +             close(output->writeback_out_fence_fd);
> > > > > > +             output->writeback_out_fence_fd = -1;
> > > > > > +     }
> > > > > >  }
> > > > > >
> > > > > >  /*
> > > > > > @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
> > > > > >               else
> > > > > >                       /* no modeset in universal commit, no change to crtc. */
> > > > > >                       output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> > > > > > +
> > > > > > +             if (s == COMMIT_ATOMIC) {
> > > > > > +                     if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> > > > > > +                             igt_assert(output->writeback_out_fence_fd >= 0);
> > > > > > +
> > > > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> > > > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> > > > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > > > +             }
> > > > > >       }
> > > > > >
> > > > > >       if (display->first_commit) {
> > > > > > @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
> > > > > >       igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
> > > > > >  }
> > > > > >
> > > > > > +/**
> > > > > > + * igt_output_set_writeback_fb:
> > > > > > + * @output: Target output
> > > > > > + * @fb: Target framebuffer
> > > > > > + *
> > > > > > + * This function sets the given @fb to be used as the target framebuffer for the
> > > > > > + * writeback engine at the next atomic commit. It will also request a writeback
> > > > > > + * out fence that will contain the fd number of the out fence created by KMS if
> > > > > > + * the given @fb is valid.
> > > > > > + */
> > > > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > > > > > +{
> > > > > > +     igt_display_t *display = output->display;
> > > > > > +
> > > > > > +     LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > > > > > +
> > > > > > +     igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > > > > > +     /* only request a writeback out fence if the framebuffer is valid */
> > > > > > +     if (fb)
> > > > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > > > +                                       (ptrdiff_t)&output->writeback_out_fence_fd);
> > > > > > +}
> > > > > > +
> > > > > >  /**
> > > > > >   * igt_wait_for_vblank_count:
> > > > > >   * @drm_fd: A drm file descriptor
> > > > > > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > > > > > index a448a003..cacc6b90 100644
> > > > > > --- a/lib/igt_kms.h
> > > > > > +++ b/lib/igt_kms.h
> > > > > > @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
> > > > > >         IGT_CONNECTOR_BROADCAST_RGB,
> > > > > >         IGT_CONNECTOR_CONTENT_PROTECTION,
> > > > > >         IGT_CONNECTOR_VRR_CAPABLE,
> > > > > > +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> > > > > > +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> > > > > > +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > > >         IGT_NUM_CONNECTOR_PROPS
> > > > > >  };
> > > > > >
> > > > > > @@ -364,6 +367,8 @@ typedef struct {
> > > > > >       bool use_override_mode;
> > > > > >       drmModeModeInfo override_mode;
> > > > > >
> > > > > > +     int32_t writeback_out_fence_fd;
> > > > > > +
> > > > > >       /* bitmask of changed properties */
> > > > > >       uint64_t changed;
> > > > > >
> > > > > > @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
> > > > > >  igt_output_t *igt_output_from_connector(igt_display_t *display,
> > > > > >      drmModeConnector *connector);
> > > > > >  const drmModeModeInfo *igt_std_1024_mode_get(void);
> > > > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
> > > > > >
> > > > > >  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
> > > > > >  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> > > > > > --
> > > > > > 2.21.0
> > > > > >
> > > > > >
> > > > > > --
> > > > > > Rodrigo Siqueira
> > > > > > https://siqueira.tech
> > > > >
> > > > > --
> > > > > ====================
> > > > > > I would like to |
> > > > > > fix the world,  |
> > > > > > but they're not |
> > > > > > giving me the   |
> > > > >  \ source code!  /
> > > > >   ---------------
> > > > >     ¯\_(ツ)_/¯
> >
> >



-- 

Rodrigo Siqueira
https://siqueira.tech
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
@ 2019-07-09 15:07               ` Rodrigo Siqueira
  0 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-09 15:07 UTC (permalink / raw)
  To: Ser, Simon
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey

On Tue, Jul 9, 2019 at 11:42 AM Ser, Simon <simon.ser@intel.com> wrote:
>
> On Tue, 2019-07-09 at 11:32 -0300, Rodrigo Siqueira wrote:
> > On Wed, Jul 3, 2019 at 9:15 AM Ser, Simon <simon.ser@intel.com> wrote:
> > > On Tue, 2019-06-18 at 18:56 -0300, Rodrigo Siqueira wrote:
> > > > On Thu, Jun 13, 2019 at 11:54 AM Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> > > > > On Wed, Jun 12, 2019 at 11:16:02PM -0300, Brian Starkey wrote:
> > > > > > Add support in igt_kms for writeback connectors, with the ability
> > > > > > to attach framebuffers.
> > > > > >
> > > > > > v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> > > > > > drmModeGetResources()
> > > > >
> > > > > Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > >
> > > > > Thanks for updating this! Given that I have done the last changes and this is
> > > > > mostly a refresh, not sure if I should add more Reviewed-by's to the other
> > > > > patches.
> > > >
> > > > Thanks Liviu!
> > > >
> > > > I just forgot to add my SoB, and for some reason, gmail does not allow
> > > > me to send an email on someone behalf.
> > >
> > > FWIW, that's a good thing, and it's required to pass DMARC checks.
> > >
> > > Instead, git-send-email should add a From line at the beginning of the
> > > message when sending a patch on behalf of someone else. I wonder what
> > > happened here.
> >
> > Thank you for your help.
> >
> > I’m using neomutt for sending patches, and I’ll take a look at
> > git-send-email. Additionally, it looks like Gmail requires that I add
> > a new account in order to allow me to send patches on someone behalf.
> > I’ll take some time to read about this issue, and I will try to resend
> > the patchset again.
>
> When sending a patch on someone else's behalf, you shouldn't send the
> e-mail with the sender (From header) set to someone else. You should
> use your normal address. The From line in the body of the message will
> make Git understand the author is someone else.
>
> So no new account setup required.
>
> I really recommend using git-send-email for patches. There are too many
> ways to make a mistake if you try sending emails manually. Here is a
> tutorial:
> https://git-send-email.io/

Thank you very much for the tutorial! I'll read it and prepare to
migrate from 'neomutt -H' to git-send-mail.

> > Btw, if you have time, could you take a look in this series?
>
> Sure, I've already began looking at the series. I'll continue soon.

Thank you again for your help.

> Thanks for your work!
>
> > Best regards
> >
> > > > Btw, I can fix it after
> > > > everybody agrees that the kms_writeback is ready for landing.
> > > >
> > > >
> > > > > Best regards,
> > > > > Liviu
> > > > >
> > > > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > > > [rebased and updated to the latest igt style]
> > > > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > > > ---
> > > > > >  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > >  lib/igt_kms.h |  6 ++++++
> > > > > >  2 files changed, 63 insertions(+)
> > > > > >
> > > > > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > > > > index da188a39..140db346 100644
> > > > > > --- a/lib/igt_kms.c
> > > > > > +++ b/lib/igt_kms.c
> > > > > > @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
> > > > > >       [IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
> > > > > >       [IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
> > > > > >       [IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> > > > > > +     [IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> > > > > > +     [IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> > > > > > +     [IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
> > > > > >  };
> > > > > >
> > > > > >  /*
> > > > > > @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
> > > > > >       { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
> > > > > >       { DRM_MODE_CONNECTOR_DSI, "DSI" },
> > > > > >       { DRM_MODE_CONNECTOR_DPI, "DPI" },
> > > > > > +     { DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
> > > > > >       {}
> > > > > >  };
> > > > > >
> > > > > > @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
> > > > > >       if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
> > > > > >               igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
> > > > > >                                         BROADCAST_RGB_FULL);
> > > > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> > > > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> > > > > > +     if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> > > > > > +             igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > > > +             output->writeback_out_fence_fd = -1;
> > > > > > +     }
> > > > > >  }
> > > > > >
> > > > > >  /**
> > > > > > @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
> > > > > >   * For outputs:
> > > > > >   * - %IGT_CONNECTOR_CRTC_ID
> > > > > >   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> > > > > > + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> > > > > > + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
> > > > > >   * - igt_output_override_mode() to default.
> > > > > >   *
> > > > > >   * For pipes:
> > > > > > @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
> > > > > >
> > > > > >       display->drm_fd = drm_fd;
> > > > > >
> > > > > > +     drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> > > > > > +
> > > > > >       resources = drmModeGetResources(display->drm_fd);
> > > > > >       if (!resources)
> > > > > >               goto out;
> > > > > > @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
> > > > > >       kmstest_free_connector_config(&output->config);
> > > > > >       free(output->name);
> > > > > >       output->name = NULL;
> > > > > > +
> > > > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > > > +             close(output->writeback_out_fence_fd);
> > > > > > +             output->writeback_out_fence_fd = -1;
> > > > > > +     }
> > > > > >  }
> > > > > >
> > > > > >  /**
> > > > > > @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
> > > > > >                                         output->props[i],
> > > > > >                                         output->values[i]));
> > > > > >       }
> > > > > > +
> > > > > > +     if (output->writeback_out_fence_fd != -1) {
> > > > > > +             close(output->writeback_out_fence_fd);
> > > > > > +             output->writeback_out_fence_fd = -1;
> > > > > > +     }
> > > > > >  }
> > > > > >
> > > > > >  /*
> > > > > > @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
> > > > > >               else
> > > > > >                       /* no modeset in universal commit, no change to crtc. */
> > > > > >                       output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> > > > > > +
> > > > > > +             if (s == COMMIT_ATOMIC) {
> > > > > > +                     if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> > > > > > +                             igt_assert(output->writeback_out_fence_fd >= 0);
> > > > > > +
> > > > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> > > > > > +                     output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> > > > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > > > > +                     igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> > > > > > +             }
> > > > > >       }
> > > > > >
> > > > > >       if (display->first_commit) {
> > > > > > @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
> > > > > >       igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
> > > > > >  }
> > > > > >
> > > > > > +/**
> > > > > > + * igt_output_set_writeback_fb:
> > > > > > + * @output: Target output
> > > > > > + * @fb: Target framebuffer
> > > > > > + *
> > > > > > + * This function sets the given @fb to be used as the target framebuffer for the
> > > > > > + * writeback engine at the next atomic commit. It will also request a writeback
> > > > > > + * out fence that will contain the fd number of the out fence created by KMS if
> > > > > > + * the given @fb is valid.
> > > > > > + */
> > > > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> > > > > > +{
> > > > > > +     igt_display_t *display = output->display;
> > > > > > +
> > > > > > +     LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> > > > > > +
> > > > > > +     igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> > > > > > +     /* only request a writeback out fence if the framebuffer is valid */
> > > > > > +     if (fb)
> > > > > > +             igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > > > +                                       (ptrdiff_t)&output->writeback_out_fence_fd);
> > > > > > +}
> > > > > > +
> > > > > >  /**
> > > > > >   * igt_wait_for_vblank_count:
> > > > > >   * @drm_fd: A drm file descriptor
> > > > > > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > > > > > index a448a003..cacc6b90 100644
> > > > > > --- a/lib/igt_kms.h
> > > > > > +++ b/lib/igt_kms.h
> > > > > > @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
> > > > > >         IGT_CONNECTOR_BROADCAST_RGB,
> > > > > >         IGT_CONNECTOR_CONTENT_PROTECTION,
> > > > > >         IGT_CONNECTOR_VRR_CAPABLE,
> > > > > > +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> > > > > > +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> > > > > > +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> > > > > >         IGT_NUM_CONNECTOR_PROPS
> > > > > >  };
> > > > > >
> > > > > > @@ -364,6 +367,8 @@ typedef struct {
> > > > > >       bool use_override_mode;
> > > > > >       drmModeModeInfo override_mode;
> > > > > >
> > > > > > +     int32_t writeback_out_fence_fd;
> > > > > > +
> > > > > >       /* bitmask of changed properties */
> > > > > >       uint64_t changed;
> > > > > >
> > > > > > @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
> > > > > >  igt_output_t *igt_output_from_connector(igt_display_t *display,
> > > > > >      drmModeConnector *connector);
> > > > > >  const drmModeModeInfo *igt_std_1024_mode_get(void);
> > > > > > +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
> > > > > >
> > > > > >  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
> > > > > >  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> > > > > > --
> > > > > > 2.21.0
> > > > > >
> > > > > >
> > > > > > --
> > > > > > Rodrigo Siqueira
> > > > > > https://siqueira.tech
> > > > >
> > > > > --
> > > > > ====================
> > > > > > I would like to |
> > > > > > fix the world,  |
> > > > > > but they're not |
> > > > > > giving me the   |
> > > > >  \ source code!  /
> > > > >   ---------------
> > > > >     ¯\_(ツ)_/¯
> >
> >



-- 

Rodrigo Siqueira
https://siqueira.tech
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
  2019-06-13  2:16   ` [Intel-gfx] " Brian Starkey
@ 2019-07-10  8:48     ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-10  8:48 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> Add support in igt_kms for writeback connectors, with the ability
> to attach framebuffers.
> 
> v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> drmModeGetResources()
> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> [rebased and updated to the latest igt style]
> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>

This patch LGTM.

Reviewed-by: Simon Ser <simon.ser@intel.com>

> ---
>  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_kms.h |  6 ++++++
>  2 files changed, 63 insertions(+)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index da188a39..140db346 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
>  	[IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
>  	[IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
>  	[IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> +	[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> +	[IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> +	[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
>  };
>  
>  /*
> @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
>  	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
>  	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
>  	{ DRM_MODE_CONNECTOR_DPI, "DPI" },
> +	{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
>  	{}
>  };
>  
> @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
>  	if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
>  		igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
>  					  BROADCAST_RGB_FULL);
> +	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> +	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> +		igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /**
> @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
>   * For outputs:
>   * - %IGT_CONNECTOR_CRTC_ID
>   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
>   * - igt_output_override_mode() to default.
>   *
>   * For pipes:
> @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
>  
>  	display->drm_fd = drm_fd;
>  
> +	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> +
>  	resources = drmModeGetResources(display->drm_fd);
>  	if (!resources)
>  		goto out;
> @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
>  	kmstest_free_connector_config(&output->config);
>  	free(output->name);
>  	output->name = NULL;
> +
> +	if (output->writeback_out_fence_fd != -1) {
> +		close(output->writeback_out_fence_fd);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /**
> @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
>  					  output->props[i],
>  					  output->values[i]));
>  	}
> +
> +	if (output->writeback_out_fence_fd != -1) {
> +		close(output->writeback_out_fence_fd);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /*
> @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
>  		else
>  			/* no modeset in universal commit, no change to crtc. */
>  			output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> +
> +		if (s == COMMIT_ATOMIC) {
> +			if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> +				igt_assert(output->writeback_out_fence_fd >= 0);
> +
> +			output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> +			output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> +			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> +			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> +		}
>  	}
>  
>  	if (display->first_commit) {
> @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
>  	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
>  }
>  
> +/**
> + * igt_output_set_writeback_fb:
> + * @output: Target output
> + * @fb: Target framebuffer
> + *
> + * This function sets the given @fb to be used as the target framebuffer for the
> + * writeback engine at the next atomic commit. It will also request a writeback
> + * out fence that will contain the fd number of the out fence created by KMS if
> + * the given @fb is valid.
> + */
> +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> +{
> +	igt_display_t *display = output->display;
> +
> +	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> +
> +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> +	/* only request a writeback out fence if the framebuffer is valid */
> +	if (fb)
> +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> +					  (ptrdiff_t)&output->writeback_out_fence_fd);
> +}
> +
>  /**
>   * igt_wait_for_vblank_count:
>   * @drm_fd: A drm file descriptor
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index a448a003..cacc6b90 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
>         IGT_CONNECTOR_BROADCAST_RGB,
>         IGT_CONNECTOR_CONTENT_PROTECTION,
>         IGT_CONNECTOR_VRR_CAPABLE,
> +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
>         IGT_NUM_CONNECTOR_PROPS
>  };
>  
> @@ -364,6 +367,8 @@ typedef struct {
>  	bool use_override_mode;
>  	drmModeModeInfo override_mode;
>  
> +	int32_t writeback_out_fence_fd;
> +
>  	/* bitmask of changed properties */
>  	uint64_t changed;
>  
> @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
>  igt_output_t *igt_output_from_connector(igt_display_t *display,
>      drmModeConnector *connector);
>  const drmModeModeInfo *igt_std_1024_mode_get(void);
> +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
>  
>  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
>  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> -- 
> 2.21.0
> 
> 
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support
@ 2019-07-10  8:48     ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-10  8:48 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> Add support in igt_kms for writeback connectors, with the ability
> to attach framebuffers.
> 
> v5: Rebase and add DRM_CLIENT_CAP_WRITEBACK_CONNECTORS before
> drmModeGetResources()
> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> [rebased and updated to the latest igt style]
> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>

This patch LGTM.

Reviewed-by: Simon Ser <simon.ser@intel.com>

> ---
>  lib/igt_kms.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_kms.h |  6 ++++++
>  2 files changed, 63 insertions(+)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index da188a39..140db346 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -325,6 +325,9 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
>  	[IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
>  	[IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
>  	[IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
> +	[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS] = "WRITEBACK_PIXEL_FORMATS",
> +	[IGT_CONNECTOR_WRITEBACK_FB_ID] = "WRITEBACK_FB_ID",
> +	[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = "WRITEBACK_OUT_FENCE_PTR",
>  };
>  
>  /*
> @@ -557,6 +560,7 @@ static const struct type_name connector_type_names[] = {
>  	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
>  	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
>  	{ DRM_MODE_CONNECTOR_DPI, "DPI" },
> +	{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
>  	{}
>  };
>  
> @@ -1889,6 +1893,12 @@ static void igt_output_reset(igt_output_t *output)
>  	if (igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
>  		igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB,
>  					  BROADCAST_RGB_FULL);
> +	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID))
> +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, 0);
> +	if (igt_output_has_prop(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR)) {
> +		igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /**
> @@ -1901,6 +1911,8 @@ static void igt_output_reset(igt_output_t *output)
>   * For outputs:
>   * - %IGT_CONNECTOR_CRTC_ID
>   * - %IGT_CONNECTOR_BROADCAST_RGB (if applicable)
> + * - %IGT_CONNECTOR_WRITEBACK_FB_ID
> + * - %IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR
>   * - igt_output_override_mode() to default.
>   *
>   * For pipes:
> @@ -1970,6 +1982,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
>  
>  	display->drm_fd = drm_fd;
>  
> +	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
> +
>  	resources = drmModeGetResources(display->drm_fd);
>  	if (!resources)
>  		goto out;
> @@ -2263,6 +2277,11 @@ static void igt_output_fini(igt_output_t *output)
>  	kmstest_free_connector_config(&output->config);
>  	free(output->name);
>  	output->name = NULL;
> +
> +	if (output->writeback_out_fence_fd != -1) {
> +		close(output->writeback_out_fence_fd);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /**
> @@ -3325,6 +3344,11 @@ static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAto
>  					  output->props[i],
>  					  output->values[i]));
>  	}
> +
> +	if (output->writeback_out_fence_fd != -1) {
> +		close(output->writeback_out_fence_fd);
> +		output->writeback_out_fence_fd = -1;
> +	}
>  }
>  
>  /*
> @@ -3447,6 +3471,16 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
>  		else
>  			/* no modeset in universal commit, no change to crtc. */
>  			output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
> +
> +		if (s == COMMIT_ATOMIC) {
> +			if (igt_output_is_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR))
> +				igt_assert(output->writeback_out_fence_fd >= 0);
> +
> +			output->values[IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR] = 0;
> +			output->values[IGT_CONNECTOR_WRITEBACK_FB_ID] = 0;
> +			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> +			igt_output_clear_prop_changed(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR);
> +		}
>  	}
>  
>  	if (display->first_commit) {
> @@ -4119,6 +4153,29 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
>  	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
>  }
>  
> +/**
> + * igt_output_set_writeback_fb:
> + * @output: Target output
> + * @fb: Target framebuffer
> + *
> + * This function sets the given @fb to be used as the target framebuffer for the
> + * writeback engine at the next atomic commit. It will also request a writeback
> + * out fence that will contain the fd number of the out fence created by KMS if
> + * the given @fb is valid.
> + */
> +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb)
> +{
> +	igt_display_t *display = output->display;
> +
> +	LOG(display, "%s: output_set_writeback_fb(%d)\n", output->name, fb ? fb->fb_id : 0);
> +
> +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb ? fb->fb_id : 0);
> +	/* only request a writeback out fence if the framebuffer is valid */
> +	if (fb)
> +		igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
> +					  (ptrdiff_t)&output->writeback_out_fence_fd);
> +}
> +
>  /**
>   * igt_wait_for_vblank_count:
>   * @drm_fd: A drm file descriptor
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index a448a003..cacc6b90 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -123,6 +123,9 @@ enum igt_atomic_connector_properties {
>         IGT_CONNECTOR_BROADCAST_RGB,
>         IGT_CONNECTOR_CONTENT_PROTECTION,
>         IGT_CONNECTOR_VRR_CAPABLE,
> +       IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS,
> +       IGT_CONNECTOR_WRITEBACK_FB_ID,
> +       IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR,
>         IGT_NUM_CONNECTOR_PROPS
>  };
>  
> @@ -364,6 +367,8 @@ typedef struct {
>  	bool use_override_mode;
>  	drmModeModeInfo override_mode;
>  
> +	int32_t writeback_out_fence_fd;
> +
>  	/* bitmask of changed properties */
>  	uint64_t changed;
>  
> @@ -414,6 +419,7 @@ igt_plane_t *igt_output_get_plane_type_index(igt_output_t *output,
>  igt_output_t *igt_output_from_connector(igt_display_t *display,
>      drmModeConnector *connector);
>  const drmModeModeInfo *igt_std_1024_mode_get(void);
> +void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
>  
>  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
>  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> -- 
> 2.21.0
> 
> 
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-06-13  2:16   ` [igt-dev] " Brian Starkey
@ 2019-07-10 11:57     ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-10 11:57 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

Hi,

Thanks for the patch! Here are a few comments.

For bonus points, it would be nice to add igt_describe descriptions of
each sub-test.

On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> behaviour is correct.
> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> [rebased and updated do_writeback_test() function to address feedback]
> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> ---
>  tests/Makefile.sources |   1 +
>  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
>  tests/meson.build      |   1 +
>  3 files changed, 316 insertions(+)
>  create mode 100644 tests/kms_writeback.c
> 
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index 027ed82f..03cc8efa 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -77,6 +77,7 @@ TESTS_progs = \
>  	kms_universal_plane \
>  	kms_vblank \
>  	kms_vrr \
> +	kms_writeback \
>  	meta_test \
>  	perf \
>  	perf_pmu \
> diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> new file mode 100644
> index 00000000..66ef48a6
> --- /dev/null
> +++ b/tests/kms_writeback.c
> @@ -0,0 +1,314 @@
> +/*
> + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#include <errno.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <string.h>
> +
> +#include "igt.h"
> +#include "igt_core.h"
> +#include "igt_fb.h"
> +
> +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> +{
> +	drmModePropertyBlobRes *blob = NULL;
> +	uint64_t blob_id;
> +	int ret;
> +
> +	ret = kmstest_get_property(output->display->drm_fd,
> +				   output->config.connector->connector_id,
> +				   DRM_MODE_OBJECT_CONNECTOR,
> +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> +				   NULL, &blob_id, NULL);
> +	if (ret)
> +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> +
> +	igt_assert(blob);
> +
> +	return blob;
> +}
> +
> +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> +{
> +	igt_fb_t input_fb, output_fb;
> +	igt_plane_t *plane;
> +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> +	int width, height, ret;
> +	drmModeModeInfo override_mode = {
> +		.clock = 25175,
> +		.hdisplay = 640,
> +		.hsync_start = 656,
> +		.hsync_end = 752,
> +		.htotal = 800,
> +		.hskew = 0,
> +		.vdisplay = 480,
> +		.vsync_start = 490,
> +		.vsync_end = 492,
> +		.vtotal = 525,
> +		.vscan = 0,
> +		.vrefresh = 60,
> +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> +		.name = {"640x480-60"},
> +	};
> +	igt_output_override_mode(output, &override_mode);
> +
> +	width = override_mode.hdisplay;
> +	height = override_mode.vdisplay;
> +
> +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> +	igt_assert(ret >= 0);
> +
> +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> +	igt_assert(ret >= 0);
> +
> +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> +	igt_plane_set_fb(plane, &input_fb);
> +	igt_output_set_writeback_fb(output, &output_fb);
> +
> +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);

Okay, we're using atomic test-only mode to know if we can perform tests
with the writeback output. It's probably fine, but we don't use
WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.

> +	igt_plane_set_fb(plane, NULL);
> +	igt_remove_fb(display->drm_fd, &input_fb);
> +	igt_remove_fb(display->drm_fd, &output_fb);
> +
> +	return !ret;
> +}
> +
> +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> +{
> +	int i;
> +
> +	for (i = 0; i < display->n_outputs; i++) {
> +		igt_output_t *output = &display->outputs[i];
> +		int j;
> +
> +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
> +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);

Hmm. Is this really necessary? "Real" userspace won't do this, so I
don't think we need to either.

> +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> +			igt_output_set_pipe(output, j);
> +
> +			if (check_writeback_config(display, output)) {
> +				igt_debug("Using connector %u:%s on pipe %d\n",
> +					  output->config.connector->connector_id,
> +					  output->name, j);
> +				return output;
> +			}

We could probably add an igt_debug statement in case we don't use this
writeback output.

> +		}
> +
> +		/* Restore any connectors we don't use, so we don't trip on them later */
> +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> +	}
> +
> +	return NULL;
> +}
> +
> +static void check_writeback_fb_id(igt_output_t *output)
> +{
> +	uint64_t check_fb_id;
> +
> +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> +	igt_assert(check_fb_id == 0);
> +}
> +
> +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> +			      uint32_t fb_id, int32_t *out_fence_ptr,
> +			      bool ptr_valid)

flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
probably remove the parameter from this function.

> +{
> +	int ret;
> +	igt_display_t *display = output->display;
> +	struct kmstest_connector_config *config = &output->config;
> +
> +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> +
> +	if (ptr_valid)
> +		*out_fence_ptr = 0;
> +
> +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> +
> +	if (ptr_valid)
> +		igt_assert(*out_fence_ptr == -1);

I'm confused. Why should this be -1 even if we
igt_display_try_commit_atomic succeeds?

> +	/* WRITEBACK_FB_ID must always read as zero */
> +	check_writeback_fb_id(output);
> +
> +	return ret;
> +}
> +
> +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> +{
> +	int i, ret;
> +	int32_t out_fence;
> +	struct {
> +		uint32_t fb_id;
> +		bool ptr_valid;
> +		int32_t *out_fence_ptr;
> +	} invalid_tests[] = {
> +		{
> +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> +			.fb_id = 0,
> +			.ptr_valid = true,
> +			.out_fence_ptr = &out_fence,
> +		},
> +		{
> +			/* Invalid output buffer. */
> +			.fb_id = invalid_fb->fb_id,
> +			.ptr_valid = true,
> +			.out_fence_ptr = &out_fence,
> +		},

This doesn't belong in this function (invalid_out_fence), since this
checks an invalid framebuffer, not an invalid fence. We should probably
move it to writeback_fb_id (and rename that function to test_fb?).

> +		{
> +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> +			.fb_id = valid_fb->fb_id,
> +			.ptr_valid = false,
> +			.out_fence_ptr = (int32_t *)0x8,
> +		},
> +	};
> +
> +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> +					invalid_tests[i].fb_id,
> +					invalid_tests[i].out_fence_ptr,
> +					invalid_tests[i].ptr_valid);
> +		igt_assert(ret != 0);

Maybe we can check for -ret == EINVAL?

> +	}
> +}
> +
> +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)

invalid_fb doesn't seem to be used here. valid_fb seems to be set to
the input framebuffer. It's probably not a good idea to use the same FB
for input and writeback output.

> +{
> +
> +	int ret;
> +
> +	/* Valid output buffer */
> +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> +				valid_fb->fb_id, NULL, false);
> +	igt_assert(ret == 0);
> +
> +	/* Invalid object for WRITEBACK_FB_ID */
> +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> +				output->id, NULL, false);
> +	igt_assert(ret == -EINVAL);
> +
> +	/* Zero WRITEBACK_FB_ID */
> +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> +				0, NULL, false);
> +	igt_assert(ret == 0);
> +}
> +
> +igt_main
> +{
> +	igt_display_t display;
> +	igt_output_t *output;
> +	igt_plane_t *plane;
> +	igt_fb_t input_fb;
> +	drmModeModeInfo mode;
> +	int ret;
> +
> +	memset(&display, 0, sizeof(display));
> +
> +	igt_fixture {
> +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> +		igt_display_require(&display, display.drm_fd);
> +
> +		kmstest_set_vt_graphics_mode();
> +
> +		igt_display_require(&display, display.drm_fd);
> +
> +		igt_require(display.is_atomic);
> +
> +		output = kms_writeback_get_output(&display);
> +		igt_require(output);
> +
> +		if (output->use_override_mode)
> +			memcpy(&mode, &output->override_mode, sizeof(mode));
> +		else
> +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> +
> +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> +		igt_require(plane);

Maybe we can assert on this?

> +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> +				    mode.vdisplay,
> +				    DRM_FORMAT_XRGB8888,
> +				    igt_fb_mod_to_tiling(0),

This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
better to make this clear.

(Applies to other lines of this patch)

> +				    &input_fb);
> +		igt_assert(ret >= 0);
> +		igt_plane_set_fb(plane, &input_fb);
> +	}
> +
> +	igt_subtest("writeback-pixel-formats") {
> +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);

Need to drmModeFreePropertyBlob this.

> +		const char *valid_chars = "0123456 ABCGNRUVXY";
> +		unsigned int i;
> +		char *c;
> +
> +		/*
> +		 * We don't have a comprehensive list of formats, so just check
> +		 * that the blob length is sensible and that it doesn't contain
> +		 * any outlandish characters
> +		 */
> +		igt_assert(!(formats_blob->length % 4));
> +		c = formats_blob->data;
> +		for (i = 0; i < formats_blob->length; i++)
> +			igt_assert_f(strchr(valid_chars, c[i]),
> +				     "Unexpected character %c\n", c[i]);

Honestly, I'm not a fan of this check. There's no guarantee that fourcc
codes will be made from ASCII characters, in fact some formats already
have non-printable chars in them. I don't want to have to update this
test when a new fourcc format is added.

We currently don't have a test for IN_FORMATS. If we really want to
check formats, we could have a big array of known formats and add a
bool is_valid_format(uint32_t fmt) function.

> +	}
> +
> +	igt_subtest("writeback-invalid-out-fence") {
> +		igt_fb_t invalid_fb;

invalid_output_fb would be a better name IMHO.

> +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> +				    mode.vdisplay / 2,
> +				    DRM_FORMAT_XRGB8888,
> +				    igt_fb_mod_to_tiling(0),
> +				    &invalid_fb);
> +		igt_require(ret > 0);

We should probably use a different variable: ret is signed,
igt_create_fb isn't. Also ret doesn't make it clear that the return
value is the KMS framebuffer ID.

(Applies to other subtests)

> +		invalid_out_fence(output, &input_fb, &invalid_fb);

(Still not sure why we provide the input FB to this function.)

> +		igt_remove_fb(display.drm_fd, &invalid_fb);
> +	}
> +
> +	igt_subtest("writeback-fb-id") {
> +		igt_fb_t output_fb;
> +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> +				    DRM_FORMAT_XRGB8888,
> +				    igt_fb_mod_to_tiling(0),
> +				    &output_fb);
> +		igt_require(ret > 0);
> +
> +		writeback_fb_id(output, &input_fb, &output_fb);
> +
> +		igt_remove_fb(display.drm_fd, &output_fb);
> +	}
> +
> +	igt_fixture {
> +		igt_remove_fb(display.drm_fd, &input_fb);
> +		igt_display_fini(&display);
> +	}
> +}
> diff --git a/tests/meson.build b/tests/meson.build
> index f168fbba..9c77cfcd 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -63,6 +63,7 @@ test_progs = [
>  	'kms_universal_plane',
>  	'kms_vblank',
>  	'kms_vrr',
> +	'kms_writeback',
>  	'meta_test',
>  	'panfrost_get_param',
>  	'panfrost_gem_new',
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-10 11:57     ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-10 11:57 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

Hi,

Thanks for the patch! Here are a few comments.

For bonus points, it would be nice to add igt_describe descriptions of
each sub-test.

On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> behaviour is correct.
> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> [rebased and updated do_writeback_test() function to address feedback]
> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> ---
>  tests/Makefile.sources |   1 +
>  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
>  tests/meson.build      |   1 +
>  3 files changed, 316 insertions(+)
>  create mode 100644 tests/kms_writeback.c
> 
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index 027ed82f..03cc8efa 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -77,6 +77,7 @@ TESTS_progs = \
>  	kms_universal_plane \
>  	kms_vblank \
>  	kms_vrr \
> +	kms_writeback \
>  	meta_test \
>  	perf \
>  	perf_pmu \
> diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> new file mode 100644
> index 00000000..66ef48a6
> --- /dev/null
> +++ b/tests/kms_writeback.c
> @@ -0,0 +1,314 @@
> +/*
> + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#include <errno.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <string.h>
> +
> +#include "igt.h"
> +#include "igt_core.h"
> +#include "igt_fb.h"
> +
> +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> +{
> +	drmModePropertyBlobRes *blob = NULL;
> +	uint64_t blob_id;
> +	int ret;
> +
> +	ret = kmstest_get_property(output->display->drm_fd,
> +				   output->config.connector->connector_id,
> +				   DRM_MODE_OBJECT_CONNECTOR,
> +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> +				   NULL, &blob_id, NULL);
> +	if (ret)
> +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> +
> +	igt_assert(blob);
> +
> +	return blob;
> +}
> +
> +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> +{
> +	igt_fb_t input_fb, output_fb;
> +	igt_plane_t *plane;
> +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> +	int width, height, ret;
> +	drmModeModeInfo override_mode = {
> +		.clock = 25175,
> +		.hdisplay = 640,
> +		.hsync_start = 656,
> +		.hsync_end = 752,
> +		.htotal = 800,
> +		.hskew = 0,
> +		.vdisplay = 480,
> +		.vsync_start = 490,
> +		.vsync_end = 492,
> +		.vtotal = 525,
> +		.vscan = 0,
> +		.vrefresh = 60,
> +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> +		.name = {"640x480-60"},
> +	};
> +	igt_output_override_mode(output, &override_mode);
> +
> +	width = override_mode.hdisplay;
> +	height = override_mode.vdisplay;
> +
> +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> +	igt_assert(ret >= 0);
> +
> +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> +	igt_assert(ret >= 0);
> +
> +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> +	igt_plane_set_fb(plane, &input_fb);
> +	igt_output_set_writeback_fb(output, &output_fb);
> +
> +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);

Okay, we're using atomic test-only mode to know if we can perform tests
with the writeback output. It's probably fine, but we don't use
WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.

> +	igt_plane_set_fb(plane, NULL);
> +	igt_remove_fb(display->drm_fd, &input_fb);
> +	igt_remove_fb(display->drm_fd, &output_fb);
> +
> +	return !ret;
> +}
> +
> +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> +{
> +	int i;
> +
> +	for (i = 0; i < display->n_outputs; i++) {
> +		igt_output_t *output = &display->outputs[i];
> +		int j;
> +
> +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
> +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);

Hmm. Is this really necessary? "Real" userspace won't do this, so I
don't think we need to either.

> +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> +			igt_output_set_pipe(output, j);
> +
> +			if (check_writeback_config(display, output)) {
> +				igt_debug("Using connector %u:%s on pipe %d\n",
> +					  output->config.connector->connector_id,
> +					  output->name, j);
> +				return output;
> +			}

We could probably add an igt_debug statement in case we don't use this
writeback output.

> +		}
> +
> +		/* Restore any connectors we don't use, so we don't trip on them later */
> +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> +	}
> +
> +	return NULL;
> +}
> +
> +static void check_writeback_fb_id(igt_output_t *output)
> +{
> +	uint64_t check_fb_id;
> +
> +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> +	igt_assert(check_fb_id == 0);
> +}
> +
> +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> +			      uint32_t fb_id, int32_t *out_fence_ptr,
> +			      bool ptr_valid)

flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
probably remove the parameter from this function.

> +{
> +	int ret;
> +	igt_display_t *display = output->display;
> +	struct kmstest_connector_config *config = &output->config;
> +
> +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> +
> +	if (ptr_valid)
> +		*out_fence_ptr = 0;
> +
> +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> +
> +	if (ptr_valid)
> +		igt_assert(*out_fence_ptr == -1);

I'm confused. Why should this be -1 even if we
igt_display_try_commit_atomic succeeds?

> +	/* WRITEBACK_FB_ID must always read as zero */
> +	check_writeback_fb_id(output);
> +
> +	return ret;
> +}
> +
> +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> +{
> +	int i, ret;
> +	int32_t out_fence;
> +	struct {
> +		uint32_t fb_id;
> +		bool ptr_valid;
> +		int32_t *out_fence_ptr;
> +	} invalid_tests[] = {
> +		{
> +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> +			.fb_id = 0,
> +			.ptr_valid = true,
> +			.out_fence_ptr = &out_fence,
> +		},
> +		{
> +			/* Invalid output buffer. */
> +			.fb_id = invalid_fb->fb_id,
> +			.ptr_valid = true,
> +			.out_fence_ptr = &out_fence,
> +		},

This doesn't belong in this function (invalid_out_fence), since this
checks an invalid framebuffer, not an invalid fence. We should probably
move it to writeback_fb_id (and rename that function to test_fb?).

> +		{
> +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> +			.fb_id = valid_fb->fb_id,
> +			.ptr_valid = false,
> +			.out_fence_ptr = (int32_t *)0x8,
> +		},
> +	};
> +
> +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> +					invalid_tests[i].fb_id,
> +					invalid_tests[i].out_fence_ptr,
> +					invalid_tests[i].ptr_valid);
> +		igt_assert(ret != 0);

Maybe we can check for -ret == EINVAL?

> +	}
> +}
> +
> +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)

invalid_fb doesn't seem to be used here. valid_fb seems to be set to
the input framebuffer. It's probably not a good idea to use the same FB
for input and writeback output.

> +{
> +
> +	int ret;
> +
> +	/* Valid output buffer */
> +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> +				valid_fb->fb_id, NULL, false);
> +	igt_assert(ret == 0);
> +
> +	/* Invalid object for WRITEBACK_FB_ID */
> +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> +				output->id, NULL, false);
> +	igt_assert(ret == -EINVAL);
> +
> +	/* Zero WRITEBACK_FB_ID */
> +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> +				0, NULL, false);
> +	igt_assert(ret == 0);
> +}
> +
> +igt_main
> +{
> +	igt_display_t display;
> +	igt_output_t *output;
> +	igt_plane_t *plane;
> +	igt_fb_t input_fb;
> +	drmModeModeInfo mode;
> +	int ret;
> +
> +	memset(&display, 0, sizeof(display));
> +
> +	igt_fixture {
> +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> +		igt_display_require(&display, display.drm_fd);
> +
> +		kmstest_set_vt_graphics_mode();
> +
> +		igt_display_require(&display, display.drm_fd);
> +
> +		igt_require(display.is_atomic);
> +
> +		output = kms_writeback_get_output(&display);
> +		igt_require(output);
> +
> +		if (output->use_override_mode)
> +			memcpy(&mode, &output->override_mode, sizeof(mode));
> +		else
> +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> +
> +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> +		igt_require(plane);

Maybe we can assert on this?

> +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> +				    mode.vdisplay,
> +				    DRM_FORMAT_XRGB8888,
> +				    igt_fb_mod_to_tiling(0),

This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
better to make this clear.

(Applies to other lines of this patch)

> +				    &input_fb);
> +		igt_assert(ret >= 0);
> +		igt_plane_set_fb(plane, &input_fb);
> +	}
> +
> +	igt_subtest("writeback-pixel-formats") {
> +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);

Need to drmModeFreePropertyBlob this.

> +		const char *valid_chars = "0123456 ABCGNRUVXY";
> +		unsigned int i;
> +		char *c;
> +
> +		/*
> +		 * We don't have a comprehensive list of formats, so just check
> +		 * that the blob length is sensible and that it doesn't contain
> +		 * any outlandish characters
> +		 */
> +		igt_assert(!(formats_blob->length % 4));
> +		c = formats_blob->data;
> +		for (i = 0; i < formats_blob->length; i++)
> +			igt_assert_f(strchr(valid_chars, c[i]),
> +				     "Unexpected character %c\n", c[i]);

Honestly, I'm not a fan of this check. There's no guarantee that fourcc
codes will be made from ASCII characters, in fact some formats already
have non-printable chars in them. I don't want to have to update this
test when a new fourcc format is added.

We currently don't have a test for IN_FORMATS. If we really want to
check formats, we could have a big array of known formats and add a
bool is_valid_format(uint32_t fmt) function.

> +	}
> +
> +	igt_subtest("writeback-invalid-out-fence") {
> +		igt_fb_t invalid_fb;

invalid_output_fb would be a better name IMHO.

> +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> +				    mode.vdisplay / 2,
> +				    DRM_FORMAT_XRGB8888,
> +				    igt_fb_mod_to_tiling(0),
> +				    &invalid_fb);
> +		igt_require(ret > 0);

We should probably use a different variable: ret is signed,
igt_create_fb isn't. Also ret doesn't make it clear that the return
value is the KMS framebuffer ID.

(Applies to other subtests)

> +		invalid_out_fence(output, &input_fb, &invalid_fb);

(Still not sure why we provide the input FB to this function.)

> +		igt_remove_fb(display.drm_fd, &invalid_fb);
> +	}
> +
> +	igt_subtest("writeback-fb-id") {
> +		igt_fb_t output_fb;
> +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> +				    DRM_FORMAT_XRGB8888,
> +				    igt_fb_mod_to_tiling(0),
> +				    &output_fb);
> +		igt_require(ret > 0);
> +
> +		writeback_fb_id(output, &input_fb, &output_fb);
> +
> +		igt_remove_fb(display.drm_fd, &output_fb);
> +	}
> +
> +	igt_fixture {
> +		igt_remove_fb(display.drm_fd, &input_fb);
> +		igt_display_fini(&display);
> +	}
> +}
> diff --git a/tests/meson.build b/tests/meson.build
> index f168fbba..9c77cfcd 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -63,6 +63,7 @@ test_progs = [
>  	'kms_universal_plane',
>  	'kms_vblank',
>  	'kms_vrr',
> +	'kms_writeback',
>  	'meta_test',
>  	'panfrost_get_param',
>  	'panfrost_gem_new',
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
  2019-06-13  2:17   ` [Intel-gfx] " Brian Starkey
@ 2019-07-10 15:30     ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-10 15:30 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

Mostly LGTM, here are a few nits.

On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> To use writeback buffers as a CRC source, we need to be able to hash
> them. Implement a simple FVA-1a hashing routine for this purpose.
> 
> Doing a bytewise hash on the framebuffer directly can be very slow if
> the memory is noncached. By making a copy of each line in the FB first
> (which can take advantage of word-access speedup), we can do the hash
> on a cached copy, which is much faster (10x speedup on my platform).
> 
> v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
>     Chris Wilson
> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> [rebased and updated to the most recent API]
> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> ---
>  lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_fb.h |  3 +++
>  2 files changed, 69 insertions(+)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 9d4f905e..d07dae39 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
>  	return false;
>  }
>  
> +/*
> + * This implements the FNV-1a hashing algorithm instead of CRC, for
> + * simplicity
> + * http://www.isthe.com/chongo/tech/comp/fnv/index.html
> + *
> + * hash = offset_basis
> + * for each octet_of_data to be hashed
> + *         hash = hash xor octet_of_data
> + *         hash = hash * FNV_prime
> + * return hash
> + *
> + * 32 bit offset_basis = 2166136261
> + * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
> + */
> +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
> +{
> +#define FNV1a_OFFSET_BIAS 2166136261
> +#define FNV1a_PRIME 16777619

I'd just use plain uint32_t variables for those, but no big deal.

> +	uint32_t hash;
> +	void *map;
> +	char *ptr, *line = NULL;
> +	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
> +	uint32_t stride = calc_plane_stride(fb, 0);

We could return -EINVAL in case fb->num_planes != 1.

> +	if (fb->is_dumb)
> +		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
> +					      PROT_READ);
> +	else
> +		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
> +				    PROT_READ);
> +	ptr = map;

Nit: no need for this, can assign the result of mmap directly to ptr.

> +
> +	/*
> +	 * Framebuffers are often uncached, which can make byte-wise accesses
> +	 * very slow. We copy each line of the FB into a local buffer to speed
> +	 * up the hashing.
> +	 */
> +	line = malloc(stride);
> +	if (!line) {
> +		munmap(map, fb->size);
> +		return -ENOMEM;
> +	}
> +
> +	hash = FNV1a_OFFSET_BIAS;
> +
> +	for (y = 0; y < fb->height; y++, ptr += stride) {
> +
> +		igt_memcpy_from_wc(line, ptr, stride);

Nit: no need to copy the whole stride actually, we can just copy
fb->width * cpp since we're only going to read that.

> +
> +		for (x = 0; x < fb->width * cpp; x++) {
> +			hash ^= line[x];
> +			hash *= FNV1a_PRIME;
> +		}
> +	}
> +
> +	crc->n_words = 1;
> +	crc->crc[0] = hash;
> +
> +	free(line);
> +	munmap(map, fb->size);
> +
> +	return 0;
> +#undef FNV1a_OFFSET_BIAS
> +#undef FNV1a_PRIME
> +}
> +
>  /**
>   * igt_format_is_yuv:
>   * @drm_format: drm fourcc
> diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> index adefebe1..a2741c05 100644
> --- a/lib/igt_fb.h
> +++ b/lib/igt_fb.h
> @@ -37,6 +37,7 @@
>  #include <i915_drm.h>
>  
>  #include "igt_color_encoding.h"
> +#include "igt_debugfs.h"
>  
>  /*
>   * Internal format to denote a buffer compatible with pixman's
> @@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
>  void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
>  			   bool allow_yuv);
>  
> +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
> +
>  #endif /* __IGT_FB_H__ */
>  
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
@ 2019-07-10 15:30     ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-10 15:30 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

Mostly LGTM, here are a few nits.

On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> To use writeback buffers as a CRC source, we need to be able to hash
> them. Implement a simple FVA-1a hashing routine for this purpose.
> 
> Doing a bytewise hash on the framebuffer directly can be very slow if
> the memory is noncached. By making a copy of each line in the FB first
> (which can take advantage of word-access speedup), we can do the hash
> on a cached copy, which is much faster (10x speedup on my platform).
> 
> v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
>     Chris Wilson
> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> [rebased and updated to the most recent API]
> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> ---
>  lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_fb.h |  3 +++
>  2 files changed, 69 insertions(+)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 9d4f905e..d07dae39 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
>  	return false;
>  }
>  
> +/*
> + * This implements the FNV-1a hashing algorithm instead of CRC, for
> + * simplicity
> + * http://www.isthe.com/chongo/tech/comp/fnv/index.html
> + *
> + * hash = offset_basis
> + * for each octet_of_data to be hashed
> + *         hash = hash xor octet_of_data
> + *         hash = hash * FNV_prime
> + * return hash
> + *
> + * 32 bit offset_basis = 2166136261
> + * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
> + */
> +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
> +{
> +#define FNV1a_OFFSET_BIAS 2166136261
> +#define FNV1a_PRIME 16777619

I'd just use plain uint32_t variables for those, but no big deal.

> +	uint32_t hash;
> +	void *map;
> +	char *ptr, *line = NULL;
> +	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
> +	uint32_t stride = calc_plane_stride(fb, 0);

We could return -EINVAL in case fb->num_planes != 1.

> +	if (fb->is_dumb)
> +		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
> +					      PROT_READ);
> +	else
> +		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
> +				    PROT_READ);
> +	ptr = map;

Nit: no need for this, can assign the result of mmap directly to ptr.

> +
> +	/*
> +	 * Framebuffers are often uncached, which can make byte-wise accesses
> +	 * very slow. We copy each line of the FB into a local buffer to speed
> +	 * up the hashing.
> +	 */
> +	line = malloc(stride);
> +	if (!line) {
> +		munmap(map, fb->size);
> +		return -ENOMEM;
> +	}
> +
> +	hash = FNV1a_OFFSET_BIAS;
> +
> +	for (y = 0; y < fb->height; y++, ptr += stride) {
> +
> +		igt_memcpy_from_wc(line, ptr, stride);

Nit: no need to copy the whole stride actually, we can just copy
fb->width * cpp since we're only going to read that.

> +
> +		for (x = 0; x < fb->width * cpp; x++) {
> +			hash ^= line[x];
> +			hash *= FNV1a_PRIME;
> +		}
> +	}
> +
> +	crc->n_words = 1;
> +	crc->crc[0] = hash;
> +
> +	free(line);
> +	munmap(map, fb->size);
> +
> +	return 0;
> +#undef FNV1a_OFFSET_BIAS
> +#undef FNV1a_PRIME
> +}
> +
>  /**
>   * igt_format_is_yuv:
>   * @drm_format: drm fourcc
> diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> index adefebe1..a2741c05 100644
> --- a/lib/igt_fb.h
> +++ b/lib/igt_fb.h
> @@ -37,6 +37,7 @@
>  #include <i915_drm.h>
>  
>  #include "igt_color_encoding.h"
> +#include "igt_debugfs.h"
>  
>  /*
>   * Internal format to denote a buffer compatible with pixman's
> @@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
>  void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
>  			   bool allow_yuv);
>  
> +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
> +
>  #endif /* __IGT_FB_H__ */
>  
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
  2019-07-10 15:30     ` Ser, Simon
@ 2019-07-10 15:34       ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-10 15:34 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

On Wed, 2019-07-10 at 15:30 +0000, Ser, Simon wrote:
> Mostly LGTM, here are a few nits.
> 
> On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> > To use writeback buffers as a CRC source, we need to be able to hash
> > them. Implement a simple FVA-1a hashing routine for this purpose.
> > 
> > Doing a bytewise hash on the framebuffer directly can be very slow if
> > the memory is noncached. By making a copy of each line in the FB first
> > (which can take advantage of word-access speedup), we can do the hash
> > on a cached copy, which is much faster (10x speedup on my platform).
> > 
> > v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
> >     Chris Wilson
> > 
> > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > [rebased and updated to the most recent API]
> > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > ---
> >  lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  lib/igt_fb.h |  3 +++
> >  2 files changed, 69 insertions(+)
> > 
> > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > index 9d4f905e..d07dae39 100644
> > --- a/lib/igt_fb.c
> > +++ b/lib/igt_fb.c
> > @@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
> >  	return false;
> >  }
> >  
> > +/*
> > + * This implements the FNV-1a hashing algorithm instead of CRC, for
> > + * simplicity
> > + * http://www.isthe.com/chongo/tech/comp/fnv/index.html
> > + *
> > + * hash = offset_basis
> > + * for each octet_of_data to be hashed
> > + *         hash = hash xor octet_of_data
> > + *         hash = hash * FNV_prime
> > + * return hash
> > + *
> > + * 32 bit offset_basis = 2166136261
> > + * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
> > + */
> > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
> > +{
> > +#define FNV1a_OFFSET_BIAS 2166136261
> > +#define FNV1a_PRIME 16777619
> 
> I'd just use plain uint32_t variables for those, but no big deal.
> 
> > +	uint32_t hash;
> > +	void *map;
> > +	char *ptr, *line = NULL;
> > +	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
> > +	uint32_t stride = calc_plane_stride(fb, 0);
> 
> We could return -EINVAL in case fb->num_planes != 1.

Let's not waste cycles. With this ^ fixed, this patch is:

Reviewed-by: Simon Ser <simon.ser@intel.com>

Other nits are optional.

> > +	if (fb->is_dumb)
> > +		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
> > +					      PROT_READ);
> > +	else
> > +		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
> > +				    PROT_READ);
> > +	ptr = map;
> 
> Nit: no need for this, can assign the result of mmap directly to ptr.
> 
> > +
> > +	/*
> > +	 * Framebuffers are often uncached, which can make byte-wise accesses
> > +	 * very slow. We copy each line of the FB into a local buffer to speed
> > +	 * up the hashing.
> > +	 */
> > +	line = malloc(stride);
> > +	if (!line) {
> > +		munmap(map, fb->size);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	hash = FNV1a_OFFSET_BIAS;
> > +
> > +	for (y = 0; y < fb->height; y++, ptr += stride) {
> > +
> > +		igt_memcpy_from_wc(line, ptr, stride);
> 
> Nit: no need to copy the whole stride actually, we can just copy
> fb->width * cpp since we're only going to read that.
> 
> > +
> > +		for (x = 0; x < fb->width * cpp; x++) {
> > +			hash ^= line[x];
> > +			hash *= FNV1a_PRIME;
> > +		}
> > +	}
> > +
> > +	crc->n_words = 1;
> > +	crc->crc[0] = hash;
> > +
> > +	free(line);
> > +	munmap(map, fb->size);
> > +
> > +	return 0;
> > +#undef FNV1a_OFFSET_BIAS
> > +#undef FNV1a_PRIME
> > +}
> > +
> >  /**
> >   * igt_format_is_yuv:
> >   * @drm_format: drm fourcc
> > diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> > index adefebe1..a2741c05 100644
> > --- a/lib/igt_fb.h
> > +++ b/lib/igt_fb.h
> > @@ -37,6 +37,7 @@
> >  #include <i915_drm.h>
> >  
> >  #include "igt_color_encoding.h"
> > +#include "igt_debugfs.h"
> >  
> >  /*
> >   * Internal format to denote a buffer compatible with pixman's
> > @@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
> >  void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
> >  			   bool allow_yuv);
> >  
> > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
> > +
> >  #endif /* __IGT_FB_H__ */
> >  
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
@ 2019-07-10 15:34       ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-10 15:34 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

On Wed, 2019-07-10 at 15:30 +0000, Ser, Simon wrote:
> Mostly LGTM, here are a few nits.
> 
> On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> > To use writeback buffers as a CRC source, we need to be able to hash
> > them. Implement a simple FVA-1a hashing routine for this purpose.
> > 
> > Doing a bytewise hash on the framebuffer directly can be very slow if
> > the memory is noncached. By making a copy of each line in the FB first
> > (which can take advantage of word-access speedup), we can do the hash
> > on a cached copy, which is much faster (10x speedup on my platform).
> > 
> > v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
> >     Chris Wilson
> > 
> > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > [rebased and updated to the most recent API]
> > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > ---
> >  lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  lib/igt_fb.h |  3 +++
> >  2 files changed, 69 insertions(+)
> > 
> > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > index 9d4f905e..d07dae39 100644
> > --- a/lib/igt_fb.c
> > +++ b/lib/igt_fb.c
> > @@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
> >  	return false;
> >  }
> >  
> > +/*
> > + * This implements the FNV-1a hashing algorithm instead of CRC, for
> > + * simplicity
> > + * http://www.isthe.com/chongo/tech/comp/fnv/index.html
> > + *
> > + * hash = offset_basis
> > + * for each octet_of_data to be hashed
> > + *         hash = hash xor octet_of_data
> > + *         hash = hash * FNV_prime
> > + * return hash
> > + *
> > + * 32 bit offset_basis = 2166136261
> > + * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
> > + */
> > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
> > +{
> > +#define FNV1a_OFFSET_BIAS 2166136261
> > +#define FNV1a_PRIME 16777619
> 
> I'd just use plain uint32_t variables for those, but no big deal.
> 
> > +	uint32_t hash;
> > +	void *map;
> > +	char *ptr, *line = NULL;
> > +	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
> > +	uint32_t stride = calc_plane_stride(fb, 0);
> 
> We could return -EINVAL in case fb->num_planes != 1.

Let's not waste cycles. With this ^ fixed, this patch is:

Reviewed-by: Simon Ser <simon.ser@intel.com>

Other nits are optional.

> > +	if (fb->is_dumb)
> > +		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
> > +					      PROT_READ);
> > +	else
> > +		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
> > +				    PROT_READ);
> > +	ptr = map;
> 
> Nit: no need for this, can assign the result of mmap directly to ptr.
> 
> > +
> > +	/*
> > +	 * Framebuffers are often uncached, which can make byte-wise accesses
> > +	 * very slow. We copy each line of the FB into a local buffer to speed
> > +	 * up the hashing.
> > +	 */
> > +	line = malloc(stride);
> > +	if (!line) {
> > +		munmap(map, fb->size);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	hash = FNV1a_OFFSET_BIAS;
> > +
> > +	for (y = 0; y < fb->height; y++, ptr += stride) {
> > +
> > +		igt_memcpy_from_wc(line, ptr, stride);
> 
> Nit: no need to copy the whole stride actually, we can just copy
> fb->width * cpp since we're only going to read that.
> 
> > +
> > +		for (x = 0; x < fb->width * cpp; x++) {
> > +			hash ^= line[x];
> > +			hash *= FNV1a_PRIME;
> > +		}
> > +	}
> > +
> > +	crc->n_words = 1;
> > +	crc->crc[0] = hash;
> > +
> > +	free(line);
> > +	munmap(map, fb->size);
> > +
> > +	return 0;
> > +#undef FNV1a_OFFSET_BIAS
> > +#undef FNV1a_PRIME
> > +}
> > +
> >  /**
> >   * igt_format_is_yuv:
> >   * @drm_format: drm fourcc
> > diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> > index adefebe1..a2741c05 100644
> > --- a/lib/igt_fb.h
> > +++ b/lib/igt_fb.h
> > @@ -37,6 +37,7 @@
> >  #include <i915_drm.h>
> >  
> >  #include "igt_color_encoding.h"
> > +#include "igt_debugfs.h"
> >  
> >  /*
> >   * Internal format to denote a buffer compatible with pixman's
> > @@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
> >  void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
> >  			   bool allow_yuv);
> >  
> > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
> > +
> >  #endif /* __IGT_FB_H__ */
> >  
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-07-10 11:57     ` Ser, Simon
@ 2019-07-12  2:44       ` Rodrigo Siqueira
  -1 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-12  2:44 UTC (permalink / raw)
  To: Ser, Simon; +Cc: intel-gfx, igt-dev, nd


[-- Attachment #1.1: Type: text/plain, Size: 15891 bytes --]

On 07/10, Ser, Simon wrote:
> Hi,
> 
> Thanks for the patch! Here are a few comments.
> 
> For bonus points, it would be nice to add igt_describe descriptions of
> each sub-test.

Hi Simon,

First of all, thanks for your feedback; I already applied most of your
suggestions. I just have some inline comments/questions.
 
> On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> > Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> > WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> > behaviour is correct.
> > 
> > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > [rebased and updated do_writeback_test() function to address feedback]
> > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > ---
> >  tests/Makefile.sources |   1 +
> >  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
> >  tests/meson.build      |   1 +
> >  3 files changed, 316 insertions(+)
> >  create mode 100644 tests/kms_writeback.c
> > 
> > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > index 027ed82f..03cc8efa 100644
> > --- a/tests/Makefile.sources
> > +++ b/tests/Makefile.sources
> > @@ -77,6 +77,7 @@ TESTS_progs = \
> >  	kms_universal_plane \
> >  	kms_vblank \
> >  	kms_vrr \
> > +	kms_writeback \
> >  	meta_test \
> >  	perf \
> >  	perf_pmu \
> > diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> > new file mode 100644
> > index 00000000..66ef48a6
> > --- /dev/null
> > +++ b/tests/kms_writeback.c
> > @@ -0,0 +1,314 @@
> > +/*
> > + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the next
> > + * paragraph) shall be included in all copies or substantial portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + *
> > + */
> > +
> > +#include <errno.h>
> > +#include <stdbool.h>
> > +#include <stdio.h>
> > +#include <string.h>
> > +
> > +#include "igt.h"
> > +#include "igt_core.h"
> > +#include "igt_fb.h"
> > +
> > +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> > +{
> > +	drmModePropertyBlobRes *blob = NULL;
> > +	uint64_t blob_id;
> > +	int ret;
> > +
> > +	ret = kmstest_get_property(output->display->drm_fd,
> > +				   output->config.connector->connector_id,
> > +				   DRM_MODE_OBJECT_CONNECTOR,
> > +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> > +				   NULL, &blob_id, NULL);
> > +	if (ret)
> > +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> > +
> > +	igt_assert(blob);
> > +
> > +	return blob;
> > +}
> > +
> > +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> > +{
> > +	igt_fb_t input_fb, output_fb;
> > +	igt_plane_t *plane;
> > +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> > +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> > +	int width, height, ret;
> > +	drmModeModeInfo override_mode = {
> > +		.clock = 25175,
> > +		.hdisplay = 640,
> > +		.hsync_start = 656,
> > +		.hsync_end = 752,
> > +		.htotal = 800,
> > +		.hskew = 0,
> > +		.vdisplay = 480,
> > +		.vsync_start = 490,
> > +		.vsync_end = 492,
> > +		.vtotal = 525,
> > +		.vscan = 0,
> > +		.vrefresh = 60,
> > +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> > +		.name = {"640x480-60"},
> > +	};
> > +	igt_output_override_mode(output, &override_mode);
> > +
> > +	width = override_mode.hdisplay;
> > +	height = override_mode.vdisplay;
> > +
> > +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> > +	igt_assert(ret >= 0);
> > +
> > +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> > +	igt_assert(ret >= 0);
> > +
> > +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > +	igt_plane_set_fb(plane, &input_fb);
> > +	igt_output_set_writeback_fb(output, &output_fb);
> > +
> > +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> > +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> 
> Okay, we're using atomic test-only mode to know if we can perform tests
> with the writeback output. It's probably fine, but we don't use
> WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.

Sorry, I did not fully understand part. Did you expect to see something
like the below code before igt_display_try_commit_atomic()?

 igt_output_set_prop_value(output, WRITEBACK_PIXEL_FORMATS,
                           DRM_FORMAT_XRGB8888);

> > +	igt_plane_set_fb(plane, NULL);
> > +	igt_remove_fb(display->drm_fd, &input_fb);
> > +	igt_remove_fb(display->drm_fd, &output_fb);
> > +
> > +	return !ret;
> > +}
> > +
> > +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < display->n_outputs; i++) {
> > +		igt_output_t *output = &display->outputs[i];
> > +		int j;
> > +
> > +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> > +			continue;
> > +
> > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
> 
> Hmm. Is this really necessary? "Real" userspace won't do this, so I
> don't think we need to either.

Hmmm, I have a little experience with userspace; however, I tested
kms_writeback on top of vkms without this line, and everything worked
well. If I remove this line, should I also drop the line that force
connector to FORCE_CONNECTOR_UNSPECIFIED?

Another question, if FORCE_CONNECTOR_ON is something that userspace
won't want to do, why do we have it?
 
> > +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> > +			igt_output_set_pipe(output, j);
> > +
> > +			if (check_writeback_config(display, output)) {
> > +				igt_debug("Using connector %u:%s on pipe %d\n",
> > +					  output->config.connector->connector_id,
> > +					  output->name, j);
> > +				return output;
> > +			}
> 
> We could probably add an igt_debug statement in case we don't use this
> writeback output.
> 
> > +		}
> > +
> > +		/* Restore any connectors we don't use, so we don't trip on them later */
> > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> > +	}
> > +
> > +	return NULL;
> > +}
> > +
> > +static void check_writeback_fb_id(igt_output_t *output)
> > +{
> > +	uint64_t check_fb_id;
> > +
> > +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > +	igt_assert(check_fb_id == 0);
> > +}
> > +
> > +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> > +			      uint32_t fb_id, int32_t *out_fence_ptr,
> > +			      bool ptr_valid)
> 
> flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
> probably remove the parameter from this function.
> 
> > +{
> > +	int ret;
> > +	igt_display_t *display = output->display;
> > +	struct kmstest_connector_config *config = &output->config;
> > +
> > +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> > +
> > +	if (ptr_valid)
> > +		*out_fence_ptr = 0;
> > +
> > +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> > +
> > +	if (ptr_valid)
> > +		igt_assert(*out_fence_ptr == -1);
> 
> I'm confused. Why should this be -1 even if we
> igt_display_try_commit_atomic succeeds?

I inspected the drm_mode_atomic_ioctl() function and I noticed that It
calls complete_signaling() in its turn this function assign -1 to
out_fence_ptr. Since all of this happens at the end of atomic_commit, I
believe that we don’t need it. I already removed it.
 
> > +	/* WRITEBACK_FB_ID must always read as zero */
> > +	check_writeback_fb_id(output);
> > +
> > +	return ret;
> > +}
> > +
> > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > +{
> > +	int i, ret;
> > +	int32_t out_fence;
> > +	struct {
> > +		uint32_t fb_id;
> > +		bool ptr_valid;
> > +		int32_t *out_fence_ptr;
> > +	} invalid_tests[] = {
> > +		{
> > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > +			.fb_id = 0,
> > +			.ptr_valid = true,
> > +			.out_fence_ptr = &out_fence,
> > +		},
> > +		{
> > +			/* Invalid output buffer. */
> > +			.fb_id = invalid_fb->fb_id,
> > +			.ptr_valid = true,
> > +			.out_fence_ptr = &out_fence,
> > +		},
> 
> This doesn't belong in this function (invalid_out_fence), since this
> checks an invalid framebuffer, not an invalid fence. We should probably
> move it to writeback_fb_id (and rename that function to test_fb?).
> 
> > +		{
> > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > +			.fb_id = valid_fb->fb_id,
> > +			.ptr_valid = false,
> > +			.out_fence_ptr = (int32_t *)0x8,
> > +		},
> > +	};
> > +
> > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > +					invalid_tests[i].fb_id,
> > +					invalid_tests[i].out_fence_ptr,
> > +					invalid_tests[i].ptr_valid);
> > +		igt_assert(ret != 0);
> 
> Maybe we can check for -ret == EINVAL?
> 
> > +	}
> > +}
> > +
> > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> 
> invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> the input framebuffer. It's probably not a good idea to use the same FB
> for input and writeback output.
> 
> > +{
> > +
> > +	int ret;
> > +
> > +	/* Valid output buffer */
> > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > +				valid_fb->fb_id, NULL, false);
> > +	igt_assert(ret == 0);
> > +
> > +	/* Invalid object for WRITEBACK_FB_ID */
> > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > +				output->id, NULL, false);
> > +	igt_assert(ret == -EINVAL);
> > +
> > +	/* Zero WRITEBACK_FB_ID */
> > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > +				0, NULL, false);
> > +	igt_assert(ret == 0);
> > +}
> > +
> > +igt_main
> > +{
> > +	igt_display_t display;
> > +	igt_output_t *output;
> > +	igt_plane_t *plane;
> > +	igt_fb_t input_fb;
> > +	drmModeModeInfo mode;
> > +	int ret;
> > +
> > +	memset(&display, 0, sizeof(display));
> > +
> > +	igt_fixture {
> > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > +		igt_display_require(&display, display.drm_fd);
> > +
> > +		kmstest_set_vt_graphics_mode();
> > +
> > +		igt_display_require(&display, display.drm_fd);
> > +
> > +		igt_require(display.is_atomic);
> > +
> > +		output = kms_writeback_get_output(&display);
> > +		igt_require(output);
> > +
> > +		if (output->use_override_mode)
> > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > +		else
> > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > +
> > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > +		igt_require(plane);
> 
> Maybe we can assert on this?
> 
> > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > +				    mode.vdisplay,
> > +				    DRM_FORMAT_XRGB8888,
> > +				    igt_fb_mod_to_tiling(0),
> 
> This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> better to make this clear.
> 
> (Applies to other lines of this patch)
> 
> > +				    &input_fb);
> > +		igt_assert(ret >= 0);
> > +		igt_plane_set_fb(plane, &input_fb);
> > +	}
> > +
> > +	igt_subtest("writeback-pixel-formats") {
> > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> 
> Need to drmModeFreePropertyBlob this.
> 
> > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > +		unsigned int i;
> > +		char *c;
> > +
> > +		/*
> > +		 * We don't have a comprehensive list of formats, so just check
> > +		 * that the blob length is sensible and that it doesn't contain
> > +		 * any outlandish characters
> > +		 */
> > +		igt_assert(!(formats_blob->length % 4));
> > +		c = formats_blob->data;
> > +		for (i = 0; i < formats_blob->length; i++)
> > +			igt_assert_f(strchr(valid_chars, c[i]),
> > +				     "Unexpected character %c\n", c[i]);
> 
> Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> codes will be made from ASCII characters, in fact some formats already
> have non-printable chars in them. I don't want to have to update this
> test when a new fourcc format is added.
> 
> We currently don't have a test for IN_FORMATS. If we really want to
> check formats, we could have a big array of known formats and add a
> bool is_valid_format(uint32_t fmt) function.

Agree with you. How about remove this test?

Thanks
Best Regards

> > +	}
> > +
> > +	igt_subtest("writeback-invalid-out-fence") {
> > +		igt_fb_t invalid_fb;
> 
> invalid_output_fb would be a better name IMHO.
> 
> > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> > +				    mode.vdisplay / 2,
> > +				    DRM_FORMAT_XRGB8888,
> > +				    igt_fb_mod_to_tiling(0),
> > +				    &invalid_fb);
> > +		igt_require(ret > 0);
> 
> We should probably use a different variable: ret is signed,
> igt_create_fb isn't. Also ret doesn't make it clear that the return
> value is the KMS framebuffer ID.
> 
> (Applies to other subtests)
> 
> > +		invalid_out_fence(output, &input_fb, &invalid_fb);
> 
> (Still not sure why we provide the input FB to this function.)
> 
> > +		igt_remove_fb(display.drm_fd, &invalid_fb);
> > +	}
> > +
> > +	igt_subtest("writeback-fb-id") {
> > +		igt_fb_t output_fb;
> > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> > +				    DRM_FORMAT_XRGB8888,
> > +				    igt_fb_mod_to_tiling(0),
> > +				    &output_fb);
> > +		igt_require(ret > 0);
> > +
> > +		writeback_fb_id(output, &input_fb, &output_fb);
> > +
> > +		igt_remove_fb(display.drm_fd, &output_fb);
> > +	}
> > +
> > +	igt_fixture {
> > +		igt_remove_fb(display.drm_fd, &input_fb);
> > +		igt_display_fini(&display);
> > +	}
> > +}
> > diff --git a/tests/meson.build b/tests/meson.build
> > index f168fbba..9c77cfcd 100644
> > --- a/tests/meson.build
> > +++ b/tests/meson.build
> > @@ -63,6 +63,7 @@ test_progs = [
> >  	'kms_universal_plane',
> >  	'kms_vblank',
> >  	'kms_vrr',
> > +	'kms_writeback',
> >  	'meta_test',
> >  	'panfrost_get_param',
> >  	'panfrost_gem_new',
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-12  2:44       ` Rodrigo Siqueira
  0 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-12  2:44 UTC (permalink / raw)
  To: Ser, Simon
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey


[-- Attachment #1.1: Type: text/plain, Size: 15891 bytes --]

On 07/10, Ser, Simon wrote:
> Hi,
> 
> Thanks for the patch! Here are a few comments.
> 
> For bonus points, it would be nice to add igt_describe descriptions of
> each sub-test.

Hi Simon,

First of all, thanks for your feedback; I already applied most of your
suggestions. I just have some inline comments/questions.
 
> On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> > Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> > WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> > behaviour is correct.
> > 
> > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > [rebased and updated do_writeback_test() function to address feedback]
> > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > ---
> >  tests/Makefile.sources |   1 +
> >  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
> >  tests/meson.build      |   1 +
> >  3 files changed, 316 insertions(+)
> >  create mode 100644 tests/kms_writeback.c
> > 
> > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > index 027ed82f..03cc8efa 100644
> > --- a/tests/Makefile.sources
> > +++ b/tests/Makefile.sources
> > @@ -77,6 +77,7 @@ TESTS_progs = \
> >  	kms_universal_plane \
> >  	kms_vblank \
> >  	kms_vrr \
> > +	kms_writeback \
> >  	meta_test \
> >  	perf \
> >  	perf_pmu \
> > diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> > new file mode 100644
> > index 00000000..66ef48a6
> > --- /dev/null
> > +++ b/tests/kms_writeback.c
> > @@ -0,0 +1,314 @@
> > +/*
> > + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the next
> > + * paragraph) shall be included in all copies or substantial portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + *
> > + */
> > +
> > +#include <errno.h>
> > +#include <stdbool.h>
> > +#include <stdio.h>
> > +#include <string.h>
> > +
> > +#include "igt.h"
> > +#include "igt_core.h"
> > +#include "igt_fb.h"
> > +
> > +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> > +{
> > +	drmModePropertyBlobRes *blob = NULL;
> > +	uint64_t blob_id;
> > +	int ret;
> > +
> > +	ret = kmstest_get_property(output->display->drm_fd,
> > +				   output->config.connector->connector_id,
> > +				   DRM_MODE_OBJECT_CONNECTOR,
> > +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> > +				   NULL, &blob_id, NULL);
> > +	if (ret)
> > +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> > +
> > +	igt_assert(blob);
> > +
> > +	return blob;
> > +}
> > +
> > +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> > +{
> > +	igt_fb_t input_fb, output_fb;
> > +	igt_plane_t *plane;
> > +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> > +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> > +	int width, height, ret;
> > +	drmModeModeInfo override_mode = {
> > +		.clock = 25175,
> > +		.hdisplay = 640,
> > +		.hsync_start = 656,
> > +		.hsync_end = 752,
> > +		.htotal = 800,
> > +		.hskew = 0,
> > +		.vdisplay = 480,
> > +		.vsync_start = 490,
> > +		.vsync_end = 492,
> > +		.vtotal = 525,
> > +		.vscan = 0,
> > +		.vrefresh = 60,
> > +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> > +		.name = {"640x480-60"},
> > +	};
> > +	igt_output_override_mode(output, &override_mode);
> > +
> > +	width = override_mode.hdisplay;
> > +	height = override_mode.vdisplay;
> > +
> > +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> > +	igt_assert(ret >= 0);
> > +
> > +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> > +	igt_assert(ret >= 0);
> > +
> > +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > +	igt_plane_set_fb(plane, &input_fb);
> > +	igt_output_set_writeback_fb(output, &output_fb);
> > +
> > +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> > +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> 
> Okay, we're using atomic test-only mode to know if we can perform tests
> with the writeback output. It's probably fine, but we don't use
> WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.

Sorry, I did not fully understand part. Did you expect to see something
like the below code before igt_display_try_commit_atomic()?

 igt_output_set_prop_value(output, WRITEBACK_PIXEL_FORMATS,
                           DRM_FORMAT_XRGB8888);

> > +	igt_plane_set_fb(plane, NULL);
> > +	igt_remove_fb(display->drm_fd, &input_fb);
> > +	igt_remove_fb(display->drm_fd, &output_fb);
> > +
> > +	return !ret;
> > +}
> > +
> > +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < display->n_outputs; i++) {
> > +		igt_output_t *output = &display->outputs[i];
> > +		int j;
> > +
> > +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> > +			continue;
> > +
> > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
> 
> Hmm. Is this really necessary? "Real" userspace won't do this, so I
> don't think we need to either.

Hmmm, I have a little experience with userspace; however, I tested
kms_writeback on top of vkms without this line, and everything worked
well. If I remove this line, should I also drop the line that force
connector to FORCE_CONNECTOR_UNSPECIFIED?

Another question, if FORCE_CONNECTOR_ON is something that userspace
won't want to do, why do we have it?
 
> > +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> > +			igt_output_set_pipe(output, j);
> > +
> > +			if (check_writeback_config(display, output)) {
> > +				igt_debug("Using connector %u:%s on pipe %d\n",
> > +					  output->config.connector->connector_id,
> > +					  output->name, j);
> > +				return output;
> > +			}
> 
> We could probably add an igt_debug statement in case we don't use this
> writeback output.
> 
> > +		}
> > +
> > +		/* Restore any connectors we don't use, so we don't trip on them later */
> > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> > +	}
> > +
> > +	return NULL;
> > +}
> > +
> > +static void check_writeback_fb_id(igt_output_t *output)
> > +{
> > +	uint64_t check_fb_id;
> > +
> > +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > +	igt_assert(check_fb_id == 0);
> > +}
> > +
> > +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> > +			      uint32_t fb_id, int32_t *out_fence_ptr,
> > +			      bool ptr_valid)
> 
> flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
> probably remove the parameter from this function.
> 
> > +{
> > +	int ret;
> > +	igt_display_t *display = output->display;
> > +	struct kmstest_connector_config *config = &output->config;
> > +
> > +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> > +
> > +	if (ptr_valid)
> > +		*out_fence_ptr = 0;
> > +
> > +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> > +
> > +	if (ptr_valid)
> > +		igt_assert(*out_fence_ptr == -1);
> 
> I'm confused. Why should this be -1 even if we
> igt_display_try_commit_atomic succeeds?

I inspected the drm_mode_atomic_ioctl() function and I noticed that It
calls complete_signaling() in its turn this function assign -1 to
out_fence_ptr. Since all of this happens at the end of atomic_commit, I
believe that we don’t need it. I already removed it.
 
> > +	/* WRITEBACK_FB_ID must always read as zero */
> > +	check_writeback_fb_id(output);
> > +
> > +	return ret;
> > +}
> > +
> > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > +{
> > +	int i, ret;
> > +	int32_t out_fence;
> > +	struct {
> > +		uint32_t fb_id;
> > +		bool ptr_valid;
> > +		int32_t *out_fence_ptr;
> > +	} invalid_tests[] = {
> > +		{
> > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > +			.fb_id = 0,
> > +			.ptr_valid = true,
> > +			.out_fence_ptr = &out_fence,
> > +		},
> > +		{
> > +			/* Invalid output buffer. */
> > +			.fb_id = invalid_fb->fb_id,
> > +			.ptr_valid = true,
> > +			.out_fence_ptr = &out_fence,
> > +		},
> 
> This doesn't belong in this function (invalid_out_fence), since this
> checks an invalid framebuffer, not an invalid fence. We should probably
> move it to writeback_fb_id (and rename that function to test_fb?).
> 
> > +		{
> > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > +			.fb_id = valid_fb->fb_id,
> > +			.ptr_valid = false,
> > +			.out_fence_ptr = (int32_t *)0x8,
> > +		},
> > +	};
> > +
> > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > +					invalid_tests[i].fb_id,
> > +					invalid_tests[i].out_fence_ptr,
> > +					invalid_tests[i].ptr_valid);
> > +		igt_assert(ret != 0);
> 
> Maybe we can check for -ret == EINVAL?
> 
> > +	}
> > +}
> > +
> > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> 
> invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> the input framebuffer. It's probably not a good idea to use the same FB
> for input and writeback output.
> 
> > +{
> > +
> > +	int ret;
> > +
> > +	/* Valid output buffer */
> > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > +				valid_fb->fb_id, NULL, false);
> > +	igt_assert(ret == 0);
> > +
> > +	/* Invalid object for WRITEBACK_FB_ID */
> > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > +				output->id, NULL, false);
> > +	igt_assert(ret == -EINVAL);
> > +
> > +	/* Zero WRITEBACK_FB_ID */
> > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > +				0, NULL, false);
> > +	igt_assert(ret == 0);
> > +}
> > +
> > +igt_main
> > +{
> > +	igt_display_t display;
> > +	igt_output_t *output;
> > +	igt_plane_t *plane;
> > +	igt_fb_t input_fb;
> > +	drmModeModeInfo mode;
> > +	int ret;
> > +
> > +	memset(&display, 0, sizeof(display));
> > +
> > +	igt_fixture {
> > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > +		igt_display_require(&display, display.drm_fd);
> > +
> > +		kmstest_set_vt_graphics_mode();
> > +
> > +		igt_display_require(&display, display.drm_fd);
> > +
> > +		igt_require(display.is_atomic);
> > +
> > +		output = kms_writeback_get_output(&display);
> > +		igt_require(output);
> > +
> > +		if (output->use_override_mode)
> > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > +		else
> > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > +
> > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > +		igt_require(plane);
> 
> Maybe we can assert on this?
> 
> > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > +				    mode.vdisplay,
> > +				    DRM_FORMAT_XRGB8888,
> > +				    igt_fb_mod_to_tiling(0),
> 
> This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> better to make this clear.
> 
> (Applies to other lines of this patch)
> 
> > +				    &input_fb);
> > +		igt_assert(ret >= 0);
> > +		igt_plane_set_fb(plane, &input_fb);
> > +	}
> > +
> > +	igt_subtest("writeback-pixel-formats") {
> > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> 
> Need to drmModeFreePropertyBlob this.
> 
> > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > +		unsigned int i;
> > +		char *c;
> > +
> > +		/*
> > +		 * We don't have a comprehensive list of formats, so just check
> > +		 * that the blob length is sensible and that it doesn't contain
> > +		 * any outlandish characters
> > +		 */
> > +		igt_assert(!(formats_blob->length % 4));
> > +		c = formats_blob->data;
> > +		for (i = 0; i < formats_blob->length; i++)
> > +			igt_assert_f(strchr(valid_chars, c[i]),
> > +				     "Unexpected character %c\n", c[i]);
> 
> Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> codes will be made from ASCII characters, in fact some formats already
> have non-printable chars in them. I don't want to have to update this
> test when a new fourcc format is added.
> 
> We currently don't have a test for IN_FORMATS. If we really want to
> check formats, we could have a big array of known formats and add a
> bool is_valid_format(uint32_t fmt) function.

Agree with you. How about remove this test?

Thanks
Best Regards

> > +	}
> > +
> > +	igt_subtest("writeback-invalid-out-fence") {
> > +		igt_fb_t invalid_fb;
> 
> invalid_output_fb would be a better name IMHO.
> 
> > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> > +				    mode.vdisplay / 2,
> > +				    DRM_FORMAT_XRGB8888,
> > +				    igt_fb_mod_to_tiling(0),
> > +				    &invalid_fb);
> > +		igt_require(ret > 0);
> 
> We should probably use a different variable: ret is signed,
> igt_create_fb isn't. Also ret doesn't make it clear that the return
> value is the KMS framebuffer ID.
> 
> (Applies to other subtests)
> 
> > +		invalid_out_fence(output, &input_fb, &invalid_fb);
> 
> (Still not sure why we provide the input FB to this function.)
> 
> > +		igt_remove_fb(display.drm_fd, &invalid_fb);
> > +	}
> > +
> > +	igt_subtest("writeback-fb-id") {
> > +		igt_fb_t output_fb;
> > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> > +				    DRM_FORMAT_XRGB8888,
> > +				    igt_fb_mod_to_tiling(0),
> > +				    &output_fb);
> > +		igt_require(ret > 0);
> > +
> > +		writeback_fb_id(output, &input_fb, &output_fb);
> > +
> > +		igt_remove_fb(display.drm_fd, &output_fb);
> > +	}
> > +
> > +	igt_fixture {
> > +		igt_remove_fb(display.drm_fd, &input_fb);
> > +		igt_display_fini(&display);
> > +	}
> > +}
> > diff --git a/tests/meson.build b/tests/meson.build
> > index f168fbba..9c77cfcd 100644
> > --- a/tests/meson.build
> > +++ b/tests/meson.build
> > @@ -63,6 +63,7 @@ test_progs = [
> >  	'kms_universal_plane',
> >  	'kms_vblank',
> >  	'kms_vrr',
> > +	'kms_writeback',
> >  	'meta_test',
> >  	'panfrost_get_param',
> >  	'panfrost_gem_new',
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
  2019-07-10 15:34       ` Ser, Simon
@ 2019-07-12  2:49         ` Rodrigo Siqueira
  -1 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-12  2:49 UTC (permalink / raw)
  To: Ser, Simon; +Cc: intel-gfx, igt-dev, nd


[-- Attachment #1.1: Type: text/plain, Size: 5271 bytes --]

On 07/10, Ser, Simon wrote:
> On Wed, 2019-07-10 at 15:30 +0000, Ser, Simon wrote:
> > Mostly LGTM, here are a few nits.
> > 
> > On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> > > To use writeback buffers as a CRC source, we need to be able to hash
> > > them. Implement a simple FVA-1a hashing routine for this purpose.
> > > 
> > > Doing a bytewise hash on the framebuffer directly can be very slow if
> > > the memory is noncached. By making a copy of each line in the FB first
> > > (which can take advantage of word-access speedup), we can do the hash
> > > on a cached copy, which is much faster (10x speedup on my platform).
> > > 
> > > v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
> > >     Chris Wilson
> > > 
> > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > [rebased and updated to the most recent API]
> > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > ---
> > >  lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  lib/igt_fb.h |  3 +++
> > >  2 files changed, 69 insertions(+)
> > > 
> > > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > > index 9d4f905e..d07dae39 100644
> > > --- a/lib/igt_fb.c
> > > +++ b/lib/igt_fb.c
> > > @@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
> > >  	return false;
> > >  }
> > >  
> > > +/*
> > > + * This implements the FNV-1a hashing algorithm instead of CRC, for
> > > + * simplicity
> > > + * http://www.isthe.com/chongo/tech/comp/fnv/index.html
> > > + *
> > > + * hash = offset_basis
> > > + * for each octet_of_data to be hashed
> > > + *         hash = hash xor octet_of_data
> > > + *         hash = hash * FNV_prime
> > > + * return hash
> > > + *
> > > + * 32 bit offset_basis = 2166136261
> > > + * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
> > > + */
> > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
> > > +{
> > > +#define FNV1a_OFFSET_BIAS 2166136261
> > > +#define FNV1a_PRIME 16777619
> > 
> > I'd just use plain uint32_t variables for those, but no big deal.
> > 
> > > +	uint32_t hash;
> > > +	void *map;
> > > +	char *ptr, *line = NULL;
> > > +	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
> > > +	uint32_t stride = calc_plane_stride(fb, 0);
> > 
> > We could return -EINVAL in case fb->num_planes != 1.
> 
> Let's not waste cycles. With this ^ fixed, this patch is:
> 
> Reviewed-by: Simon Ser <simon.ser@intel.com>
> 
> Other nits are optional.

I agreed with all your suggestions, and I already applied all of them.
Should I wait for the other patches review, or should I resend the new
version?

Thanks for all the feedback
Best Regards
 
> > > +	if (fb->is_dumb)
> > > +		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
> > > +					      PROT_READ);
> > > +	else
> > > +		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
> > > +				    PROT_READ);
> > > +	ptr = map;
> > 
> > Nit: no need for this, can assign the result of mmap directly to ptr.
> > 
> > > +
> > > +	/*
> > > +	 * Framebuffers are often uncached, which can make byte-wise accesses
> > > +	 * very slow. We copy each line of the FB into a local buffer to speed
> > > +	 * up the hashing.
> > > +	 */
> > > +	line = malloc(stride);
> > > +	if (!line) {
> > > +		munmap(map, fb->size);
> > > +		return -ENOMEM;
> > > +	}
> > > +
> > > +	hash = FNV1a_OFFSET_BIAS;
> > > +
> > > +	for (y = 0; y < fb->height; y++, ptr += stride) {
> > > +
> > > +		igt_memcpy_from_wc(line, ptr, stride);
> > 
> > Nit: no need to copy the whole stride actually, we can just copy
> > fb->width * cpp since we're only going to read that.
> > 
> > > +
> > > +		for (x = 0; x < fb->width * cpp; x++) {
> > > +			hash ^= line[x];
> > > +			hash *= FNV1a_PRIME;
> > > +		}
> > > +	}
> > > +
> > > +	crc->n_words = 1;
> > > +	crc->crc[0] = hash;
> > > +
> > > +	free(line);
> > > +	munmap(map, fb->size);
> > > +
> > > +	return 0;
> > > +#undef FNV1a_OFFSET_BIAS
> > > +#undef FNV1a_PRIME
> > > +}
> > > +
> > >  /**
> > >   * igt_format_is_yuv:
> > >   * @drm_format: drm fourcc
> > > diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> > > index adefebe1..a2741c05 100644
> > > --- a/lib/igt_fb.h
> > > +++ b/lib/igt_fb.h
> > > @@ -37,6 +37,7 @@
> > >  #include <i915_drm.h>
> > >  
> > >  #include "igt_color_encoding.h"
> > > +#include "igt_debugfs.h"
> > >  
> > >  /*
> > >   * Internal format to denote a buffer compatible with pixman's
> > > @@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
> > >  void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
> > >  			   bool allow_yuv);
> > >  
> > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
> > > +
> > >  #endif /* __IGT_FB_H__ */
> > >  
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
@ 2019-07-12  2:49         ` Rodrigo Siqueira
  0 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-12  2:49 UTC (permalink / raw)
  To: Ser, Simon
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey


[-- Attachment #1.1: Type: text/plain, Size: 5271 bytes --]

On 07/10, Ser, Simon wrote:
> On Wed, 2019-07-10 at 15:30 +0000, Ser, Simon wrote:
> > Mostly LGTM, here are a few nits.
> > 
> > On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> > > To use writeback buffers as a CRC source, we need to be able to hash
> > > them. Implement a simple FVA-1a hashing routine for this purpose.
> > > 
> > > Doing a bytewise hash on the framebuffer directly can be very slow if
> > > the memory is noncached. By making a copy of each line in the FB first
> > > (which can take advantage of word-access speedup), we can do the hash
> > > on a cached copy, which is much faster (10x speedup on my platform).
> > > 
> > > v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
> > >     Chris Wilson
> > > 
> > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > [rebased and updated to the most recent API]
> > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > ---
> > >  lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  lib/igt_fb.h |  3 +++
> > >  2 files changed, 69 insertions(+)
> > > 
> > > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > > index 9d4f905e..d07dae39 100644
> > > --- a/lib/igt_fb.c
> > > +++ b/lib/igt_fb.c
> > > @@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
> > >  	return false;
> > >  }
> > >  
> > > +/*
> > > + * This implements the FNV-1a hashing algorithm instead of CRC, for
> > > + * simplicity
> > > + * http://www.isthe.com/chongo/tech/comp/fnv/index.html
> > > + *
> > > + * hash = offset_basis
> > > + * for each octet_of_data to be hashed
> > > + *         hash = hash xor octet_of_data
> > > + *         hash = hash * FNV_prime
> > > + * return hash
> > > + *
> > > + * 32 bit offset_basis = 2166136261
> > > + * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
> > > + */
> > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
> > > +{
> > > +#define FNV1a_OFFSET_BIAS 2166136261
> > > +#define FNV1a_PRIME 16777619
> > 
> > I'd just use plain uint32_t variables for those, but no big deal.
> > 
> > > +	uint32_t hash;
> > > +	void *map;
> > > +	char *ptr, *line = NULL;
> > > +	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
> > > +	uint32_t stride = calc_plane_stride(fb, 0);
> > 
> > We could return -EINVAL in case fb->num_planes != 1.
> 
> Let's not waste cycles. With this ^ fixed, this patch is:
> 
> Reviewed-by: Simon Ser <simon.ser@intel.com>
> 
> Other nits are optional.

I agreed with all your suggestions, and I already applied all of them.
Should I wait for the other patches review, or should I resend the new
version?

Thanks for all the feedback
Best Regards
 
> > > +	if (fb->is_dumb)
> > > +		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
> > > +					      PROT_READ);
> > > +	else
> > > +		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
> > > +				    PROT_READ);
> > > +	ptr = map;
> > 
> > Nit: no need for this, can assign the result of mmap directly to ptr.
> > 
> > > +
> > > +	/*
> > > +	 * Framebuffers are often uncached, which can make byte-wise accesses
> > > +	 * very slow. We copy each line of the FB into a local buffer to speed
> > > +	 * up the hashing.
> > > +	 */
> > > +	line = malloc(stride);
> > > +	if (!line) {
> > > +		munmap(map, fb->size);
> > > +		return -ENOMEM;
> > > +	}
> > > +
> > > +	hash = FNV1a_OFFSET_BIAS;
> > > +
> > > +	for (y = 0; y < fb->height; y++, ptr += stride) {
> > > +
> > > +		igt_memcpy_from_wc(line, ptr, stride);
> > 
> > Nit: no need to copy the whole stride actually, we can just copy
> > fb->width * cpp since we're only going to read that.
> > 
> > > +
> > > +		for (x = 0; x < fb->width * cpp; x++) {
> > > +			hash ^= line[x];
> > > +			hash *= FNV1a_PRIME;
> > > +		}
> > > +	}
> > > +
> > > +	crc->n_words = 1;
> > > +	crc->crc[0] = hash;
> > > +
> > > +	free(line);
> > > +	munmap(map, fb->size);
> > > +
> > > +	return 0;
> > > +#undef FNV1a_OFFSET_BIAS
> > > +#undef FNV1a_PRIME
> > > +}
> > > +
> > >  /**
> > >   * igt_format_is_yuv:
> > >   * @drm_format: drm fourcc
> > > diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> > > index adefebe1..a2741c05 100644
> > > --- a/lib/igt_fb.h
> > > +++ b/lib/igt_fb.h
> > > @@ -37,6 +37,7 @@
> > >  #include <i915_drm.h>
> > >  
> > >  #include "igt_color_encoding.h"
> > > +#include "igt_debugfs.h"
> > >  
> > >  /*
> > >   * Internal format to denote a buffer compatible with pixman's
> > > @@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
> > >  void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
> > >  			   bool allow_yuv);
> > >  
> > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
> > > +
> > >  #endif /* __IGT_FB_H__ */
> > >  
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-07-12  2:44       ` Rodrigo Siqueira
@ 2019-07-12 11:40         ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-12 11:40 UTC (permalink / raw)
  To: rodrigosiqueiramelo; +Cc: intel-gfx, igt-dev, nd

On Thu, 2019-07-11 at 23:44 -0300, Rodrigo Siqueira wrote:
> On 07/10, Ser, Simon wrote:
> > Hi,
> > 
> > Thanks for the patch! Here are a few comments.
> > 
> > For bonus points, it would be nice to add igt_describe descriptions of
> > each sub-test.
> 
> Hi Simon,
> 
> First of all, thanks for your feedback; I already applied most of your
> suggestions. I just have some inline comments/questions.
>  
> > On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> > > Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> > > WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> > > behaviour is correct.
> > > 
> > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > [rebased and updated do_writeback_test() function to address feedback]
> > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > ---
> > >  tests/Makefile.sources |   1 +
> > >  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
> > >  tests/meson.build      |   1 +
> > >  3 files changed, 316 insertions(+)
> > >  create mode 100644 tests/kms_writeback.c
> > > 
> > > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > > index 027ed82f..03cc8efa 100644
> > > --- a/tests/Makefile.sources
> > > +++ b/tests/Makefile.sources
> > > @@ -77,6 +77,7 @@ TESTS_progs = \
> > >  	kms_universal_plane \
> > >  	kms_vblank \
> > >  	kms_vrr \
> > > +	kms_writeback \
> > >  	meta_test \
> > >  	perf \
> > >  	perf_pmu \
> > > diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> > > new file mode 100644
> > > index 00000000..66ef48a6
> > > --- /dev/null
> > > +++ b/tests/kms_writeback.c
> > > @@ -0,0 +1,314 @@
> > > +/*
> > > + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> > > + *
> > > + * Permission is hereby granted, free of charge, to any person obtaining a
> > > + * copy of this software and associated documentation files (the "Software"),
> > > + * to deal in the Software without restriction, including without limitation
> > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > > + * and/or sell copies of the Software, and to permit persons to whom the
> > > + * Software is furnished to do so, subject to the following conditions:
> > > + *
> > > + * The above copyright notice and this permission notice (including the next
> > > + * paragraph) shall be included in all copies or substantial portions of the
> > > + * Software.
> > > + *
> > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > > + * IN THE SOFTWARE.
> > > + *
> > > + */
> > > +
> > > +#include <errno.h>
> > > +#include <stdbool.h>
> > > +#include <stdio.h>
> > > +#include <string.h>
> > > +
> > > +#include "igt.h"
> > > +#include "igt_core.h"
> > > +#include "igt_fb.h"
> > > +
> > > +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> > > +{
> > > +	drmModePropertyBlobRes *blob = NULL;
> > > +	uint64_t blob_id;
> > > +	int ret;
> > > +
> > > +	ret = kmstest_get_property(output->display->drm_fd,
> > > +				   output->config.connector->connector_id,
> > > +				   DRM_MODE_OBJECT_CONNECTOR,
> > > +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> > > +				   NULL, &blob_id, NULL);
> > > +	if (ret)
> > > +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> > > +
> > > +	igt_assert(blob);
> > > +
> > > +	return blob;
> > > +}
> > > +
> > > +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> > > +{
> > > +	igt_fb_t input_fb, output_fb;
> > > +	igt_plane_t *plane;
> > > +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> > > +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> > > +	int width, height, ret;
> > > +	drmModeModeInfo override_mode = {
> > > +		.clock = 25175,
> > > +		.hdisplay = 640,
> > > +		.hsync_start = 656,
> > > +		.hsync_end = 752,
> > > +		.htotal = 800,
> > > +		.hskew = 0,
> > > +		.vdisplay = 480,
> > > +		.vsync_start = 490,
> > > +		.vsync_end = 492,
> > > +		.vtotal = 525,
> > > +		.vscan = 0,
> > > +		.vrefresh = 60,
> > > +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> > > +		.name = {"640x480-60"},
> > > +	};
> > > +	igt_output_override_mode(output, &override_mode);
> > > +
> > > +	width = override_mode.hdisplay;
> > > +	height = override_mode.vdisplay;
> > > +
> > > +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> > > +	igt_assert(ret >= 0);
> > > +
> > > +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> > > +	igt_assert(ret >= 0);
> > > +
> > > +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > +	igt_plane_set_fb(plane, &input_fb);
> > > +	igt_output_set_writeback_fb(output, &output_fb);
> > > +
> > > +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> > > +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> > 
> > Okay, we're using atomic test-only mode to know if we can perform tests
> > with the writeback output. It's probably fine, but we don't use
> > WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.
> 
> Sorry, I did not fully understand part. Did you expect to see something
> like the below code before igt_display_try_commit_atomic()?
> 
>  igt_output_set_prop_value(output, WRITEBACK_PIXEL_FORMATS,
>                            DRM_FORMAT_XRGB8888);

Hmm, no, we cannot change the list of writeback formats (it's
immutable).

This comment doesn't require any action, it's just me thinking aloud :P

I'm just thinking that it would be nice to choose our format depending
on the WRITEBACK_PIXEL_FORMATS property. And probably run tests with
each supported format (or, alternatively, choose a random one). That
way we can make sure WRITEBACK_PIXEL_FORMATS isn't broken.

However, this can be left for a later patch.

> > > +	igt_plane_set_fb(plane, NULL);
> > > +	igt_remove_fb(display->drm_fd, &input_fb);
> > > +	igt_remove_fb(display->drm_fd, &output_fb);
> > > +
> > > +	return !ret;
> > > +}
> > > +
> > > +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> > > +{
> > > +	int i;
> > > +
> > > +	for (i = 0; i < display->n_outputs; i++) {
> > > +		igt_output_t *output = &display->outputs[i];
> > > +		int j;
> > > +
> > > +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> > > +			continue;
> > > +
> > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
> > 
> > Hmm. Is this really necessary? "Real" userspace won't do this, so I
> > don't think we need to either.
> 
> Hmmm, I have a little experience with userspace; however, I tested
> kms_writeback on top of vkms without this line, and everything worked
> well. If I remove this line, should I also drop the line that force
> connector to FORCE_CONNECTOR_UNSPECIFIED?

I believe so.

> Another question, if FORCE_CONNECTOR_ON is something that userspace
> won't want to do, why do we have it?

We use kmstest_force_connector in injection tests: those pick a
disconnected HDMI connector and trick the kernel into thinking it's
connected. We generally also force an EDID and this is used to emulate
a screen (e.g. a screen that supports audio, 4K or 3D).

This is only meant to be used for testing though, hence "real userspace
shouldn't use it".

> > > +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> > > +			igt_output_set_pipe(output, j);
> > > +
> > > +			if (check_writeback_config(display, output)) {
> > > +				igt_debug("Using connector %u:%s on pipe %d\n",
> > > +					  output->config.connector->connector_id,
> > > +					  output->name, j);
> > > +				return output;
> > > +			}
> > 
> > We could probably add an igt_debug statement in case we don't use this
> > writeback output.
> > 
> > > +		}
> > > +
> > > +		/* Restore any connectors we don't use, so we don't trip on them later */
> > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> > > +	}
> > > +
> > > +	return NULL;
> > > +}
> > > +
> > > +static void check_writeback_fb_id(igt_output_t *output)
> > > +{
> > > +	uint64_t check_fb_id;
> > > +
> > > +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > +	igt_assert(check_fb_id == 0);
> > > +}
> > > +
> > > +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> > > +			      uint32_t fb_id, int32_t *out_fence_ptr,
> > > +			      bool ptr_valid)
> > 
> > flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
> > probably remove the parameter from this function.
> > 
> > > +{
> > > +	int ret;
> > > +	igt_display_t *display = output->display;
> > > +	struct kmstest_connector_config *config = &output->config;
> > > +
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> > > +
> > > +	if (ptr_valid)
> > > +		*out_fence_ptr = 0;
> > > +
> > > +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> > > +
> > > +	if (ptr_valid)
> > > +		igt_assert(*out_fence_ptr == -1);
> > 
> > I'm confused. Why should this be -1 even if we
> > igt_display_try_commit_atomic succeeds?
> 
> I inspected the drm_mode_atomic_ioctl() function and I noticed that It
> calls complete_signaling() in its turn this function assign -1 to
> out_fence_ptr. Since all of this happens at the end of atomic_commit, I
> believe that we don’t need it. I already removed it.

I think I'm still confused :)

I'm probably missing something. As far as I understand, we are doing an
atomic commit, sometimes with a valid WRITEBACK_FB_ID and
WRITEBACK_OUT_FENCE_PTR. In this case it should start the writeback
process in the kernel and we should get a valid out_fence_ptr?

Why do we always get -1?

> > > +	/* WRITEBACK_FB_ID must always read as zero */
> > > +	check_writeback_fb_id(output);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > +{
> > > +	int i, ret;
> > > +	int32_t out_fence;
> > > +	struct {
> > > +		uint32_t fb_id;
> > > +		bool ptr_valid;
> > > +		int32_t *out_fence_ptr;
> > > +	} invalid_tests[] = {
> > > +		{
> > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > +			.fb_id = 0,
> > > +			.ptr_valid = true,
> > > +			.out_fence_ptr = &out_fence,
> > > +		},
> > > +		{
> > > +			/* Invalid output buffer. */
> > > +			.fb_id = invalid_fb->fb_id,
> > > +			.ptr_valid = true,
> > > +			.out_fence_ptr = &out_fence,
> > > +		},
> > 
> > This doesn't belong in this function (invalid_out_fence), since this
> > checks an invalid framebuffer, not an invalid fence. We should probably
> > move it to writeback_fb_id (and rename that function to test_fb?).
> > 
> > > +		{
> > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > +			.fb_id = valid_fb->fb_id,
> > > +			.ptr_valid = false,
> > > +			.out_fence_ptr = (int32_t *)0x8,
> > > +		},
> > > +	};
> > > +
> > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +					invalid_tests[i].fb_id,
> > > +					invalid_tests[i].out_fence_ptr,
> > > +					invalid_tests[i].ptr_valid);
> > > +		igt_assert(ret != 0);
> > 
> > Maybe we can check for -ret == EINVAL?
> > 
> > > +	}
> > > +}
> > > +
> > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > 
> > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > the input framebuffer. It's probably not a good idea to use the same FB
> > for input and writeback output.
> > 
> > > +{
> > > +
> > > +	int ret;
> > > +
> > > +	/* Valid output buffer */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				valid_fb->fb_id, NULL, false);
> > > +	igt_assert(ret == 0);
> > > +
> > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				output->id, NULL, false);
> > > +	igt_assert(ret == -EINVAL);
> > > +
> > > +	/* Zero WRITEBACK_FB_ID */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				0, NULL, false);
> > > +	igt_assert(ret == 0);
> > > +}
> > > +
> > > +igt_main
> > > +{
> > > +	igt_display_t display;
> > > +	igt_output_t *output;
> > > +	igt_plane_t *plane;
> > > +	igt_fb_t input_fb;
> > > +	drmModeModeInfo mode;
> > > +	int ret;
> > > +
> > > +	memset(&display, 0, sizeof(display));
> > > +
> > > +	igt_fixture {
> > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > +		igt_display_require(&display, display.drm_fd);
> > > +
> > > +		kmstest_set_vt_graphics_mode();
> > > +
> > > +		igt_display_require(&display, display.drm_fd);
> > > +
> > > +		igt_require(display.is_atomic);
> > > +
> > > +		output = kms_writeback_get_output(&display);
> > > +		igt_require(output);
> > > +
> > > +		if (output->use_override_mode)
> > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > +		else
> > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > +
> > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > +		igt_require(plane);
> > 
> > Maybe we can assert on this?
> > 
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > +				    mode.vdisplay,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > 
> > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > better to make this clear.
> > 
> > (Applies to other lines of this patch)
> > 
> > > +				    &input_fb);
> > > +		igt_assert(ret >= 0);
> > > +		igt_plane_set_fb(plane, &input_fb);
> > > +	}
> > > +
> > > +	igt_subtest("writeback-pixel-formats") {
> > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > 
> > Need to drmModeFreePropertyBlob this.
> > 
> > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > +		unsigned int i;
> > > +		char *c;
> > > +
> > > +		/*
> > > +		 * We don't have a comprehensive list of formats, so just check
> > > +		 * that the blob length is sensible and that it doesn't contain
> > > +		 * any outlandish characters
> > > +		 */
> > > +		igt_assert(!(formats_blob->length % 4));
> > > +		c = formats_blob->data;
> > > +		for (i = 0; i < formats_blob->length; i++)
> > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > +				     "Unexpected character %c\n", c[i]);
> > 
> > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > codes will be made from ASCII characters, in fact some formats already
> > have non-printable chars in them. I don't want to have to update this
> > test when a new fourcc format is added.
> > 
> > We currently don't have a test for IN_FORMATS. If we really want to
> > check formats, we could have a big array of known formats and add a
> > bool is_valid_format(uint32_t fmt) function.
> 
> Agree with you. How about remove this test?

I guess we could always keep the length % 4 test, even if it's just a
sanity test. At least this one won't ever need to be changed.

I don't feel strongly about it.

> Thanks
> Best Regards
> 
> > > +	}
> > > +
> > > +	igt_subtest("writeback-invalid-out-fence") {
> > > +		igt_fb_t invalid_fb;
> > 
> > invalid_output_fb would be a better name IMHO.
> > 
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> > > +				    mode.vdisplay / 2,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > > +				    &invalid_fb);
> > > +		igt_require(ret > 0);
> > 
> > We should probably use a different variable: ret is signed,
> > igt_create_fb isn't. Also ret doesn't make it clear that the return
> > value is the KMS framebuffer ID.
> > 
> > (Applies to other subtests)
> > 
> > > +		invalid_out_fence(output, &input_fb, &invalid_fb);
> > 
> > (Still not sure why we provide the input FB to this function.)
> > 
> > > +		igt_remove_fb(display.drm_fd, &invalid_fb);
> > > +	}
> > > +
> > > +	igt_subtest("writeback-fb-id") {
> > > +		igt_fb_t output_fb;
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > > +				    &output_fb);
> > > +		igt_require(ret > 0);
> > > +
> > > +		writeback_fb_id(output, &input_fb, &output_fb);
> > > +
> > > +		igt_remove_fb(display.drm_fd, &output_fb);
> > > +	}
> > > +
> > > +	igt_fixture {
> > > +		igt_remove_fb(display.drm_fd, &input_fb);
> > > +		igt_display_fini(&display);
> > > +	}
> > > +}
> > > diff --git a/tests/meson.build b/tests/meson.build
> > > index f168fbba..9c77cfcd 100644
> > > --- a/tests/meson.build
> > > +++ b/tests/meson.build
> > > @@ -63,6 +63,7 @@ test_progs = [
> > >  	'kms_universal_plane',
> > >  	'kms_vblank',
> > >  	'kms_vrr',
> > > +	'kms_writeback',
> > >  	'meta_test',
> > >  	'panfrost_get_param',
> > >  	'panfrost_gem_new',
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-12 11:40         ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-12 11:40 UTC (permalink / raw)
  To: rodrigosiqueiramelo
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey

On Thu, 2019-07-11 at 23:44 -0300, Rodrigo Siqueira wrote:
> On 07/10, Ser, Simon wrote:
> > Hi,
> > 
> > Thanks for the patch! Here are a few comments.
> > 
> > For bonus points, it would be nice to add igt_describe descriptions of
> > each sub-test.
> 
> Hi Simon,
> 
> First of all, thanks for your feedback; I already applied most of your
> suggestions. I just have some inline comments/questions.
>  
> > On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> > > Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> > > WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> > > behaviour is correct.
> > > 
> > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > [rebased and updated do_writeback_test() function to address feedback]
> > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > ---
> > >  tests/Makefile.sources |   1 +
> > >  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
> > >  tests/meson.build      |   1 +
> > >  3 files changed, 316 insertions(+)
> > >  create mode 100644 tests/kms_writeback.c
> > > 
> > > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > > index 027ed82f..03cc8efa 100644
> > > --- a/tests/Makefile.sources
> > > +++ b/tests/Makefile.sources
> > > @@ -77,6 +77,7 @@ TESTS_progs = \
> > >  	kms_universal_plane \
> > >  	kms_vblank \
> > >  	kms_vrr \
> > > +	kms_writeback \
> > >  	meta_test \
> > >  	perf \
> > >  	perf_pmu \
> > > diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> > > new file mode 100644
> > > index 00000000..66ef48a6
> > > --- /dev/null
> > > +++ b/tests/kms_writeback.c
> > > @@ -0,0 +1,314 @@
> > > +/*
> > > + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> > > + *
> > > + * Permission is hereby granted, free of charge, to any person obtaining a
> > > + * copy of this software and associated documentation files (the "Software"),
> > > + * to deal in the Software without restriction, including without limitation
> > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > > + * and/or sell copies of the Software, and to permit persons to whom the
> > > + * Software is furnished to do so, subject to the following conditions:
> > > + *
> > > + * The above copyright notice and this permission notice (including the next
> > > + * paragraph) shall be included in all copies or substantial portions of the
> > > + * Software.
> > > + *
> > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > > + * IN THE SOFTWARE.
> > > + *
> > > + */
> > > +
> > > +#include <errno.h>
> > > +#include <stdbool.h>
> > > +#include <stdio.h>
> > > +#include <string.h>
> > > +
> > > +#include "igt.h"
> > > +#include "igt_core.h"
> > > +#include "igt_fb.h"
> > > +
> > > +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> > > +{
> > > +	drmModePropertyBlobRes *blob = NULL;
> > > +	uint64_t blob_id;
> > > +	int ret;
> > > +
> > > +	ret = kmstest_get_property(output->display->drm_fd,
> > > +				   output->config.connector->connector_id,
> > > +				   DRM_MODE_OBJECT_CONNECTOR,
> > > +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> > > +				   NULL, &blob_id, NULL);
> > > +	if (ret)
> > > +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> > > +
> > > +	igt_assert(blob);
> > > +
> > > +	return blob;
> > > +}
> > > +
> > > +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> > > +{
> > > +	igt_fb_t input_fb, output_fb;
> > > +	igt_plane_t *plane;
> > > +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> > > +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> > > +	int width, height, ret;
> > > +	drmModeModeInfo override_mode = {
> > > +		.clock = 25175,
> > > +		.hdisplay = 640,
> > > +		.hsync_start = 656,
> > > +		.hsync_end = 752,
> > > +		.htotal = 800,
> > > +		.hskew = 0,
> > > +		.vdisplay = 480,
> > > +		.vsync_start = 490,
> > > +		.vsync_end = 492,
> > > +		.vtotal = 525,
> > > +		.vscan = 0,
> > > +		.vrefresh = 60,
> > > +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> > > +		.name = {"640x480-60"},
> > > +	};
> > > +	igt_output_override_mode(output, &override_mode);
> > > +
> > > +	width = override_mode.hdisplay;
> > > +	height = override_mode.vdisplay;
> > > +
> > > +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> > > +	igt_assert(ret >= 0);
> > > +
> > > +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> > > +	igt_assert(ret >= 0);
> > > +
> > > +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > +	igt_plane_set_fb(plane, &input_fb);
> > > +	igt_output_set_writeback_fb(output, &output_fb);
> > > +
> > > +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> > > +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> > 
> > Okay, we're using atomic test-only mode to know if we can perform tests
> > with the writeback output. It's probably fine, but we don't use
> > WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.
> 
> Sorry, I did not fully understand part. Did you expect to see something
> like the below code before igt_display_try_commit_atomic()?
> 
>  igt_output_set_prop_value(output, WRITEBACK_PIXEL_FORMATS,
>                            DRM_FORMAT_XRGB8888);

Hmm, no, we cannot change the list of writeback formats (it's
immutable).

This comment doesn't require any action, it's just me thinking aloud :P

I'm just thinking that it would be nice to choose our format depending
on the WRITEBACK_PIXEL_FORMATS property. And probably run tests with
each supported format (or, alternatively, choose a random one). That
way we can make sure WRITEBACK_PIXEL_FORMATS isn't broken.

However, this can be left for a later patch.

> > > +	igt_plane_set_fb(plane, NULL);
> > > +	igt_remove_fb(display->drm_fd, &input_fb);
> > > +	igt_remove_fb(display->drm_fd, &output_fb);
> > > +
> > > +	return !ret;
> > > +}
> > > +
> > > +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> > > +{
> > > +	int i;
> > > +
> > > +	for (i = 0; i < display->n_outputs; i++) {
> > > +		igt_output_t *output = &display->outputs[i];
> > > +		int j;
> > > +
> > > +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> > > +			continue;
> > > +
> > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
> > 
> > Hmm. Is this really necessary? "Real" userspace won't do this, so I
> > don't think we need to either.
> 
> Hmmm, I have a little experience with userspace; however, I tested
> kms_writeback on top of vkms without this line, and everything worked
> well. If I remove this line, should I also drop the line that force
> connector to FORCE_CONNECTOR_UNSPECIFIED?

I believe so.

> Another question, if FORCE_CONNECTOR_ON is something that userspace
> won't want to do, why do we have it?

We use kmstest_force_connector in injection tests: those pick a
disconnected HDMI connector and trick the kernel into thinking it's
connected. We generally also force an EDID and this is used to emulate
a screen (e.g. a screen that supports audio, 4K or 3D).

This is only meant to be used for testing though, hence "real userspace
shouldn't use it".

> > > +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> > > +			igt_output_set_pipe(output, j);
> > > +
> > > +			if (check_writeback_config(display, output)) {
> > > +				igt_debug("Using connector %u:%s on pipe %d\n",
> > > +					  output->config.connector->connector_id,
> > > +					  output->name, j);
> > > +				return output;
> > > +			}
> > 
> > We could probably add an igt_debug statement in case we don't use this
> > writeback output.
> > 
> > > +		}
> > > +
> > > +		/* Restore any connectors we don't use, so we don't trip on them later */
> > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> > > +	}
> > > +
> > > +	return NULL;
> > > +}
> > > +
> > > +static void check_writeback_fb_id(igt_output_t *output)
> > > +{
> > > +	uint64_t check_fb_id;
> > > +
> > > +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > +	igt_assert(check_fb_id == 0);
> > > +}
> > > +
> > > +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> > > +			      uint32_t fb_id, int32_t *out_fence_ptr,
> > > +			      bool ptr_valid)
> > 
> > flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
> > probably remove the parameter from this function.
> > 
> > > +{
> > > +	int ret;
> > > +	igt_display_t *display = output->display;
> > > +	struct kmstest_connector_config *config = &output->config;
> > > +
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> > > +
> > > +	if (ptr_valid)
> > > +		*out_fence_ptr = 0;
> > > +
> > > +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> > > +
> > > +	if (ptr_valid)
> > > +		igt_assert(*out_fence_ptr == -1);
> > 
> > I'm confused. Why should this be -1 even if we
> > igt_display_try_commit_atomic succeeds?
> 
> I inspected the drm_mode_atomic_ioctl() function and I noticed that It
> calls complete_signaling() in its turn this function assign -1 to
> out_fence_ptr. Since all of this happens at the end of atomic_commit, I
> believe that we don’t need it. I already removed it.

I think I'm still confused :)

I'm probably missing something. As far as I understand, we are doing an
atomic commit, sometimes with a valid WRITEBACK_FB_ID and
WRITEBACK_OUT_FENCE_PTR. In this case it should start the writeback
process in the kernel and we should get a valid out_fence_ptr?

Why do we always get -1?

> > > +	/* WRITEBACK_FB_ID must always read as zero */
> > > +	check_writeback_fb_id(output);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > +{
> > > +	int i, ret;
> > > +	int32_t out_fence;
> > > +	struct {
> > > +		uint32_t fb_id;
> > > +		bool ptr_valid;
> > > +		int32_t *out_fence_ptr;
> > > +	} invalid_tests[] = {
> > > +		{
> > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > +			.fb_id = 0,
> > > +			.ptr_valid = true,
> > > +			.out_fence_ptr = &out_fence,
> > > +		},
> > > +		{
> > > +			/* Invalid output buffer. */
> > > +			.fb_id = invalid_fb->fb_id,
> > > +			.ptr_valid = true,
> > > +			.out_fence_ptr = &out_fence,
> > > +		},
> > 
> > This doesn't belong in this function (invalid_out_fence), since this
> > checks an invalid framebuffer, not an invalid fence. We should probably
> > move it to writeback_fb_id (and rename that function to test_fb?).
> > 
> > > +		{
> > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > +			.fb_id = valid_fb->fb_id,
> > > +			.ptr_valid = false,
> > > +			.out_fence_ptr = (int32_t *)0x8,
> > > +		},
> > > +	};
> > > +
> > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +					invalid_tests[i].fb_id,
> > > +					invalid_tests[i].out_fence_ptr,
> > > +					invalid_tests[i].ptr_valid);
> > > +		igt_assert(ret != 0);
> > 
> > Maybe we can check for -ret == EINVAL?
> > 
> > > +	}
> > > +}
> > > +
> > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > 
> > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > the input framebuffer. It's probably not a good idea to use the same FB
> > for input and writeback output.
> > 
> > > +{
> > > +
> > > +	int ret;
> > > +
> > > +	/* Valid output buffer */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				valid_fb->fb_id, NULL, false);
> > > +	igt_assert(ret == 0);
> > > +
> > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				output->id, NULL, false);
> > > +	igt_assert(ret == -EINVAL);
> > > +
> > > +	/* Zero WRITEBACK_FB_ID */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				0, NULL, false);
> > > +	igt_assert(ret == 0);
> > > +}
> > > +
> > > +igt_main
> > > +{
> > > +	igt_display_t display;
> > > +	igt_output_t *output;
> > > +	igt_plane_t *plane;
> > > +	igt_fb_t input_fb;
> > > +	drmModeModeInfo mode;
> > > +	int ret;
> > > +
> > > +	memset(&display, 0, sizeof(display));
> > > +
> > > +	igt_fixture {
> > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > +		igt_display_require(&display, display.drm_fd);
> > > +
> > > +		kmstest_set_vt_graphics_mode();
> > > +
> > > +		igt_display_require(&display, display.drm_fd);
> > > +
> > > +		igt_require(display.is_atomic);
> > > +
> > > +		output = kms_writeback_get_output(&display);
> > > +		igt_require(output);
> > > +
> > > +		if (output->use_override_mode)
> > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > +		else
> > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > +
> > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > +		igt_require(plane);
> > 
> > Maybe we can assert on this?
> > 
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > +				    mode.vdisplay,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > 
> > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > better to make this clear.
> > 
> > (Applies to other lines of this patch)
> > 
> > > +				    &input_fb);
> > > +		igt_assert(ret >= 0);
> > > +		igt_plane_set_fb(plane, &input_fb);
> > > +	}
> > > +
> > > +	igt_subtest("writeback-pixel-formats") {
> > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > 
> > Need to drmModeFreePropertyBlob this.
> > 
> > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > +		unsigned int i;
> > > +		char *c;
> > > +
> > > +		/*
> > > +		 * We don't have a comprehensive list of formats, so just check
> > > +		 * that the blob length is sensible and that it doesn't contain
> > > +		 * any outlandish characters
> > > +		 */
> > > +		igt_assert(!(formats_blob->length % 4));
> > > +		c = formats_blob->data;
> > > +		for (i = 0; i < formats_blob->length; i++)
> > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > +				     "Unexpected character %c\n", c[i]);
> > 
> > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > codes will be made from ASCII characters, in fact some formats already
> > have non-printable chars in them. I don't want to have to update this
> > test when a new fourcc format is added.
> > 
> > We currently don't have a test for IN_FORMATS. If we really want to
> > check formats, we could have a big array of known formats and add a
> > bool is_valid_format(uint32_t fmt) function.
> 
> Agree with you. How about remove this test?

I guess we could always keep the length % 4 test, even if it's just a
sanity test. At least this one won't ever need to be changed.

I don't feel strongly about it.

> Thanks
> Best Regards
> 
> > > +	}
> > > +
> > > +	igt_subtest("writeback-invalid-out-fence") {
> > > +		igt_fb_t invalid_fb;
> > 
> > invalid_output_fb would be a better name IMHO.
> > 
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> > > +				    mode.vdisplay / 2,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > > +				    &invalid_fb);
> > > +		igt_require(ret > 0);
> > 
> > We should probably use a different variable: ret is signed,
> > igt_create_fb isn't. Also ret doesn't make it clear that the return
> > value is the KMS framebuffer ID.
> > 
> > (Applies to other subtests)
> > 
> > > +		invalid_out_fence(output, &input_fb, &invalid_fb);
> > 
> > (Still not sure why we provide the input FB to this function.)
> > 
> > > +		igt_remove_fb(display.drm_fd, &invalid_fb);
> > > +	}
> > > +
> > > +	igt_subtest("writeback-fb-id") {
> > > +		igt_fb_t output_fb;
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > > +				    &output_fb);
> > > +		igt_require(ret > 0);
> > > +
> > > +		writeback_fb_id(output, &input_fb, &output_fb);
> > > +
> > > +		igt_remove_fb(display.drm_fd, &output_fb);
> > > +	}
> > > +
> > > +	igt_fixture {
> > > +		igt_remove_fb(display.drm_fd, &input_fb);
> > > +		igt_display_fini(&display);
> > > +	}
> > > +}
> > > diff --git a/tests/meson.build b/tests/meson.build
> > > index f168fbba..9c77cfcd 100644
> > > --- a/tests/meson.build
> > > +++ b/tests/meson.build
> > > @@ -63,6 +63,7 @@ test_progs = [
> > >  	'kms_universal_plane',
> > >  	'kms_vblank',
> > >  	'kms_vrr',
> > > +	'kms_writeback',
> > >  	'meta_test',
> > >  	'panfrost_get_param',
> > >  	'panfrost_gem_new',
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
  2019-07-12  2:49         ` Rodrigo Siqueira
@ 2019-07-12 12:17           ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-12 12:17 UTC (permalink / raw)
  To: rodrigosiqueiramelo; +Cc: intel-gfx, igt-dev, nd

On Thu, 2019-07-11 at 23:49 -0300, Rodrigo Siqueira wrote:
> On 07/10, Ser, Simon wrote:
> > On Wed, 2019-07-10 at 15:30 +0000, Ser, Simon wrote:
> > > Mostly LGTM, here are a few nits.
> > > 
> > > On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> > > > To use writeback buffers as a CRC source, we need to be able to hash
> > > > them. Implement a simple FVA-1a hashing routine for this purpose.
> > > > 
> > > > Doing a bytewise hash on the framebuffer directly can be very slow if
> > > > the memory is noncached. By making a copy of each line in the FB first
> > > > (which can take advantage of word-access speedup), we can do the hash
> > > > on a cached copy, which is much faster (10x speedup on my platform).
> > > > 
> > > > v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
> > > >     Chris Wilson
> > > > 
> > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > [rebased and updated to the most recent API]
> > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > ---
> > > >  lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > > >  lib/igt_fb.h |  3 +++
> > > >  2 files changed, 69 insertions(+)
> > > > 
> > > > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > > > index 9d4f905e..d07dae39 100644
> > > > --- a/lib/igt_fb.c
> > > > +++ b/lib/igt_fb.c
> > > > @@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
> > > >  	return false;
> > > >  }
> > > >  
> > > > +/*
> > > > + * This implements the FNV-1a hashing algorithm instead of CRC, for
> > > > + * simplicity
> > > > + * http://www.isthe.com/chongo/tech/comp/fnv/index.html
> > > > + *
> > > > + * hash = offset_basis
> > > > + * for each octet_of_data to be hashed
> > > > + *         hash = hash xor octet_of_data
> > > > + *         hash = hash * FNV_prime
> > > > + * return hash
> > > > + *
> > > > + * 32 bit offset_basis = 2166136261
> > > > + * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
> > > > + */
> > > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
> > > > +{
> > > > +#define FNV1a_OFFSET_BIAS 2166136261
> > > > +#define FNV1a_PRIME 16777619
> > > 
> > > I'd just use plain uint32_t variables for those, but no big deal.
> > > 
> > > > +	uint32_t hash;
> > > > +	void *map;
> > > > +	char *ptr, *line = NULL;
> > > > +	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
> > > > +	uint32_t stride = calc_plane_stride(fb, 0);
> > > 
> > > We could return -EINVAL in case fb->num_planes != 1.
> > 
> > Let's not waste cycles. With this ^ fixed, this patch is:
> > 
> > Reviewed-by: Simon Ser <simon.ser@intel.com>
> > 
> > Other nits are optional.
> 
> I agreed with all your suggestions, and I already applied all of them.
> Should I wait for the other patches review, or should I resend the new
> version?

I'm fine with waiting for the full review before a new version of the
whole patchset, but you can also send an updated version of a single
patch with:

    git send-email --in-reply-to="<cover.1560374714.git.rodrigosiqueiramelo@gmail.com>" -1 <commit hash>

where In-Reply-To is the Message-Id of the patch you want to update. I
agree it's a little tedious since you need to extract the Message-Id
from the message header.

> Thanks for all the feedback

:)

> Best Regards
>  
> > > > +	if (fb->is_dumb)
> > > > +		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
> > > > +					      PROT_READ);
> > > > +	else
> > > > +		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
> > > > +				    PROT_READ);
> > > > +	ptr = map;
> > > 
> > > Nit: no need for this, can assign the result of mmap directly to ptr.
> > > 
> > > > +
> > > > +	/*
> > > > +	 * Framebuffers are often uncached, which can make byte-wise accesses
> > > > +	 * very slow. We copy each line of the FB into a local buffer to speed
> > > > +	 * up the hashing.
> > > > +	 */
> > > > +	line = malloc(stride);
> > > > +	if (!line) {
> > > > +		munmap(map, fb->size);
> > > > +		return -ENOMEM;
> > > > +	}
> > > > +
> > > > +	hash = FNV1a_OFFSET_BIAS;
> > > > +
> > > > +	for (y = 0; y < fb->height; y++, ptr += stride) {
> > > > +
> > > > +		igt_memcpy_from_wc(line, ptr, stride);
> > > 
> > > Nit: no need to copy the whole stride actually, we can just copy
> > > fb->width * cpp since we're only going to read that.
> > > 
> > > > +
> > > > +		for (x = 0; x < fb->width * cpp; x++) {
> > > > +			hash ^= line[x];
> > > > +			hash *= FNV1a_PRIME;
> > > > +		}
> > > > +	}
> > > > +
> > > > +	crc->n_words = 1;
> > > > +	crc->crc[0] = hash;
> > > > +
> > > > +	free(line);
> > > > +	munmap(map, fb->size);
> > > > +
> > > > +	return 0;
> > > > +#undef FNV1a_OFFSET_BIAS
> > > > +#undef FNV1a_PRIME
> > > > +}
> > > > +
> > > >  /**
> > > >   * igt_format_is_yuv:
> > > >   * @drm_format: drm fourcc
> > > > diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> > > > index adefebe1..a2741c05 100644
> > > > --- a/lib/igt_fb.h
> > > > +++ b/lib/igt_fb.h
> > > > @@ -37,6 +37,7 @@
> > > >  #include <i915_drm.h>
> > > >  
> > > >  #include "igt_color_encoding.h"
> > > > +#include "igt_debugfs.h"
> > > >  
> > > >  /*
> > > >   * Internal format to denote a buffer compatible with pixman's
> > > > @@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
> > > >  void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
> > > >  			   bool allow_yuv);
> > > >  
> > > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
> > > > +
> > > >  #endif /* __IGT_FB_H__ */
> > > >  
> > > > _______________________________________________
> > > > igt-dev mailing list
> > > > igt-dev@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
@ 2019-07-12 12:17           ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-12 12:17 UTC (permalink / raw)
  To: rodrigosiqueiramelo
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey

On Thu, 2019-07-11 at 23:49 -0300, Rodrigo Siqueira wrote:
> On 07/10, Ser, Simon wrote:
> > On Wed, 2019-07-10 at 15:30 +0000, Ser, Simon wrote:
> > > Mostly LGTM, here are a few nits.
> > > 
> > > On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> > > > To use writeback buffers as a CRC source, we need to be able to hash
> > > > them. Implement a simple FVA-1a hashing routine for this purpose.
> > > > 
> > > > Doing a bytewise hash on the framebuffer directly can be very slow if
> > > > the memory is noncached. By making a copy of each line in the FB first
> > > > (which can take advantage of word-access speedup), we can do the hash
> > > > on a cached copy, which is much faster (10x speedup on my platform).
> > > > 
> > > > v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
> > > >     Chris Wilson
> > > > 
> > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > [rebased and updated to the most recent API]
> > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > ---
> > > >  lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > > >  lib/igt_fb.h |  3 +++
> > > >  2 files changed, 69 insertions(+)
> > > > 
> > > > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > > > index 9d4f905e..d07dae39 100644
> > > > --- a/lib/igt_fb.c
> > > > +++ b/lib/igt_fb.c
> > > > @@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
> > > >  	return false;
> > > >  }
> > > >  
> > > > +/*
> > > > + * This implements the FNV-1a hashing algorithm instead of CRC, for
> > > > + * simplicity
> > > > + * http://www.isthe.com/chongo/tech/comp/fnv/index.html
> > > > + *
> > > > + * hash = offset_basis
> > > > + * for each octet_of_data to be hashed
> > > > + *         hash = hash xor octet_of_data
> > > > + *         hash = hash * FNV_prime
> > > > + * return hash
> > > > + *
> > > > + * 32 bit offset_basis = 2166136261
> > > > + * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
> > > > + */
> > > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
> > > > +{
> > > > +#define FNV1a_OFFSET_BIAS 2166136261
> > > > +#define FNV1a_PRIME 16777619
> > > 
> > > I'd just use plain uint32_t variables for those, but no big deal.
> > > 
> > > > +	uint32_t hash;
> > > > +	void *map;
> > > > +	char *ptr, *line = NULL;
> > > > +	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
> > > > +	uint32_t stride = calc_plane_stride(fb, 0);
> > > 
> > > We could return -EINVAL in case fb->num_planes != 1.
> > 
> > Let's not waste cycles. With this ^ fixed, this patch is:
> > 
> > Reviewed-by: Simon Ser <simon.ser@intel.com>
> > 
> > Other nits are optional.
> 
> I agreed with all your suggestions, and I already applied all of them.
> Should I wait for the other patches review, or should I resend the new
> version?

I'm fine with waiting for the full review before a new version of the
whole patchset, but you can also send an updated version of a single
patch with:

    git send-email --in-reply-to="<cover.1560374714.git.rodrigosiqueiramelo@gmail.com>" -1 <commit hash>

where In-Reply-To is the Message-Id of the patch you want to update. I
agree it's a little tedious since you need to extract the Message-Id
from the message header.

> Thanks for all the feedback

:)

> Best Regards
>  
> > > > +	if (fb->is_dumb)
> > > > +		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
> > > > +					      PROT_READ);
> > > > +	else
> > > > +		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
> > > > +				    PROT_READ);
> > > > +	ptr = map;
> > > 
> > > Nit: no need for this, can assign the result of mmap directly to ptr.
> > > 
> > > > +
> > > > +	/*
> > > > +	 * Framebuffers are often uncached, which can make byte-wise accesses
> > > > +	 * very slow. We copy each line of the FB into a local buffer to speed
> > > > +	 * up the hashing.
> > > > +	 */
> > > > +	line = malloc(stride);
> > > > +	if (!line) {
> > > > +		munmap(map, fb->size);
> > > > +		return -ENOMEM;
> > > > +	}
> > > > +
> > > > +	hash = FNV1a_OFFSET_BIAS;
> > > > +
> > > > +	for (y = 0; y < fb->height; y++, ptr += stride) {
> > > > +
> > > > +		igt_memcpy_from_wc(line, ptr, stride);
> > > 
> > > Nit: no need to copy the whole stride actually, we can just copy
> > > fb->width * cpp since we're only going to read that.
> > > 
> > > > +
> > > > +		for (x = 0; x < fb->width * cpp; x++) {
> > > > +			hash ^= line[x];
> > > > +			hash *= FNV1a_PRIME;
> > > > +		}
> > > > +	}
> > > > +
> > > > +	crc->n_words = 1;
> > > > +	crc->crc[0] = hash;
> > > > +
> > > > +	free(line);
> > > > +	munmap(map, fb->size);
> > > > +
> > > > +	return 0;
> > > > +#undef FNV1a_OFFSET_BIAS
> > > > +#undef FNV1a_PRIME
> > > > +}
> > > > +
> > > >  /**
> > > >   * igt_format_is_yuv:
> > > >   * @drm_format: drm fourcc
> > > > diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> > > > index adefebe1..a2741c05 100644
> > > > --- a/lib/igt_fb.h
> > > > +++ b/lib/igt_fb.h
> > > > @@ -37,6 +37,7 @@
> > > >  #include <i915_drm.h>
> > > >  
> > > >  #include "igt_color_encoding.h"
> > > > +#include "igt_debugfs.h"
> > > >  
> > > >  /*
> > > >   * Internal format to denote a buffer compatible with pixman's
> > > > @@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
> > > >  void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
> > > >  			   bool allow_yuv);
> > > >  
> > > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
> > > > +
> > > >  #endif /* __IGT_FB_H__ */
> > > >  
> > > > _______________________________________________
> > > > igt-dev mailing list
> > > > igt-dev@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 4/6] kms_writeback: Add writeback-check-output
  2019-06-13  2:17   ` [igt-dev] " Brian Starkey
@ 2019-07-12 12:34     ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-12 12:34 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

Mostly looks good, here are a few comments.

On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> Add a test which makes commits using the writeback connector, and
> checks the output buffer hash to make sure it is/isn't written as
> appropriate.
> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> ---
>  tests/kms_writeback.c | 124 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 124 insertions(+)
> 
> diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> index 66ef48a6..0f20dadd 100644
> --- a/tests/kms_writeback.c
> +++ b/tests/kms_writeback.c
> @@ -30,6 +30,7 @@
>  #include "igt.h"
>  #include "igt_core.h"
>  #include "igt_fb.h"
> +#include "sw_sync.h"
>  
>  static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
>  {
> @@ -221,6 +222,116 @@ static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *
>  	igt_assert(ret == 0);
>  }
>  
> +static void fill_fb(igt_fb_t *fb, double color[3])
> +{
> +	cairo_t *cr = igt_get_cairo_ctx(fb->fd, fb);
> +	igt_assert(cr);
> +
> +	igt_paint_color(cr, 0, 0, fb->width, fb->height,
> +			color[0], color[1], color[2]);
> +}
> +
> +static void get_and_wait_out_fence(igt_output_t *output)
> +{
> +	int ret;
> +
> +	igt_assert(output->writeback_out_fence_fd >= 0);
> +
> +	ret = sync_fence_wait(output->writeback_out_fence_fd, 1000);
> +	igt_assert(ret == 0);

When filtering failures in CI Bug Log, "ret == 0" is not very helpful
and may not be unique. Can we add a descriptive error message, with
something among the lines of:

    igt_assert_f(ret == 0, "sync_fence_wait failed: %s\n", strerror(-ret));

> +	close(output->writeback_out_fence_fd);
> +	output->writeback_out_fence_fd = -1;
> +}
> +
> +static void writeback_sequence(igt_output_t *output, igt_plane_t *plane,
> +				igt_fb_t *in_fb, igt_fb_t *out_fbs[], int n_commits)
> +{
> +	int i, color_idx = 0;
> +	double in_fb_colors[2][3] = {
> +		{ 1.0, 0.0, 0.0 },
> +		{ 0.0, 1.0, 0.0 },
> +	};
> +	double clear_color[3] = { 1.0, 1.0, 1.0 };
> +	igt_crc_t cleared_crc, out_expected;
> +
> +	for (i = 0; i < n_commits; i++, color_idx++) {
> +		/* Change the input color each time */
> +		fill_fb(in_fb, in_fb_colors[color_idx % 2]);

Why do we need two indexes (i and color_idx)? I think [i % 2] should
work just fine.

> +		if (out_fbs[i]) {
> +			igt_crc_t out_before;
> +
> +			/* Get the expected CRC */
> +			fill_fb(out_fbs[i], in_fb_colors[color_idx % 2]);
> +			igt_fb_get_crc(out_fbs[i], &out_expected);

Using out_fbs[i] to compute the expected CRC is a little bit confusing.
I think we can just use in_fb here (which is already filled with the
proper color).

> +			fill_fb(out_fbs[i], clear_color);
> +			if (i == 0)
> +				igt_fb_get_crc(out_fbs[i], &cleared_crc);
> +			igt_fb_get_crc(out_fbs[i], &out_before);
> +			igt_assert_crc_equal(&cleared_crc, &out_before);
> +		}
> +
> +		/* Commit */
> +		igt_plane_set_fb(plane, in_fb);
> +		igt_output_set_writeback_fb(output, out_fbs[i]);
> +
> +		igt_display_commit_atomic(output->display,
> +					  DRM_MODE_ATOMIC_ALLOW_MODESET,
> +					  NULL);
> +		if (out_fbs[i])
> +			get_and_wait_out_fence(output);
> +
> +		/* Make sure the old output buffer is untouched */
> +		if (i > 0 && out_fbs[i - 1] && (out_fbs[i] != out_fbs[i - 1])) {

Nit: unnecessary parentheses here

> +			igt_crc_t out_prev;
> +			igt_fb_get_crc(out_fbs[i - 1], &out_prev);
> +			igt_assert_crc_equal(&cleared_crc, &out_prev);
> +		}
> +
> +		/* Make sure this output buffer is written */
> +		if (out_fbs[i]) {
> +			igt_crc_t out_after;
> +			igt_fb_get_crc(out_fbs[i], &out_after);
> +			igt_assert_crc_equal(&out_expected, &out_after);
> +
> +			/* And clear it, for the next time */
> +			fill_fb(out_fbs[i], clear_color);
> +		}
> +	}
> +}
> +
> +static void writeback_check_output(igt_output_t *output, igt_plane_t *plane,
> +				   igt_fb_t *input_fb, igt_fb_t *output_fb)
> +{
> +	igt_fb_t *out_fbs[2] = { 0 };
> +	igt_fb_t second_out_fb;
> +	int ret;
> +
> +	/* One commit, with a writeback. */
> +	writeback_sequence(output, plane, input_fb, &output_fb, 1);
> +
> +	/* Two commits, the second with no writeback */
> +	out_fbs[0] = output_fb;
> +	writeback_sequence(output, plane, input_fb, out_fbs, 2);
> +
> +	/* Two commits, both with writeback */
> +	out_fbs[1] = output_fb;
> +	writeback_sequence(output, plane, input_fb, out_fbs, 2);
> +
> +	ret = igt_create_fb(output_fb->fd, output_fb->width, output_fb->height,
> +			    DRM_FORMAT_XRGB8888,
> +			    igt_fb_mod_to_tiling(0),
> +			    &second_out_fb);
> +	igt_require(ret > 0);

unsigned int cast to int here

> +	/* Two commits, with different writeback buffers */
> +	out_fbs[1] = &second_out_fb;
> +	writeback_sequence(output, plane, input_fb, out_fbs, 2);
> +
> +	igt_remove_fb(output_fb->fd, &second_out_fb);
> +}
> +
>  igt_main
>  {
>  	igt_display_t display;
> @@ -307,6 +418,19 @@ igt_main
>  		igt_remove_fb(display.drm_fd, &output_fb);
>  	}
>  
> +	igt_subtest("writeback-check-output") {
> +		igt_fb_t output_fb;
> +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> +				    DRM_FORMAT_XRGB8888,
> +				    igt_fb_mod_to_tiling(0),
> +				    &output_fb);
> +		igt_require(ret > 0);

unsigned int cast to int here

> +		writeback_check_output(output, plane, &input_fb, &output_fb);
> +
> +		igt_remove_fb(display.drm_fd, &output_fb);
> +	}
> +
>  	igt_fixture {
>  		igt_remove_fb(display.drm_fd, &input_fb);
>  		igt_display_fini(&display);
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 4/6] kms_writeback: Add writeback-check-output
@ 2019-07-12 12:34     ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-12 12:34 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

Mostly looks good, here are a few comments.

On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> Add a test which makes commits using the writeback connector, and
> checks the output buffer hash to make sure it is/isn't written as
> appropriate.
> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> ---
>  tests/kms_writeback.c | 124 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 124 insertions(+)
> 
> diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> index 66ef48a6..0f20dadd 100644
> --- a/tests/kms_writeback.c
> +++ b/tests/kms_writeback.c
> @@ -30,6 +30,7 @@
>  #include "igt.h"
>  #include "igt_core.h"
>  #include "igt_fb.h"
> +#include "sw_sync.h"
>  
>  static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
>  {
> @@ -221,6 +222,116 @@ static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *
>  	igt_assert(ret == 0);
>  }
>  
> +static void fill_fb(igt_fb_t *fb, double color[3])
> +{
> +	cairo_t *cr = igt_get_cairo_ctx(fb->fd, fb);
> +	igt_assert(cr);
> +
> +	igt_paint_color(cr, 0, 0, fb->width, fb->height,
> +			color[0], color[1], color[2]);
> +}
> +
> +static void get_and_wait_out_fence(igt_output_t *output)
> +{
> +	int ret;
> +
> +	igt_assert(output->writeback_out_fence_fd >= 0);
> +
> +	ret = sync_fence_wait(output->writeback_out_fence_fd, 1000);
> +	igt_assert(ret == 0);

When filtering failures in CI Bug Log, "ret == 0" is not very helpful
and may not be unique. Can we add a descriptive error message, with
something among the lines of:

    igt_assert_f(ret == 0, "sync_fence_wait failed: %s\n", strerror(-ret));

> +	close(output->writeback_out_fence_fd);
> +	output->writeback_out_fence_fd = -1;
> +}
> +
> +static void writeback_sequence(igt_output_t *output, igt_plane_t *plane,
> +				igt_fb_t *in_fb, igt_fb_t *out_fbs[], int n_commits)
> +{
> +	int i, color_idx = 0;
> +	double in_fb_colors[2][3] = {
> +		{ 1.0, 0.0, 0.0 },
> +		{ 0.0, 1.0, 0.0 },
> +	};
> +	double clear_color[3] = { 1.0, 1.0, 1.0 };
> +	igt_crc_t cleared_crc, out_expected;
> +
> +	for (i = 0; i < n_commits; i++, color_idx++) {
> +		/* Change the input color each time */
> +		fill_fb(in_fb, in_fb_colors[color_idx % 2]);

Why do we need two indexes (i and color_idx)? I think [i % 2] should
work just fine.

> +		if (out_fbs[i]) {
> +			igt_crc_t out_before;
> +
> +			/* Get the expected CRC */
> +			fill_fb(out_fbs[i], in_fb_colors[color_idx % 2]);
> +			igt_fb_get_crc(out_fbs[i], &out_expected);

Using out_fbs[i] to compute the expected CRC is a little bit confusing.
I think we can just use in_fb here (which is already filled with the
proper color).

> +			fill_fb(out_fbs[i], clear_color);
> +			if (i == 0)
> +				igt_fb_get_crc(out_fbs[i], &cleared_crc);
> +			igt_fb_get_crc(out_fbs[i], &out_before);
> +			igt_assert_crc_equal(&cleared_crc, &out_before);
> +		}
> +
> +		/* Commit */
> +		igt_plane_set_fb(plane, in_fb);
> +		igt_output_set_writeback_fb(output, out_fbs[i]);
> +
> +		igt_display_commit_atomic(output->display,
> +					  DRM_MODE_ATOMIC_ALLOW_MODESET,
> +					  NULL);
> +		if (out_fbs[i])
> +			get_and_wait_out_fence(output);
> +
> +		/* Make sure the old output buffer is untouched */
> +		if (i > 0 && out_fbs[i - 1] && (out_fbs[i] != out_fbs[i - 1])) {

Nit: unnecessary parentheses here

> +			igt_crc_t out_prev;
> +			igt_fb_get_crc(out_fbs[i - 1], &out_prev);
> +			igt_assert_crc_equal(&cleared_crc, &out_prev);
> +		}
> +
> +		/* Make sure this output buffer is written */
> +		if (out_fbs[i]) {
> +			igt_crc_t out_after;
> +			igt_fb_get_crc(out_fbs[i], &out_after);
> +			igt_assert_crc_equal(&out_expected, &out_after);
> +
> +			/* And clear it, for the next time */
> +			fill_fb(out_fbs[i], clear_color);
> +		}
> +	}
> +}
> +
> +static void writeback_check_output(igt_output_t *output, igt_plane_t *plane,
> +				   igt_fb_t *input_fb, igt_fb_t *output_fb)
> +{
> +	igt_fb_t *out_fbs[2] = { 0 };
> +	igt_fb_t second_out_fb;
> +	int ret;
> +
> +	/* One commit, with a writeback. */
> +	writeback_sequence(output, plane, input_fb, &output_fb, 1);
> +
> +	/* Two commits, the second with no writeback */
> +	out_fbs[0] = output_fb;
> +	writeback_sequence(output, plane, input_fb, out_fbs, 2);
> +
> +	/* Two commits, both with writeback */
> +	out_fbs[1] = output_fb;
> +	writeback_sequence(output, plane, input_fb, out_fbs, 2);
> +
> +	ret = igt_create_fb(output_fb->fd, output_fb->width, output_fb->height,
> +			    DRM_FORMAT_XRGB8888,
> +			    igt_fb_mod_to_tiling(0),
> +			    &second_out_fb);
> +	igt_require(ret > 0);

unsigned int cast to int here

> +	/* Two commits, with different writeback buffers */
> +	out_fbs[1] = &second_out_fb;
> +	writeback_sequence(output, plane, input_fb, out_fbs, 2);
> +
> +	igt_remove_fb(output_fb->fd, &second_out_fb);
> +}
> +
>  igt_main
>  {
>  	igt_display_t display;
> @@ -307,6 +418,19 @@ igt_main
>  		igt_remove_fb(display.drm_fd, &output_fb);
>  	}
>  
> +	igt_subtest("writeback-check-output") {
> +		igt_fb_t output_fb;
> +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> +				    DRM_FORMAT_XRGB8888,
> +				    igt_fb_mod_to_tiling(0),
> +				    &output_fb);
> +		igt_require(ret > 0);

unsigned int cast to int here

> +		writeback_check_output(output, plane, &input_fb, &output_fb);
> +
> +		igt_remove_fb(display.drm_fd, &output_fb);
> +	}
> +
>  	igt_fixture {
>  		igt_remove_fb(display.drm_fd, &input_fb);
>  		igt_display_fini(&display);
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 5/6] lib/igt_kms: Add igt_output_clone_pipe for cloning
  2019-06-13  2:18   ` [igt-dev] " Brian Starkey
@ 2019-07-12 12:54     ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-12 12:54 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

So, to test these last two patches we'd need specific hardware right?
Because VKMS doesn't support cloning yet (does it?).

What kind of hardware supports cloned writeback outputs? I have a
Raspberry Pi which supports writeback via VC4, but I don't think it has
writeback cloning. I'm also not willing to install any proprietary
driver.

I guess we could land the first part of the series, and wait for VKMS
to support cloned outputs to land the last two patches.

Any other ideas?

On Wed, 2019-06-12 at 23:18 -0300, Brian Starkey wrote:
> An output can be added as a clone of any other output(s) attached to a
> pipe using igt_output_clone_pipe()
> 
> v5: Drop field out_fence_requested from struct igt_pipe (Brian Starkey)
> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> ---
>  lib/igt_kms.c | 100 +++++++++++++++++++++++++++++++-------------------
>  lib/igt_kms.h |   4 ++
>  2 files changed, 66 insertions(+), 38 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 140db346..b85a0404 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -1765,6 +1765,17 @@ static void igt_display_log_shift(igt_display_t *display, int shift)
>  	igt_assert(display->log_shift >= 0);
>  }
>  
> +static int igt_output_idx(igt_output_t *output)
> +{
> +	int i;
> +
> +	for (i = 0; i < output->display->n_outputs; i++)
> +		if (&output->display->outputs[i] == output)
> +			return i;
> +
> +	return -1;
> +}
> +
>  static void igt_output_refresh(igt_output_t *output)
>  {
>  	igt_display_t *display = output->display;
> @@ -2317,42 +2328,6 @@ void igt_display_fini(igt_display_t *display)
>  	display->planes = NULL;
>  }
>  
> -static void igt_display_refresh(igt_display_t *display)
> -{
> -	igt_output_t *output;
> -	int i;
> -
> -	unsigned long pipes_in_use = 0;
> -
> -       /* Check that two outputs aren't trying to use the same pipe */
> -	for (i = 0; i < display->n_outputs; i++) {
> -		output = &display->outputs[i];
> -
> -		if (output->pending_pipe != PIPE_NONE) {
> -			if (pipes_in_use & (1 << output->pending_pipe))
> -				goto report_dup;
> -
> -			pipes_in_use |= 1 << output->pending_pipe;
> -		}
> -
> -		if (output->force_reprobe)
> -			igt_output_refresh(output);
> -	}
> -
> -	return;
> -
> -report_dup:
> -	for (; i > 0; i--) {
> -		igt_output_t *b = &display->outputs[i - 1];
> -
> -		igt_assert_f(output->pending_pipe !=
> -			     b->pending_pipe,
> -			     "%s and %s are both trying to use pipe %s\n",
> -			     igt_output_name(output), igt_output_name(b),
> -			     kmstest_pipe_name(output->pending_pipe));
> -	}
> -}
> -
>  static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
>  {
>  	igt_display_t *display = output->display;
> @@ -2376,6 +2351,40 @@ static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
>  	return &display->pipes[pipe];
>  }
>  
> +static void igt_display_refresh(igt_display_t *display)
> +{
> +	igt_output_t *output;
> +	igt_pipe_t *pipe;
> +	int i;
> +
> +	unsigned long pipes_in_use = 0;
> +	unsigned long pending_crtc_idx_mask;
> +
> +	/* Check that outputs and pipes agree wrt. cloning */
> +	for (i = 0; i < display->n_outputs; i++) {
> +		output = &display->outputs[i];
> +		pending_crtc_idx_mask = 1 << output->pending_pipe;
> +
> +		pipe = igt_output_get_driving_pipe(output);
> +		if (pipe) {
> +			igt_assert_f(pipe->outputs & (1 << igt_output_idx(output)),
> +				     "Output %s not expected to be using pipe %s\n",
> +				     igt_output_name(output),
> +				     kmstest_pipe_name(pipe->pipe));
> +
> +			if (pipes_in_use & pending_crtc_idx_mask)
> +				LOG(display, "Output %s clones pipe %s\n",
> +				    igt_output_name(output),
> +				    kmstest_pipe_name(pipe->pipe));
> +		}
> +
> +		pipes_in_use |= pending_crtc_idx_mask;
> +
> +		if (output->force_reprobe)
> +			igt_output_refresh(output);
> +	}
> +}
> +
>  static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, int plane_idx)
>  {
>  	igt_require_f(plane_idx >= 0 && plane_idx < pipe->n_planes,
> @@ -3766,6 +3775,7 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
>  	output->use_override_mode = !!mode;
>  
>  	if (pipe) {
> +		igt_debug("overriding pipe mode in %s way\n", output->display->is_atomic ? "atomic" : "legacy");
>  		if (output->display->is_atomic)
>  			igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
>  		else
> @@ -3773,6 +3783,16 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
>  	}
>  }
>  
> +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe)
> +{
> +	igt_display_t *display = output->display;
> +	uint32_t current_clones = display->pipes[pipe].outputs;
> +
> +	igt_output_set_pipe(output, pipe);
> +
> +	display->pipes[pipe].outputs |= current_clones;
> +}
> +
>  /*
>   * igt_output_set_pipe:
>   * @output: Target output for which the pipe is being set to
> @@ -3789,11 +3809,15 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
>  
>  	igt_assert(output->name);
>  
> -	if (output->pending_pipe != PIPE_NONE)
> +	if (output->pending_pipe != PIPE_NONE) {
>  		old_pipe = igt_output_get_driving_pipe(output);
> +		old_pipe->outputs &= ~(1 << igt_output_idx(output));
> +	}
>  
> -	if (pipe != PIPE_NONE)
> +	if (pipe != PIPE_NONE) {
>  		pipe_obj = &display->pipes[pipe];
> +		pipe_obj->outputs = (1 << igt_output_idx(output));
> +	}
>  
>  	LOG(display, "%s: set_pipe(%s)\n", igt_output_name(output),
>  	    kmstest_pipe_name(pipe));
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index cacc6b90..676839bb 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -354,6 +354,8 @@ struct igt_pipe {
>  	uint32_t crtc_id;
>  
>  	int32_t out_fence_fd;
> +
> +	uint32_t outputs;
>  };
>  
>  typedef struct {
> @@ -411,6 +413,8 @@ const char *igt_output_name(igt_output_t *output);
>  drmModeModeInfo *igt_output_get_mode(igt_output_t *output);
>  void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode);
>  void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
> +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe);
> +
>  igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
>  igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
>  int igt_output_count_plane_type(igt_output_t *output, int plane_type);
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 5/6] lib/igt_kms: Add igt_output_clone_pipe for cloning
@ 2019-07-12 12:54     ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-12 12:54 UTC (permalink / raw)
  To: Liviu.Dudau, Hiler, Arkadiusz, Brian.Starkey, Latvala, Petri,
	rodrigosiqueiramelo, daniel
  Cc: igt-dev, intel-gfx, nd

So, to test these last two patches we'd need specific hardware right?
Because VKMS doesn't support cloning yet (does it?).

What kind of hardware supports cloned writeback outputs? I have a
Raspberry Pi which supports writeback via VC4, but I don't think it has
writeback cloning. I'm also not willing to install any proprietary
driver.

I guess we could land the first part of the series, and wait for VKMS
to support cloned outputs to land the last two patches.

Any other ideas?

On Wed, 2019-06-12 at 23:18 -0300, Brian Starkey wrote:
> An output can be added as a clone of any other output(s) attached to a
> pipe using igt_output_clone_pipe()
> 
> v5: Drop field out_fence_requested from struct igt_pipe (Brian Starkey)
> 
> Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> ---
>  lib/igt_kms.c | 100 +++++++++++++++++++++++++++++++-------------------
>  lib/igt_kms.h |   4 ++
>  2 files changed, 66 insertions(+), 38 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 140db346..b85a0404 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -1765,6 +1765,17 @@ static void igt_display_log_shift(igt_display_t *display, int shift)
>  	igt_assert(display->log_shift >= 0);
>  }
>  
> +static int igt_output_idx(igt_output_t *output)
> +{
> +	int i;
> +
> +	for (i = 0; i < output->display->n_outputs; i++)
> +		if (&output->display->outputs[i] == output)
> +			return i;
> +
> +	return -1;
> +}
> +
>  static void igt_output_refresh(igt_output_t *output)
>  {
>  	igt_display_t *display = output->display;
> @@ -2317,42 +2328,6 @@ void igt_display_fini(igt_display_t *display)
>  	display->planes = NULL;
>  }
>  
> -static void igt_display_refresh(igt_display_t *display)
> -{
> -	igt_output_t *output;
> -	int i;
> -
> -	unsigned long pipes_in_use = 0;
> -
> -       /* Check that two outputs aren't trying to use the same pipe */
> -	for (i = 0; i < display->n_outputs; i++) {
> -		output = &display->outputs[i];
> -
> -		if (output->pending_pipe != PIPE_NONE) {
> -			if (pipes_in_use & (1 << output->pending_pipe))
> -				goto report_dup;
> -
> -			pipes_in_use |= 1 << output->pending_pipe;
> -		}
> -
> -		if (output->force_reprobe)
> -			igt_output_refresh(output);
> -	}
> -
> -	return;
> -
> -report_dup:
> -	for (; i > 0; i--) {
> -		igt_output_t *b = &display->outputs[i - 1];
> -
> -		igt_assert_f(output->pending_pipe !=
> -			     b->pending_pipe,
> -			     "%s and %s are both trying to use pipe %s\n",
> -			     igt_output_name(output), igt_output_name(b),
> -			     kmstest_pipe_name(output->pending_pipe));
> -	}
> -}
> -
>  static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
>  {
>  	igt_display_t *display = output->display;
> @@ -2376,6 +2351,40 @@ static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
>  	return &display->pipes[pipe];
>  }
>  
> +static void igt_display_refresh(igt_display_t *display)
> +{
> +	igt_output_t *output;
> +	igt_pipe_t *pipe;
> +	int i;
> +
> +	unsigned long pipes_in_use = 0;
> +	unsigned long pending_crtc_idx_mask;
> +
> +	/* Check that outputs and pipes agree wrt. cloning */
> +	for (i = 0; i < display->n_outputs; i++) {
> +		output = &display->outputs[i];
> +		pending_crtc_idx_mask = 1 << output->pending_pipe;
> +
> +		pipe = igt_output_get_driving_pipe(output);
> +		if (pipe) {
> +			igt_assert_f(pipe->outputs & (1 << igt_output_idx(output)),
> +				     "Output %s not expected to be using pipe %s\n",
> +				     igt_output_name(output),
> +				     kmstest_pipe_name(pipe->pipe));
> +
> +			if (pipes_in_use & pending_crtc_idx_mask)
> +				LOG(display, "Output %s clones pipe %s\n",
> +				    igt_output_name(output),
> +				    kmstest_pipe_name(pipe->pipe));
> +		}
> +
> +		pipes_in_use |= pending_crtc_idx_mask;
> +
> +		if (output->force_reprobe)
> +			igt_output_refresh(output);
> +	}
> +}
> +
>  static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, int plane_idx)
>  {
>  	igt_require_f(plane_idx >= 0 && plane_idx < pipe->n_planes,
> @@ -3766,6 +3775,7 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
>  	output->use_override_mode = !!mode;
>  
>  	if (pipe) {
> +		igt_debug("overriding pipe mode in %s way\n", output->display->is_atomic ? "atomic" : "legacy");
>  		if (output->display->is_atomic)
>  			igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
>  		else
> @@ -3773,6 +3783,16 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
>  	}
>  }
>  
> +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe)
> +{
> +	igt_display_t *display = output->display;
> +	uint32_t current_clones = display->pipes[pipe].outputs;
> +
> +	igt_output_set_pipe(output, pipe);
> +
> +	display->pipes[pipe].outputs |= current_clones;
> +}
> +
>  /*
>   * igt_output_set_pipe:
>   * @output: Target output for which the pipe is being set to
> @@ -3789,11 +3809,15 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
>  
>  	igt_assert(output->name);
>  
> -	if (output->pending_pipe != PIPE_NONE)
> +	if (output->pending_pipe != PIPE_NONE) {
>  		old_pipe = igt_output_get_driving_pipe(output);
> +		old_pipe->outputs &= ~(1 << igt_output_idx(output));
> +	}
>  
> -	if (pipe != PIPE_NONE)
> +	if (pipe != PIPE_NONE) {
>  		pipe_obj = &display->pipes[pipe];
> +		pipe_obj->outputs = (1 << igt_output_idx(output));
> +	}
>  
>  	LOG(display, "%s: set_pipe(%s)\n", igt_output_name(output),
>  	    kmstest_pipe_name(pipe));
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index cacc6b90..676839bb 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -354,6 +354,8 @@ struct igt_pipe {
>  	uint32_t crtc_id;
>  
>  	int32_t out_fence_fd;
> +
> +	uint32_t outputs;
>  };
>  
>  typedef struct {
> @@ -411,6 +413,8 @@ const char *igt_output_name(igt_output_t *output);
>  drmModeModeInfo *igt_output_get_mode(igt_output_t *output);
>  void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode);
>  void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
> +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe);
> +
>  igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
>  igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
>  int igt_output_count_plane_type(igt_output_t *output, int plane_type);
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-07-12  2:44       ` Rodrigo Siqueira
@ 2019-07-16 15:22         ` Liviu.Dudau
  -1 siblings, 0 replies; 71+ messages in thread
From: Liviu.Dudau @ 2019-07-16 15:22 UTC (permalink / raw)
  To: Rodrigo Siqueira; +Cc: igt-dev, intel-gfx, Ser, Simon, nd

Hi Rodrigo,

On Thu, Jul 11, 2019 at 11:44:35PM -0300, Rodrigo Siqueira wrote:
> On 07/10, Ser, Simon wrote:
> > Hi,
> > 
> > Thanks for the patch! Here are a few comments.
> > 
> > For bonus points, it would be nice to add igt_describe descriptions of
> > each sub-test.
> 
> Hi Simon,
> 
> First of all, thanks for your feedback; I already applied most of your
> suggestions. I just have some inline comments/questions.
>  
> > On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> > > Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> > > WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> > > behaviour is correct.
> > > 
> > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > [rebased and updated do_writeback_test() function to address feedback]
> > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > ---
> > >  tests/Makefile.sources |   1 +
> > >  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
> > >  tests/meson.build      |   1 +
> > >  3 files changed, 316 insertions(+)
> > >  create mode 100644 tests/kms_writeback.c
> > > 
> > > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > > index 027ed82f..03cc8efa 100644
> > > --- a/tests/Makefile.sources
> > > +++ b/tests/Makefile.sources
> > > @@ -77,6 +77,7 @@ TESTS_progs = \
> > >  	kms_universal_plane \
> > >  	kms_vblank \
> > >  	kms_vrr \
> > > +	kms_writeback \
> > >  	meta_test \
> > >  	perf \
> > >  	perf_pmu \
> > > diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> > > new file mode 100644
> > > index 00000000..66ef48a6
> > > --- /dev/null
> > > +++ b/tests/kms_writeback.c
> > > @@ -0,0 +1,314 @@
> > > +/*
> > > + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> > > + *
> > > + * Permission is hereby granted, free of charge, to any person obtaining a
> > > + * copy of this software and associated documentation files (the "Software"),
> > > + * to deal in the Software without restriction, including without limitation
> > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > > + * and/or sell copies of the Software, and to permit persons to whom the
> > > + * Software is furnished to do so, subject to the following conditions:
> > > + *
> > > + * The above copyright notice and this permission notice (including the next
> > > + * paragraph) shall be included in all copies or substantial portions of the
> > > + * Software.
> > > + *
> > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > > + * IN THE SOFTWARE.
> > > + *
> > > + */
> > > +
> > > +#include <errno.h>
> > > +#include <stdbool.h>
> > > +#include <stdio.h>
> > > +#include <string.h>
> > > +
> > > +#include "igt.h"
> > > +#include "igt_core.h"
> > > +#include "igt_fb.h"
> > > +
> > > +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> > > +{
> > > +	drmModePropertyBlobRes *blob = NULL;
> > > +	uint64_t blob_id;
> > > +	int ret;
> > > +
> > > +	ret = kmstest_get_property(output->display->drm_fd,
> > > +				   output->config.connector->connector_id,
> > > +				   DRM_MODE_OBJECT_CONNECTOR,
> > > +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> > > +				   NULL, &blob_id, NULL);
> > > +	if (ret)
> > > +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> > > +
> > > +	igt_assert(blob);
> > > +
> > > +	return blob;
> > > +}
> > > +
> > > +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> > > +{
> > > +	igt_fb_t input_fb, output_fb;
> > > +	igt_plane_t *plane;
> > > +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> > > +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> > > +	int width, height, ret;
> > > +	drmModeModeInfo override_mode = {
> > > +		.clock = 25175,
> > > +		.hdisplay = 640,
> > > +		.hsync_start = 656,
> > > +		.hsync_end = 752,
> > > +		.htotal = 800,
> > > +		.hskew = 0,
> > > +		.vdisplay = 480,
> > > +		.vsync_start = 490,
> > > +		.vsync_end = 492,
> > > +		.vtotal = 525,
> > > +		.vscan = 0,
> > > +		.vrefresh = 60,
> > > +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> > > +		.name = {"640x480-60"},
> > > +	};
> > > +	igt_output_override_mode(output, &override_mode);
> > > +
> > > +	width = override_mode.hdisplay;
> > > +	height = override_mode.vdisplay;
> > > +
> > > +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> > > +	igt_assert(ret >= 0);
> > > +
> > > +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> > > +	igt_assert(ret >= 0);
> > > +
> > > +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > +	igt_plane_set_fb(plane, &input_fb);
> > > +	igt_output_set_writeback_fb(output, &output_fb);
> > > +
> > > +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> > > +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> > 
> > Okay, we're using atomic test-only mode to know if we can perform tests
> > with the writeback output. It's probably fine, but we don't use
> > WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.
> 
> Sorry, I did not fully understand part. Did you expect to see something
> like the below code before igt_display_try_commit_atomic()?
> 
>  igt_output_set_prop_value(output, WRITEBACK_PIXEL_FORMATS,
>                            DRM_FORMAT_XRGB8888);
> 
> > > +	igt_plane_set_fb(plane, NULL);
> > > +	igt_remove_fb(display->drm_fd, &input_fb);
> > > +	igt_remove_fb(display->drm_fd, &output_fb);
> > > +
> > > +	return !ret;
> > > +}
> > > +
> > > +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> > > +{
> > > +	int i;
> > > +
> > > +	for (i = 0; i < display->n_outputs; i++) {
> > > +		igt_output_t *output = &display->outputs[i];
> > > +		int j;
> > > +
> > > +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> > > +			continue;
> > > +
> > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
> > 
> > Hmm. Is this really necessary? "Real" userspace won't do this, so I
> > don't think we need to either.
> 
> Hmmm, I have a little experience with userspace; however, I tested
> kms_writeback on top of vkms without this line, and everything worked
> well. If I remove this line, should I also drop the line that force
> connector to FORCE_CONNECTOR_UNSPECIFIED?
> 
> Another question, if FORCE_CONNECTOR_ON is something that userspace
> won't want to do, why do we have it?

This is probably a left-over from the times when the design of the writeback
connectors called for them to be always disconnected, in order not to trip old
userspace. Last iteration before upstreaming the writeback into DRM we switched
to an earlier design where DRM_CLIENT_CAP_WRITEBACK_CONNECTORS is needed in order
to expose the writeback connector, and then it is reported as connected. You
can drop this from the patch.

>  
> > > +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> > > +			igt_output_set_pipe(output, j);
> > > +
> > > +			if (check_writeback_config(display, output)) {
> > > +				igt_debug("Using connector %u:%s on pipe %d\n",
> > > +					  output->config.connector->connector_id,
> > > +					  output->name, j);
> > > +				return output;
> > > +			}
> > 
> > We could probably add an igt_debug statement in case we don't use this
> > writeback output.
> > 
> > > +		}
> > > +
> > > +		/* Restore any connectors we don't use, so we don't trip on them later */
> > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> > > +	}
> > > +
> > > +	return NULL;
> > > +}
> > > +
> > > +static void check_writeback_fb_id(igt_output_t *output)
> > > +{
> > > +	uint64_t check_fb_id;
> > > +
> > > +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > +	igt_assert(check_fb_id == 0);
> > > +}
> > > +
> > > +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> > > +			      uint32_t fb_id, int32_t *out_fence_ptr,
> > > +			      bool ptr_valid)
> > 
> > flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
> > probably remove the parameter from this function.
> > 
> > > +{
> > > +	int ret;
> > > +	igt_display_t *display = output->display;
> > > +	struct kmstest_connector_config *config = &output->config;
> > > +
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> > > +
> > > +	if (ptr_valid)
> > > +		*out_fence_ptr = 0;
> > > +
> > > +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> > > +
> > > +	if (ptr_valid)
> > > +		igt_assert(*out_fence_ptr == -1);
> > 
> > I'm confused. Why should this be -1 even if we
> > igt_display_try_commit_atomic succeeds?
> 
> I inspected the drm_mode_atomic_ioctl() function and I noticed that It
> calls complete_signaling() in its turn this function assign -1 to
> out_fence_ptr. Since all of this happens at the end of atomic_commit, I
> believe that we don’t need it. I already removed it.

Yeah, I think the reasons for that have been lost into the mist of time.

>  
> > > +	/* WRITEBACK_FB_ID must always read as zero */
> > > +	check_writeback_fb_id(output);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > +{
> > > +	int i, ret;
> > > +	int32_t out_fence;
> > > +	struct {
> > > +		uint32_t fb_id;
> > > +		bool ptr_valid;
> > > +		int32_t *out_fence_ptr;
> > > +	} invalid_tests[] = {
> > > +		{
> > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > +			.fb_id = 0,
> > > +			.ptr_valid = true,
> > > +			.out_fence_ptr = &out_fence,
> > > +		},
> > > +		{
> > > +			/* Invalid output buffer. */
> > > +			.fb_id = invalid_fb->fb_id,
> > > +			.ptr_valid = true,
> > > +			.out_fence_ptr = &out_fence,
> > > +		},
> > 
> > This doesn't belong in this function (invalid_out_fence), since this
> > checks an invalid framebuffer, not an invalid fence. We should probably
> > move it to writeback_fb_id (and rename that function to test_fb?).

It tries to test that you can't trick the driver to do any work on a fence if
the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
invalid fb with valid fence, valid fb but invalid fence and assumes that no
fb with invalid fence is a NOP anyway.

> > 
> > > +		{
> > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > +			.fb_id = valid_fb->fb_id,
> > > +			.ptr_valid = false,
> > > +			.out_fence_ptr = (int32_t *)0x8,
> > > +		},
> > > +	};
> > > +
> > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +					invalid_tests[i].fb_id,
> > > +					invalid_tests[i].out_fence_ptr,
> > > +					invalid_tests[i].ptr_valid);
> > > +		igt_assert(ret != 0);
> > 
> > Maybe we can check for -ret == EINVAL?
> > 
> > > +	}
> > > +}
> > > +
> > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > 
> > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > the input framebuffer. It's probably not a good idea to use the same FB
> > for input and writeback output.
> > 
> > > +{
> > > +
> > > +	int ret;
> > > +
> > > +	/* Valid output buffer */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				valid_fb->fb_id, NULL, false);
> > > +	igt_assert(ret == 0);
> > > +
> > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				output->id, NULL, false);
> > > +	igt_assert(ret == -EINVAL);
> > > +
> > > +	/* Zero WRITEBACK_FB_ID */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				0, NULL, false);
> > > +	igt_assert(ret == 0);
> > > +}
> > > +
> > > +igt_main
> > > +{
> > > +	igt_display_t display;
> > > +	igt_output_t *output;
> > > +	igt_plane_t *plane;
> > > +	igt_fb_t input_fb;
> > > +	drmModeModeInfo mode;
> > > +	int ret;
> > > +
> > > +	memset(&display, 0, sizeof(display));
> > > +
> > > +	igt_fixture {
> > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > +		igt_display_require(&display, display.drm_fd);
> > > +
> > > +		kmstest_set_vt_graphics_mode();
> > > +
> > > +		igt_display_require(&display, display.drm_fd);
> > > +
> > > +		igt_require(display.is_atomic);
> > > +
> > > +		output = kms_writeback_get_output(&display);
> > > +		igt_require(output);
> > > +
> > > +		if (output->use_override_mode)
> > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > +		else
> > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > +
> > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > +		igt_require(plane);
> > 
> > Maybe we can assert on this?
> > 
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > +				    mode.vdisplay,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > 
> > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > better to make this clear.

Agree. The patchset pre-dates the modifiers support (or has the same age, I
forgot)

> > 
> > (Applies to other lines of this patch)
> > 
> > > +				    &input_fb);
> > > +		igt_assert(ret >= 0);
> > > +		igt_plane_set_fb(plane, &input_fb);
> > > +	}
> > > +
> > > +	igt_subtest("writeback-pixel-formats") {
> > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > 
> > Need to drmModeFreePropertyBlob this.
> > 
> > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > +		unsigned int i;
> > > +		char *c;
> > > +
> > > +		/*
> > > +		 * We don't have a comprehensive list of formats, so just check
> > > +		 * that the blob length is sensible and that it doesn't contain
> > > +		 * any outlandish characters
> > > +		 */
> > > +		igt_assert(!(formats_blob->length % 4));
> > > +		c = formats_blob->data;
> > > +		for (i = 0; i < formats_blob->length; i++)
> > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > +				     "Unexpected character %c\n", c[i]);
> > 
> > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > codes will be made from ASCII characters, in fact some formats already
> > have non-printable chars in them. I don't want to have to update this
> > test when a new fourcc format is added.

Like the comments says, we don't have a full list of formats to check against.
Suggestions on how to improve are welcome, but I don't think we should delay
(any longer) the patchset due to this.

Best regards,
Liviu

> > 
> > We currently don't have a test for IN_FORMATS. If we really want to
> > check formats, we could have a big array of known formats and add a
> > bool is_valid_format(uint32_t fmt) function.
> 
> Agree with you. How about remove this test?
> 
> Thanks
> Best Regards
> 
> > > +	}
> > > +
> > > +	igt_subtest("writeback-invalid-out-fence") {
> > > +		igt_fb_t invalid_fb;
> > 
> > invalid_output_fb would be a better name IMHO.
> > 
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> > > +				    mode.vdisplay / 2,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > > +				    &invalid_fb);
> > > +		igt_require(ret > 0);
> > 
> > We should probably use a different variable: ret is signed,
> > igt_create_fb isn't. Also ret doesn't make it clear that the return
> > value is the KMS framebuffer ID.
> > 
> > (Applies to other subtests)
> > 
> > > +		invalid_out_fence(output, &input_fb, &invalid_fb);
> > 
> > (Still not sure why we provide the input FB to this function.)
> > 
> > > +		igt_remove_fb(display.drm_fd, &invalid_fb);
> > > +	}
> > > +
> > > +	igt_subtest("writeback-fb-id") {
> > > +		igt_fb_t output_fb;
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > > +				    &output_fb);
> > > +		igt_require(ret > 0);
> > > +
> > > +		writeback_fb_id(output, &input_fb, &output_fb);
> > > +
> > > +		igt_remove_fb(display.drm_fd, &output_fb);
> > > +	}
> > > +
> > > +	igt_fixture {
> > > +		igt_remove_fb(display.drm_fd, &input_fb);
> > > +		igt_display_fini(&display);
> > > +	}
> > > +}
> > > diff --git a/tests/meson.build b/tests/meson.build
> > > index f168fbba..9c77cfcd 100644
> > > --- a/tests/meson.build
> > > +++ b/tests/meson.build
> > > @@ -63,6 +63,7 @@ test_progs = [
> > >  	'kms_universal_plane',
> > >  	'kms_vblank',
> > >  	'kms_vrr',
> > > +	'kms_writeback',
> > >  	'meta_test',
> > >  	'panfrost_get_param',
> > >  	'panfrost_gem_new',
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> 
> -- 
> Rodrigo Siqueira
> https://siqueira.tech



-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-16 15:22         ` Liviu.Dudau
  0 siblings, 0 replies; 71+ messages in thread
From: Liviu.Dudau @ 2019-07-16 15:22 UTC (permalink / raw)
  To: Rodrigo Siqueira
  Cc: igt-dev, Latvala, Petri, intel-gfx, daniel, nd, Brian.Starkey

Hi Rodrigo,

On Thu, Jul 11, 2019 at 11:44:35PM -0300, Rodrigo Siqueira wrote:
> On 07/10, Ser, Simon wrote:
> > Hi,
> > 
> > Thanks for the patch! Here are a few comments.
> > 
> > For bonus points, it would be nice to add igt_describe descriptions of
> > each sub-test.
> 
> Hi Simon,
> 
> First of all, thanks for your feedback; I already applied most of your
> suggestions. I just have some inline comments/questions.
>  
> > On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> > > Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> > > WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> > > behaviour is correct.
> > > 
> > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > [rebased and updated do_writeback_test() function to address feedback]
> > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > ---
> > >  tests/Makefile.sources |   1 +
> > >  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
> > >  tests/meson.build      |   1 +
> > >  3 files changed, 316 insertions(+)
> > >  create mode 100644 tests/kms_writeback.c
> > > 
> > > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > > index 027ed82f..03cc8efa 100644
> > > --- a/tests/Makefile.sources
> > > +++ b/tests/Makefile.sources
> > > @@ -77,6 +77,7 @@ TESTS_progs = \
> > >  	kms_universal_plane \
> > >  	kms_vblank \
> > >  	kms_vrr \
> > > +	kms_writeback \
> > >  	meta_test \
> > >  	perf \
> > >  	perf_pmu \
> > > diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> > > new file mode 100644
> > > index 00000000..66ef48a6
> > > --- /dev/null
> > > +++ b/tests/kms_writeback.c
> > > @@ -0,0 +1,314 @@
> > > +/*
> > > + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> > > + *
> > > + * Permission is hereby granted, free of charge, to any person obtaining a
> > > + * copy of this software and associated documentation files (the "Software"),
> > > + * to deal in the Software without restriction, including without limitation
> > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > > + * and/or sell copies of the Software, and to permit persons to whom the
> > > + * Software is furnished to do so, subject to the following conditions:
> > > + *
> > > + * The above copyright notice and this permission notice (including the next
> > > + * paragraph) shall be included in all copies or substantial portions of the
> > > + * Software.
> > > + *
> > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > > + * IN THE SOFTWARE.
> > > + *
> > > + */
> > > +
> > > +#include <errno.h>
> > > +#include <stdbool.h>
> > > +#include <stdio.h>
> > > +#include <string.h>
> > > +
> > > +#include "igt.h"
> > > +#include "igt_core.h"
> > > +#include "igt_fb.h"
> > > +
> > > +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> > > +{
> > > +	drmModePropertyBlobRes *blob = NULL;
> > > +	uint64_t blob_id;
> > > +	int ret;
> > > +
> > > +	ret = kmstest_get_property(output->display->drm_fd,
> > > +				   output->config.connector->connector_id,
> > > +				   DRM_MODE_OBJECT_CONNECTOR,
> > > +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> > > +				   NULL, &blob_id, NULL);
> > > +	if (ret)
> > > +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> > > +
> > > +	igt_assert(blob);
> > > +
> > > +	return blob;
> > > +}
> > > +
> > > +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> > > +{
> > > +	igt_fb_t input_fb, output_fb;
> > > +	igt_plane_t *plane;
> > > +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> > > +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> > > +	int width, height, ret;
> > > +	drmModeModeInfo override_mode = {
> > > +		.clock = 25175,
> > > +		.hdisplay = 640,
> > > +		.hsync_start = 656,
> > > +		.hsync_end = 752,
> > > +		.htotal = 800,
> > > +		.hskew = 0,
> > > +		.vdisplay = 480,
> > > +		.vsync_start = 490,
> > > +		.vsync_end = 492,
> > > +		.vtotal = 525,
> > > +		.vscan = 0,
> > > +		.vrefresh = 60,
> > > +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> > > +		.name = {"640x480-60"},
> > > +	};
> > > +	igt_output_override_mode(output, &override_mode);
> > > +
> > > +	width = override_mode.hdisplay;
> > > +	height = override_mode.vdisplay;
> > > +
> > > +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> > > +	igt_assert(ret >= 0);
> > > +
> > > +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> > > +	igt_assert(ret >= 0);
> > > +
> > > +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > +	igt_plane_set_fb(plane, &input_fb);
> > > +	igt_output_set_writeback_fb(output, &output_fb);
> > > +
> > > +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> > > +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> > 
> > Okay, we're using atomic test-only mode to know if we can perform tests
> > with the writeback output. It's probably fine, but we don't use
> > WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.
> 
> Sorry, I did not fully understand part. Did you expect to see something
> like the below code before igt_display_try_commit_atomic()?
> 
>  igt_output_set_prop_value(output, WRITEBACK_PIXEL_FORMATS,
>                            DRM_FORMAT_XRGB8888);
> 
> > > +	igt_plane_set_fb(plane, NULL);
> > > +	igt_remove_fb(display->drm_fd, &input_fb);
> > > +	igt_remove_fb(display->drm_fd, &output_fb);
> > > +
> > > +	return !ret;
> > > +}
> > > +
> > > +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> > > +{
> > > +	int i;
> > > +
> > > +	for (i = 0; i < display->n_outputs; i++) {
> > > +		igt_output_t *output = &display->outputs[i];
> > > +		int j;
> > > +
> > > +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> > > +			continue;
> > > +
> > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
> > 
> > Hmm. Is this really necessary? "Real" userspace won't do this, so I
> > don't think we need to either.
> 
> Hmmm, I have a little experience with userspace; however, I tested
> kms_writeback on top of vkms without this line, and everything worked
> well. If I remove this line, should I also drop the line that force
> connector to FORCE_CONNECTOR_UNSPECIFIED?
> 
> Another question, if FORCE_CONNECTOR_ON is something that userspace
> won't want to do, why do we have it?

This is probably a left-over from the times when the design of the writeback
connectors called for them to be always disconnected, in order not to trip old
userspace. Last iteration before upstreaming the writeback into DRM we switched
to an earlier design where DRM_CLIENT_CAP_WRITEBACK_CONNECTORS is needed in order
to expose the writeback connector, and then it is reported as connected. You
can drop this from the patch.

>  
> > > +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> > > +			igt_output_set_pipe(output, j);
> > > +
> > > +			if (check_writeback_config(display, output)) {
> > > +				igt_debug("Using connector %u:%s on pipe %d\n",
> > > +					  output->config.connector->connector_id,
> > > +					  output->name, j);
> > > +				return output;
> > > +			}
> > 
> > We could probably add an igt_debug statement in case we don't use this
> > writeback output.
> > 
> > > +		}
> > > +
> > > +		/* Restore any connectors we don't use, so we don't trip on them later */
> > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> > > +	}
> > > +
> > > +	return NULL;
> > > +}
> > > +
> > > +static void check_writeback_fb_id(igt_output_t *output)
> > > +{
> > > +	uint64_t check_fb_id;
> > > +
> > > +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > +	igt_assert(check_fb_id == 0);
> > > +}
> > > +
> > > +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> > > +			      uint32_t fb_id, int32_t *out_fence_ptr,
> > > +			      bool ptr_valid)
> > 
> > flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
> > probably remove the parameter from this function.
> > 
> > > +{
> > > +	int ret;
> > > +	igt_display_t *display = output->display;
> > > +	struct kmstest_connector_config *config = &output->config;
> > > +
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> > > +
> > > +	if (ptr_valid)
> > > +		*out_fence_ptr = 0;
> > > +
> > > +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> > > +
> > > +	if (ptr_valid)
> > > +		igt_assert(*out_fence_ptr == -1);
> > 
> > I'm confused. Why should this be -1 even if we
> > igt_display_try_commit_atomic succeeds?
> 
> I inspected the drm_mode_atomic_ioctl() function and I noticed that It
> calls complete_signaling() in its turn this function assign -1 to
> out_fence_ptr. Since all of this happens at the end of atomic_commit, I
> believe that we don’t need it. I already removed it.

Yeah, I think the reasons for that have been lost into the mist of time.

>  
> > > +	/* WRITEBACK_FB_ID must always read as zero */
> > > +	check_writeback_fb_id(output);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > +{
> > > +	int i, ret;
> > > +	int32_t out_fence;
> > > +	struct {
> > > +		uint32_t fb_id;
> > > +		bool ptr_valid;
> > > +		int32_t *out_fence_ptr;
> > > +	} invalid_tests[] = {
> > > +		{
> > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > +			.fb_id = 0,
> > > +			.ptr_valid = true,
> > > +			.out_fence_ptr = &out_fence,
> > > +		},
> > > +		{
> > > +			/* Invalid output buffer. */
> > > +			.fb_id = invalid_fb->fb_id,
> > > +			.ptr_valid = true,
> > > +			.out_fence_ptr = &out_fence,
> > > +		},
> > 
> > This doesn't belong in this function (invalid_out_fence), since this
> > checks an invalid framebuffer, not an invalid fence. We should probably
> > move it to writeback_fb_id (and rename that function to test_fb?).

It tries to test that you can't trick the driver to do any work on a fence if
the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
invalid fb with valid fence, valid fb but invalid fence and assumes that no
fb with invalid fence is a NOP anyway.

> > 
> > > +		{
> > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > +			.fb_id = valid_fb->fb_id,
> > > +			.ptr_valid = false,
> > > +			.out_fence_ptr = (int32_t *)0x8,
> > > +		},
> > > +	};
> > > +
> > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +					invalid_tests[i].fb_id,
> > > +					invalid_tests[i].out_fence_ptr,
> > > +					invalid_tests[i].ptr_valid);
> > > +		igt_assert(ret != 0);
> > 
> > Maybe we can check for -ret == EINVAL?
> > 
> > > +	}
> > > +}
> > > +
> > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > 
> > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > the input framebuffer. It's probably not a good idea to use the same FB
> > for input and writeback output.
> > 
> > > +{
> > > +
> > > +	int ret;
> > > +
> > > +	/* Valid output buffer */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				valid_fb->fb_id, NULL, false);
> > > +	igt_assert(ret == 0);
> > > +
> > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				output->id, NULL, false);
> > > +	igt_assert(ret == -EINVAL);
> > > +
> > > +	/* Zero WRITEBACK_FB_ID */
> > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > +				0, NULL, false);
> > > +	igt_assert(ret == 0);
> > > +}
> > > +
> > > +igt_main
> > > +{
> > > +	igt_display_t display;
> > > +	igt_output_t *output;
> > > +	igt_plane_t *plane;
> > > +	igt_fb_t input_fb;
> > > +	drmModeModeInfo mode;
> > > +	int ret;
> > > +
> > > +	memset(&display, 0, sizeof(display));
> > > +
> > > +	igt_fixture {
> > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > +		igt_display_require(&display, display.drm_fd);
> > > +
> > > +		kmstest_set_vt_graphics_mode();
> > > +
> > > +		igt_display_require(&display, display.drm_fd);
> > > +
> > > +		igt_require(display.is_atomic);
> > > +
> > > +		output = kms_writeback_get_output(&display);
> > > +		igt_require(output);
> > > +
> > > +		if (output->use_override_mode)
> > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > +		else
> > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > +
> > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > +		igt_require(plane);
> > 
> > Maybe we can assert on this?
> > 
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > +				    mode.vdisplay,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > 
> > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > better to make this clear.

Agree. The patchset pre-dates the modifiers support (or has the same age, I
forgot)

> > 
> > (Applies to other lines of this patch)
> > 
> > > +				    &input_fb);
> > > +		igt_assert(ret >= 0);
> > > +		igt_plane_set_fb(plane, &input_fb);
> > > +	}
> > > +
> > > +	igt_subtest("writeback-pixel-formats") {
> > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > 
> > Need to drmModeFreePropertyBlob this.
> > 
> > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > +		unsigned int i;
> > > +		char *c;
> > > +
> > > +		/*
> > > +		 * We don't have a comprehensive list of formats, so just check
> > > +		 * that the blob length is sensible and that it doesn't contain
> > > +		 * any outlandish characters
> > > +		 */
> > > +		igt_assert(!(formats_blob->length % 4));
> > > +		c = formats_blob->data;
> > > +		for (i = 0; i < formats_blob->length; i++)
> > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > +				     "Unexpected character %c\n", c[i]);
> > 
> > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > codes will be made from ASCII characters, in fact some formats already
> > have non-printable chars in them. I don't want to have to update this
> > test when a new fourcc format is added.

Like the comments says, we don't have a full list of formats to check against.
Suggestions on how to improve are welcome, but I don't think we should delay
(any longer) the patchset due to this.

Best regards,
Liviu

> > 
> > We currently don't have a test for IN_FORMATS. If we really want to
> > check formats, we could have a big array of known formats and add a
> > bool is_valid_format(uint32_t fmt) function.
> 
> Agree with you. How about remove this test?
> 
> Thanks
> Best Regards
> 
> > > +	}
> > > +
> > > +	igt_subtest("writeback-invalid-out-fence") {
> > > +		igt_fb_t invalid_fb;
> > 
> > invalid_output_fb would be a better name IMHO.
> > 
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> > > +				    mode.vdisplay / 2,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > > +				    &invalid_fb);
> > > +		igt_require(ret > 0);
> > 
> > We should probably use a different variable: ret is signed,
> > igt_create_fb isn't. Also ret doesn't make it clear that the return
> > value is the KMS framebuffer ID.
> > 
> > (Applies to other subtests)
> > 
> > > +		invalid_out_fence(output, &input_fb, &invalid_fb);
> > 
> > (Still not sure why we provide the input FB to this function.)
> > 
> > > +		igt_remove_fb(display.drm_fd, &invalid_fb);
> > > +	}
> > > +
> > > +	igt_subtest("writeback-fb-id") {
> > > +		igt_fb_t output_fb;
> > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> > > +				    DRM_FORMAT_XRGB8888,
> > > +				    igt_fb_mod_to_tiling(0),
> > > +				    &output_fb);
> > > +		igt_require(ret > 0);
> > > +
> > > +		writeback_fb_id(output, &input_fb, &output_fb);
> > > +
> > > +		igt_remove_fb(display.drm_fd, &output_fb);
> > > +	}
> > > +
> > > +	igt_fixture {
> > > +		igt_remove_fb(display.drm_fd, &input_fb);
> > > +		igt_display_fini(&display);
> > > +	}
> > > +}
> > > diff --git a/tests/meson.build b/tests/meson.build
> > > index f168fbba..9c77cfcd 100644
> > > --- a/tests/meson.build
> > > +++ b/tests/meson.build
> > > @@ -63,6 +63,7 @@ test_progs = [
> > >  	'kms_universal_plane',
> > >  	'kms_vblank',
> > >  	'kms_vrr',
> > > +	'kms_writeback',
> > >  	'meta_test',
> > >  	'panfrost_get_param',
> > >  	'panfrost_gem_new',
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> 
> -- 
> Rodrigo Siqueira
> https://siqueira.tech



-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-07-12 11:40         ` Ser, Simon
@ 2019-07-17  1:21           ` Rodrigo Siqueira
  -1 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-17  1:21 UTC (permalink / raw)
  To: Ser, Simon; +Cc: intel-gfx, igt-dev, nd


[-- Attachment #1.1: Type: text/plain, Size: 19646 bytes --]

On 07/12, Ser, Simon wrote:
> On Thu, 2019-07-11 at 23:44 -0300, Rodrigo Siqueira wrote:
> > On 07/10, Ser, Simon wrote:
> > > Hi,
> > > 
> > > Thanks for the patch! Here are a few comments.
> > > 
> > > For bonus points, it would be nice to add igt_describe descriptions of
> > > each sub-test.
> > 
> > Hi Simon,
> > 
> > First of all, thanks for your feedback; I already applied most of your
> > suggestions. I just have some inline comments/questions.
> >  
> > > On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> > > > Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> > > > WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> > > > behaviour is correct.
> > > > 
> > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > [rebased and updated do_writeback_test() function to address feedback]
> > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > ---
> > > >  tests/Makefile.sources |   1 +
> > > >  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
> > > >  tests/meson.build      |   1 +
> > > >  3 files changed, 316 insertions(+)
> > > >  create mode 100644 tests/kms_writeback.c
> > > > 
> > > > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > > > index 027ed82f..03cc8efa 100644
> > > > --- a/tests/Makefile.sources
> > > > +++ b/tests/Makefile.sources
> > > > @@ -77,6 +77,7 @@ TESTS_progs = \
> > > >  	kms_universal_plane \
> > > >  	kms_vblank \
> > > >  	kms_vrr \
> > > > +	kms_writeback \
> > > >  	meta_test \
> > > >  	perf \
> > > >  	perf_pmu \
> > > > diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> > > > new file mode 100644
> > > > index 00000000..66ef48a6
> > > > --- /dev/null
> > > > +++ b/tests/kms_writeback.c
> > > > @@ -0,0 +1,314 @@
> > > > +/*
> > > > + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> > > > + *
> > > > + * Permission is hereby granted, free of charge, to any person obtaining a
> > > > + * copy of this software and associated documentation files (the "Software"),
> > > > + * to deal in the Software without restriction, including without limitation
> > > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > > > + * and/or sell copies of the Software, and to permit persons to whom the
> > > > + * Software is furnished to do so, subject to the following conditions:
> > > > + *
> > > > + * The above copyright notice and this permission notice (including the next
> > > > + * paragraph) shall be included in all copies or substantial portions of the
> > > > + * Software.
> > > > + *
> > > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > > > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > > > + * IN THE SOFTWARE.
> > > > + *
> > > > + */
> > > > +
> > > > +#include <errno.h>
> > > > +#include <stdbool.h>
> > > > +#include <stdio.h>
> > > > +#include <string.h>
> > > > +
> > > > +#include "igt.h"
> > > > +#include "igt_core.h"
> > > > +#include "igt_fb.h"
> > > > +
> > > > +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> > > > +{
> > > > +	drmModePropertyBlobRes *blob = NULL;
> > > > +	uint64_t blob_id;
> > > > +	int ret;
> > > > +
> > > > +	ret = kmstest_get_property(output->display->drm_fd,
> > > > +				   output->config.connector->connector_id,
> > > > +				   DRM_MODE_OBJECT_CONNECTOR,
> > > > +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> > > > +				   NULL, &blob_id, NULL);
> > > > +	if (ret)
> > > > +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> > > > +
> > > > +	igt_assert(blob);
> > > > +
> > > > +	return blob;
> > > > +}
> > > > +
> > > > +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> > > > +{
> > > > +	igt_fb_t input_fb, output_fb;
> > > > +	igt_plane_t *plane;
> > > > +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> > > > +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> > > > +	int width, height, ret;
> > > > +	drmModeModeInfo override_mode = {
> > > > +		.clock = 25175,
> > > > +		.hdisplay = 640,
> > > > +		.hsync_start = 656,
> > > > +		.hsync_end = 752,
> > > > +		.htotal = 800,
> > > > +		.hskew = 0,
> > > > +		.vdisplay = 480,
> > > > +		.vsync_start = 490,
> > > > +		.vsync_end = 492,
> > > > +		.vtotal = 525,
> > > > +		.vscan = 0,
> > > > +		.vrefresh = 60,
> > > > +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> > > > +		.name = {"640x480-60"},
> > > > +	};
> > > > +	igt_output_override_mode(output, &override_mode);
> > > > +
> > > > +	width = override_mode.hdisplay;
> > > > +	height = override_mode.vdisplay;
> > > > +
> > > > +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> > > > +	igt_assert(ret >= 0);
> > > > +
> > > > +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> > > > +	igt_assert(ret >= 0);
> > > > +
> > > > +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > +	igt_plane_set_fb(plane, &input_fb);
> > > > +	igt_output_set_writeback_fb(output, &output_fb);
> > > > +
> > > > +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> > > > +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> > > 
> > > Okay, we're using atomic test-only mode to know if we can perform tests
> > > with the writeback output. It's probably fine, but we don't use
> > > WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.
> > 
> > Sorry, I did not fully understand part. Did you expect to see something
> > like the below code before igt_display_try_commit_atomic()?
> > 
> >  igt_output_set_prop_value(output, WRITEBACK_PIXEL_FORMATS,
> >                            DRM_FORMAT_XRGB8888);
> 
> Hmm, no, we cannot change the list of writeback formats (it's
> immutable).
> 
> This comment doesn't require any action, it's just me thinking aloud :P
> 
> I'm just thinking that it would be nice to choose our format depending
> on the WRITEBACK_PIXEL_FORMATS property. And probably run tests with
> each supported format (or, alternatively, choose a random one). That
> way we can make sure WRITEBACK_PIXEL_FORMATS isn't broken.
> 
> However, this can be left for a later patch.
> 
> > > > +	igt_plane_set_fb(plane, NULL);
> > > > +	igt_remove_fb(display->drm_fd, &input_fb);
> > > > +	igt_remove_fb(display->drm_fd, &output_fb);
> > > > +
> > > > +	return !ret;
> > > > +}
> > > > +
> > > > +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> > > > +{
> > > > +	int i;
> > > > +
> > > > +	for (i = 0; i < display->n_outputs; i++) {
> > > > +		igt_output_t *output = &display->outputs[i];
> > > > +		int j;
> > > > +
> > > > +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> > > > +			continue;
> > > > +
> > > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
> > > 
> > > Hmm. Is this really necessary? "Real" userspace won't do this, so I
> > > don't think we need to either.
> > 
> > Hmmm, I have a little experience with userspace; however, I tested
> > kms_writeback on top of vkms without this line, and everything worked
> > well. If I remove this line, should I also drop the line that force
> > connector to FORCE_CONNECTOR_UNSPECIFIED?
> 
> I believe so.
> 
> > Another question, if FORCE_CONNECTOR_ON is something that userspace
> > won't want to do, why do we have it?
> 
> We use kmstest_force_connector in injection tests: those pick a
> disconnected HDMI connector and trick the kernel into thinking it's
> connected. We generally also force an EDID and this is used to emulate
> a screen (e.g. a screen that supports audio, 4K or 3D).
> 
> This is only meant to be used for testing though, hence "real userspace
> shouldn't use it".
>

Ahhh, I see. Thanks for the explanation
 
> > > > +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> > > > +			igt_output_set_pipe(output, j);
> > > > +
> > > > +			if (check_writeback_config(display, output)) {
> > > > +				igt_debug("Using connector %u:%s on pipe %d\n",
> > > > +					  output->config.connector->connector_id,
> > > > +					  output->name, j);
> > > > +				return output;
> > > > +			}
> > > 
> > > We could probably add an igt_debug statement in case we don't use this
> > > writeback output.
> > > 
> > > > +		}
> > > > +
> > > > +		/* Restore any connectors we don't use, so we don't trip on them later */
> > > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> > > > +	}
> > > > +
> > > > +	return NULL;
> > > > +}
> > > > +
> > > > +static void check_writeback_fb_id(igt_output_t *output)
> > > > +{
> > > > +	uint64_t check_fb_id;
> > > > +
> > > > +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > > +	igt_assert(check_fb_id == 0);
> > > > +}
> > > > +
> > > > +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> > > > +			      uint32_t fb_id, int32_t *out_fence_ptr,
> > > > +			      bool ptr_valid)
> > > 
> > > flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
> > > probably remove the parameter from this function.
> > > 
> > > > +{
> > > > +	int ret;
> > > > +	igt_display_t *display = output->display;
> > > > +	struct kmstest_connector_config *config = &output->config;
> > > > +
> > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> > > > +
> > > > +	if (ptr_valid)
> > > > +		*out_fence_ptr = 0;
> > > > +
> > > > +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> > > > +
> > > > +	if (ptr_valid)
> > > > +		igt_assert(*out_fence_ptr == -1);
> > > 
> > > I'm confused. Why should this be -1 even if we
> > > igt_display_try_commit_atomic succeeds?
> > 
> > I inspected the drm_mode_atomic_ioctl() function and I noticed that It
> > calls complete_signaling() in its turn this function assign -1 to
> > out_fence_ptr. Since all of this happens at the end of atomic_commit, I
> > believe that we don’t need it. I already removed it.
> 
> I think I'm still confused :)
> 
> I'm probably missing something. As far as I understand, we are doing an
> atomic commit, sometimes with a valid WRITEBACK_FB_ID and
> WRITEBACK_OUT_FENCE_PTR. In this case it should start the writeback
> process in the kernel and we should get a valid out_fence_ptr?
> 
> Why do we always get -1?

FWIU userspace uses the WRITEBACK_OUT_FENCE_PTR to provide a pointer for
the kernel to fill with a sync_file file descriptor, which will signal
once the writeback is finished. If the signal was correctly handled, the
out_fence_ptr would be set to -1, because of this we always get -1.

Thanks for your feedback, I'll prepare a new version soon.
 
> > > > +	/* WRITEBACK_FB_ID must always read as zero */
> > > > +	check_writeback_fb_id(output);
> > > > +
> > > > +	return ret;
> > > > +}
> > > > +
> > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > +{
> > > > +	int i, ret;
> > > > +	int32_t out_fence;
> > > > +	struct {
> > > > +		uint32_t fb_id;
> > > > +		bool ptr_valid;
> > > > +		int32_t *out_fence_ptr;
> > > > +	} invalid_tests[] = {
> > > > +		{
> > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > +			.fb_id = 0,
> > > > +			.ptr_valid = true,
> > > > +			.out_fence_ptr = &out_fence,
> > > > +		},
> > > > +		{
> > > > +			/* Invalid output buffer. */
> > > > +			.fb_id = invalid_fb->fb_id,
> > > > +			.ptr_valid = true,
> > > > +			.out_fence_ptr = &out_fence,
> > > > +		},
> > > 
> > > This doesn't belong in this function (invalid_out_fence), since this
> > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > 
> > > > +		{
> > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > +			.fb_id = valid_fb->fb_id,
> > > > +			.ptr_valid = false,
> > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > +		},
> > > > +	};
> > > > +
> > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +					invalid_tests[i].fb_id,
> > > > +					invalid_tests[i].out_fence_ptr,
> > > > +					invalid_tests[i].ptr_valid);
> > > > +		igt_assert(ret != 0);
> > > 
> > > Maybe we can check for -ret == EINVAL?
> > > 
> > > > +	}
> > > > +}
> > > > +
> > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > 
> > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > the input framebuffer. It's probably not a good idea to use the same FB
> > > for input and writeback output.
> > > 
> > > > +{
> > > > +
> > > > +	int ret;
> > > > +
> > > > +	/* Valid output buffer */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				valid_fb->fb_id, NULL, false);
> > > > +	igt_assert(ret == 0);
> > > > +
> > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				output->id, NULL, false);
> > > > +	igt_assert(ret == -EINVAL);
> > > > +
> > > > +	/* Zero WRITEBACK_FB_ID */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				0, NULL, false);
> > > > +	igt_assert(ret == 0);
> > > > +}
> > > > +
> > > > +igt_main
> > > > +{
> > > > +	igt_display_t display;
> > > > +	igt_output_t *output;
> > > > +	igt_plane_t *plane;
> > > > +	igt_fb_t input_fb;
> > > > +	drmModeModeInfo mode;
> > > > +	int ret;
> > > > +
> > > > +	memset(&display, 0, sizeof(display));
> > > > +
> > > > +	igt_fixture {
> > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > +		igt_display_require(&display, display.drm_fd);
> > > > +
> > > > +		kmstest_set_vt_graphics_mode();
> > > > +
> > > > +		igt_display_require(&display, display.drm_fd);
> > > > +
> > > > +		igt_require(display.is_atomic);
> > > > +
> > > > +		output = kms_writeback_get_output(&display);
> > > > +		igt_require(output);
> > > > +
> > > > +		if (output->use_override_mode)
> > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > +		else
> > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > +
> > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > +		igt_require(plane);
> > > 
> > > Maybe we can assert on this?
> > > 
> > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > +				    mode.vdisplay,
> > > > +				    DRM_FORMAT_XRGB8888,
> > > > +				    igt_fb_mod_to_tiling(0),
> > > 
> > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > better to make this clear.
> > > 
> > > (Applies to other lines of this patch)
> > > 
> > > > +				    &input_fb);
> > > > +		igt_assert(ret >= 0);
> > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > +	}
> > > > +
> > > > +	igt_subtest("writeback-pixel-formats") {
> > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > 
> > > Need to drmModeFreePropertyBlob this.
> > > 
> > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > +		unsigned int i;
> > > > +		char *c;
> > > > +
> > > > +		/*
> > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > +		 * any outlandish characters
> > > > +		 */
> > > > +		igt_assert(!(formats_blob->length % 4));
> > > > +		c = formats_blob->data;
> > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > +				     "Unexpected character %c\n", c[i]);
> > > 
> > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > codes will be made from ASCII characters, in fact some formats already
> > > have non-printable chars in them. I don't want to have to update this
> > > test when a new fourcc format is added.
> > > 
> > > We currently don't have a test for IN_FORMATS. If we really want to
> > > check formats, we could have a big array of known formats and add a
> > > bool is_valid_format(uint32_t fmt) function.
> > 
> > Agree with you. How about remove this test?
> 
> I guess we could always keep the length % 4 test, even if it's just a
> sanity test. At least this one won't ever need to be changed.
> 
> I don't feel strongly about it.
> 
> > Thanks
> > Best Regards
> > 
> > > > +	}
> > > > +
> > > > +	igt_subtest("writeback-invalid-out-fence") {
> > > > +		igt_fb_t invalid_fb;
> > > 
> > > invalid_output_fb would be a better name IMHO.
> > > 
> > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> > > > +				    mode.vdisplay / 2,
> > > > +				    DRM_FORMAT_XRGB8888,
> > > > +				    igt_fb_mod_to_tiling(0),
> > > > +				    &invalid_fb);
> > > > +		igt_require(ret > 0);
> > > 
> > > We should probably use a different variable: ret is signed,
> > > igt_create_fb isn't. Also ret doesn't make it clear that the return
> > > value is the KMS framebuffer ID.
> > > 
> > > (Applies to other subtests)
> > > 
> > > > +		invalid_out_fence(output, &input_fb, &invalid_fb);
> > > 
> > > (Still not sure why we provide the input FB to this function.)
> > > 
> > > > +		igt_remove_fb(display.drm_fd, &invalid_fb);
> > > > +	}
> > > > +
> > > > +	igt_subtest("writeback-fb-id") {
> > > > +		igt_fb_t output_fb;
> > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> > > > +				    DRM_FORMAT_XRGB8888,
> > > > +				    igt_fb_mod_to_tiling(0),
> > > > +				    &output_fb);
> > > > +		igt_require(ret > 0);
> > > > +
> > > > +		writeback_fb_id(output, &input_fb, &output_fb);
> > > > +
> > > > +		igt_remove_fb(display.drm_fd, &output_fb);
> > > > +	}
> > > > +
> > > > +	igt_fixture {
> > > > +		igt_remove_fb(display.drm_fd, &input_fb);
> > > > +		igt_display_fini(&display);
> > > > +	}
> > > > +}
> > > > diff --git a/tests/meson.build b/tests/meson.build
> > > > index f168fbba..9c77cfcd 100644
> > > > --- a/tests/meson.build
> > > > +++ b/tests/meson.build
> > > > @@ -63,6 +63,7 @@ test_progs = [
> > > >  	'kms_universal_plane',
> > > >  	'kms_vblank',
> > > >  	'kms_vrr',
> > > > +	'kms_writeback',
> > > >  	'meta_test',
> > > >  	'panfrost_get_param',
> > > >  	'panfrost_gem_new',
> > > > _______________________________________________
> > > > igt-dev mailing list
> > > > igt-dev@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-17  1:21           ` Rodrigo Siqueira
  0 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-17  1:21 UTC (permalink / raw)
  To: Ser, Simon
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey


[-- Attachment #1.1: Type: text/plain, Size: 19646 bytes --]

On 07/12, Ser, Simon wrote:
> On Thu, 2019-07-11 at 23:44 -0300, Rodrigo Siqueira wrote:
> > On 07/10, Ser, Simon wrote:
> > > Hi,
> > > 
> > > Thanks for the patch! Here are a few comments.
> > > 
> > > For bonus points, it would be nice to add igt_describe descriptions of
> > > each sub-test.
> > 
> > Hi Simon,
> > 
> > First of all, thanks for your feedback; I already applied most of your
> > suggestions. I just have some inline comments/questions.
> >  
> > > On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> > > > Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> > > > WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> > > > behaviour is correct.
> > > > 
> > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > [rebased and updated do_writeback_test() function to address feedback]
> > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > ---
> > > >  tests/Makefile.sources |   1 +
> > > >  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
> > > >  tests/meson.build      |   1 +
> > > >  3 files changed, 316 insertions(+)
> > > >  create mode 100644 tests/kms_writeback.c
> > > > 
> > > > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > > > index 027ed82f..03cc8efa 100644
> > > > --- a/tests/Makefile.sources
> > > > +++ b/tests/Makefile.sources
> > > > @@ -77,6 +77,7 @@ TESTS_progs = \
> > > >  	kms_universal_plane \
> > > >  	kms_vblank \
> > > >  	kms_vrr \
> > > > +	kms_writeback \
> > > >  	meta_test \
> > > >  	perf \
> > > >  	perf_pmu \
> > > > diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> > > > new file mode 100644
> > > > index 00000000..66ef48a6
> > > > --- /dev/null
> > > > +++ b/tests/kms_writeback.c
> > > > @@ -0,0 +1,314 @@
> > > > +/*
> > > > + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> > > > + *
> > > > + * Permission is hereby granted, free of charge, to any person obtaining a
> > > > + * copy of this software and associated documentation files (the "Software"),
> > > > + * to deal in the Software without restriction, including without limitation
> > > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > > > + * and/or sell copies of the Software, and to permit persons to whom the
> > > > + * Software is furnished to do so, subject to the following conditions:
> > > > + *
> > > > + * The above copyright notice and this permission notice (including the next
> > > > + * paragraph) shall be included in all copies or substantial portions of the
> > > > + * Software.
> > > > + *
> > > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > > > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > > > + * IN THE SOFTWARE.
> > > > + *
> > > > + */
> > > > +
> > > > +#include <errno.h>
> > > > +#include <stdbool.h>
> > > > +#include <stdio.h>
> > > > +#include <string.h>
> > > > +
> > > > +#include "igt.h"
> > > > +#include "igt_core.h"
> > > > +#include "igt_fb.h"
> > > > +
> > > > +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> > > > +{
> > > > +	drmModePropertyBlobRes *blob = NULL;
> > > > +	uint64_t blob_id;
> > > > +	int ret;
> > > > +
> > > > +	ret = kmstest_get_property(output->display->drm_fd,
> > > > +				   output->config.connector->connector_id,
> > > > +				   DRM_MODE_OBJECT_CONNECTOR,
> > > > +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> > > > +				   NULL, &blob_id, NULL);
> > > > +	if (ret)
> > > > +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> > > > +
> > > > +	igt_assert(blob);
> > > > +
> > > > +	return blob;
> > > > +}
> > > > +
> > > > +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> > > > +{
> > > > +	igt_fb_t input_fb, output_fb;
> > > > +	igt_plane_t *plane;
> > > > +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> > > > +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> > > > +	int width, height, ret;
> > > > +	drmModeModeInfo override_mode = {
> > > > +		.clock = 25175,
> > > > +		.hdisplay = 640,
> > > > +		.hsync_start = 656,
> > > > +		.hsync_end = 752,
> > > > +		.htotal = 800,
> > > > +		.hskew = 0,
> > > > +		.vdisplay = 480,
> > > > +		.vsync_start = 490,
> > > > +		.vsync_end = 492,
> > > > +		.vtotal = 525,
> > > > +		.vscan = 0,
> > > > +		.vrefresh = 60,
> > > > +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> > > > +		.name = {"640x480-60"},
> > > > +	};
> > > > +	igt_output_override_mode(output, &override_mode);
> > > > +
> > > > +	width = override_mode.hdisplay;
> > > > +	height = override_mode.vdisplay;
> > > > +
> > > > +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> > > > +	igt_assert(ret >= 0);
> > > > +
> > > > +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> > > > +	igt_assert(ret >= 0);
> > > > +
> > > > +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > +	igt_plane_set_fb(plane, &input_fb);
> > > > +	igt_output_set_writeback_fb(output, &output_fb);
> > > > +
> > > > +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> > > > +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> > > 
> > > Okay, we're using atomic test-only mode to know if we can perform tests
> > > with the writeback output. It's probably fine, but we don't use
> > > WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.
> > 
> > Sorry, I did not fully understand part. Did you expect to see something
> > like the below code before igt_display_try_commit_atomic()?
> > 
> >  igt_output_set_prop_value(output, WRITEBACK_PIXEL_FORMATS,
> >                            DRM_FORMAT_XRGB8888);
> 
> Hmm, no, we cannot change the list of writeback formats (it's
> immutable).
> 
> This comment doesn't require any action, it's just me thinking aloud :P
> 
> I'm just thinking that it would be nice to choose our format depending
> on the WRITEBACK_PIXEL_FORMATS property. And probably run tests with
> each supported format (or, alternatively, choose a random one). That
> way we can make sure WRITEBACK_PIXEL_FORMATS isn't broken.
> 
> However, this can be left for a later patch.
> 
> > > > +	igt_plane_set_fb(plane, NULL);
> > > > +	igt_remove_fb(display->drm_fd, &input_fb);
> > > > +	igt_remove_fb(display->drm_fd, &output_fb);
> > > > +
> > > > +	return !ret;
> > > > +}
> > > > +
> > > > +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> > > > +{
> > > > +	int i;
> > > > +
> > > > +	for (i = 0; i < display->n_outputs; i++) {
> > > > +		igt_output_t *output = &display->outputs[i];
> > > > +		int j;
> > > > +
> > > > +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> > > > +			continue;
> > > > +
> > > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
> > > 
> > > Hmm. Is this really necessary? "Real" userspace won't do this, so I
> > > don't think we need to either.
> > 
> > Hmmm, I have a little experience with userspace; however, I tested
> > kms_writeback on top of vkms without this line, and everything worked
> > well. If I remove this line, should I also drop the line that force
> > connector to FORCE_CONNECTOR_UNSPECIFIED?
> 
> I believe so.
> 
> > Another question, if FORCE_CONNECTOR_ON is something that userspace
> > won't want to do, why do we have it?
> 
> We use kmstest_force_connector in injection tests: those pick a
> disconnected HDMI connector and trick the kernel into thinking it's
> connected. We generally also force an EDID and this is used to emulate
> a screen (e.g. a screen that supports audio, 4K or 3D).
> 
> This is only meant to be used for testing though, hence "real userspace
> shouldn't use it".
>

Ahhh, I see. Thanks for the explanation
 
> > > > +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> > > > +			igt_output_set_pipe(output, j);
> > > > +
> > > > +			if (check_writeback_config(display, output)) {
> > > > +				igt_debug("Using connector %u:%s on pipe %d\n",
> > > > +					  output->config.connector->connector_id,
> > > > +					  output->name, j);
> > > > +				return output;
> > > > +			}
> > > 
> > > We could probably add an igt_debug statement in case we don't use this
> > > writeback output.
> > > 
> > > > +		}
> > > > +
> > > > +		/* Restore any connectors we don't use, so we don't trip on them later */
> > > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> > > > +	}
> > > > +
> > > > +	return NULL;
> > > > +}
> > > > +
> > > > +static void check_writeback_fb_id(igt_output_t *output)
> > > > +{
> > > > +	uint64_t check_fb_id;
> > > > +
> > > > +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > > +	igt_assert(check_fb_id == 0);
> > > > +}
> > > > +
> > > > +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> > > > +			      uint32_t fb_id, int32_t *out_fence_ptr,
> > > > +			      bool ptr_valid)
> > > 
> > > flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
> > > probably remove the parameter from this function.
> > > 
> > > > +{
> > > > +	int ret;
> > > > +	igt_display_t *display = output->display;
> > > > +	struct kmstest_connector_config *config = &output->config;
> > > > +
> > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> > > > +
> > > > +	if (ptr_valid)
> > > > +		*out_fence_ptr = 0;
> > > > +
> > > > +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> > > > +
> > > > +	if (ptr_valid)
> > > > +		igt_assert(*out_fence_ptr == -1);
> > > 
> > > I'm confused. Why should this be -1 even if we
> > > igt_display_try_commit_atomic succeeds?
> > 
> > I inspected the drm_mode_atomic_ioctl() function and I noticed that It
> > calls complete_signaling() in its turn this function assign -1 to
> > out_fence_ptr. Since all of this happens at the end of atomic_commit, I
> > believe that we don’t need it. I already removed it.
> 
> I think I'm still confused :)
> 
> I'm probably missing something. As far as I understand, we are doing an
> atomic commit, sometimes with a valid WRITEBACK_FB_ID and
> WRITEBACK_OUT_FENCE_PTR. In this case it should start the writeback
> process in the kernel and we should get a valid out_fence_ptr?
> 
> Why do we always get -1?

FWIU userspace uses the WRITEBACK_OUT_FENCE_PTR to provide a pointer for
the kernel to fill with a sync_file file descriptor, which will signal
once the writeback is finished. If the signal was correctly handled, the
out_fence_ptr would be set to -1, because of this we always get -1.

Thanks for your feedback, I'll prepare a new version soon.
 
> > > > +	/* WRITEBACK_FB_ID must always read as zero */
> > > > +	check_writeback_fb_id(output);
> > > > +
> > > > +	return ret;
> > > > +}
> > > > +
> > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > +{
> > > > +	int i, ret;
> > > > +	int32_t out_fence;
> > > > +	struct {
> > > > +		uint32_t fb_id;
> > > > +		bool ptr_valid;
> > > > +		int32_t *out_fence_ptr;
> > > > +	} invalid_tests[] = {
> > > > +		{
> > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > +			.fb_id = 0,
> > > > +			.ptr_valid = true,
> > > > +			.out_fence_ptr = &out_fence,
> > > > +		},
> > > > +		{
> > > > +			/* Invalid output buffer. */
> > > > +			.fb_id = invalid_fb->fb_id,
> > > > +			.ptr_valid = true,
> > > > +			.out_fence_ptr = &out_fence,
> > > > +		},
> > > 
> > > This doesn't belong in this function (invalid_out_fence), since this
> > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > 
> > > > +		{
> > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > +			.fb_id = valid_fb->fb_id,
> > > > +			.ptr_valid = false,
> > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > +		},
> > > > +	};
> > > > +
> > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +					invalid_tests[i].fb_id,
> > > > +					invalid_tests[i].out_fence_ptr,
> > > > +					invalid_tests[i].ptr_valid);
> > > > +		igt_assert(ret != 0);
> > > 
> > > Maybe we can check for -ret == EINVAL?
> > > 
> > > > +	}
> > > > +}
> > > > +
> > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > 
> > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > the input framebuffer. It's probably not a good idea to use the same FB
> > > for input and writeback output.
> > > 
> > > > +{
> > > > +
> > > > +	int ret;
> > > > +
> > > > +	/* Valid output buffer */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				valid_fb->fb_id, NULL, false);
> > > > +	igt_assert(ret == 0);
> > > > +
> > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				output->id, NULL, false);
> > > > +	igt_assert(ret == -EINVAL);
> > > > +
> > > > +	/* Zero WRITEBACK_FB_ID */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				0, NULL, false);
> > > > +	igt_assert(ret == 0);
> > > > +}
> > > > +
> > > > +igt_main
> > > > +{
> > > > +	igt_display_t display;
> > > > +	igt_output_t *output;
> > > > +	igt_plane_t *plane;
> > > > +	igt_fb_t input_fb;
> > > > +	drmModeModeInfo mode;
> > > > +	int ret;
> > > > +
> > > > +	memset(&display, 0, sizeof(display));
> > > > +
> > > > +	igt_fixture {
> > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > +		igt_display_require(&display, display.drm_fd);
> > > > +
> > > > +		kmstest_set_vt_graphics_mode();
> > > > +
> > > > +		igt_display_require(&display, display.drm_fd);
> > > > +
> > > > +		igt_require(display.is_atomic);
> > > > +
> > > > +		output = kms_writeback_get_output(&display);
> > > > +		igt_require(output);
> > > > +
> > > > +		if (output->use_override_mode)
> > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > +		else
> > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > +
> > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > +		igt_require(plane);
> > > 
> > > Maybe we can assert on this?
> > > 
> > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > +				    mode.vdisplay,
> > > > +				    DRM_FORMAT_XRGB8888,
> > > > +				    igt_fb_mod_to_tiling(0),
> > > 
> > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > better to make this clear.
> > > 
> > > (Applies to other lines of this patch)
> > > 
> > > > +				    &input_fb);
> > > > +		igt_assert(ret >= 0);
> > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > +	}
> > > > +
> > > > +	igt_subtest("writeback-pixel-formats") {
> > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > 
> > > Need to drmModeFreePropertyBlob this.
> > > 
> > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > +		unsigned int i;
> > > > +		char *c;
> > > > +
> > > > +		/*
> > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > +		 * any outlandish characters
> > > > +		 */
> > > > +		igt_assert(!(formats_blob->length % 4));
> > > > +		c = formats_blob->data;
> > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > +				     "Unexpected character %c\n", c[i]);
> > > 
> > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > codes will be made from ASCII characters, in fact some formats already
> > > have non-printable chars in them. I don't want to have to update this
> > > test when a new fourcc format is added.
> > > 
> > > We currently don't have a test for IN_FORMATS. If we really want to
> > > check formats, we could have a big array of known formats and add a
> > > bool is_valid_format(uint32_t fmt) function.
> > 
> > Agree with you. How about remove this test?
> 
> I guess we could always keep the length % 4 test, even if it's just a
> sanity test. At least this one won't ever need to be changed.
> 
> I don't feel strongly about it.
> 
> > Thanks
> > Best Regards
> > 
> > > > +	}
> > > > +
> > > > +	igt_subtest("writeback-invalid-out-fence") {
> > > > +		igt_fb_t invalid_fb;
> > > 
> > > invalid_output_fb would be a better name IMHO.
> > > 
> > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> > > > +				    mode.vdisplay / 2,
> > > > +				    DRM_FORMAT_XRGB8888,
> > > > +				    igt_fb_mod_to_tiling(0),
> > > > +				    &invalid_fb);
> > > > +		igt_require(ret > 0);
> > > 
> > > We should probably use a different variable: ret is signed,
> > > igt_create_fb isn't. Also ret doesn't make it clear that the return
> > > value is the KMS framebuffer ID.
> > > 
> > > (Applies to other subtests)
> > > 
> > > > +		invalid_out_fence(output, &input_fb, &invalid_fb);
> > > 
> > > (Still not sure why we provide the input FB to this function.)
> > > 
> > > > +		igt_remove_fb(display.drm_fd, &invalid_fb);
> > > > +	}
> > > > +
> > > > +	igt_subtest("writeback-fb-id") {
> > > > +		igt_fb_t output_fb;
> > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> > > > +				    DRM_FORMAT_XRGB8888,
> > > > +				    igt_fb_mod_to_tiling(0),
> > > > +				    &output_fb);
> > > > +		igt_require(ret > 0);
> > > > +
> > > > +		writeback_fb_id(output, &input_fb, &output_fb);
> > > > +
> > > > +		igt_remove_fb(display.drm_fd, &output_fb);
> > > > +	}
> > > > +
> > > > +	igt_fixture {
> > > > +		igt_remove_fb(display.drm_fd, &input_fb);
> > > > +		igt_display_fini(&display);
> > > > +	}
> > > > +}
> > > > diff --git a/tests/meson.build b/tests/meson.build
> > > > index f168fbba..9c77cfcd 100644
> > > > --- a/tests/meson.build
> > > > +++ b/tests/meson.build
> > > > @@ -63,6 +63,7 @@ test_progs = [
> > > >  	'kms_universal_plane',
> > > >  	'kms_vblank',
> > > >  	'kms_vrr',
> > > > +	'kms_writeback',
> > > >  	'meta_test',
> > > >  	'panfrost_get_param',
> > > >  	'panfrost_gem_new',
> > > > _______________________________________________
> > > > igt-dev mailing list
> > > > igt-dev@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
  2019-07-12 12:17           ` Ser, Simon
@ 2019-07-17  1:25             ` Rodrigo Siqueira
  -1 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-17  1:25 UTC (permalink / raw)
  To: Ser, Simon; +Cc: intel-gfx, igt-dev, nd


[-- Attachment #1.1: Type: text/plain, Size: 6567 bytes --]

On 07/12, Ser, Simon wrote:
> On Thu, 2019-07-11 at 23:49 -0300, Rodrigo Siqueira wrote:
> > On 07/10, Ser, Simon wrote:
> > > On Wed, 2019-07-10 at 15:30 +0000, Ser, Simon wrote:
> > > > Mostly LGTM, here are a few nits.
> > > > 
> > > > On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> > > > > To use writeback buffers as a CRC source, we need to be able to hash
> > > > > them. Implement a simple FVA-1a hashing routine for this purpose.
> > > > > 
> > > > > Doing a bytewise hash on the framebuffer directly can be very slow if
> > > > > the memory is noncached. By making a copy of each line in the FB first
> > > > > (which can take advantage of word-access speedup), we can do the hash
> > > > > on a cached copy, which is much faster (10x speedup on my platform).
> > > > > 
> > > > > v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
> > > > >     Chris Wilson
> > > > > 
> > > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > > [rebased and updated to the most recent API]
> > > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > > ---
> > > > >  lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > >  lib/igt_fb.h |  3 +++
> > > > >  2 files changed, 69 insertions(+)
> > > > > 
> > > > > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > > > > index 9d4f905e..d07dae39 100644
> > > > > --- a/lib/igt_fb.c
> > > > > +++ b/lib/igt_fb.c
> > > > > @@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
> > > > >  	return false;
> > > > >  }
> > > > >  
> > > > > +/*
> > > > > + * This implements the FNV-1a hashing algorithm instead of CRC, for
> > > > > + * simplicity
> > > > > + * http://www.isthe.com/chongo/tech/comp/fnv/index.html
> > > > > + *
> > > > > + * hash = offset_basis
> > > > > + * for each octet_of_data to be hashed
> > > > > + *         hash = hash xor octet_of_data
> > > > > + *         hash = hash * FNV_prime
> > > > > + * return hash
> > > > > + *
> > > > > + * 32 bit offset_basis = 2166136261
> > > > > + * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
> > > > > + */
> > > > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
> > > > > +{
> > > > > +#define FNV1a_OFFSET_BIAS 2166136261
> > > > > +#define FNV1a_PRIME 16777619
> > > > 
> > > > I'd just use plain uint32_t variables for those, but no big deal.
> > > > 
> > > > > +	uint32_t hash;
> > > > > +	void *map;
> > > > > +	char *ptr, *line = NULL;
> > > > > +	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
> > > > > +	uint32_t stride = calc_plane_stride(fb, 0);
> > > > 
> > > > We could return -EINVAL in case fb->num_planes != 1.
> > > 
> > > Let's not waste cycles. With this ^ fixed, this patch is:
> > > 
> > > Reviewed-by: Simon Ser <simon.ser@intel.com>
> > > 
> > > Other nits are optional.
> > 
> > I agreed with all your suggestions, and I already applied all of them.
> > Should I wait for the other patches review, or should I resend the new
> > version?
> 
> I'm fine with waiting for the full review before a new version of the
> whole patchset, but you can also send an updated version of a single
> patch with:
> 
>     git send-email --in-reply-to="<cover.1560374714.git.rodrigosiqueiramelo@gmail.com>" -1 <commit hash>
> 
> where In-Reply-To is the Message-Id of the patch you want to update. I
> agree it's a little tedious since you need to extract the Message-Id
> from the message header.

Thanks for the tip with git-send-mail. Since I already applied most of
your suggestions, I'll send a full version soon.
 
> > Thanks for all the feedback
> 
> :)
> 
> > Best Regards
> >  
> > > > > +	if (fb->is_dumb)
> > > > > +		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
> > > > > +					      PROT_READ);
> > > > > +	else
> > > > > +		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
> > > > > +				    PROT_READ);
> > > > > +	ptr = map;
> > > > 
> > > > Nit: no need for this, can assign the result of mmap directly to ptr.
> > > > 
> > > > > +
> > > > > +	/*
> > > > > +	 * Framebuffers are often uncached, which can make byte-wise accesses
> > > > > +	 * very slow. We copy each line of the FB into a local buffer to speed
> > > > > +	 * up the hashing.
> > > > > +	 */
> > > > > +	line = malloc(stride);
> > > > > +	if (!line) {
> > > > > +		munmap(map, fb->size);
> > > > > +		return -ENOMEM;
> > > > > +	}
> > > > > +
> > > > > +	hash = FNV1a_OFFSET_BIAS;
> > > > > +
> > > > > +	for (y = 0; y < fb->height; y++, ptr += stride) {
> > > > > +
> > > > > +		igt_memcpy_from_wc(line, ptr, stride);
> > > > 
> > > > Nit: no need to copy the whole stride actually, we can just copy
> > > > fb->width * cpp since we're only going to read that.
> > > > 
> > > > > +
> > > > > +		for (x = 0; x < fb->width * cpp; x++) {
> > > > > +			hash ^= line[x];
> > > > > +			hash *= FNV1a_PRIME;
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	crc->n_words = 1;
> > > > > +	crc->crc[0] = hash;
> > > > > +
> > > > > +	free(line);
> > > > > +	munmap(map, fb->size);
> > > > > +
> > > > > +	return 0;
> > > > > +#undef FNV1a_OFFSET_BIAS
> > > > > +#undef FNV1a_PRIME
> > > > > +}
> > > > > +
> > > > >  /**
> > > > >   * igt_format_is_yuv:
> > > > >   * @drm_format: drm fourcc
> > > > > diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> > > > > index adefebe1..a2741c05 100644
> > > > > --- a/lib/igt_fb.h
> > > > > +++ b/lib/igt_fb.h
> > > > > @@ -37,6 +37,7 @@
> > > > >  #include <i915_drm.h>
> > > > >  
> > > > >  #include "igt_color_encoding.h"
> > > > > +#include "igt_debugfs.h"
> > > > >  
> > > > >  /*
> > > > >   * Internal format to denote a buffer compatible with pixman's
> > > > > @@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
> > > > >  void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
> > > > >  			   bool allow_yuv);
> > > > >  
> > > > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
> > > > > +
> > > > >  #endif /* __IGT_FB_H__ */
> > > > >  
> > > > > _______________________________________________
> > > > > igt-dev mailing list
> > > > > igt-dev@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> > > > _______________________________________________
> > > > igt-dev mailing list
> > > > igt-dev@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer
@ 2019-07-17  1:25             ` Rodrigo Siqueira
  0 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-17  1:25 UTC (permalink / raw)
  To: Ser, Simon
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey


[-- Attachment #1.1: Type: text/plain, Size: 6567 bytes --]

On 07/12, Ser, Simon wrote:
> On Thu, 2019-07-11 at 23:49 -0300, Rodrigo Siqueira wrote:
> > On 07/10, Ser, Simon wrote:
> > > On Wed, 2019-07-10 at 15:30 +0000, Ser, Simon wrote:
> > > > Mostly LGTM, here are a few nits.
> > > > 
> > > > On Wed, 2019-06-12 at 23:17 -0300, Brian Starkey wrote:
> > > > > To use writeback buffers as a CRC source, we need to be able to hash
> > > > > them. Implement a simple FVA-1a hashing routine for this purpose.
> > > > > 
> > > > > Doing a bytewise hash on the framebuffer directly can be very slow if
> > > > > the memory is noncached. By making a copy of each line in the FB first
> > > > > (which can take advantage of word-access speedup), we can do the hash
> > > > > on a cached copy, which is much faster (10x speedup on my platform).
> > > > > 
> > > > > v6: use igt_memcpy_from_wc() instead of plain memcpy, as suggested by
> > > > >     Chris Wilson
> > > > > 
> > > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > > [rebased and updated to the most recent API]
> > > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > > ---
> > > > >  lib/igt_fb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > >  lib/igt_fb.h |  3 +++
> > > > >  2 files changed, 69 insertions(+)
> > > > > 
> > > > > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > > > > index 9d4f905e..d07dae39 100644
> > > > > --- a/lib/igt_fb.c
> > > > > +++ b/lib/igt_fb.c
> > > > > @@ -3256,6 +3256,72 @@ bool igt_fb_supported_format(uint32_t drm_format)
> > > > >  	return false;
> > > > >  }
> > > > >  
> > > > > +/*
> > > > > + * This implements the FNV-1a hashing algorithm instead of CRC, for
> > > > > + * simplicity
> > > > > + * http://www.isthe.com/chongo/tech/comp/fnv/index.html
> > > > > + *
> > > > > + * hash = offset_basis
> > > > > + * for each octet_of_data to be hashed
> > > > > + *         hash = hash xor octet_of_data
> > > > > + *         hash = hash * FNV_prime
> > > > > + * return hash
> > > > > + *
> > > > > + * 32 bit offset_basis = 2166136261
> > > > > + * 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
> > > > > + */
> > > > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc)
> > > > > +{
> > > > > +#define FNV1a_OFFSET_BIAS 2166136261
> > > > > +#define FNV1a_PRIME 16777619
> > > > 
> > > > I'd just use plain uint32_t variables for those, but no big deal.
> > > > 
> > > > > +	uint32_t hash;
> > > > > +	void *map;
> > > > > +	char *ptr, *line = NULL;
> > > > > +	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
> > > > > +	uint32_t stride = calc_plane_stride(fb, 0);
> > > > 
> > > > We could return -EINVAL in case fb->num_planes != 1.
> > > 
> > > Let's not waste cycles. With this ^ fixed, this patch is:
> > > 
> > > Reviewed-by: Simon Ser <simon.ser@intel.com>
> > > 
> > > Other nits are optional.
> > 
> > I agreed with all your suggestions, and I already applied all of them.
> > Should I wait for the other patches review, or should I resend the new
> > version?
> 
> I'm fine with waiting for the full review before a new version of the
> whole patchset, but you can also send an updated version of a single
> patch with:
> 
>     git send-email --in-reply-to="<cover.1560374714.git.rodrigosiqueiramelo@gmail.com>" -1 <commit hash>
> 
> where In-Reply-To is the Message-Id of the patch you want to update. I
> agree it's a little tedious since you need to extract the Message-Id
> from the message header.

Thanks for the tip with git-send-mail. Since I already applied most of
your suggestions, I'll send a full version soon.
 
> > Thanks for all the feedback
> 
> :)
> 
> > Best Regards
> >  
> > > > > +	if (fb->is_dumb)
> > > > > +		map = kmstest_dumb_map_buffer(fb->fd, fb->gem_handle, fb->size,
> > > > > +					      PROT_READ);
> > > > > +	else
> > > > > +		map = gem_mmap__gtt(fb->fd, fb->gem_handle, fb->size,
> > > > > +				    PROT_READ);
> > > > > +	ptr = map;
> > > > 
> > > > Nit: no need for this, can assign the result of mmap directly to ptr.
> > > > 
> > > > > +
> > > > > +	/*
> > > > > +	 * Framebuffers are often uncached, which can make byte-wise accesses
> > > > > +	 * very slow. We copy each line of the FB into a local buffer to speed
> > > > > +	 * up the hashing.
> > > > > +	 */
> > > > > +	line = malloc(stride);
> > > > > +	if (!line) {
> > > > > +		munmap(map, fb->size);
> > > > > +		return -ENOMEM;
> > > > > +	}
> > > > > +
> > > > > +	hash = FNV1a_OFFSET_BIAS;
> > > > > +
> > > > > +	for (y = 0; y < fb->height; y++, ptr += stride) {
> > > > > +
> > > > > +		igt_memcpy_from_wc(line, ptr, stride);
> > > > 
> > > > Nit: no need to copy the whole stride actually, we can just copy
> > > > fb->width * cpp since we're only going to read that.
> > > > 
> > > > > +
> > > > > +		for (x = 0; x < fb->width * cpp; x++) {
> > > > > +			hash ^= line[x];
> > > > > +			hash *= FNV1a_PRIME;
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	crc->n_words = 1;
> > > > > +	crc->crc[0] = hash;
> > > > > +
> > > > > +	free(line);
> > > > > +	munmap(map, fb->size);
> > > > > +
> > > > > +	return 0;
> > > > > +#undef FNV1a_OFFSET_BIAS
> > > > > +#undef FNV1a_PRIME
> > > > > +}
> > > > > +
> > > > >  /**
> > > > >   * igt_format_is_yuv:
> > > > >   * @drm_format: drm fourcc
> > > > > diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> > > > > index adefebe1..a2741c05 100644
> > > > > --- a/lib/igt_fb.h
> > > > > +++ b/lib/igt_fb.h
> > > > > @@ -37,6 +37,7 @@
> > > > >  #include <i915_drm.h>
> > > > >  
> > > > >  #include "igt_color_encoding.h"
> > > > > +#include "igt_debugfs.h"
> > > > >  
> > > > >  /*
> > > > >   * Internal format to denote a buffer compatible with pixman's
> > > > > @@ -194,5 +195,7 @@ int igt_format_plane_bpp(uint32_t drm_format, int plane);
> > > > >  void igt_format_array_fill(uint32_t **formats_array, unsigned int *count,
> > > > >  			   bool allow_yuv);
> > > > >  
> > > > > +int igt_fb_get_crc(struct igt_fb *fb, igt_crc_t *crc);
> > > > > +
> > > > >  #endif /* __IGT_FB_H__ */
> > > > >  
> > > > > _______________________________________________
> > > > > igt-dev mailing list
> > > > > igt-dev@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
> > > > _______________________________________________
> > > > igt-dev mailing list
> > > > igt-dev@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 5/6] lib/igt_kms: Add igt_output_clone_pipe for cloning
  2019-07-12 12:54     ` Ser, Simon
@ 2019-07-17  1:47       ` Rodrigo Siqueira
  -1 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-17  1:47 UTC (permalink / raw)
  To: Ser, Simon; +Cc: intel-gfx, igt-dev, nd


[-- Attachment #1.1: Type: text/plain, Size: 7553 bytes --]

On 07/12, Ser, Simon wrote:
> So, to test these last two patches we'd need specific hardware right?
> Because VKMS doesn't support cloning yet (does it?).

hmmm... actually, VKMS successfully pass in this test. However, if you
compare "writeback-check-output" and "writeback-check-output-clone", you
will notice they are very similar. Maybe, this test does not correctly
validating cloning feature?

> What kind of hardware supports cloned writeback outputs? I have a
> Raspberry Pi which supports writeback via VC4, but I don't think it has
> writeback cloning. I'm also not willing to install any proprietary
> driver.
> 
> I guess we could land the first part of the series, and wait for VKMS
> to support cloned outputs to land the last two patches.
> 
> Any other ideas?

btw, I'm totally comfortable with the idea of focusing on the first part
of this series.

Thanks
 
> On Wed, 2019-06-12 at 23:18 -0300, Brian Starkey wrote:
> > An output can be added as a clone of any other output(s) attached to a
> > pipe using igt_output_clone_pipe()
> > 
> > v5: Drop field out_fence_requested from struct igt_pipe (Brian Starkey)
> > 
> > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > ---
> >  lib/igt_kms.c | 100 +++++++++++++++++++++++++++++++-------------------
> >  lib/igt_kms.h |   4 ++
> >  2 files changed, 66 insertions(+), 38 deletions(-)
> > 
> > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > index 140db346..b85a0404 100644
> > --- a/lib/igt_kms.c
> > +++ b/lib/igt_kms.c
> > @@ -1765,6 +1765,17 @@ static void igt_display_log_shift(igt_display_t *display, int shift)
> >  	igt_assert(display->log_shift >= 0);
> >  }
> >  
> > +static int igt_output_idx(igt_output_t *output)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < output->display->n_outputs; i++)
> > +		if (&output->display->outputs[i] == output)
> > +			return i;
> > +
> > +	return -1;
> > +}
> > +
> >  static void igt_output_refresh(igt_output_t *output)
> >  {
> >  	igt_display_t *display = output->display;
> > @@ -2317,42 +2328,6 @@ void igt_display_fini(igt_display_t *display)
> >  	display->planes = NULL;
> >  }
> >  
> > -static void igt_display_refresh(igt_display_t *display)
> > -{
> > -	igt_output_t *output;
> > -	int i;
> > -
> > -	unsigned long pipes_in_use = 0;
> > -
> > -       /* Check that two outputs aren't trying to use the same pipe */
> > -	for (i = 0; i < display->n_outputs; i++) {
> > -		output = &display->outputs[i];
> > -
> > -		if (output->pending_pipe != PIPE_NONE) {
> > -			if (pipes_in_use & (1 << output->pending_pipe))
> > -				goto report_dup;
> > -
> > -			pipes_in_use |= 1 << output->pending_pipe;
> > -		}
> > -
> > -		if (output->force_reprobe)
> > -			igt_output_refresh(output);
> > -	}
> > -
> > -	return;
> > -
> > -report_dup:
> > -	for (; i > 0; i--) {
> > -		igt_output_t *b = &display->outputs[i - 1];
> > -
> > -		igt_assert_f(output->pending_pipe !=
> > -			     b->pending_pipe,
> > -			     "%s and %s are both trying to use pipe %s\n",
> > -			     igt_output_name(output), igt_output_name(b),
> > -			     kmstest_pipe_name(output->pending_pipe));
> > -	}
> > -}
> > -
> >  static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
> >  {
> >  	igt_display_t *display = output->display;
> > @@ -2376,6 +2351,40 @@ static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
> >  	return &display->pipes[pipe];
> >  }
> >  
> > +static void igt_display_refresh(igt_display_t *display)
> > +{
> > +	igt_output_t *output;
> > +	igt_pipe_t *pipe;
> > +	int i;
> > +
> > +	unsigned long pipes_in_use = 0;
> > +	unsigned long pending_crtc_idx_mask;
> > +
> > +	/* Check that outputs and pipes agree wrt. cloning */
> > +	for (i = 0; i < display->n_outputs; i++) {
> > +		output = &display->outputs[i];
> > +		pending_crtc_idx_mask = 1 << output->pending_pipe;
> > +
> > +		pipe = igt_output_get_driving_pipe(output);
> > +		if (pipe) {
> > +			igt_assert_f(pipe->outputs & (1 << igt_output_idx(output)),
> > +				     "Output %s not expected to be using pipe %s\n",
> > +				     igt_output_name(output),
> > +				     kmstest_pipe_name(pipe->pipe));
> > +
> > +			if (pipes_in_use & pending_crtc_idx_mask)
> > +				LOG(display, "Output %s clones pipe %s\n",
> > +				    igt_output_name(output),
> > +				    kmstest_pipe_name(pipe->pipe));
> > +		}
> > +
> > +		pipes_in_use |= pending_crtc_idx_mask;
> > +
> > +		if (output->force_reprobe)
> > +			igt_output_refresh(output);
> > +	}
> > +}
> > +
> >  static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, int plane_idx)
> >  {
> >  	igt_require_f(plane_idx >= 0 && plane_idx < pipe->n_planes,
> > @@ -3766,6 +3775,7 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
> >  	output->use_override_mode = !!mode;
> >  
> >  	if (pipe) {
> > +		igt_debug("overriding pipe mode in %s way\n", output->display->is_atomic ? "atomic" : "legacy");
> >  		if (output->display->is_atomic)
> >  			igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
> >  		else
> > @@ -3773,6 +3783,16 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
> >  	}
> >  }
> >  
> > +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe)
> > +{
> > +	igt_display_t *display = output->display;
> > +	uint32_t current_clones = display->pipes[pipe].outputs;
> > +
> > +	igt_output_set_pipe(output, pipe);
> > +
> > +	display->pipes[pipe].outputs |= current_clones;
> > +}
> > +
> >  /*
> >   * igt_output_set_pipe:
> >   * @output: Target output for which the pipe is being set to
> > @@ -3789,11 +3809,15 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
> >  
> >  	igt_assert(output->name);
> >  
> > -	if (output->pending_pipe != PIPE_NONE)
> > +	if (output->pending_pipe != PIPE_NONE) {
> >  		old_pipe = igt_output_get_driving_pipe(output);
> > +		old_pipe->outputs &= ~(1 << igt_output_idx(output));
> > +	}
> >  
> > -	if (pipe != PIPE_NONE)
> > +	if (pipe != PIPE_NONE) {
> >  		pipe_obj = &display->pipes[pipe];
> > +		pipe_obj->outputs = (1 << igt_output_idx(output));
> > +	}
> >  
> >  	LOG(display, "%s: set_pipe(%s)\n", igt_output_name(output),
> >  	    kmstest_pipe_name(pipe));
> > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > index cacc6b90..676839bb 100644
> > --- a/lib/igt_kms.h
> > +++ b/lib/igt_kms.h
> > @@ -354,6 +354,8 @@ struct igt_pipe {
> >  	uint32_t crtc_id;
> >  
> >  	int32_t out_fence_fd;
> > +
> > +	uint32_t outputs;
> >  };
> >  
> >  typedef struct {
> > @@ -411,6 +413,8 @@ const char *igt_output_name(igt_output_t *output);
> >  drmModeModeInfo *igt_output_get_mode(igt_output_t *output);
> >  void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode);
> >  void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
> > +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe);
> > +
> >  igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
> >  igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
> >  int igt_output_count_plane_type(igt_output_t *output, int plane_type);
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 5/6] lib/igt_kms: Add igt_output_clone_pipe for cloning
@ 2019-07-17  1:47       ` Rodrigo Siqueira
  0 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-17  1:47 UTC (permalink / raw)
  To: Ser, Simon
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey


[-- Attachment #1.1: Type: text/plain, Size: 7553 bytes --]

On 07/12, Ser, Simon wrote:
> So, to test these last two patches we'd need specific hardware right?
> Because VKMS doesn't support cloning yet (does it?).

hmmm... actually, VKMS successfully pass in this test. However, if you
compare "writeback-check-output" and "writeback-check-output-clone", you
will notice they are very similar. Maybe, this test does not correctly
validating cloning feature?

> What kind of hardware supports cloned writeback outputs? I have a
> Raspberry Pi which supports writeback via VC4, but I don't think it has
> writeback cloning. I'm also not willing to install any proprietary
> driver.
> 
> I guess we could land the first part of the series, and wait for VKMS
> to support cloned outputs to land the last two patches.
> 
> Any other ideas?

btw, I'm totally comfortable with the idea of focusing on the first part
of this series.

Thanks
 
> On Wed, 2019-06-12 at 23:18 -0300, Brian Starkey wrote:
> > An output can be added as a clone of any other output(s) attached to a
> > pipe using igt_output_clone_pipe()
> > 
> > v5: Drop field out_fence_requested from struct igt_pipe (Brian Starkey)
> > 
> > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > ---
> >  lib/igt_kms.c | 100 +++++++++++++++++++++++++++++++-------------------
> >  lib/igt_kms.h |   4 ++
> >  2 files changed, 66 insertions(+), 38 deletions(-)
> > 
> > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > index 140db346..b85a0404 100644
> > --- a/lib/igt_kms.c
> > +++ b/lib/igt_kms.c
> > @@ -1765,6 +1765,17 @@ static void igt_display_log_shift(igt_display_t *display, int shift)
> >  	igt_assert(display->log_shift >= 0);
> >  }
> >  
> > +static int igt_output_idx(igt_output_t *output)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < output->display->n_outputs; i++)
> > +		if (&output->display->outputs[i] == output)
> > +			return i;
> > +
> > +	return -1;
> > +}
> > +
> >  static void igt_output_refresh(igt_output_t *output)
> >  {
> >  	igt_display_t *display = output->display;
> > @@ -2317,42 +2328,6 @@ void igt_display_fini(igt_display_t *display)
> >  	display->planes = NULL;
> >  }
> >  
> > -static void igt_display_refresh(igt_display_t *display)
> > -{
> > -	igt_output_t *output;
> > -	int i;
> > -
> > -	unsigned long pipes_in_use = 0;
> > -
> > -       /* Check that two outputs aren't trying to use the same pipe */
> > -	for (i = 0; i < display->n_outputs; i++) {
> > -		output = &display->outputs[i];
> > -
> > -		if (output->pending_pipe != PIPE_NONE) {
> > -			if (pipes_in_use & (1 << output->pending_pipe))
> > -				goto report_dup;
> > -
> > -			pipes_in_use |= 1 << output->pending_pipe;
> > -		}
> > -
> > -		if (output->force_reprobe)
> > -			igt_output_refresh(output);
> > -	}
> > -
> > -	return;
> > -
> > -report_dup:
> > -	for (; i > 0; i--) {
> > -		igt_output_t *b = &display->outputs[i - 1];
> > -
> > -		igt_assert_f(output->pending_pipe !=
> > -			     b->pending_pipe,
> > -			     "%s and %s are both trying to use pipe %s\n",
> > -			     igt_output_name(output), igt_output_name(b),
> > -			     kmstest_pipe_name(output->pending_pipe));
> > -	}
> > -}
> > -
> >  static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
> >  {
> >  	igt_display_t *display = output->display;
> > @@ -2376,6 +2351,40 @@ static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
> >  	return &display->pipes[pipe];
> >  }
> >  
> > +static void igt_display_refresh(igt_display_t *display)
> > +{
> > +	igt_output_t *output;
> > +	igt_pipe_t *pipe;
> > +	int i;
> > +
> > +	unsigned long pipes_in_use = 0;
> > +	unsigned long pending_crtc_idx_mask;
> > +
> > +	/* Check that outputs and pipes agree wrt. cloning */
> > +	for (i = 0; i < display->n_outputs; i++) {
> > +		output = &display->outputs[i];
> > +		pending_crtc_idx_mask = 1 << output->pending_pipe;
> > +
> > +		pipe = igt_output_get_driving_pipe(output);
> > +		if (pipe) {
> > +			igt_assert_f(pipe->outputs & (1 << igt_output_idx(output)),
> > +				     "Output %s not expected to be using pipe %s\n",
> > +				     igt_output_name(output),
> > +				     kmstest_pipe_name(pipe->pipe));
> > +
> > +			if (pipes_in_use & pending_crtc_idx_mask)
> > +				LOG(display, "Output %s clones pipe %s\n",
> > +				    igt_output_name(output),
> > +				    kmstest_pipe_name(pipe->pipe));
> > +		}
> > +
> > +		pipes_in_use |= pending_crtc_idx_mask;
> > +
> > +		if (output->force_reprobe)
> > +			igt_output_refresh(output);
> > +	}
> > +}
> > +
> >  static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, int plane_idx)
> >  {
> >  	igt_require_f(plane_idx >= 0 && plane_idx < pipe->n_planes,
> > @@ -3766,6 +3775,7 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
> >  	output->use_override_mode = !!mode;
> >  
> >  	if (pipe) {
> > +		igt_debug("overriding pipe mode in %s way\n", output->display->is_atomic ? "atomic" : "legacy");
> >  		if (output->display->is_atomic)
> >  			igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
> >  		else
> > @@ -3773,6 +3783,16 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
> >  	}
> >  }
> >  
> > +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe)
> > +{
> > +	igt_display_t *display = output->display;
> > +	uint32_t current_clones = display->pipes[pipe].outputs;
> > +
> > +	igt_output_set_pipe(output, pipe);
> > +
> > +	display->pipes[pipe].outputs |= current_clones;
> > +}
> > +
> >  /*
> >   * igt_output_set_pipe:
> >   * @output: Target output for which the pipe is being set to
> > @@ -3789,11 +3809,15 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
> >  
> >  	igt_assert(output->name);
> >  
> > -	if (output->pending_pipe != PIPE_NONE)
> > +	if (output->pending_pipe != PIPE_NONE) {
> >  		old_pipe = igt_output_get_driving_pipe(output);
> > +		old_pipe->outputs &= ~(1 << igt_output_idx(output));
> > +	}
> >  
> > -	if (pipe != PIPE_NONE)
> > +	if (pipe != PIPE_NONE) {
> >  		pipe_obj = &display->pipes[pipe];
> > +		pipe_obj->outputs = (1 << igt_output_idx(output));
> > +	}
> >  
> >  	LOG(display, "%s: set_pipe(%s)\n", igt_output_name(output),
> >  	    kmstest_pipe_name(pipe));
> > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > index cacc6b90..676839bb 100644
> > --- a/lib/igt_kms.h
> > +++ b/lib/igt_kms.h
> > @@ -354,6 +354,8 @@ struct igt_pipe {
> >  	uint32_t crtc_id;
> >  
> >  	int32_t out_fence_fd;
> > +
> > +	uint32_t outputs;
> >  };
> >  
> >  typedef struct {
> > @@ -411,6 +413,8 @@ const char *igt_output_name(igt_output_t *output);
> >  drmModeModeInfo *igt_output_get_mode(igt_output_t *output);
> >  void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode);
> >  void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
> > +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe);
> > +
> >  igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
> >  igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
> >  int igt_output_count_plane_type(igt_output_t *output, int plane_type);
> > _______________________________________________
> > igt-dev mailing list
> > igt-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Rodrigo Siqueira
https://siqueira.tech

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-07-16 15:22         ` Liviu.Dudau
@ 2019-07-17 11:46           ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-17 11:46 UTC (permalink / raw)
  To: Liviu.Dudau, rodrigosiqueiramelo; +Cc: intel-gfx, igt-dev, nd

Thanks for the clarification!

On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > +{
> > > > +	int i, ret;
> > > > +	int32_t out_fence;
> > > > +	struct {
> > > > +		uint32_t fb_id;
> > > > +		bool ptr_valid;
> > > > +		int32_t *out_fence_ptr;
> > > > +	} invalid_tests[] = {
> > > > +		{
> > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > +			.fb_id = 0,
> > > > +			.ptr_valid = true,
> > > > +			.out_fence_ptr = &out_fence,
> > > > +		},
> > > > +		{
> > > > +			/* Invalid output buffer. */
> > > > +			.fb_id = invalid_fb->fb_id,
> > > > +			.ptr_valid = true,
> > > > +			.out_fence_ptr = &out_fence,
> > > > +		},
> > > 
> > > This doesn't belong in this function (invalid_out_fence), since this
> > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > move it to writeback_fb_id (and rename that function to test_fb?).
> 
> It tries to test that you can't trick the driver to do any work on a fence if
> the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> invalid fb with valid fence, valid fb but invalid fence and assumes that no
> fb with invalid fence is a NOP anyway.

Yeah, that makes sense, it's just confusing to put it in a function
named invalid_out_fence. Here the out fence is valid, but the output
buffer isn't, so it should probably be moved away (or this function
should be renamed).

> > > > +		{
> > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > +			.fb_id = valid_fb->fb_id,
> > > > +			.ptr_valid = false,
> > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > +		},
> > > > +	};
> > > > +
> > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +					invalid_tests[i].fb_id,
> > > > +					invalid_tests[i].out_fence_ptr,
> > > > +					invalid_tests[i].ptr_valid);
> > > > +		igt_assert(ret != 0);
> > > 
> > > Maybe we can check for -ret == EINVAL?
> > > 
> > > > +	}
> > > > +}
> > > > +
> > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > 
> > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > the input framebuffer. It's probably not a good idea to use the same FB
> > > for input and writeback output.
> > > 
> > > > +{
> > > > +
> > > > +	int ret;
> > > > +
> > > > +	/* Valid output buffer */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				valid_fb->fb_id, NULL, false);
> > > > +	igt_assert(ret == 0);
> > > > +
> > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				output->id, NULL, false);
> > > > +	igt_assert(ret == -EINVAL);
> > > > +
> > > > +	/* Zero WRITEBACK_FB_ID */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				0, NULL, false);
> > > > +	igt_assert(ret == 0);
> > > > +}
> > > > +
> > > > +igt_main
> > > > +{
> > > > +	igt_display_t display;
> > > > +	igt_output_t *output;
> > > > +	igt_plane_t *plane;
> > > > +	igt_fb_t input_fb;
> > > > +	drmModeModeInfo mode;
> > > > +	int ret;
> > > > +
> > > > +	memset(&display, 0, sizeof(display));
> > > > +
> > > > +	igt_fixture {
> > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > +		igt_display_require(&display, display.drm_fd);
> > > > +
> > > > +		kmstest_set_vt_graphics_mode();
> > > > +
> > > > +		igt_display_require(&display, display.drm_fd);
> > > > +
> > > > +		igt_require(display.is_atomic);
> > > > +
> > > > +		output = kms_writeback_get_output(&display);
> > > > +		igt_require(output);
> > > > +
> > > > +		if (output->use_override_mode)
> > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > +		else
> > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > +
> > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > +		igt_require(plane);
> > > 
> > > Maybe we can assert on this?
> > > 
> > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > +				    mode.vdisplay,
> > > > +				    DRM_FORMAT_XRGB8888,
> > > > +				    igt_fb_mod_to_tiling(0),
> > > 
> > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > better to make this clear.
> 
> Agree. The patchset pre-dates the modifiers support (or has the same age, I
> forgot)
> 
> > > (Applies to other lines of this patch)
> > > 
> > > > +				    &input_fb);
> > > > +		igt_assert(ret >= 0);
> > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > +	}
> > > > +
> > > > +	igt_subtest("writeback-pixel-formats") {
> > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > 
> > > Need to drmModeFreePropertyBlob this.
> > > 
> > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > +		unsigned int i;
> > > > +		char *c;
> > > > +
> > > > +		/*
> > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > +		 * any outlandish characters
> > > > +		 */
> > > > +		igt_assert(!(formats_blob->length % 4));
> > > > +		c = formats_blob->data;
> > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > +				     "Unexpected character %c\n", c[i]);
> > > 
> > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > codes will be made from ASCII characters, in fact some formats already
> > > have non-printable chars in them. I don't want to have to update this
> > > test when a new fourcc format is added.
> 
> Like the comments says, we don't have a full list of formats to check against.
> Suggestions on how to improve are welcome, but I don't think we should delay
> (any longer) the patchset due to this.

Agreed.

> Best regards,
> Liviu
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [Intel-gfx] [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-17 11:46           ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-17 11:46 UTC (permalink / raw)
  To: Liviu.Dudau, rodrigosiqueiramelo; +Cc: intel-gfx, igt-dev, nd

Thanks for the clarification!

On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > +{
> > > > +	int i, ret;
> > > > +	int32_t out_fence;
> > > > +	struct {
> > > > +		uint32_t fb_id;
> > > > +		bool ptr_valid;
> > > > +		int32_t *out_fence_ptr;
> > > > +	} invalid_tests[] = {
> > > > +		{
> > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > +			.fb_id = 0,
> > > > +			.ptr_valid = true,
> > > > +			.out_fence_ptr = &out_fence,
> > > > +		},
> > > > +		{
> > > > +			/* Invalid output buffer. */
> > > > +			.fb_id = invalid_fb->fb_id,
> > > > +			.ptr_valid = true,
> > > > +			.out_fence_ptr = &out_fence,
> > > > +		},
> > > 
> > > This doesn't belong in this function (invalid_out_fence), since this
> > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > move it to writeback_fb_id (and rename that function to test_fb?).
> 
> It tries to test that you can't trick the driver to do any work on a fence if
> the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> invalid fb with valid fence, valid fb but invalid fence and assumes that no
> fb with invalid fence is a NOP anyway.

Yeah, that makes sense, it's just confusing to put it in a function
named invalid_out_fence. Here the out fence is valid, but the output
buffer isn't, so it should probably be moved away (or this function
should be renamed).

> > > > +		{
> > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > +			.fb_id = valid_fb->fb_id,
> > > > +			.ptr_valid = false,
> > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > +		},
> > > > +	};
> > > > +
> > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +					invalid_tests[i].fb_id,
> > > > +					invalid_tests[i].out_fence_ptr,
> > > > +					invalid_tests[i].ptr_valid);
> > > > +		igt_assert(ret != 0);
> > > 
> > > Maybe we can check for -ret == EINVAL?
> > > 
> > > > +	}
> > > > +}
> > > > +
> > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > 
> > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > the input framebuffer. It's probably not a good idea to use the same FB
> > > for input and writeback output.
> > > 
> > > > +{
> > > > +
> > > > +	int ret;
> > > > +
> > > > +	/* Valid output buffer */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				valid_fb->fb_id, NULL, false);
> > > > +	igt_assert(ret == 0);
> > > > +
> > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				output->id, NULL, false);
> > > > +	igt_assert(ret == -EINVAL);
> > > > +
> > > > +	/* Zero WRITEBACK_FB_ID */
> > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > +				0, NULL, false);
> > > > +	igt_assert(ret == 0);
> > > > +}
> > > > +
> > > > +igt_main
> > > > +{
> > > > +	igt_display_t display;
> > > > +	igt_output_t *output;
> > > > +	igt_plane_t *plane;
> > > > +	igt_fb_t input_fb;
> > > > +	drmModeModeInfo mode;
> > > > +	int ret;
> > > > +
> > > > +	memset(&display, 0, sizeof(display));
> > > > +
> > > > +	igt_fixture {
> > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > +		igt_display_require(&display, display.drm_fd);
> > > > +
> > > > +		kmstest_set_vt_graphics_mode();
> > > > +
> > > > +		igt_display_require(&display, display.drm_fd);
> > > > +
> > > > +		igt_require(display.is_atomic);
> > > > +
> > > > +		output = kms_writeback_get_output(&display);
> > > > +		igt_require(output);
> > > > +
> > > > +		if (output->use_override_mode)
> > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > +		else
> > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > +
> > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > +		igt_require(plane);
> > > 
> > > Maybe we can assert on this?
> > > 
> > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > +				    mode.vdisplay,
> > > > +				    DRM_FORMAT_XRGB8888,
> > > > +				    igt_fb_mod_to_tiling(0),
> > > 
> > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > better to make this clear.
> 
> Agree. The patchset pre-dates the modifiers support (or has the same age, I
> forgot)
> 
> > > (Applies to other lines of this patch)
> > > 
> > > > +				    &input_fb);
> > > > +		igt_assert(ret >= 0);
> > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > +	}
> > > > +
> > > > +	igt_subtest("writeback-pixel-formats") {
> > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > 
> > > Need to drmModeFreePropertyBlob this.
> > > 
> > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > +		unsigned int i;
> > > > +		char *c;
> > > > +
> > > > +		/*
> > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > +		 * any outlandish characters
> > > > +		 */
> > > > +		igt_assert(!(formats_blob->length % 4));
> > > > +		c = formats_blob->data;
> > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > +				     "Unexpected character %c\n", c[i]);
> > > 
> > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > codes will be made from ASCII characters, in fact some formats already
> > > have non-printable chars in them. I don't want to have to update this
> > > test when a new fourcc format is added.
> 
> Like the comments says, we don't have a full list of formats to check against.
> Suggestions on how to improve are welcome, but I don't think we should delay
> (any longer) the patchset due to this.

Agreed.

> Best regards,
> Liviu
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-07-17  1:21           ` Rodrigo Siqueira
@ 2019-07-17 13:00             ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-17 13:00 UTC (permalink / raw)
  To: rodrigosiqueiramelo; +Cc: intel-gfx, igt-dev, nd

On Tue, 2019-07-16 at 22:21 -0300, Rodrigo Siqueira wrote:
> On 07/12, Ser, Simon wrote:
> > On Thu, 2019-07-11 at 23:44 -0300, Rodrigo Siqueira wrote:
> > > On 07/10, Ser, Simon wrote:
> > > > Hi,
> > > > 
> > > > Thanks for the patch! Here are a few comments.
> > > > 
> > > > For bonus points, it would be nice to add igt_describe descriptions of
> > > > each sub-test.
> > > 
> > > Hi Simon,
> > > 
> > > First of all, thanks for your feedback; I already applied most of your
> > > suggestions. I just have some inline comments/questions.
> > >  
> > > > On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> > > > > Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> > > > > WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> > > > > behaviour is correct.
> > > > > 
> > > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > > [rebased and updated do_writeback_test() function to address feedback]
> > > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > > ---
> > > > >  tests/Makefile.sources |   1 +
> > > > >  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
> > > > >  tests/meson.build      |   1 +
> > > > >  3 files changed, 316 insertions(+)
> > > > >  create mode 100644 tests/kms_writeback.c
> > > > > 
> > > > > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > > > > index 027ed82f..03cc8efa 100644
> > > > > --- a/tests/Makefile.sources
> > > > > +++ b/tests/Makefile.sources
> > > > > @@ -77,6 +77,7 @@ TESTS_progs = \
> > > > >  	kms_universal_plane \
> > > > >  	kms_vblank \
> > > > >  	kms_vrr \
> > > > > +	kms_writeback \
> > > > >  	meta_test \
> > > > >  	perf \
> > > > >  	perf_pmu \
> > > > > diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> > > > > new file mode 100644
> > > > > index 00000000..66ef48a6
> > > > > --- /dev/null
> > > > > +++ b/tests/kms_writeback.c
> > > > > @@ -0,0 +1,314 @@
> > > > > +/*
> > > > > + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> > > > > + *
> > > > > + * Permission is hereby granted, free of charge, to any person obtaining a
> > > > > + * copy of this software and associated documentation files (the "Software"),
> > > > > + * to deal in the Software without restriction, including without limitation
> > > > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > > > > + * and/or sell copies of the Software, and to permit persons to whom the
> > > > > + * Software is furnished to do so, subject to the following conditions:
> > > > > + *
> > > > > + * The above copyright notice and this permission notice (including the next
> > > > > + * paragraph) shall be included in all copies or substantial portions of the
> > > > > + * Software.
> > > > > + *
> > > > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > > > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > > > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > > > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > > > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > > > > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > > > > + * IN THE SOFTWARE.
> > > > > + *
> > > > > + */
> > > > > +
> > > > > +#include <errno.h>
> > > > > +#include <stdbool.h>
> > > > > +#include <stdio.h>
> > > > > +#include <string.h>
> > > > > +
> > > > > +#include "igt.h"
> > > > > +#include "igt_core.h"
> > > > > +#include "igt_fb.h"
> > > > > +
> > > > > +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> > > > > +{
> > > > > +	drmModePropertyBlobRes *blob = NULL;
> > > > > +	uint64_t blob_id;
> > > > > +	int ret;
> > > > > +
> > > > > +	ret = kmstest_get_property(output->display->drm_fd,
> > > > > +				   output->config.connector->connector_id,
> > > > > +				   DRM_MODE_OBJECT_CONNECTOR,
> > > > > +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> > > > > +				   NULL, &blob_id, NULL);
> > > > > +	if (ret)
> > > > > +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> > > > > +
> > > > > +	igt_assert(blob);
> > > > > +
> > > > > +	return blob;
> > > > > +}
> > > > > +
> > > > > +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> > > > > +{
> > > > > +	igt_fb_t input_fb, output_fb;
> > > > > +	igt_plane_t *plane;
> > > > > +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> > > > > +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> > > > > +	int width, height, ret;
> > > > > +	drmModeModeInfo override_mode = {
> > > > > +		.clock = 25175,
> > > > > +		.hdisplay = 640,
> > > > > +		.hsync_start = 656,
> > > > > +		.hsync_end = 752,
> > > > > +		.htotal = 800,
> > > > > +		.hskew = 0,
> > > > > +		.vdisplay = 480,
> > > > > +		.vsync_start = 490,
> > > > > +		.vsync_end = 492,
> > > > > +		.vtotal = 525,
> > > > > +		.vscan = 0,
> > > > > +		.vrefresh = 60,
> > > > > +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> > > > > +		.name = {"640x480-60"},
> > > > > +	};
> > > > > +	igt_output_override_mode(output, &override_mode);
> > > > > +
> > > > > +	width = override_mode.hdisplay;
> > > > > +	height = override_mode.vdisplay;
> > > > > +
> > > > > +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> > > > > +	igt_assert(ret >= 0);
> > > > > +
> > > > > +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> > > > > +	igt_assert(ret >= 0);
> > > > > +
> > > > > +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > +	igt_plane_set_fb(plane, &input_fb);
> > > > > +	igt_output_set_writeback_fb(output, &output_fb);
> > > > > +
> > > > > +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> > > > > +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> > > > 
> > > > Okay, we're using atomic test-only mode to know if we can perform tests
> > > > with the writeback output. It's probably fine, but we don't use
> > > > WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.
> > > 
> > > Sorry, I did not fully understand part. Did you expect to see something
> > > like the below code before igt_display_try_commit_atomic()?
> > > 
> > >  igt_output_set_prop_value(output, WRITEBACK_PIXEL_FORMATS,
> > >                            DRM_FORMAT_XRGB8888);
> > 
> > Hmm, no, we cannot change the list of writeback formats (it's
> > immutable).
> > 
> > This comment doesn't require any action, it's just me thinking aloud :P
> > 
> > I'm just thinking that it would be nice to choose our format depending
> > on the WRITEBACK_PIXEL_FORMATS property. And probably run tests with
> > each supported format (or, alternatively, choose a random one). That
> > way we can make sure WRITEBACK_PIXEL_FORMATS isn't broken.
> > 
> > However, this can be left for a later patch.
> > 
> > > > > +	igt_plane_set_fb(plane, NULL);
> > > > > +	igt_remove_fb(display->drm_fd, &input_fb);
> > > > > +	igt_remove_fb(display->drm_fd, &output_fb);
> > > > > +
> > > > > +	return !ret;
> > > > > +}
> > > > > +
> > > > > +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> > > > > +{
> > > > > +	int i;
> > > > > +
> > > > > +	for (i = 0; i < display->n_outputs; i++) {
> > > > > +		igt_output_t *output = &display->outputs[i];
> > > > > +		int j;
> > > > > +
> > > > > +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> > > > > +			continue;
> > > > > +
> > > > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
> > > > 
> > > > Hmm. Is this really necessary? "Real" userspace won't do this, so I
> > > > don't think we need to either.
> > > 
> > > Hmmm, I have a little experience with userspace; however, I tested
> > > kms_writeback on top of vkms without this line, and everything worked
> > > well. If I remove this line, should I also drop the line that force
> > > connector to FORCE_CONNECTOR_UNSPECIFIED?
> > 
> > I believe so.
> > 
> > > Another question, if FORCE_CONNECTOR_ON is something that userspace
> > > won't want to do, why do we have it?
> > 
> > We use kmstest_force_connector in injection tests: those pick a
> > disconnected HDMI connector and trick the kernel into thinking it's
> > connected. We generally also force an EDID and this is used to emulate
> > a screen (e.g. a screen that supports audio, 4K or 3D).
> > 
> > This is only meant to be used for testing though, hence "real userspace
> > shouldn't use it".
> > 
> 
> Ahhh, I see. Thanks for the explanation
>  
> > > > > +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> > > > > +			igt_output_set_pipe(output, j);
> > > > > +
> > > > > +			if (check_writeback_config(display, output)) {
> > > > > +				igt_debug("Using connector %u:%s on pipe %d\n",
> > > > > +					  output->config.connector->connector_id,
> > > > > +					  output->name, j);
> > > > > +				return output;
> > > > > +			}
> > > > 
> > > > We could probably add an igt_debug statement in case we don't use this
> > > > writeback output.
> > > > 
> > > > > +		}
> > > > > +
> > > > > +		/* Restore any connectors we don't use, so we don't trip on them later */
> > > > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> > > > > +	}
> > > > > +
> > > > > +	return NULL;
> > > > > +}
> > > > > +
> > > > > +static void check_writeback_fb_id(igt_output_t *output)
> > > > > +{
> > > > > +	uint64_t check_fb_id;
> > > > > +
> > > > > +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > > > +	igt_assert(check_fb_id == 0);
> > > > > +}
> > > > > +
> > > > > +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> > > > > +			      uint32_t fb_id, int32_t *out_fence_ptr,
> > > > > +			      bool ptr_valid)
> > > > 
> > > > flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
> > > > probably remove the parameter from this function.
> > > > 
> > > > > +{
> > > > > +	int ret;
> > > > > +	igt_display_t *display = output->display;
> > > > > +	struct kmstest_connector_config *config = &output->config;
> > > > > +
> > > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> > > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> > > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> > > > > +
> > > > > +	if (ptr_valid)
> > > > > +		*out_fence_ptr = 0;
> > > > > +
> > > > > +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> > > > > +
> > > > > +	if (ptr_valid)
> > > > > +		igt_assert(*out_fence_ptr == -1);
> > > > 
> > > > I'm confused. Why should this be -1 even if we
> > > > igt_display_try_commit_atomic succeeds?
> > > 
> > > I inspected the drm_mode_atomic_ioctl() function and I noticed that It
> > > calls complete_signaling() in its turn this function assign -1 to
> > > out_fence_ptr. Since all of this happens at the end of atomic_commit, I
> > > believe that we don’t need it. I already removed it.
> > 
> > I think I'm still confused :)
> > 
> > I'm probably missing something. As far as I understand, we are doing an
> > atomic commit, sometimes with a valid WRITEBACK_FB_ID and
> > WRITEBACK_OUT_FENCE_PTR. In this case it should start the writeback
> > process in the kernel and we should get a valid out_fence_ptr?
> > 
> > Why do we always get -1?
> 
> FWIU userspace uses the WRITEBACK_OUT_FENCE_PTR to provide a pointer for
> the kernel to fill with a sync_file file descriptor, which will signal
> once the writeback is finished. If the signal was correctly handled, the
> out_fence_ptr would be set to -1, because of this we always get -1.

But in case a writeback operation has been successfully started, it
won't be -1 (since it will be a valid FD). As I've understood it, this
function will always be called without triggering a writeback
operation.

Maybe we should rename do_writeback_test to do_noop_writeback (or a
better name) and add a comment explaining that *out_fence_ptr will be
-1 because:

- Either ret != 0 and we submitted a bad commit
- Either ret == 0 (valid commit) but out_fence_ptr == NULL (so no
  writeback operation started)

Maybe we could igt_assert(ret != 0 || out_fence_ptr == NULL) to make
sure we don't call this function and successfully trigger a writeback
operation.

What do you think?

> Thanks for your feedback, I'll prepare a new version soon.
>  
> > > > > +	/* WRITEBACK_FB_ID must always read as zero */
> > > > > +	check_writeback_fb_id(output);
> > > > > +
> > > > > +	return ret;
> > > > > +}
> > > > > +
> > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > +{
> > > > > +	int i, ret;
> > > > > +	int32_t out_fence;
> > > > > +	struct {
> > > > > +		uint32_t fb_id;
> > > > > +		bool ptr_valid;
> > > > > +		int32_t *out_fence_ptr;
> > > > > +	} invalid_tests[] = {
> > > > > +		{
> > > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > +			.fb_id = 0,
> > > > > +			.ptr_valid = true,
> > > > > +			.out_fence_ptr = &out_fence,
> > > > > +		},
> > > > > +		{
> > > > > +			/* Invalid output buffer. */
> > > > > +			.fb_id = invalid_fb->fb_id,
> > > > > +			.ptr_valid = true,
> > > > > +			.out_fence_ptr = &out_fence,
> > > > > +		},
> > > > 
> > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > > 
> > > > > +		{
> > > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > +			.fb_id = valid_fb->fb_id,
> > > > > +			.ptr_valid = false,
> > > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > > +		},
> > > > > +	};
> > > > > +
> > > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +					invalid_tests[i].fb_id,
> > > > > +					invalid_tests[i].out_fence_ptr,
> > > > > +					invalid_tests[i].ptr_valid);
> > > > > +		igt_assert(ret != 0);
> > > > 
> > > > Maybe we can check for -ret == EINVAL?
> > > > 
> > > > > +	}
> > > > > +}
> > > > > +
> > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > 
> > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > for input and writeback output.
> > > > 
> > > > > +{
> > > > > +
> > > > > +	int ret;
> > > > > +
> > > > > +	/* Valid output buffer */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				valid_fb->fb_id, NULL, false);
> > > > > +	igt_assert(ret == 0);
> > > > > +
> > > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				output->id, NULL, false);
> > > > > +	igt_assert(ret == -EINVAL);
> > > > > +
> > > > > +	/* Zero WRITEBACK_FB_ID */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				0, NULL, false);
> > > > > +	igt_assert(ret == 0);
> > > > > +}
> > > > > +
> > > > > +igt_main
> > > > > +{
> > > > > +	igt_display_t display;
> > > > > +	igt_output_t *output;
> > > > > +	igt_plane_t *plane;
> > > > > +	igt_fb_t input_fb;
> > > > > +	drmModeModeInfo mode;
> > > > > +	int ret;
> > > > > +
> > > > > +	memset(&display, 0, sizeof(display));
> > > > > +
> > > > > +	igt_fixture {
> > > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > +
> > > > > +		kmstest_set_vt_graphics_mode();
> > > > > +
> > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > +
> > > > > +		igt_require(display.is_atomic);
> > > > > +
> > > > > +		output = kms_writeback_get_output(&display);
> > > > > +		igt_require(output);
> > > > > +
> > > > > +		if (output->use_override_mode)
> > > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > +		else
> > > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > +
> > > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > +		igt_require(plane);
> > > > 
> > > > Maybe we can assert on this?
> > > > 
> > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > +				    mode.vdisplay,
> > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > +				    igt_fb_mod_to_tiling(0),
> > > > 
> > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > better to make this clear.
> > > > 
> > > > (Applies to other lines of this patch)
> > > > 
> > > > > +				    &input_fb);
> > > > > +		igt_assert(ret >= 0);
> > > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > > +	}
> > > > > +
> > > > > +	igt_subtest("writeback-pixel-formats") {
> > > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > 
> > > > Need to drmModeFreePropertyBlob this.
> > > > 
> > > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > +		unsigned int i;
> > > > > +		char *c;
> > > > > +
> > > > > +		/*
> > > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > > +		 * any outlandish characters
> > > > > +		 */
> > > > > +		igt_assert(!(formats_blob->length % 4));
> > > > > +		c = formats_blob->data;
> > > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > > +				     "Unexpected character %c\n", c[i]);
> > > > 
> > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > codes will be made from ASCII characters, in fact some formats already
> > > > have non-printable chars in them. I don't want to have to update this
> > > > test when a new fourcc format is added.
> > > > 
> > > > We currently don't have a test for IN_FORMATS. If we really want to
> > > > check formats, we could have a big array of known formats and add a
> > > > bool is_valid_format(uint32_t fmt) function.
> > > 
> > > Agree with you. How about remove this test?
> > 
> > I guess we could always keep the length % 4 test, even if it's just a
> > sanity test. At least this one won't ever need to be changed.
> > 
> > I don't feel strongly about it.
> > 
> > > Thanks
> > > Best Regards
> > > 
> > > > > +	}
> > > > > +
> > > > > +	igt_subtest("writeback-invalid-out-fence") {
> > > > > +		igt_fb_t invalid_fb;
> > > > 
> > > > invalid_output_fb would be a better name IMHO.
> > > > 
> > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> > > > > +				    mode.vdisplay / 2,
> > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > +				    igt_fb_mod_to_tiling(0),
> > > > > +				    &invalid_fb);
> > > > > +		igt_require(ret > 0);
> > > > 
> > > > We should probably use a different variable: ret is signed,
> > > > igt_create_fb isn't. Also ret doesn't make it clear that the return
> > > > value is the KMS framebuffer ID.
> > > > 
> > > > (Applies to other subtests)
> > > > 
> > > > > +		invalid_out_fence(output, &input_fb, &invalid_fb);
> > > > 
> > > > (Still not sure why we provide the input FB to this function.)
> > > > 
> > > > > +		igt_remove_fb(display.drm_fd, &invalid_fb);
> > > > > +	}
> > > > > +
> > > > > +	igt_subtest("writeback-fb-id") {
> > > > > +		igt_fb_t output_fb;
> > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > +				    igt_fb_mod_to_tiling(0),
> > > > > +				    &output_fb);
> > > > > +		igt_require(ret > 0);
> > > > > +
> > > > > +		writeback_fb_id(output, &input_fb, &output_fb);
> > > > > +
> > > > > +		igt_remove_fb(display.drm_fd, &output_fb);
> > > > > +	}
> > > > > +
> > > > > +	igt_fixture {
> > > > > +		igt_remove_fb(display.drm_fd, &input_fb);
> > > > > +		igt_display_fini(&display);
> > > > > +	}
> > > > > +}
> > > > > diff --git a/tests/meson.build b/tests/meson.build
> > > > > index f168fbba..9c77cfcd 100644
> > > > > --- a/tests/meson.build
> > > > > +++ b/tests/meson.build
> > > > > @@ -63,6 +63,7 @@ test_progs = [
> > > > >  	'kms_universal_plane',
> > > > >  	'kms_vblank',
> > > > >  	'kms_vrr',
> > > > > +	'kms_writeback',
> > > > >  	'meta_test',
> > > > >  	'panfrost_get_param',
> > > > >  	'panfrost_gem_new',
> > > > > _______________________________________________
> > > > > igt-dev mailing list
> > > > > igt-dev@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-17 13:00             ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-17 13:00 UTC (permalink / raw)
  To: rodrigosiqueiramelo
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey

On Tue, 2019-07-16 at 22:21 -0300, Rodrigo Siqueira wrote:
> On 07/12, Ser, Simon wrote:
> > On Thu, 2019-07-11 at 23:44 -0300, Rodrigo Siqueira wrote:
> > > On 07/10, Ser, Simon wrote:
> > > > Hi,
> > > > 
> > > > Thanks for the patch! Here are a few comments.
> > > > 
> > > > For bonus points, it would be nice to add igt_describe descriptions of
> > > > each sub-test.
> > > 
> > > Hi Simon,
> > > 
> > > First of all, thanks for your feedback; I already applied most of your
> > > suggestions. I just have some inline comments/questions.
> > >  
> > > > On Wed, 2019-06-12 at 23:16 -0300, Brian Starkey wrote:
> > > > > Add tests for the WRITEBACK_PIXEL_FORMATS, WRITEBACK_OUT_FENCE_PTR and
> > > > > WRITEBACK_FB_ID properties on writeback connectors, ensuring their
> > > > > behaviour is correct.
> > > > > 
> > > > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > > > [rebased and updated do_writeback_test() function to address feedback]
> > > > > Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
> > > > > ---
> > > > >  tests/Makefile.sources |   1 +
> > > > >  tests/kms_writeback.c  | 314 +++++++++++++++++++++++++++++++++++++++++
> > > > >  tests/meson.build      |   1 +
> > > > >  3 files changed, 316 insertions(+)
> > > > >  create mode 100644 tests/kms_writeback.c
> > > > > 
> > > > > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > > > > index 027ed82f..03cc8efa 100644
> > > > > --- a/tests/Makefile.sources
> > > > > +++ b/tests/Makefile.sources
> > > > > @@ -77,6 +77,7 @@ TESTS_progs = \
> > > > >  	kms_universal_plane \
> > > > >  	kms_vblank \
> > > > >  	kms_vrr \
> > > > > +	kms_writeback \
> > > > >  	meta_test \
> > > > >  	perf \
> > > > >  	perf_pmu \
> > > > > diff --git a/tests/kms_writeback.c b/tests/kms_writeback.c
> > > > > new file mode 100644
> > > > > index 00000000..66ef48a6
> > > > > --- /dev/null
> > > > > +++ b/tests/kms_writeback.c
> > > > > @@ -0,0 +1,314 @@
> > > > > +/*
> > > > > + * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
> > > > > + *
> > > > > + * Permission is hereby granted, free of charge, to any person obtaining a
> > > > > + * copy of this software and associated documentation files (the "Software"),
> > > > > + * to deal in the Software without restriction, including without limitation
> > > > > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > > > > + * and/or sell copies of the Software, and to permit persons to whom the
> > > > > + * Software is furnished to do so, subject to the following conditions:
> > > > > + *
> > > > > + * The above copyright notice and this permission notice (including the next
> > > > > + * paragraph) shall be included in all copies or substantial portions of the
> > > > > + * Software.
> > > > > + *
> > > > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > > > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > > > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > > > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > > > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > > > > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > > > > + * IN THE SOFTWARE.
> > > > > + *
> > > > > + */
> > > > > +
> > > > > +#include <errno.h>
> > > > > +#include <stdbool.h>
> > > > > +#include <stdio.h>
> > > > > +#include <string.h>
> > > > > +
> > > > > +#include "igt.h"
> > > > > +#include "igt_core.h"
> > > > > +#include "igt_fb.h"
> > > > > +
> > > > > +static drmModePropertyBlobRes *get_writeback_formats_blob(igt_output_t *output)
> > > > > +{
> > > > > +	drmModePropertyBlobRes *blob = NULL;
> > > > > +	uint64_t blob_id;
> > > > > +	int ret;
> > > > > +
> > > > > +	ret = kmstest_get_property(output->display->drm_fd,
> > > > > +				   output->config.connector->connector_id,
> > > > > +				   DRM_MODE_OBJECT_CONNECTOR,
> > > > > +				   igt_connector_prop_names[IGT_CONNECTOR_WRITEBACK_PIXEL_FORMATS],
> > > > > +				   NULL, &blob_id, NULL);
> > > > > +	if (ret)
> > > > > +		blob = drmModeGetPropertyBlob(output->display->drm_fd, blob_id);
> > > > > +
> > > > > +	igt_assert(blob);
> > > > > +
> > > > > +	return blob;
> > > > > +}
> > > > > +
> > > > > +static bool check_writeback_config(igt_display_t *display, igt_output_t *output)
> > > > > +{
> > > > > +	igt_fb_t input_fb, output_fb;
> > > > > +	igt_plane_t *plane;
> > > > > +	uint32_t writeback_format = DRM_FORMAT_XRGB8888;
> > > > > +	uint64_t tiling = igt_fb_mod_to_tiling(0);
> > > > > +	int width, height, ret;
> > > > > +	drmModeModeInfo override_mode = {
> > > > > +		.clock = 25175,
> > > > > +		.hdisplay = 640,
> > > > > +		.hsync_start = 656,
> > > > > +		.hsync_end = 752,
> > > > > +		.htotal = 800,
> > > > > +		.hskew = 0,
> > > > > +		.vdisplay = 480,
> > > > > +		.vsync_start = 490,
> > > > > +		.vsync_end = 492,
> > > > > +		.vtotal = 525,
> > > > > +		.vscan = 0,
> > > > > +		.vrefresh = 60,
> > > > > +		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> > > > > +		.name = {"640x480-60"},
> > > > > +	};
> > > > > +	igt_output_override_mode(output, &override_mode);
> > > > > +
> > > > > +	width = override_mode.hdisplay;
> > > > > +	height = override_mode.vdisplay;
> > > > > +
> > > > > +	ret = igt_create_fb(display->drm_fd, width, height, DRM_FORMAT_XRGB8888, tiling, &input_fb);
> > > > > +	igt_assert(ret >= 0);
> > > > > +
> > > > > +	ret = igt_create_fb(display->drm_fd, width, height, writeback_format, tiling, &output_fb);
> > > > > +	igt_assert(ret >= 0);
> > > > > +
> > > > > +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > +	igt_plane_set_fb(plane, &input_fb);
> > > > > +	igt_output_set_writeback_fb(output, &output_fb);
> > > > > +
> > > > > +	ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY |
> > > > > +					    DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> > > > 
> > > > Okay, we're using atomic test-only mode to know if we can perform tests
> > > > with the writeback output. It's probably fine, but we don't use
> > > > WRITEBACK_PIXEL_FORMATS, which makes me a little bit sad.
> > > 
> > > Sorry, I did not fully understand part. Did you expect to see something
> > > like the below code before igt_display_try_commit_atomic()?
> > > 
> > >  igt_output_set_prop_value(output, WRITEBACK_PIXEL_FORMATS,
> > >                            DRM_FORMAT_XRGB8888);
> > 
> > Hmm, no, we cannot change the list of writeback formats (it's
> > immutable).
> > 
> > This comment doesn't require any action, it's just me thinking aloud :P
> > 
> > I'm just thinking that it would be nice to choose our format depending
> > on the WRITEBACK_PIXEL_FORMATS property. And probably run tests with
> > each supported format (or, alternatively, choose a random one). That
> > way we can make sure WRITEBACK_PIXEL_FORMATS isn't broken.
> > 
> > However, this can be left for a later patch.
> > 
> > > > > +	igt_plane_set_fb(plane, NULL);
> > > > > +	igt_remove_fb(display->drm_fd, &input_fb);
> > > > > +	igt_remove_fb(display->drm_fd, &output_fb);
> > > > > +
> > > > > +	return !ret;
> > > > > +}
> > > > > +
> > > > > +static igt_output_t *kms_writeback_get_output(igt_display_t *display)
> > > > > +{
> > > > > +	int i;
> > > > > +
> > > > > +	for (i = 0; i < display->n_outputs; i++) {
> > > > > +		igt_output_t *output = &display->outputs[i];
> > > > > +		int j;
> > > > > +
> > > > > +		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> > > > > +			continue;
> > > > > +
> > > > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_ON);
> > > > 
> > > > Hmm. Is this really necessary? "Real" userspace won't do this, so I
> > > > don't think we need to either.
> > > 
> > > Hmmm, I have a little experience with userspace; however, I tested
> > > kms_writeback on top of vkms without this line, and everything worked
> > > well. If I remove this line, should I also drop the line that force
> > > connector to FORCE_CONNECTOR_UNSPECIFIED?
> > 
> > I believe so.
> > 
> > > Another question, if FORCE_CONNECTOR_ON is something that userspace
> > > won't want to do, why do we have it?
> > 
> > We use kmstest_force_connector in injection tests: those pick a
> > disconnected HDMI connector and trick the kernel into thinking it's
> > connected. We generally also force an EDID and this is used to emulate
> > a screen (e.g. a screen that supports audio, 4K or 3D).
> > 
> > This is only meant to be used for testing though, hence "real userspace
> > shouldn't use it".
> > 
> 
> Ahhh, I see. Thanks for the explanation
>  
> > > > > +		for (j = 0; j < igt_display_get_n_pipes(display); j++) {
> > > > > +			igt_output_set_pipe(output, j);
> > > > > +
> > > > > +			if (check_writeback_config(display, output)) {
> > > > > +				igt_debug("Using connector %u:%s on pipe %d\n",
> > > > > +					  output->config.connector->connector_id,
> > > > > +					  output->name, j);
> > > > > +				return output;
> > > > > +			}
> > > > 
> > > > We could probably add an igt_debug statement in case we don't use this
> > > > writeback output.
> > > > 
> > > > > +		}
> > > > > +
> > > > > +		/* Restore any connectors we don't use, so we don't trip on them later */
> > > > > +		kmstest_force_connector(display->drm_fd, output->config.connector, FORCE_CONNECTOR_UNSPECIFIED);
> > > > > +	}
> > > > > +
> > > > > +	return NULL;
> > > > > +}
> > > > > +
> > > > > +static void check_writeback_fb_id(igt_output_t *output)
> > > > > +{
> > > > > +	uint64_t check_fb_id;
> > > > > +
> > > > > +	check_fb_id = igt_output_get_prop(output, IGT_CONNECTOR_WRITEBACK_FB_ID);
> > > > > +	igt_assert(check_fb_id == 0);
> > > > > +}
> > > > > +
> > > > > +static int do_writeback_test(igt_output_t *output, uint32_t flags,
> > > > > +			      uint32_t fb_id, int32_t *out_fence_ptr,
> > > > > +			      bool ptr_valid)
> > > > 
> > > > flags seems to always be set to DRM_MODE_ATOMIC_ALLOW_MODESET. We can
> > > > probably remove the parameter from this function.
> > > > 
> > > > > +{
> > > > > +	int ret;
> > > > > +	igt_display_t *display = output->display;
> > > > > +	struct kmstest_connector_config *config = &output->config;
> > > > > +
> > > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, config->crtc->crtc_id);
> > > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_FB_ID, fb_id);
> > > > > +	igt_output_set_prop_value(output, IGT_CONNECTOR_WRITEBACK_OUT_FENCE_PTR, (uint64_t)out_fence_ptr);
> > > > > +
> > > > > +	if (ptr_valid)
> > > > > +		*out_fence_ptr = 0;
> > > > > +
> > > > > +	ret = igt_display_try_commit_atomic(display, flags, NULL);
> > > > > +
> > > > > +	if (ptr_valid)
> > > > > +		igt_assert(*out_fence_ptr == -1);
> > > > 
> > > > I'm confused. Why should this be -1 even if we
> > > > igt_display_try_commit_atomic succeeds?
> > > 
> > > I inspected the drm_mode_atomic_ioctl() function and I noticed that It
> > > calls complete_signaling() in its turn this function assign -1 to
> > > out_fence_ptr. Since all of this happens at the end of atomic_commit, I
> > > believe that we don’t need it. I already removed it.
> > 
> > I think I'm still confused :)
> > 
> > I'm probably missing something. As far as I understand, we are doing an
> > atomic commit, sometimes with a valid WRITEBACK_FB_ID and
> > WRITEBACK_OUT_FENCE_PTR. In this case it should start the writeback
> > process in the kernel and we should get a valid out_fence_ptr?
> > 
> > Why do we always get -1?
> 
> FWIU userspace uses the WRITEBACK_OUT_FENCE_PTR to provide a pointer for
> the kernel to fill with a sync_file file descriptor, which will signal
> once the writeback is finished. If the signal was correctly handled, the
> out_fence_ptr would be set to -1, because of this we always get -1.

But in case a writeback operation has been successfully started, it
won't be -1 (since it will be a valid FD). As I've understood it, this
function will always be called without triggering a writeback
operation.

Maybe we should rename do_writeback_test to do_noop_writeback (or a
better name) and add a comment explaining that *out_fence_ptr will be
-1 because:

- Either ret != 0 and we submitted a bad commit
- Either ret == 0 (valid commit) but out_fence_ptr == NULL (so no
  writeback operation started)

Maybe we could igt_assert(ret != 0 || out_fence_ptr == NULL) to make
sure we don't call this function and successfully trigger a writeback
operation.

What do you think?

> Thanks for your feedback, I'll prepare a new version soon.
>  
> > > > > +	/* WRITEBACK_FB_ID must always read as zero */
> > > > > +	check_writeback_fb_id(output);
> > > > > +
> > > > > +	return ret;
> > > > > +}
> > > > > +
> > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > +{
> > > > > +	int i, ret;
> > > > > +	int32_t out_fence;
> > > > > +	struct {
> > > > > +		uint32_t fb_id;
> > > > > +		bool ptr_valid;
> > > > > +		int32_t *out_fence_ptr;
> > > > > +	} invalid_tests[] = {
> > > > > +		{
> > > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > +			.fb_id = 0,
> > > > > +			.ptr_valid = true,
> > > > > +			.out_fence_ptr = &out_fence,
> > > > > +		},
> > > > > +		{
> > > > > +			/* Invalid output buffer. */
> > > > > +			.fb_id = invalid_fb->fb_id,
> > > > > +			.ptr_valid = true,
> > > > > +			.out_fence_ptr = &out_fence,
> > > > > +		},
> > > > 
> > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > > 
> > > > > +		{
> > > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > +			.fb_id = valid_fb->fb_id,
> > > > > +			.ptr_valid = false,
> > > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > > +		},
> > > > > +	};
> > > > > +
> > > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +					invalid_tests[i].fb_id,
> > > > > +					invalid_tests[i].out_fence_ptr,
> > > > > +					invalid_tests[i].ptr_valid);
> > > > > +		igt_assert(ret != 0);
> > > > 
> > > > Maybe we can check for -ret == EINVAL?
> > > > 
> > > > > +	}
> > > > > +}
> > > > > +
> > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > 
> > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > for input and writeback output.
> > > > 
> > > > > +{
> > > > > +
> > > > > +	int ret;
> > > > > +
> > > > > +	/* Valid output buffer */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				valid_fb->fb_id, NULL, false);
> > > > > +	igt_assert(ret == 0);
> > > > > +
> > > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				output->id, NULL, false);
> > > > > +	igt_assert(ret == -EINVAL);
> > > > > +
> > > > > +	/* Zero WRITEBACK_FB_ID */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				0, NULL, false);
> > > > > +	igt_assert(ret == 0);
> > > > > +}
> > > > > +
> > > > > +igt_main
> > > > > +{
> > > > > +	igt_display_t display;
> > > > > +	igt_output_t *output;
> > > > > +	igt_plane_t *plane;
> > > > > +	igt_fb_t input_fb;
> > > > > +	drmModeModeInfo mode;
> > > > > +	int ret;
> > > > > +
> > > > > +	memset(&display, 0, sizeof(display));
> > > > > +
> > > > > +	igt_fixture {
> > > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > +
> > > > > +		kmstest_set_vt_graphics_mode();
> > > > > +
> > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > +
> > > > > +		igt_require(display.is_atomic);
> > > > > +
> > > > > +		output = kms_writeback_get_output(&display);
> > > > > +		igt_require(output);
> > > > > +
> > > > > +		if (output->use_override_mode)
> > > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > +		else
> > > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > +
> > > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > +		igt_require(plane);
> > > > 
> > > > Maybe we can assert on this?
> > > > 
> > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > +				    mode.vdisplay,
> > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > +				    igt_fb_mod_to_tiling(0),
> > > > 
> > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > better to make this clear.
> > > > 
> > > > (Applies to other lines of this patch)
> > > > 
> > > > > +				    &input_fb);
> > > > > +		igt_assert(ret >= 0);
> > > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > > +	}
> > > > > +
> > > > > +	igt_subtest("writeback-pixel-formats") {
> > > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > 
> > > > Need to drmModeFreePropertyBlob this.
> > > > 
> > > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > +		unsigned int i;
> > > > > +		char *c;
> > > > > +
> > > > > +		/*
> > > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > > +		 * any outlandish characters
> > > > > +		 */
> > > > > +		igt_assert(!(formats_blob->length % 4));
> > > > > +		c = formats_blob->data;
> > > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > > +				     "Unexpected character %c\n", c[i]);
> > > > 
> > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > codes will be made from ASCII characters, in fact some formats already
> > > > have non-printable chars in them. I don't want to have to update this
> > > > test when a new fourcc format is added.
> > > > 
> > > > We currently don't have a test for IN_FORMATS. If we really want to
> > > > check formats, we could have a big array of known formats and add a
> > > > bool is_valid_format(uint32_t fmt) function.
> > > 
> > > Agree with you. How about remove this test?
> > 
> > I guess we could always keep the length % 4 test, even if it's just a
> > sanity test. At least this one won't ever need to be changed.
> > 
> > I don't feel strongly about it.
> > 
> > > Thanks
> > > Best Regards
> > > 
> > > > > +	}
> > > > > +
> > > > > +	igt_subtest("writeback-invalid-out-fence") {
> > > > > +		igt_fb_t invalid_fb;
> > > > 
> > > > invalid_output_fb would be a better name IMHO.
> > > > 
> > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay / 2,
> > > > > +				    mode.vdisplay / 2,
> > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > +				    igt_fb_mod_to_tiling(0),
> > > > > +				    &invalid_fb);
> > > > > +		igt_require(ret > 0);
> > > > 
> > > > We should probably use a different variable: ret is signed,
> > > > igt_create_fb isn't. Also ret doesn't make it clear that the return
> > > > value is the KMS framebuffer ID.
> > > > 
> > > > (Applies to other subtests)
> > > > 
> > > > > +		invalid_out_fence(output, &input_fb, &invalid_fb);
> > > > 
> > > > (Still not sure why we provide the input FB to this function.)
> > > > 
> > > > > +		igt_remove_fb(display.drm_fd, &invalid_fb);
> > > > > +	}
> > > > > +
> > > > > +	igt_subtest("writeback-fb-id") {
> > > > > +		igt_fb_t output_fb;
> > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay, mode.vdisplay,
> > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > +				    igt_fb_mod_to_tiling(0),
> > > > > +				    &output_fb);
> > > > > +		igt_require(ret > 0);
> > > > > +
> > > > > +		writeback_fb_id(output, &input_fb, &output_fb);
> > > > > +
> > > > > +		igt_remove_fb(display.drm_fd, &output_fb);
> > > > > +	}
> > > > > +
> > > > > +	igt_fixture {
> > > > > +		igt_remove_fb(display.drm_fd, &input_fb);
> > > > > +		igt_display_fini(&display);
> > > > > +	}
> > > > > +}
> > > > > diff --git a/tests/meson.build b/tests/meson.build
> > > > > index f168fbba..9c77cfcd 100644
> > > > > --- a/tests/meson.build
> > > > > +++ b/tests/meson.build
> > > > > @@ -63,6 +63,7 @@ test_progs = [
> > > > >  	'kms_universal_plane',
> > > > >  	'kms_vblank',
> > > > >  	'kms_vrr',
> > > > > +	'kms_writeback',
> > > > >  	'meta_test',
> > > > >  	'panfrost_get_param',
> > > > >  	'panfrost_gem_new',
> > > > > _______________________________________________
> > > > > igt-dev mailing list
> > > > > igt-dev@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 5/6] lib/igt_kms: Add igt_output_clone_pipe for cloning
  2019-07-17  1:47       ` Rodrigo Siqueira
@ 2019-07-17 13:10         ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-17 13:10 UTC (permalink / raw)
  To: rodrigosiqueiramelo; +Cc: intel-gfx, igt-dev, nd

On Tue, 2019-07-16 at 22:47 -0300, Rodrigo Siqueira wrote:
> On 07/12, Ser, Simon wrote:
> > So, to test these last two patches we'd need specific hardware right?
> > Because VKMS doesn't support cloning yet (does it?).
> 
> hmmm... actually, VKMS successfully pass in this test. However, if you
> compare "writeback-check-output" and "writeback-check-output-clone", you
> will notice they are very similar. Maybe, this test does not correctly
> validating cloning feature?

Hmm. Are you sure it doesn't skip at igt_require(clone)? It should,
because VKMS only exposes one connector… Might be a bug in the test.

> > What kind of hardware supports cloned writeback outputs? I have a
> > Raspberry Pi which supports writeback via VC4, but I don't think it has
> > writeback cloning. I'm also not willing to install any proprietary
> > driver.
> > 
> > I guess we could land the first part of the series, and wait for VKMS
> > to support cloned outputs to land the last two patches.
> > 
> > Any other ideas?
> 
> btw, I'm totally comfortable with the idea of focusing on the first part
> of this series.

Yeah, let's land the first part and keep cloning for later :)

> Thanks
>  
> > On Wed, 2019-06-12 at 23:18 -0300, Brian Starkey wrote:
> > > An output can be added as a clone of any other output(s) attached to a
> > > pipe using igt_output_clone_pipe()
> > > 
> > > v5: Drop field out_fence_requested from struct igt_pipe (Brian Starkey)
> > > 
> > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > ---
> > >  lib/igt_kms.c | 100 +++++++++++++++++++++++++++++++-------------------
> > >  lib/igt_kms.h |   4 ++
> > >  2 files changed, 66 insertions(+), 38 deletions(-)
> > > 
> > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > index 140db346..b85a0404 100644
> > > --- a/lib/igt_kms.c
> > > +++ b/lib/igt_kms.c
> > > @@ -1765,6 +1765,17 @@ static void igt_display_log_shift(igt_display_t *display, int shift)
> > >  	igt_assert(display->log_shift >= 0);
> > >  }
> > >  
> > > +static int igt_output_idx(igt_output_t *output)
> > > +{
> > > +	int i;
> > > +
> > > +	for (i = 0; i < output->display->n_outputs; i++)
> > > +		if (&output->display->outputs[i] == output)
> > > +			return i;
> > > +
> > > +	return -1;
> > > +}
> > > +
> > >  static void igt_output_refresh(igt_output_t *output)
> > >  {
> > >  	igt_display_t *display = output->display;
> > > @@ -2317,42 +2328,6 @@ void igt_display_fini(igt_display_t *display)
> > >  	display->planes = NULL;
> > >  }
> > >  
> > > -static void igt_display_refresh(igt_display_t *display)
> > > -{
> > > -	igt_output_t *output;
> > > -	int i;
> > > -
> > > -	unsigned long pipes_in_use = 0;
> > > -
> > > -       /* Check that two outputs aren't trying to use the same pipe */
> > > -	for (i = 0; i < display->n_outputs; i++) {
> > > -		output = &display->outputs[i];
> > > -
> > > -		if (output->pending_pipe != PIPE_NONE) {
> > > -			if (pipes_in_use & (1 << output->pending_pipe))
> > > -				goto report_dup;
> > > -
> > > -			pipes_in_use |= 1 << output->pending_pipe;
> > > -		}
> > > -
> > > -		if (output->force_reprobe)
> > > -			igt_output_refresh(output);
> > > -	}
> > > -
> > > -	return;
> > > -
> > > -report_dup:
> > > -	for (; i > 0; i--) {
> > > -		igt_output_t *b = &display->outputs[i - 1];
> > > -
> > > -		igt_assert_f(output->pending_pipe !=
> > > -			     b->pending_pipe,
> > > -			     "%s and %s are both trying to use pipe %s\n",
> > > -			     igt_output_name(output), igt_output_name(b),
> > > -			     kmstest_pipe_name(output->pending_pipe));
> > > -	}
> > > -}
> > > -
> > >  static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
> > >  {
> > >  	igt_display_t *display = output->display;
> > > @@ -2376,6 +2351,40 @@ static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
> > >  	return &display->pipes[pipe];
> > >  }
> > >  
> > > +static void igt_display_refresh(igt_display_t *display)
> > > +{
> > > +	igt_output_t *output;
> > > +	igt_pipe_t *pipe;
> > > +	int i;
> > > +
> > > +	unsigned long pipes_in_use = 0;
> > > +	unsigned long pending_crtc_idx_mask;
> > > +
> > > +	/* Check that outputs and pipes agree wrt. cloning */
> > > +	for (i = 0; i < display->n_outputs; i++) {
> > > +		output = &display->outputs[i];
> > > +		pending_crtc_idx_mask = 1 << output->pending_pipe;
> > > +
> > > +		pipe = igt_output_get_driving_pipe(output);
> > > +		if (pipe) {
> > > +			igt_assert_f(pipe->outputs & (1 << igt_output_idx(output)),
> > > +				     "Output %s not expected to be using pipe %s\n",
> > > +				     igt_output_name(output),
> > > +				     kmstest_pipe_name(pipe->pipe));
> > > +
> > > +			if (pipes_in_use & pending_crtc_idx_mask)
> > > +				LOG(display, "Output %s clones pipe %s\n",
> > > +				    igt_output_name(output),
> > > +				    kmstest_pipe_name(pipe->pipe));
> > > +		}
> > > +
> > > +		pipes_in_use |= pending_crtc_idx_mask;
> > > +
> > > +		if (output->force_reprobe)
> > > +			igt_output_refresh(output);
> > > +	}
> > > +}
> > > +
> > >  static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, int plane_idx)
> > >  {
> > >  	igt_require_f(plane_idx >= 0 && plane_idx < pipe->n_planes,
> > > @@ -3766,6 +3775,7 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
> > >  	output->use_override_mode = !!mode;
> > >  
> > >  	if (pipe) {
> > > +		igt_debug("overriding pipe mode in %s way\n", output->display->is_atomic ? "atomic" : "legacy");
> > >  		if (output->display->is_atomic)
> > >  			igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
> > >  		else
> > > @@ -3773,6 +3783,16 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
> > >  	}
> > >  }
> > >  
> > > +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe)
> > > +{
> > > +	igt_display_t *display = output->display;
> > > +	uint32_t current_clones = display->pipes[pipe].outputs;
> > > +
> > > +	igt_output_set_pipe(output, pipe);
> > > +
> > > +	display->pipes[pipe].outputs |= current_clones;
> > > +}
> > > +
> > >  /*
> > >   * igt_output_set_pipe:
> > >   * @output: Target output for which the pipe is being set to
> > > @@ -3789,11 +3809,15 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
> > >  
> > >  	igt_assert(output->name);
> > >  
> > > -	if (output->pending_pipe != PIPE_NONE)
> > > +	if (output->pending_pipe != PIPE_NONE) {
> > >  		old_pipe = igt_output_get_driving_pipe(output);
> > > +		old_pipe->outputs &= ~(1 << igt_output_idx(output));
> > > +	}
> > >  
> > > -	if (pipe != PIPE_NONE)
> > > +	if (pipe != PIPE_NONE) {
> > >  		pipe_obj = &display->pipes[pipe];
> > > +		pipe_obj->outputs = (1 << igt_output_idx(output));
> > > +	}
> > >  
> > >  	LOG(display, "%s: set_pipe(%s)\n", igt_output_name(output),
> > >  	    kmstest_pipe_name(pipe));
> > > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > > index cacc6b90..676839bb 100644
> > > --- a/lib/igt_kms.h
> > > +++ b/lib/igt_kms.h
> > > @@ -354,6 +354,8 @@ struct igt_pipe {
> > >  	uint32_t crtc_id;
> > >  
> > >  	int32_t out_fence_fd;
> > > +
> > > +	uint32_t outputs;
> > >  };
> > >  
> > >  typedef struct {
> > > @@ -411,6 +413,8 @@ const char *igt_output_name(igt_output_t *output);
> > >  drmModeModeInfo *igt_output_get_mode(igt_output_t *output);
> > >  void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode);
> > >  void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
> > > +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe);
> > > +
> > >  igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
> > >  igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
> > >  int igt_output_count_plane_type(igt_output_t *output, int plane_type);
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 5/6] lib/igt_kms: Add igt_output_clone_pipe for cloning
@ 2019-07-17 13:10         ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-17 13:10 UTC (permalink / raw)
  To: rodrigosiqueiramelo
  Cc: Latvala, Petri, intel-gfx, Liviu.Dudau, igt-dev, daniel, nd,
	Brian.Starkey

On Tue, 2019-07-16 at 22:47 -0300, Rodrigo Siqueira wrote:
> On 07/12, Ser, Simon wrote:
> > So, to test these last two patches we'd need specific hardware right?
> > Because VKMS doesn't support cloning yet (does it?).
> 
> hmmm... actually, VKMS successfully pass in this test. However, if you
> compare "writeback-check-output" and "writeback-check-output-clone", you
> will notice they are very similar. Maybe, this test does not correctly
> validating cloning feature?

Hmm. Are you sure it doesn't skip at igt_require(clone)? It should,
because VKMS only exposes one connector… Might be a bug in the test.

> > What kind of hardware supports cloned writeback outputs? I have a
> > Raspberry Pi which supports writeback via VC4, but I don't think it has
> > writeback cloning. I'm also not willing to install any proprietary
> > driver.
> > 
> > I guess we could land the first part of the series, and wait for VKMS
> > to support cloned outputs to land the last two patches.
> > 
> > Any other ideas?
> 
> btw, I'm totally comfortable with the idea of focusing on the first part
> of this series.

Yeah, let's land the first part and keep cloning for later :)

> Thanks
>  
> > On Wed, 2019-06-12 at 23:18 -0300, Brian Starkey wrote:
> > > An output can be added as a clone of any other output(s) attached to a
> > > pipe using igt_output_clone_pipe()
> > > 
> > > v5: Drop field out_fence_requested from struct igt_pipe (Brian Starkey)
> > > 
> > > Signed-off-by: Brian Starkey <brian.starkey@arm.com>
> > > ---
> > >  lib/igt_kms.c | 100 +++++++++++++++++++++++++++++++-------------------
> > >  lib/igt_kms.h |   4 ++
> > >  2 files changed, 66 insertions(+), 38 deletions(-)
> > > 
> > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > index 140db346..b85a0404 100644
> > > --- a/lib/igt_kms.c
> > > +++ b/lib/igt_kms.c
> > > @@ -1765,6 +1765,17 @@ static void igt_display_log_shift(igt_display_t *display, int shift)
> > >  	igt_assert(display->log_shift >= 0);
> > >  }
> > >  
> > > +static int igt_output_idx(igt_output_t *output)
> > > +{
> > > +	int i;
> > > +
> > > +	for (i = 0; i < output->display->n_outputs; i++)
> > > +		if (&output->display->outputs[i] == output)
> > > +			return i;
> > > +
> > > +	return -1;
> > > +}
> > > +
> > >  static void igt_output_refresh(igt_output_t *output)
> > >  {
> > >  	igt_display_t *display = output->display;
> > > @@ -2317,42 +2328,6 @@ void igt_display_fini(igt_display_t *display)
> > >  	display->planes = NULL;
> > >  }
> > >  
> > > -static void igt_display_refresh(igt_display_t *display)
> > > -{
> > > -	igt_output_t *output;
> > > -	int i;
> > > -
> > > -	unsigned long pipes_in_use = 0;
> > > -
> > > -       /* Check that two outputs aren't trying to use the same pipe */
> > > -	for (i = 0; i < display->n_outputs; i++) {
> > > -		output = &display->outputs[i];
> > > -
> > > -		if (output->pending_pipe != PIPE_NONE) {
> > > -			if (pipes_in_use & (1 << output->pending_pipe))
> > > -				goto report_dup;
> > > -
> > > -			pipes_in_use |= 1 << output->pending_pipe;
> > > -		}
> > > -
> > > -		if (output->force_reprobe)
> > > -			igt_output_refresh(output);
> > > -	}
> > > -
> > > -	return;
> > > -
> > > -report_dup:
> > > -	for (; i > 0; i--) {
> > > -		igt_output_t *b = &display->outputs[i - 1];
> > > -
> > > -		igt_assert_f(output->pending_pipe !=
> > > -			     b->pending_pipe,
> > > -			     "%s and %s are both trying to use pipe %s\n",
> > > -			     igt_output_name(output), igt_output_name(b),
> > > -			     kmstest_pipe_name(output->pending_pipe));
> > > -	}
> > > -}
> > > -
> > >  static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
> > >  {
> > >  	igt_display_t *display = output->display;
> > > @@ -2376,6 +2351,40 @@ static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
> > >  	return &display->pipes[pipe];
> > >  }
> > >  
> > > +static void igt_display_refresh(igt_display_t *display)
> > > +{
> > > +	igt_output_t *output;
> > > +	igt_pipe_t *pipe;
> > > +	int i;
> > > +
> > > +	unsigned long pipes_in_use = 0;
> > > +	unsigned long pending_crtc_idx_mask;
> > > +
> > > +	/* Check that outputs and pipes agree wrt. cloning */
> > > +	for (i = 0; i < display->n_outputs; i++) {
> > > +		output = &display->outputs[i];
> > > +		pending_crtc_idx_mask = 1 << output->pending_pipe;
> > > +
> > > +		pipe = igt_output_get_driving_pipe(output);
> > > +		if (pipe) {
> > > +			igt_assert_f(pipe->outputs & (1 << igt_output_idx(output)),
> > > +				     "Output %s not expected to be using pipe %s\n",
> > > +				     igt_output_name(output),
> > > +				     kmstest_pipe_name(pipe->pipe));
> > > +
> > > +			if (pipes_in_use & pending_crtc_idx_mask)
> > > +				LOG(display, "Output %s clones pipe %s\n",
> > > +				    igt_output_name(output),
> > > +				    kmstest_pipe_name(pipe->pipe));
> > > +		}
> > > +
> > > +		pipes_in_use |= pending_crtc_idx_mask;
> > > +
> > > +		if (output->force_reprobe)
> > > +			igt_output_refresh(output);
> > > +	}
> > > +}
> > > +
> > >  static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, int plane_idx)
> > >  {
> > >  	igt_require_f(plane_idx >= 0 && plane_idx < pipe->n_planes,
> > > @@ -3766,6 +3775,7 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
> > >  	output->use_override_mode = !!mode;
> > >  
> > >  	if (pipe) {
> > > +		igt_debug("overriding pipe mode in %s way\n", output->display->is_atomic ? "atomic" : "legacy");
> > >  		if (output->display->is_atomic)
> > >  			igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
> > >  		else
> > > @@ -3773,6 +3783,16 @@ void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode)
> > >  	}
> > >  }
> > >  
> > > +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe)
> > > +{
> > > +	igt_display_t *display = output->display;
> > > +	uint32_t current_clones = display->pipes[pipe].outputs;
> > > +
> > > +	igt_output_set_pipe(output, pipe);
> > > +
> > > +	display->pipes[pipe].outputs |= current_clones;
> > > +}
> > > +
> > >  /*
> > >   * igt_output_set_pipe:
> > >   * @output: Target output for which the pipe is being set to
> > > @@ -3789,11 +3809,15 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
> > >  
> > >  	igt_assert(output->name);
> > >  
> > > -	if (output->pending_pipe != PIPE_NONE)
> > > +	if (output->pending_pipe != PIPE_NONE) {
> > >  		old_pipe = igt_output_get_driving_pipe(output);
> > > +		old_pipe->outputs &= ~(1 << igt_output_idx(output));
> > > +	}
> > >  
> > > -	if (pipe != PIPE_NONE)
> > > +	if (pipe != PIPE_NONE) {
> > >  		pipe_obj = &display->pipes[pipe];
> > > +		pipe_obj->outputs = (1 << igt_output_idx(output));
> > > +	}
> > >  
> > >  	LOG(display, "%s: set_pipe(%s)\n", igt_output_name(output),
> > >  	    kmstest_pipe_name(pipe));
> > > diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> > > index cacc6b90..676839bb 100644
> > > --- a/lib/igt_kms.h
> > > +++ b/lib/igt_kms.h
> > > @@ -354,6 +354,8 @@ struct igt_pipe {
> > >  	uint32_t crtc_id;
> > >  
> > >  	int32_t out_fence_fd;
> > > +
> > > +	uint32_t outputs;
> > >  };
> > >  
> > >  typedef struct {
> > > @@ -411,6 +413,8 @@ const char *igt_output_name(igt_output_t *output);
> > >  drmModeModeInfo *igt_output_get_mode(igt_output_t *output);
> > >  void igt_output_override_mode(igt_output_t *output, const drmModeModeInfo *mode);
> > >  void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
> > > +void igt_output_clone_pipe(igt_output_t *output, enum pipe pipe);
> > > +
> > >  igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
> > >  igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
> > >  int igt_output_count_plane_type(igt_output_t *output, int plane_type);
> > > _______________________________________________
> > > igt-dev mailing list
> > > igt-dev@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-07-17 11:46           ` [Intel-gfx] " Ser, Simon
@ 2019-07-18  9:49             ` Liviu.Dudau
  -1 siblings, 0 replies; 71+ messages in thread
From: Liviu.Dudau @ 2019-07-18  9:49 UTC (permalink / raw)
  To: Ser, Simon; +Cc: rodrigosiqueiramelo, intel-gfx, igt-dev, nd

On Wed, Jul 17, 2019 at 11:46:39AM +0000, Ser, Simon wrote:
> Thanks for the clarification!
> 
> On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > +{
> > > > > +	int i, ret;
> > > > > +	int32_t out_fence;
> > > > > +	struct {
> > > > > +		uint32_t fb_id;
> > > > > +		bool ptr_valid;
> > > > > +		int32_t *out_fence_ptr;
> > > > > +	} invalid_tests[] = {
> > > > > +		{
> > > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > +			.fb_id = 0,
> > > > > +			.ptr_valid = true,
> > > > > +			.out_fence_ptr = &out_fence,
> > > > > +		},
> > > > > +		{
> > > > > +			/* Invalid output buffer. */
> > > > > +			.fb_id = invalid_fb->fb_id,
> > > > > +			.ptr_valid = true,
> > > > > +			.out_fence_ptr = &out_fence,
> > > > > +		},
> > > > 
> > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > 
> > It tries to test that you can't trick the driver to do any work on a fence if
> > the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> > invalid fb with valid fence, valid fb but invalid fence and assumes that no
> > fb with invalid fence is a NOP anyway.
> 
> Yeah, that makes sense, it's just confusing to put it in a function
> named invalid_out_fence. Here the out fence is valid, but the output
> buffer isn't, so it should probably be moved away (or this function
> should be renamed).

Don't want to offend or anything, but this does sound like bikeshedding. You
have a couple of parameters that you want to have a test for because they are
linked together (output framebuffer and fence) and you go through the
combination of possible bad options in the test. Not sure what name we can use
for the function, other than maybe 'test_invalid_parameters'? Given that 2/3
tests an invalid out fence, the name was thought to be relevant.

Having invalid out buffer test separate into its own test brings no benefits, IMHO.

Best regards,
Liviu

> 
> > > > > +		{
> > > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > +			.fb_id = valid_fb->fb_id,
> > > > > +			.ptr_valid = false,
> > > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > > +		},
> > > > > +	};
> > > > > +
> > > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +					invalid_tests[i].fb_id,
> > > > > +					invalid_tests[i].out_fence_ptr,
> > > > > +					invalid_tests[i].ptr_valid);
> > > > > +		igt_assert(ret != 0);
> > > > 
> > > > Maybe we can check for -ret == EINVAL?
> > > > 
> > > > > +	}
> > > > > +}
> > > > > +
> > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > 
> > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > for input and writeback output.
> > > > 
> > > > > +{
> > > > > +
> > > > > +	int ret;
> > > > > +
> > > > > +	/* Valid output buffer */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				valid_fb->fb_id, NULL, false);
> > > > > +	igt_assert(ret == 0);
> > > > > +
> > > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				output->id, NULL, false);
> > > > > +	igt_assert(ret == -EINVAL);
> > > > > +
> > > > > +	/* Zero WRITEBACK_FB_ID */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				0, NULL, false);
> > > > > +	igt_assert(ret == 0);
> > > > > +}
> > > > > +
> > > > > +igt_main
> > > > > +{
> > > > > +	igt_display_t display;
> > > > > +	igt_output_t *output;
> > > > > +	igt_plane_t *plane;
> > > > > +	igt_fb_t input_fb;
> > > > > +	drmModeModeInfo mode;
> > > > > +	int ret;
> > > > > +
> > > > > +	memset(&display, 0, sizeof(display));
> > > > > +
> > > > > +	igt_fixture {
> > > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > +
> > > > > +		kmstest_set_vt_graphics_mode();
> > > > > +
> > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > +
> > > > > +		igt_require(display.is_atomic);
> > > > > +
> > > > > +		output = kms_writeback_get_output(&display);
> > > > > +		igt_require(output);
> > > > > +
> > > > > +		if (output->use_override_mode)
> > > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > +		else
> > > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > +
> > > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > +		igt_require(plane);
> > > > 
> > > > Maybe we can assert on this?
> > > > 
> > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > +				    mode.vdisplay,
> > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > +				    igt_fb_mod_to_tiling(0),
> > > > 
> > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > better to make this clear.
> > 
> > Agree. The patchset pre-dates the modifiers support (or has the same age, I
> > forgot)
> > 
> > > > (Applies to other lines of this patch)
> > > > 
> > > > > +				    &input_fb);
> > > > > +		igt_assert(ret >= 0);
> > > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > > +	}
> > > > > +
> > > > > +	igt_subtest("writeback-pixel-formats") {
> > > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > 
> > > > Need to drmModeFreePropertyBlob this.
> > > > 
> > > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > +		unsigned int i;
> > > > > +		char *c;
> > > > > +
> > > > > +		/*
> > > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > > +		 * any outlandish characters
> > > > > +		 */
> > > > > +		igt_assert(!(formats_blob->length % 4));
> > > > > +		c = formats_blob->data;
> > > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > > +				     "Unexpected character %c\n", c[i]);
> > > > 
> > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > codes will be made from ASCII characters, in fact some formats already
> > > > have non-printable chars in them. I don't want to have to update this
> > > > test when a new fourcc format is added.
> > 
> > Like the comments says, we don't have a full list of formats to check against.
> > Suggestions on how to improve are welcome, but I don't think we should delay
> > (any longer) the patchset due to this.
> 
> Agreed.
> 
> > Best regards,
> > Liviu

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-18  9:49             ` Liviu.Dudau
  0 siblings, 0 replies; 71+ messages in thread
From: Liviu.Dudau @ 2019-07-18  9:49 UTC (permalink / raw)
  To: Ser, Simon; +Cc: Latvala, Petri, intel-gfx, igt-dev, daniel, nd, Brian.Starkey

On Wed, Jul 17, 2019 at 11:46:39AM +0000, Ser, Simon wrote:
> Thanks for the clarification!
> 
> On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > +{
> > > > > +	int i, ret;
> > > > > +	int32_t out_fence;
> > > > > +	struct {
> > > > > +		uint32_t fb_id;
> > > > > +		bool ptr_valid;
> > > > > +		int32_t *out_fence_ptr;
> > > > > +	} invalid_tests[] = {
> > > > > +		{
> > > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > +			.fb_id = 0,
> > > > > +			.ptr_valid = true,
> > > > > +			.out_fence_ptr = &out_fence,
> > > > > +		},
> > > > > +		{
> > > > > +			/* Invalid output buffer. */
> > > > > +			.fb_id = invalid_fb->fb_id,
> > > > > +			.ptr_valid = true,
> > > > > +			.out_fence_ptr = &out_fence,
> > > > > +		},
> > > > 
> > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > 
> > It tries to test that you can't trick the driver to do any work on a fence if
> > the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> > invalid fb with valid fence, valid fb but invalid fence and assumes that no
> > fb with invalid fence is a NOP anyway.
> 
> Yeah, that makes sense, it's just confusing to put it in a function
> named invalid_out_fence. Here the out fence is valid, but the output
> buffer isn't, so it should probably be moved away (or this function
> should be renamed).

Don't want to offend or anything, but this does sound like bikeshedding. You
have a couple of parameters that you want to have a test for because they are
linked together (output framebuffer and fence) and you go through the
combination of possible bad options in the test. Not sure what name we can use
for the function, other than maybe 'test_invalid_parameters'? Given that 2/3
tests an invalid out fence, the name was thought to be relevant.

Having invalid out buffer test separate into its own test brings no benefits, IMHO.

Best regards,
Liviu

> 
> > > > > +		{
> > > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > +			.fb_id = valid_fb->fb_id,
> > > > > +			.ptr_valid = false,
> > > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > > +		},
> > > > > +	};
> > > > > +
> > > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +					invalid_tests[i].fb_id,
> > > > > +					invalid_tests[i].out_fence_ptr,
> > > > > +					invalid_tests[i].ptr_valid);
> > > > > +		igt_assert(ret != 0);
> > > > 
> > > > Maybe we can check for -ret == EINVAL?
> > > > 
> > > > > +	}
> > > > > +}
> > > > > +
> > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > 
> > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > for input and writeback output.
> > > > 
> > > > > +{
> > > > > +
> > > > > +	int ret;
> > > > > +
> > > > > +	/* Valid output buffer */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				valid_fb->fb_id, NULL, false);
> > > > > +	igt_assert(ret == 0);
> > > > > +
> > > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				output->id, NULL, false);
> > > > > +	igt_assert(ret == -EINVAL);
> > > > > +
> > > > > +	/* Zero WRITEBACK_FB_ID */
> > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > +				0, NULL, false);
> > > > > +	igt_assert(ret == 0);
> > > > > +}
> > > > > +
> > > > > +igt_main
> > > > > +{
> > > > > +	igt_display_t display;
> > > > > +	igt_output_t *output;
> > > > > +	igt_plane_t *plane;
> > > > > +	igt_fb_t input_fb;
> > > > > +	drmModeModeInfo mode;
> > > > > +	int ret;
> > > > > +
> > > > > +	memset(&display, 0, sizeof(display));
> > > > > +
> > > > > +	igt_fixture {
> > > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > +
> > > > > +		kmstest_set_vt_graphics_mode();
> > > > > +
> > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > +
> > > > > +		igt_require(display.is_atomic);
> > > > > +
> > > > > +		output = kms_writeback_get_output(&display);
> > > > > +		igt_require(output);
> > > > > +
> > > > > +		if (output->use_override_mode)
> > > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > +		else
> > > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > +
> > > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > +		igt_require(plane);
> > > > 
> > > > Maybe we can assert on this?
> > > > 
> > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > +				    mode.vdisplay,
> > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > +				    igt_fb_mod_to_tiling(0),
> > > > 
> > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > better to make this clear.
> > 
> > Agree. The patchset pre-dates the modifiers support (or has the same age, I
> > forgot)
> > 
> > > > (Applies to other lines of this patch)
> > > > 
> > > > > +				    &input_fb);
> > > > > +		igt_assert(ret >= 0);
> > > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > > +	}
> > > > > +
> > > > > +	igt_subtest("writeback-pixel-formats") {
> > > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > 
> > > > Need to drmModeFreePropertyBlob this.
> > > > 
> > > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > +		unsigned int i;
> > > > > +		char *c;
> > > > > +
> > > > > +		/*
> > > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > > +		 * any outlandish characters
> > > > > +		 */
> > > > > +		igt_assert(!(formats_blob->length % 4));
> > > > > +		c = formats_blob->data;
> > > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > > +				     "Unexpected character %c\n", c[i]);
> > > > 
> > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > codes will be made from ASCII characters, in fact some formats already
> > > > have non-printable chars in them. I don't want to have to update this
> > > > test when a new fourcc format is added.
> > 
> > Like the comments says, we don't have a full list of formats to check against.
> > Suggestions on how to improve are welcome, but I don't think we should delay
> > (any longer) the patchset due to this.
> 
> Agreed.
> 
> > Best regards,
> > Liviu

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-07-18  9:49             ` Liviu.Dudau
@ 2019-07-18  9:56               ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-18  9:56 UTC (permalink / raw)
  To: Liviu.Dudau; +Cc: rodrigosiqueiramelo, intel-gfx, igt-dev, nd

On Thu, 2019-07-18 at 10:49 +0100, Liviu.Dudau@arm.com wrote:
> On Wed, Jul 17, 2019 at 11:46:39AM +0000, Ser, Simon wrote:
> > Thanks for the clarification!
> > 
> > On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > +{
> > > > > > +	int i, ret;
> > > > > > +	int32_t out_fence;
> > > > > > +	struct {
> > > > > > +		uint32_t fb_id;
> > > > > > +		bool ptr_valid;
> > > > > > +		int32_t *out_fence_ptr;
> > > > > > +	} invalid_tests[] = {
> > > > > > +		{
> > > > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > > +			.fb_id = 0,
> > > > > > +			.ptr_valid = true,
> > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > +		},
> > > > > > +		{
> > > > > > +			/* Invalid output buffer. */
> > > > > > +			.fb_id = invalid_fb->fb_id,
> > > > > > +			.ptr_valid = true,
> > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > +		},
> > > > > 
> > > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > 
> > > It tries to test that you can't trick the driver to do any work on a fence if
> > > the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> > > invalid fb with valid fence, valid fb but invalid fence and assumes that no
> > > fb with invalid fence is a NOP anyway.
> > 
> > Yeah, that makes sense, it's just confusing to put it in a function
> > named invalid_out_fence. Here the out fence is valid, but the output
> > buffer isn't, so it should probably be moved away (or this function
> > should be renamed).
> 
> Don't want to offend or anything, but this does sound like bikeshedding. You
> have a couple of parameters that you want to have a test for because they are
> linked together (output framebuffer and fence) and you go through the
> combination of possible bad options in the test. Not sure what name we can use
> for the function, other than maybe 'test_invalid_parameters'? Given that 2/3
> tests an invalid out fence, the name was thought to be relevant.
> 
> Having invalid out buffer test separate into its own test brings no benefits, IMHO.

Well, the issue is that I've been confused when reviewing the patch
series. I had trouble understanding what the test does and why. I also
had trouble to identify that do_writeback_test never submits a
writeback operation (see other e-mail).

A name that is relevant "all the time, most of the time", is not
relevant at all in my opinion. It just tricks the reader into thinking
the test does one thing, while it also does something else.

If it would be obvious, I wouldn't mind. But here IMHO it hurts
readability. So I'd prefer to rename the function.

If you think it's obvious, then maybe it's just me. I'd love to hear
from others if they have a different opinion.

(As a side note, I agree I have a tendency to bikeshed, I try to mark
my bikesheddings behind "nit:" flags.)

> Best regards,
> Liviu
> 
> > > > > > +		{
> > > > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > > +			.fb_id = valid_fb->fb_id,
> > > > > > +			.ptr_valid = false,
> > > > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > > > +		},
> > > > > > +	};
> > > > > > +
> > > > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > +					invalid_tests[i].fb_id,
> > > > > > +					invalid_tests[i].out_fence_ptr,
> > > > > > +					invalid_tests[i].ptr_valid);
> > > > > > +		igt_assert(ret != 0);
> > > > > 
> > > > > Maybe we can check for -ret == EINVAL?
> > > > > 
> > > > > > +	}
> > > > > > +}
> > > > > > +
> > > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > 
> > > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > > for input and writeback output.
> > > > > 
> > > > > > +{
> > > > > > +
> > > > > > +	int ret;
> > > > > > +
> > > > > > +	/* Valid output buffer */
> > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > +				valid_fb->fb_id, NULL, false);
> > > > > > +	igt_assert(ret == 0);
> > > > > > +
> > > > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > +				output->id, NULL, false);
> > > > > > +	igt_assert(ret == -EINVAL);
> > > > > > +
> > > > > > +	/* Zero WRITEBACK_FB_ID */
> > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > +				0, NULL, false);
> > > > > > +	igt_assert(ret == 0);
> > > > > > +}
> > > > > > +
> > > > > > +igt_main
> > > > > > +{
> > > > > > +	igt_display_t display;
> > > > > > +	igt_output_t *output;
> > > > > > +	igt_plane_t *plane;
> > > > > > +	igt_fb_t input_fb;
> > > > > > +	drmModeModeInfo mode;
> > > > > > +	int ret;
> > > > > > +
> > > > > > +	memset(&display, 0, sizeof(display));
> > > > > > +
> > > > > > +	igt_fixture {
> > > > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > +
> > > > > > +		kmstest_set_vt_graphics_mode();
> > > > > > +
> > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > +
> > > > > > +		igt_require(display.is_atomic);
> > > > > > +
> > > > > > +		output = kms_writeback_get_output(&display);
> > > > > > +		igt_require(output);
> > > > > > +
> > > > > > +		if (output->use_override_mode)
> > > > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > > +		else
> > > > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > > +
> > > > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > > +		igt_require(plane);
> > > > > 
> > > > > Maybe we can assert on this?
> > > > > 
> > > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > > +				    mode.vdisplay,
> > > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > > +				    igt_fb_mod_to_tiling(0),
> > > > > 
> > > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > > better to make this clear.
> > > 
> > > Agree. The patchset pre-dates the modifiers support (or has the same age, I
> > > forgot)
> > > 
> > > > > (Applies to other lines of this patch)
> > > > > 
> > > > > > +				    &input_fb);
> > > > > > +		igt_assert(ret >= 0);
> > > > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > > > +	}
> > > > > > +
> > > > > > +	igt_subtest("writeback-pixel-formats") {
> > > > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > > 
> > > > > Need to drmModeFreePropertyBlob this.
> > > > > 
> > > > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > > +		unsigned int i;
> > > > > > +		char *c;
> > > > > > +
> > > > > > +		/*
> > > > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > > > +		 * any outlandish characters
> > > > > > +		 */
> > > > > > +		igt_assert(!(formats_blob->length % 4));
> > > > > > +		c = formats_blob->data;
> > > > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > > > +				     "Unexpected character %c\n", c[i]);
> > > > > 
> > > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > > codes will be made from ASCII characters, in fact some formats already
> > > > > have non-printable chars in them. I don't want to have to update this
> > > > > test when a new fourcc format is added.
> > > 
> > > Like the comments says, we don't have a full list of formats to check against.
> > > Suggestions on how to improve are welcome, but I don't think we should delay
> > > (any longer) the patchset due to this.
> > 
> > Agreed.
> > 
> > > Best regards,
> > > Liviu
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-18  9:56               ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-18  9:56 UTC (permalink / raw)
  To: Liviu.Dudau; +Cc: Latvala, Petri, intel-gfx, igt-dev, daniel, nd, Brian.Starkey

On Thu, 2019-07-18 at 10:49 +0100, Liviu.Dudau@arm.com wrote:
> On Wed, Jul 17, 2019 at 11:46:39AM +0000, Ser, Simon wrote:
> > Thanks for the clarification!
> > 
> > On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > +{
> > > > > > +	int i, ret;
> > > > > > +	int32_t out_fence;
> > > > > > +	struct {
> > > > > > +		uint32_t fb_id;
> > > > > > +		bool ptr_valid;
> > > > > > +		int32_t *out_fence_ptr;
> > > > > > +	} invalid_tests[] = {
> > > > > > +		{
> > > > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > > +			.fb_id = 0,
> > > > > > +			.ptr_valid = true,
> > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > +		},
> > > > > > +		{
> > > > > > +			/* Invalid output buffer. */
> > > > > > +			.fb_id = invalid_fb->fb_id,
> > > > > > +			.ptr_valid = true,
> > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > +		},
> > > > > 
> > > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > 
> > > It tries to test that you can't trick the driver to do any work on a fence if
> > > the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> > > invalid fb with valid fence, valid fb but invalid fence and assumes that no
> > > fb with invalid fence is a NOP anyway.
> > 
> > Yeah, that makes sense, it's just confusing to put it in a function
> > named invalid_out_fence. Here the out fence is valid, but the output
> > buffer isn't, so it should probably be moved away (or this function
> > should be renamed).
> 
> Don't want to offend or anything, but this does sound like bikeshedding. You
> have a couple of parameters that you want to have a test for because they are
> linked together (output framebuffer and fence) and you go through the
> combination of possible bad options in the test. Not sure what name we can use
> for the function, other than maybe 'test_invalid_parameters'? Given that 2/3
> tests an invalid out fence, the name was thought to be relevant.
> 
> Having invalid out buffer test separate into its own test brings no benefits, IMHO.

Well, the issue is that I've been confused when reviewing the patch
series. I had trouble understanding what the test does and why. I also
had trouble to identify that do_writeback_test never submits a
writeback operation (see other e-mail).

A name that is relevant "all the time, most of the time", is not
relevant at all in my opinion. It just tricks the reader into thinking
the test does one thing, while it also does something else.

If it would be obvious, I wouldn't mind. But here IMHO it hurts
readability. So I'd prefer to rename the function.

If you think it's obvious, then maybe it's just me. I'd love to hear
from others if they have a different opinion.

(As a side note, I agree I have a tendency to bikeshed, I try to mark
my bikesheddings behind "nit:" flags.)

> Best regards,
> Liviu
> 
> > > > > > +		{
> > > > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > > +			.fb_id = valid_fb->fb_id,
> > > > > > +			.ptr_valid = false,
> > > > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > > > +		},
> > > > > > +	};
> > > > > > +
> > > > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > +					invalid_tests[i].fb_id,
> > > > > > +					invalid_tests[i].out_fence_ptr,
> > > > > > +					invalid_tests[i].ptr_valid);
> > > > > > +		igt_assert(ret != 0);
> > > > > 
> > > > > Maybe we can check for -ret == EINVAL?
> > > > > 
> > > > > > +	}
> > > > > > +}
> > > > > > +
> > > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > 
> > > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > > for input and writeback output.
> > > > > 
> > > > > > +{
> > > > > > +
> > > > > > +	int ret;
> > > > > > +
> > > > > > +	/* Valid output buffer */
> > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > +				valid_fb->fb_id, NULL, false);
> > > > > > +	igt_assert(ret == 0);
> > > > > > +
> > > > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > +				output->id, NULL, false);
> > > > > > +	igt_assert(ret == -EINVAL);
> > > > > > +
> > > > > > +	/* Zero WRITEBACK_FB_ID */
> > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > +				0, NULL, false);
> > > > > > +	igt_assert(ret == 0);
> > > > > > +}
> > > > > > +
> > > > > > +igt_main
> > > > > > +{
> > > > > > +	igt_display_t display;
> > > > > > +	igt_output_t *output;
> > > > > > +	igt_plane_t *plane;
> > > > > > +	igt_fb_t input_fb;
> > > > > > +	drmModeModeInfo mode;
> > > > > > +	int ret;
> > > > > > +
> > > > > > +	memset(&display, 0, sizeof(display));
> > > > > > +
> > > > > > +	igt_fixture {
> > > > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > +
> > > > > > +		kmstest_set_vt_graphics_mode();
> > > > > > +
> > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > +
> > > > > > +		igt_require(display.is_atomic);
> > > > > > +
> > > > > > +		output = kms_writeback_get_output(&display);
> > > > > > +		igt_require(output);
> > > > > > +
> > > > > > +		if (output->use_override_mode)
> > > > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > > +		else
> > > > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > > +
> > > > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > > +		igt_require(plane);
> > > > > 
> > > > > Maybe we can assert on this?
> > > > > 
> > > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > > +				    mode.vdisplay,
> > > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > > +				    igt_fb_mod_to_tiling(0),
> > > > > 
> > > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > > better to make this clear.
> > > 
> > > Agree. The patchset pre-dates the modifiers support (or has the same age, I
> > > forgot)
> > > 
> > > > > (Applies to other lines of this patch)
> > > > > 
> > > > > > +				    &input_fb);
> > > > > > +		igt_assert(ret >= 0);
> > > > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > > > +	}
> > > > > > +
> > > > > > +	igt_subtest("writeback-pixel-formats") {
> > > > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > > 
> > > > > Need to drmModeFreePropertyBlob this.
> > > > > 
> > > > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > > +		unsigned int i;
> > > > > > +		char *c;
> > > > > > +
> > > > > > +		/*
> > > > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > > > +		 * any outlandish characters
> > > > > > +		 */
> > > > > > +		igt_assert(!(formats_blob->length % 4));
> > > > > > +		c = formats_blob->data;
> > > > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > > > +				     "Unexpected character %c\n", c[i]);
> > > > > 
> > > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > > codes will be made from ASCII characters, in fact some formats already
> > > > > have non-printable chars in them. I don't want to have to update this
> > > > > test when a new fourcc format is added.
> > > 
> > > Like the comments says, we don't have a full list of formats to check against.
> > > Suggestions on how to improve are welcome, but I don't think we should delay
> > > (any longer) the patchset due to this.
> > 
> > Agreed.
> > 
> > > Best regards,
> > > Liviu
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-07-18  9:56               ` Ser, Simon
@ 2019-07-18 11:15                 ` Liviu.Dudau
  -1 siblings, 0 replies; 71+ messages in thread
From: Liviu.Dudau @ 2019-07-18 11:15 UTC (permalink / raw)
  To: Ser, Simon; +Cc: rodrigosiqueiramelo, intel-gfx, igt-dev, nd

On Thu, Jul 18, 2019 at 09:56:39AM +0000, Ser, Simon wrote:
> On Thu, 2019-07-18 at 10:49 +0100, Liviu.Dudau@arm.com wrote:
> > On Wed, Jul 17, 2019 at 11:46:39AM +0000, Ser, Simon wrote:
> > > Thanks for the clarification!
> > > 
> > > On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > > +{
> > > > > > > +	int i, ret;
> > > > > > > +	int32_t out_fence;
> > > > > > > +	struct {
> > > > > > > +		uint32_t fb_id;
> > > > > > > +		bool ptr_valid;
> > > > > > > +		int32_t *out_fence_ptr;
> > > > > > > +	} invalid_tests[] = {
> > > > > > > +		{
> > > > > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > > > +			.fb_id = 0,
> > > > > > > +			.ptr_valid = true,
> > > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > > +		},
> > > > > > > +		{
> > > > > > > +			/* Invalid output buffer. */
> > > > > > > +			.fb_id = invalid_fb->fb_id,
> > > > > > > +			.ptr_valid = true,
> > > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > > +		},
> > > > > > 
> > > > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > > 
> > > > It tries to test that you can't trick the driver to do any work on a fence if
> > > > the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> > > > invalid fb with valid fence, valid fb but invalid fence and assumes that no
> > > > fb with invalid fence is a NOP anyway.
> > > 
> > > Yeah, that makes sense, it's just confusing to put it in a function
> > > named invalid_out_fence. Here the out fence is valid, but the output
> > > buffer isn't, so it should probably be moved away (or this function
> > > should be renamed).
> > 
> > Don't want to offend or anything, but this does sound like bikeshedding. You
> > have a couple of parameters that you want to have a test for because they are
> > linked together (output framebuffer and fence) and you go through the
> > combination of possible bad options in the test. Not sure what name we can use
> > for the function, other than maybe 'test_invalid_parameters'? Given that 2/3
> > tests an invalid out fence, the name was thought to be relevant.
> > 
> > Having invalid out buffer test separate into its own test brings no benefits, IMHO.
> 
> Well, the issue is that I've been confused when reviewing the patch
> series. I had trouble understanding what the test does and why. I also
> had trouble to identify that do_writeback_test never submits a
> writeback operation (see other e-mail).
> 
> A name that is relevant "all the time, most of the time", is not
> relevant at all in my opinion. It just tricks the reader into thinking
> the test does one thing, while it also does something else.
> 
> If it would be obvious, I wouldn't mind. But here IMHO it hurts
> readability. So I'd prefer to rename the function.

I take your comments as a valid point.

Does "test_invalid_parameters" sound like a good name for the function? Is so,
Rodrigo, can you please use that name in the next revision of the patch?

> 
> If you think it's obvious, then maybe it's just me. I'd love to hear
> from others if they have a different opinion.
> 
> (As a side note, I agree I have a tendency to bikeshed, I try to mark
> my bikesheddings behind "nit:" flags.)

I've only said "it sounded like" :)

Best regards,
Liviu

> 
> > Best regards,
> > Liviu
> > 
> > > > > > > +		{
> > > > > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > > > +			.fb_id = valid_fb->fb_id,
> > > > > > > +			.ptr_valid = false,
> > > > > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > > > > +		},
> > > > > > > +	};
> > > > > > > +
> > > > > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > +					invalid_tests[i].fb_id,
> > > > > > > +					invalid_tests[i].out_fence_ptr,
> > > > > > > +					invalid_tests[i].ptr_valid);
> > > > > > > +		igt_assert(ret != 0);
> > > > > > 
> > > > > > Maybe we can check for -ret == EINVAL?
> > > > > > 
> > > > > > > +	}
> > > > > > > +}
> > > > > > > +
> > > > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > 
> > > > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > > > for input and writeback output.
> > > > > > 
> > > > > > > +{
> > > > > > > +
> > > > > > > +	int ret;
> > > > > > > +
> > > > > > > +	/* Valid output buffer */
> > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > +				valid_fb->fb_id, NULL, false);
> > > > > > > +	igt_assert(ret == 0);
> > > > > > > +
> > > > > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > +				output->id, NULL, false);
> > > > > > > +	igt_assert(ret == -EINVAL);
> > > > > > > +
> > > > > > > +	/* Zero WRITEBACK_FB_ID */
> > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > +				0, NULL, false);
> > > > > > > +	igt_assert(ret == 0);
> > > > > > > +}
> > > > > > > +
> > > > > > > +igt_main
> > > > > > > +{
> > > > > > > +	igt_display_t display;
> > > > > > > +	igt_output_t *output;
> > > > > > > +	igt_plane_t *plane;
> > > > > > > +	igt_fb_t input_fb;
> > > > > > > +	drmModeModeInfo mode;
> > > > > > > +	int ret;
> > > > > > > +
> > > > > > > +	memset(&display, 0, sizeof(display));
> > > > > > > +
> > > > > > > +	igt_fixture {
> > > > > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > > +
> > > > > > > +		kmstest_set_vt_graphics_mode();
> > > > > > > +
> > > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > > +
> > > > > > > +		igt_require(display.is_atomic);
> > > > > > > +
> > > > > > > +		output = kms_writeback_get_output(&display);
> > > > > > > +		igt_require(output);
> > > > > > > +
> > > > > > > +		if (output->use_override_mode)
> > > > > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > > > +		else
> > > > > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > > > +
> > > > > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > > > +		igt_require(plane);
> > > > > > 
> > > > > > Maybe we can assert on this?
> > > > > > 
> > > > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > > > +				    mode.vdisplay,
> > > > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > > > +				    igt_fb_mod_to_tiling(0),
> > > > > > 
> > > > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > > > better to make this clear.
> > > > 
> > > > Agree. The patchset pre-dates the modifiers support (or has the same age, I
> > > > forgot)
> > > > 
> > > > > > (Applies to other lines of this patch)
> > > > > > 
> > > > > > > +				    &input_fb);
> > > > > > > +		igt_assert(ret >= 0);
> > > > > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > > > > +	}
> > > > > > > +
> > > > > > > +	igt_subtest("writeback-pixel-formats") {
> > > > > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > > > 
> > > > > > Need to drmModeFreePropertyBlob this.
> > > > > > 
> > > > > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > > > +		unsigned int i;
> > > > > > > +		char *c;
> > > > > > > +
> > > > > > > +		/*
> > > > > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > > > > +		 * any outlandish characters
> > > > > > > +		 */
> > > > > > > +		igt_assert(!(formats_blob->length % 4));
> > > > > > > +		c = formats_blob->data;
> > > > > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > > > > +				     "Unexpected character %c\n", c[i]);
> > > > > > 
> > > > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > > > codes will be made from ASCII characters, in fact some formats already
> > > > > > have non-printable chars in them. I don't want to have to update this
> > > > > > test when a new fourcc format is added.
> > > > 
> > > > Like the comments says, we don't have a full list of formats to check against.
> > > > Suggestions on how to improve are welcome, but I don't think we should delay
> > > > (any longer) the patchset due to this.
> > > 
> > > Agreed.
> > > 
> > > > Best regards,
> > > > Liviu

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-18 11:15                 ` Liviu.Dudau
  0 siblings, 0 replies; 71+ messages in thread
From: Liviu.Dudau @ 2019-07-18 11:15 UTC (permalink / raw)
  To: Ser, Simon; +Cc: Latvala, Petri, intel-gfx, igt-dev, daniel, nd, Brian.Starkey

On Thu, Jul 18, 2019 at 09:56:39AM +0000, Ser, Simon wrote:
> On Thu, 2019-07-18 at 10:49 +0100, Liviu.Dudau@arm.com wrote:
> > On Wed, Jul 17, 2019 at 11:46:39AM +0000, Ser, Simon wrote:
> > > Thanks for the clarification!
> > > 
> > > On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > > +{
> > > > > > > +	int i, ret;
> > > > > > > +	int32_t out_fence;
> > > > > > > +	struct {
> > > > > > > +		uint32_t fb_id;
> > > > > > > +		bool ptr_valid;
> > > > > > > +		int32_t *out_fence_ptr;
> > > > > > > +	} invalid_tests[] = {
> > > > > > > +		{
> > > > > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > > > +			.fb_id = 0,
> > > > > > > +			.ptr_valid = true,
> > > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > > +		},
> > > > > > > +		{
> > > > > > > +			/* Invalid output buffer. */
> > > > > > > +			.fb_id = invalid_fb->fb_id,
> > > > > > > +			.ptr_valid = true,
> > > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > > +		},
> > > > > > 
> > > > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > > 
> > > > It tries to test that you can't trick the driver to do any work on a fence if
> > > > the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> > > > invalid fb with valid fence, valid fb but invalid fence and assumes that no
> > > > fb with invalid fence is a NOP anyway.
> > > 
> > > Yeah, that makes sense, it's just confusing to put it in a function
> > > named invalid_out_fence. Here the out fence is valid, but the output
> > > buffer isn't, so it should probably be moved away (or this function
> > > should be renamed).
> > 
> > Don't want to offend or anything, but this does sound like bikeshedding. You
> > have a couple of parameters that you want to have a test for because they are
> > linked together (output framebuffer and fence) and you go through the
> > combination of possible bad options in the test. Not sure what name we can use
> > for the function, other than maybe 'test_invalid_parameters'? Given that 2/3
> > tests an invalid out fence, the name was thought to be relevant.
> > 
> > Having invalid out buffer test separate into its own test brings no benefits, IMHO.
> 
> Well, the issue is that I've been confused when reviewing the patch
> series. I had trouble understanding what the test does and why. I also
> had trouble to identify that do_writeback_test never submits a
> writeback operation (see other e-mail).
> 
> A name that is relevant "all the time, most of the time", is not
> relevant at all in my opinion. It just tricks the reader into thinking
> the test does one thing, while it also does something else.
> 
> If it would be obvious, I wouldn't mind. But here IMHO it hurts
> readability. So I'd prefer to rename the function.

I take your comments as a valid point.

Does "test_invalid_parameters" sound like a good name for the function? Is so,
Rodrigo, can you please use that name in the next revision of the patch?

> 
> If you think it's obvious, then maybe it's just me. I'd love to hear
> from others if they have a different opinion.
> 
> (As a side note, I agree I have a tendency to bikeshed, I try to mark
> my bikesheddings behind "nit:" flags.)

I've only said "it sounded like" :)

Best regards,
Liviu

> 
> > Best regards,
> > Liviu
> > 
> > > > > > > +		{
> > > > > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > > > +			.fb_id = valid_fb->fb_id,
> > > > > > > +			.ptr_valid = false,
> > > > > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > > > > +		},
> > > > > > > +	};
> > > > > > > +
> > > > > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > +					invalid_tests[i].fb_id,
> > > > > > > +					invalid_tests[i].out_fence_ptr,
> > > > > > > +					invalid_tests[i].ptr_valid);
> > > > > > > +		igt_assert(ret != 0);
> > > > > > 
> > > > > > Maybe we can check for -ret == EINVAL?
> > > > > > 
> > > > > > > +	}
> > > > > > > +}
> > > > > > > +
> > > > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > 
> > > > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > > > for input and writeback output.
> > > > > > 
> > > > > > > +{
> > > > > > > +
> > > > > > > +	int ret;
> > > > > > > +
> > > > > > > +	/* Valid output buffer */
> > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > +				valid_fb->fb_id, NULL, false);
> > > > > > > +	igt_assert(ret == 0);
> > > > > > > +
> > > > > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > +				output->id, NULL, false);
> > > > > > > +	igt_assert(ret == -EINVAL);
> > > > > > > +
> > > > > > > +	/* Zero WRITEBACK_FB_ID */
> > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > +				0, NULL, false);
> > > > > > > +	igt_assert(ret == 0);
> > > > > > > +}
> > > > > > > +
> > > > > > > +igt_main
> > > > > > > +{
> > > > > > > +	igt_display_t display;
> > > > > > > +	igt_output_t *output;
> > > > > > > +	igt_plane_t *plane;
> > > > > > > +	igt_fb_t input_fb;
> > > > > > > +	drmModeModeInfo mode;
> > > > > > > +	int ret;
> > > > > > > +
> > > > > > > +	memset(&display, 0, sizeof(display));
> > > > > > > +
> > > > > > > +	igt_fixture {
> > > > > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > > +
> > > > > > > +		kmstest_set_vt_graphics_mode();
> > > > > > > +
> > > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > > +
> > > > > > > +		igt_require(display.is_atomic);
> > > > > > > +
> > > > > > > +		output = kms_writeback_get_output(&display);
> > > > > > > +		igt_require(output);
> > > > > > > +
> > > > > > > +		if (output->use_override_mode)
> > > > > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > > > +		else
> > > > > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > > > +
> > > > > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > > > +		igt_require(plane);
> > > > > > 
> > > > > > Maybe we can assert on this?
> > > > > > 
> > > > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > > > +				    mode.vdisplay,
> > > > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > > > +				    igt_fb_mod_to_tiling(0),
> > > > > > 
> > > > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > > > better to make this clear.
> > > > 
> > > > Agree. The patchset pre-dates the modifiers support (or has the same age, I
> > > > forgot)
> > > > 
> > > > > > (Applies to other lines of this patch)
> > > > > > 
> > > > > > > +				    &input_fb);
> > > > > > > +		igt_assert(ret >= 0);
> > > > > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > > > > +	}
> > > > > > > +
> > > > > > > +	igt_subtest("writeback-pixel-formats") {
> > > > > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > > > 
> > > > > > Need to drmModeFreePropertyBlob this.
> > > > > > 
> > > > > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > > > +		unsigned int i;
> > > > > > > +		char *c;
> > > > > > > +
> > > > > > > +		/*
> > > > > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > > > > +		 * any outlandish characters
> > > > > > > +		 */
> > > > > > > +		igt_assert(!(formats_blob->length % 4));
> > > > > > > +		c = formats_blob->data;
> > > > > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > > > > +				     "Unexpected character %c\n", c[i]);
> > > > > > 
> > > > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > > > codes will be made from ASCII characters, in fact some formats already
> > > > > > have non-printable chars in them. I don't want to have to update this
> > > > > > test when a new fourcc format is added.
> > > > 
> > > > Like the comments says, we don't have a full list of formats to check against.
> > > > Suggestions on how to improve are welcome, but I don't think we should delay
> > > > (any longer) the patchset due to this.
> > > 
> > > Agreed.
> > > 
> > > > Best regards,
> > > > Liviu

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-07-18 11:15                 ` Liviu.Dudau
@ 2019-07-18 11:46                   ` Ser, Simon
  -1 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-18 11:46 UTC (permalink / raw)
  To: Liviu.Dudau; +Cc: rodrigosiqueiramelo, intel-gfx, igt-dev, nd

On Thu, 2019-07-18 at 12:15 +0100, Liviu.Dudau@arm.com wrote:
> On Thu, Jul 18, 2019 at 09:56:39AM +0000, Ser, Simon wrote:
> > On Thu, 2019-07-18 at 10:49 +0100, Liviu.Dudau@arm.com wrote:
> > > On Wed, Jul 17, 2019 at 11:46:39AM +0000, Ser, Simon wrote:
> > > > Thanks for the clarification!
> > > > 
> > > > On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > > > +{
> > > > > > > > +	int i, ret;
> > > > > > > > +	int32_t out_fence;
> > > > > > > > +	struct {
> > > > > > > > +		uint32_t fb_id;
> > > > > > > > +		bool ptr_valid;
> > > > > > > > +		int32_t *out_fence_ptr;
> > > > > > > > +	} invalid_tests[] = {
> > > > > > > > +		{
> > > > > > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > > > > +			.fb_id = 0,
> > > > > > > > +			.ptr_valid = true,
> > > > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > > > +		},
> > > > > > > > +		{
> > > > > > > > +			/* Invalid output buffer. */
> > > > > > > > +			.fb_id = invalid_fb->fb_id,
> > > > > > > > +			.ptr_valid = true,
> > > > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > > > +		},
> > > > > > > 
> > > > > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > > > 
> > > > > It tries to test that you can't trick the driver to do any work on a fence if
> > > > > the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> > > > > invalid fb with valid fence, valid fb but invalid fence and assumes that no
> > > > > fb with invalid fence is a NOP anyway.
> > > > 
> > > > Yeah, that makes sense, it's just confusing to put it in a function
> > > > named invalid_out_fence. Here the out fence is valid, but the output
> > > > buffer isn't, so it should probably be moved away (or this function
> > > > should be renamed).
> > > 
> > > Don't want to offend or anything, but this does sound like bikeshedding. You
> > > have a couple of parameters that you want to have a test for because they are
> > > linked together (output framebuffer and fence) and you go through the
> > > combination of possible bad options in the test. Not sure what name we can use
> > > for the function, other than maybe 'test_invalid_parameters'? Given that 2/3
> > > tests an invalid out fence, the name was thought to be relevant.
> > > 
> > > Having invalid out buffer test separate into its own test brings no benefits, IMHO.
> > 
> > Well, the issue is that I've been confused when reviewing the patch
> > series. I had trouble understanding what the test does and why. I also
> > had trouble to identify that do_writeback_test never submits a
> > writeback operation (see other e-mail).
> > 
> > A name that is relevant "all the time, most of the time", is not
> > relevant at all in my opinion. It just tricks the reader into thinking
> > the test does one thing, while it also does something else.
> > 
> > If it would be obvious, I wouldn't mind. But here IMHO it hurts
> > readability. So I'd prefer to rename the function.
> 
> I take your comments as a valid point.
> 
> Does "test_invalid_parameters" sound like a good name for the function? Is so,
> Rodrigo, can you please use that name in the next revision of the patch?

Yes, this name sounds perfectly fine :)

> > If you think it's obvious, then maybe it's just me. I'd love to hear
> > from others if they have a different opinion.
> > 
> > (As a side note, I agree I have a tendency to bikeshed, I try to mark
> > my bikesheddings behind "nit:" flags.)
> 
> I've only said "it sounded like" :)

Eheh :P

> Best regards,
> Liviu
> 
> > > Best regards,
> > > Liviu
> > > 
> > > > > > > > +		{
> > > > > > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > > > > +			.fb_id = valid_fb->fb_id,
> > > > > > > > +			.ptr_valid = false,
> > > > > > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > > > > > +		},
> > > > > > > > +	};
> > > > > > > > +
> > > > > > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +					invalid_tests[i].fb_id,
> > > > > > > > +					invalid_tests[i].out_fence_ptr,
> > > > > > > > +					invalid_tests[i].ptr_valid);
> > > > > > > > +		igt_assert(ret != 0);
> > > > > > > 
> > > > > > > Maybe we can check for -ret == EINVAL?
> > > > > > > 
> > > > > > > > +	}
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > > 
> > > > > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > > > > for input and writeback output.
> > > > > > > 
> > > > > > > > +{
> > > > > > > > +
> > > > > > > > +	int ret;
> > > > > > > > +
> > > > > > > > +	/* Valid output buffer */
> > > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +				valid_fb->fb_id, NULL, false);
> > > > > > > > +	igt_assert(ret == 0);
> > > > > > > > +
> > > > > > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +				output->id, NULL, false);
> > > > > > > > +	igt_assert(ret == -EINVAL);
> > > > > > > > +
> > > > > > > > +	/* Zero WRITEBACK_FB_ID */
> > > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +				0, NULL, false);
> > > > > > > > +	igt_assert(ret == 0);
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +igt_main
> > > > > > > > +{
> > > > > > > > +	igt_display_t display;
> > > > > > > > +	igt_output_t *output;
> > > > > > > > +	igt_plane_t *plane;
> > > > > > > > +	igt_fb_t input_fb;
> > > > > > > > +	drmModeModeInfo mode;
> > > > > > > > +	int ret;
> > > > > > > > +
> > > > > > > > +	memset(&display, 0, sizeof(display));
> > > > > > > > +
> > > > > > > > +	igt_fixture {
> > > > > > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > > > +
> > > > > > > > +		kmstest_set_vt_graphics_mode();
> > > > > > > > +
> > > > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > > > +
> > > > > > > > +		igt_require(display.is_atomic);
> > > > > > > > +
> > > > > > > > +		output = kms_writeback_get_output(&display);
> > > > > > > > +		igt_require(output);
> > > > > > > > +
> > > > > > > > +		if (output->use_override_mode)
> > > > > > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > > > > +		else
> > > > > > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > > > > +
> > > > > > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > > > > +		igt_require(plane);
> > > > > > > 
> > > > > > > Maybe we can assert on this?
> > > > > > > 
> > > > > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > > > > +				    mode.vdisplay,
> > > > > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > > > > +				    igt_fb_mod_to_tiling(0),
> > > > > > > 
> > > > > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > > > > better to make this clear.
> > > > > 
> > > > > Agree. The patchset pre-dates the modifiers support (or has the same age, I
> > > > > forgot)
> > > > > 
> > > > > > > (Applies to other lines of this patch)
> > > > > > > 
> > > > > > > > +				    &input_fb);
> > > > > > > > +		igt_assert(ret >= 0);
> > > > > > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > > > > > +	}
> > > > > > > > +
> > > > > > > > +	igt_subtest("writeback-pixel-formats") {
> > > > > > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > > > > 
> > > > > > > Need to drmModeFreePropertyBlob this.
> > > > > > > 
> > > > > > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > > > > +		unsigned int i;
> > > > > > > > +		char *c;
> > > > > > > > +
> > > > > > > > +		/*
> > > > > > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > > > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > > > > > +		 * any outlandish characters
> > > > > > > > +		 */
> > > > > > > > +		igt_assert(!(formats_blob->length % 4));
> > > > > > > > +		c = formats_blob->data;
> > > > > > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > > > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > > > > > +				     "Unexpected character %c\n", c[i]);
> > > > > > > 
> > > > > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > > > > codes will be made from ASCII characters, in fact some formats already
> > > > > > > have non-printable chars in them. I don't want to have to update this
> > > > > > > test when a new fourcc format is added.
> > > > > 
> > > > > Like the comments says, we don't have a full list of formats to check against.
> > > > > Suggestions on how to improve are welcome, but I don't think we should delay
> > > > > (any longer) the patchset due to this.
> > > > 
> > > > Agreed.
> > > > 
> > > > > Best regards,
> > > > > Liviu
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-18 11:46                   ` Ser, Simon
  0 siblings, 0 replies; 71+ messages in thread
From: Ser, Simon @ 2019-07-18 11:46 UTC (permalink / raw)
  To: Liviu.Dudau; +Cc: Latvala, Petri, intel-gfx, igt-dev, daniel, nd, Brian.Starkey

On Thu, 2019-07-18 at 12:15 +0100, Liviu.Dudau@arm.com wrote:
> On Thu, Jul 18, 2019 at 09:56:39AM +0000, Ser, Simon wrote:
> > On Thu, 2019-07-18 at 10:49 +0100, Liviu.Dudau@arm.com wrote:
> > > On Wed, Jul 17, 2019 at 11:46:39AM +0000, Ser, Simon wrote:
> > > > Thanks for the clarification!
> > > > 
> > > > On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > > > +{
> > > > > > > > +	int i, ret;
> > > > > > > > +	int32_t out_fence;
> > > > > > > > +	struct {
> > > > > > > > +		uint32_t fb_id;
> > > > > > > > +		bool ptr_valid;
> > > > > > > > +		int32_t *out_fence_ptr;
> > > > > > > > +	} invalid_tests[] = {
> > > > > > > > +		{
> > > > > > > > +			/* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > > > > +			.fb_id = 0,
> > > > > > > > +			.ptr_valid = true,
> > > > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > > > +		},
> > > > > > > > +		{
> > > > > > > > +			/* Invalid output buffer. */
> > > > > > > > +			.fb_id = invalid_fb->fb_id,
> > > > > > > > +			.ptr_valid = true,
> > > > > > > > +			.out_fence_ptr = &out_fence,
> > > > > > > > +		},
> > > > > > > 
> > > > > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > > > 
> > > > > It tries to test that you can't trick the driver to do any work on a fence if
> > > > > the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> > > > > invalid fb with valid fence, valid fb but invalid fence and assumes that no
> > > > > fb with invalid fence is a NOP anyway.
> > > > 
> > > > Yeah, that makes sense, it's just confusing to put it in a function
> > > > named invalid_out_fence. Here the out fence is valid, but the output
> > > > buffer isn't, so it should probably be moved away (or this function
> > > > should be renamed).
> > > 
> > > Don't want to offend or anything, but this does sound like bikeshedding. You
> > > have a couple of parameters that you want to have a test for because they are
> > > linked together (output framebuffer and fence) and you go through the
> > > combination of possible bad options in the test. Not sure what name we can use
> > > for the function, other than maybe 'test_invalid_parameters'? Given that 2/3
> > > tests an invalid out fence, the name was thought to be relevant.
> > > 
> > > Having invalid out buffer test separate into its own test brings no benefits, IMHO.
> > 
> > Well, the issue is that I've been confused when reviewing the patch
> > series. I had trouble understanding what the test does and why. I also
> > had trouble to identify that do_writeback_test never submits a
> > writeback operation (see other e-mail).
> > 
> > A name that is relevant "all the time, most of the time", is not
> > relevant at all in my opinion. It just tricks the reader into thinking
> > the test does one thing, while it also does something else.
> > 
> > If it would be obvious, I wouldn't mind. But here IMHO it hurts
> > readability. So I'd prefer to rename the function.
> 
> I take your comments as a valid point.
> 
> Does "test_invalid_parameters" sound like a good name for the function? Is so,
> Rodrigo, can you please use that name in the next revision of the patch?

Yes, this name sounds perfectly fine :)

> > If you think it's obvious, then maybe it's just me. I'd love to hear
> > from others if they have a different opinion.
> > 
> > (As a side note, I agree I have a tendency to bikeshed, I try to mark
> > my bikesheddings behind "nit:" flags.)
> 
> I've only said "it sounded like" :)

Eheh :P

> Best regards,
> Liviu
> 
> > > Best regards,
> > > Liviu
> > > 
> > > > > > > > +		{
> > > > > > > > +			/* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > > > > +			.fb_id = valid_fb->fb_id,
> > > > > > > > +			.ptr_valid = false,
> > > > > > > > +			.out_fence_ptr = (int32_t *)0x8,
> > > > > > > > +		},
> > > > > > > > +	};
> > > > > > > > +
> > > > > > > > +	for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > > > > +		ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +					invalid_tests[i].fb_id,
> > > > > > > > +					invalid_tests[i].out_fence_ptr,
> > > > > > > > +					invalid_tests[i].ptr_valid);
> > > > > > > > +		igt_assert(ret != 0);
> > > > > > > 
> > > > > > > Maybe we can check for -ret == EINVAL?
> > > > > > > 
> > > > > > > > +	}
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > > 
> > > > > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > > > > for input and writeback output.
> > > > > > > 
> > > > > > > > +{
> > > > > > > > +
> > > > > > > > +	int ret;
> > > > > > > > +
> > > > > > > > +	/* Valid output buffer */
> > > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +				valid_fb->fb_id, NULL, false);
> > > > > > > > +	igt_assert(ret == 0);
> > > > > > > > +
> > > > > > > > +	/* Invalid object for WRITEBACK_FB_ID */
> > > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +				output->id, NULL, false);
> > > > > > > > +	igt_assert(ret == -EINVAL);
> > > > > > > > +
> > > > > > > > +	/* Zero WRITEBACK_FB_ID */
> > > > > > > > +	ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +				0, NULL, false);
> > > > > > > > +	igt_assert(ret == 0);
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +igt_main
> > > > > > > > +{
> > > > > > > > +	igt_display_t display;
> > > > > > > > +	igt_output_t *output;
> > > > > > > > +	igt_plane_t *plane;
> > > > > > > > +	igt_fb_t input_fb;
> > > > > > > > +	drmModeModeInfo mode;
> > > > > > > > +	int ret;
> > > > > > > > +
> > > > > > > > +	memset(&display, 0, sizeof(display));
> > > > > > > > +
> > > > > > > > +	igt_fixture {
> > > > > > > > +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > > > +
> > > > > > > > +		kmstest_set_vt_graphics_mode();
> > > > > > > > +
> > > > > > > > +		igt_display_require(&display, display.drm_fd);
> > > > > > > > +
> > > > > > > > +		igt_require(display.is_atomic);
> > > > > > > > +
> > > > > > > > +		output = kms_writeback_get_output(&display);
> > > > > > > > +		igt_require(output);
> > > > > > > > +
> > > > > > > > +		if (output->use_override_mode)
> > > > > > > > +			memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > > > > +		else
> > > > > > > > +			memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > > > > +
> > > > > > > > +		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > > > > +		igt_require(plane);
> > > > > > > 
> > > > > > > Maybe we can assert on this?
> > > > > > > 
> > > > > > > > +		ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > > > > +				    mode.vdisplay,
> > > > > > > > +				    DRM_FORMAT_XRGB8888,
> > > > > > > > +				    igt_fb_mod_to_tiling(0),
> > > > > > > 
> > > > > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > > > > better to make this clear.
> > > > > 
> > > > > Agree. The patchset pre-dates the modifiers support (or has the same age, I
> > > > > forgot)
> > > > > 
> > > > > > > (Applies to other lines of this patch)
> > > > > > > 
> > > > > > > > +				    &input_fb);
> > > > > > > > +		igt_assert(ret >= 0);
> > > > > > > > +		igt_plane_set_fb(plane, &input_fb);
> > > > > > > > +	}
> > > > > > > > +
> > > > > > > > +	igt_subtest("writeback-pixel-formats") {
> > > > > > > > +		drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > > > > 
> > > > > > > Need to drmModeFreePropertyBlob this.
> > > > > > > 
> > > > > > > > +		const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > > > > +		unsigned int i;
> > > > > > > > +		char *c;
> > > > > > > > +
> > > > > > > > +		/*
> > > > > > > > +		 * We don't have a comprehensive list of formats, so just check
> > > > > > > > +		 * that the blob length is sensible and that it doesn't contain
> > > > > > > > +		 * any outlandish characters
> > > > > > > > +		 */
> > > > > > > > +		igt_assert(!(formats_blob->length % 4));
> > > > > > > > +		c = formats_blob->data;
> > > > > > > > +		for (i = 0; i < formats_blob->length; i++)
> > > > > > > > +			igt_assert_f(strchr(valid_chars, c[i]),
> > > > > > > > +				     "Unexpected character %c\n", c[i]);
> > > > > > > 
> > > > > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > > > > codes will be made from ASCII characters, in fact some formats already
> > > > > > > have non-printable chars in them. I don't want to have to update this
> > > > > > > test when a new fourcc format is added.
> > > > > 
> > > > > Like the comments says, we don't have a full list of formats to check against.
> > > > > Suggestions on how to improve are welcome, but I don't think we should delay
> > > > > (any longer) the patchset due to this.
> > > > 
> > > > Agreed.
> > > > 
> > > > > Best regards,
> > > > > Liviu
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
  2019-07-18 11:15                 ` Liviu.Dudau
@ 2019-07-19  1:21                   ` Rodrigo Siqueira
  -1 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-19  1:21 UTC (permalink / raw)
  To: Liviu.Dudau; +Cc: igt-dev, intel-gfx, Ser, Simon, nd

On Thu, Jul 18, 2019 at 8:15 AM Liviu.Dudau@arm.com <Liviu.Dudau@arm.com> wrote:
>
> On Thu, Jul 18, 2019 at 09:56:39AM +0000, Ser, Simon wrote:
> > On Thu, 2019-07-18 at 10:49 +0100, Liviu.Dudau@arm.com wrote:
> > > On Wed, Jul 17, 2019 at 11:46:39AM +0000, Ser, Simon wrote:
> > > > Thanks for the clarification!
> > > >
> > > > On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > > > +{
> > > > > > > > + int i, ret;
> > > > > > > > + int32_t out_fence;
> > > > > > > > + struct {
> > > > > > > > +         uint32_t fb_id;
> > > > > > > > +         bool ptr_valid;
> > > > > > > > +         int32_t *out_fence_ptr;
> > > > > > > > + } invalid_tests[] = {
> > > > > > > > +         {
> > > > > > > > +                 /* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > > > > +                 .fb_id = 0,
> > > > > > > > +                 .ptr_valid = true,
> > > > > > > > +                 .out_fence_ptr = &out_fence,
> > > > > > > > +         },
> > > > > > > > +         {
> > > > > > > > +                 /* Invalid output buffer. */
> > > > > > > > +                 .fb_id = invalid_fb->fb_id,
> > > > > > > > +                 .ptr_valid = true,
> > > > > > > > +                 .out_fence_ptr = &out_fence,
> > > > > > > > +         },
> > > > > > >
> > > > > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > > >
> > > > > It tries to test that you can't trick the driver to do any work on a fence if
> > > > > the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> > > > > invalid fb with valid fence, valid fb but invalid fence and assumes that no
> > > > > fb with invalid fence is a NOP anyway.
> > > >
> > > > Yeah, that makes sense, it's just confusing to put it in a function
> > > > named invalid_out_fence. Here the out fence is valid, but the output
> > > > buffer isn't, so it should probably be moved away (or this function
> > > > should be renamed).
> > >
> > > Don't want to offend or anything, but this does sound like bikeshedding. You
> > > have a couple of parameters that you want to have a test for because they are
> > > linked together (output framebuffer and fence) and you go through the
> > > combination of possible bad options in the test. Not sure what name we can use
> > > for the function, other than maybe 'test_invalid_parameters'? Given that 2/3
> > > tests an invalid out fence, the name was thought to be relevant.
> > >
> > > Having invalid out buffer test separate into its own test brings no benefits, IMHO.
> >
> > Well, the issue is that I've been confused when reviewing the patch
> > series. I had trouble understanding what the test does and why. I also
> > had trouble to identify that do_writeback_test never submits a
> > writeback operation (see other e-mail).
> >
> > A name that is relevant "all the time, most of the time", is not
> > relevant at all in my opinion. It just tricks the reader into thinking
> > the test does one thing, while it also does something else.
> >
> > If it would be obvious, I wouldn't mind. But here IMHO it hurts
> > readability. So I'd prefer to rename the function.
>
> I take your comments as a valid point.
>
> Does "test_invalid_parameters" sound like a good name for the function? Is so,
> Rodrigo, can you please use that name in the next revision of the patch?

Sure, I'll do that.

Thanks

> >
> > If you think it's obvious, then maybe it's just me. I'd love to hear
> > from others if they have a different opinion.
> >
> > (As a side note, I agree I have a tendency to bikeshed, I try to mark
> > my bikesheddings behind "nit:" flags.)
>
> I've only said "it sounded like" :)
>
> Best regards,
> Liviu
>
> >
> > > Best regards,
> > > Liviu
> > >
> > > > > > > > +         {
> > > > > > > > +                 /* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > > > > +                 .fb_id = valid_fb->fb_id,
> > > > > > > > +                 .ptr_valid = false,
> > > > > > > > +                 .out_fence_ptr = (int32_t *)0x8,
> > > > > > > > +         },
> > > > > > > > + };
> > > > > > > > +
> > > > > > > > + for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > > > > +         ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +                                 invalid_tests[i].fb_id,
> > > > > > > > +                                 invalid_tests[i].out_fence_ptr,
> > > > > > > > +                                 invalid_tests[i].ptr_valid);
> > > > > > > > +         igt_assert(ret != 0);
> > > > > > >
> > > > > > > Maybe we can check for -ret == EINVAL?
> > > > > > >
> > > > > > > > + }
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > >
> > > > > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > > > > for input and writeback output.
> > > > > > >
> > > > > > > > +{
> > > > > > > > +
> > > > > > > > + int ret;
> > > > > > > > +
> > > > > > > > + /* Valid output buffer */
> > > > > > > > + ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +                         valid_fb->fb_id, NULL, false);
> > > > > > > > + igt_assert(ret == 0);
> > > > > > > > +
> > > > > > > > + /* Invalid object for WRITEBACK_FB_ID */
> > > > > > > > + ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +                         output->id, NULL, false);
> > > > > > > > + igt_assert(ret == -EINVAL);
> > > > > > > > +
> > > > > > > > + /* Zero WRITEBACK_FB_ID */
> > > > > > > > + ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +                         0, NULL, false);
> > > > > > > > + igt_assert(ret == 0);
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +igt_main
> > > > > > > > +{
> > > > > > > > + igt_display_t display;
> > > > > > > > + igt_output_t *output;
> > > > > > > > + igt_plane_t *plane;
> > > > > > > > + igt_fb_t input_fb;
> > > > > > > > + drmModeModeInfo mode;
> > > > > > > > + int ret;
> > > > > > > > +
> > > > > > > > + memset(&display, 0, sizeof(display));
> > > > > > > > +
> > > > > > > > + igt_fixture {
> > > > > > > > +         display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > > > > +         igt_display_require(&display, display.drm_fd);
> > > > > > > > +
> > > > > > > > +         kmstest_set_vt_graphics_mode();
> > > > > > > > +
> > > > > > > > +         igt_display_require(&display, display.drm_fd);
> > > > > > > > +
> > > > > > > > +         igt_require(display.is_atomic);
> > > > > > > > +
> > > > > > > > +         output = kms_writeback_get_output(&display);
> > > > > > > > +         igt_require(output);
> > > > > > > > +
> > > > > > > > +         if (output->use_override_mode)
> > > > > > > > +                 memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > > > > +         else
> > > > > > > > +                 memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > > > > +
> > > > > > > > +         plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > > > > +         igt_require(plane);
> > > > > > >
> > > > > > > Maybe we can assert on this?
> > > > > > >
> > > > > > > > +         ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > > > > +                             mode.vdisplay,
> > > > > > > > +                             DRM_FORMAT_XRGB8888,
> > > > > > > > +                             igt_fb_mod_to_tiling(0),
> > > > > > >
> > > > > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > > > > better to make this clear.
> > > > >
> > > > > Agree. The patchset pre-dates the modifiers support (or has the same age, I
> > > > > forgot)
> > > > >
> > > > > > > (Applies to other lines of this patch)
> > > > > > >
> > > > > > > > +                             &input_fb);
> > > > > > > > +         igt_assert(ret >= 0);
> > > > > > > > +         igt_plane_set_fb(plane, &input_fb);
> > > > > > > > + }
> > > > > > > > +
> > > > > > > > + igt_subtest("writeback-pixel-formats") {
> > > > > > > > +         drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > > > >
> > > > > > > Need to drmModeFreePropertyBlob this.
> > > > > > >
> > > > > > > > +         const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > > > > +         unsigned int i;
> > > > > > > > +         char *c;
> > > > > > > > +
> > > > > > > > +         /*
> > > > > > > > +          * We don't have a comprehensive list of formats, so just check
> > > > > > > > +          * that the blob length is sensible and that it doesn't contain
> > > > > > > > +          * any outlandish characters
> > > > > > > > +          */
> > > > > > > > +         igt_assert(!(formats_blob->length % 4));
> > > > > > > > +         c = formats_blob->data;
> > > > > > > > +         for (i = 0; i < formats_blob->length; i++)
> > > > > > > > +                 igt_assert_f(strchr(valid_chars, c[i]),
> > > > > > > > +                              "Unexpected character %c\n", c[i]);
> > > > > > >
> > > > > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > > > > codes will be made from ASCII characters, in fact some formats already
> > > > > > > have non-printable chars in them. I don't want to have to update this
> > > > > > > test when a new fourcc format is added.
> > > > >
> > > > > Like the comments says, we don't have a full list of formats to check against.
> > > > > Suggestions on how to improve are welcome, but I don't think we should delay
> > > > > (any longer) the patchset due to this.
> > > >
> > > > Agreed.
> > > >
> > > > > Best regards,
> > > > > Liviu
>
> --
> ====================
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---------------
>     ¯\_(ツ)_/¯



-- 

Rodrigo Siqueira
https://siqueira.tech
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [igt-dev] [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests
@ 2019-07-19  1:21                   ` Rodrigo Siqueira
  0 siblings, 0 replies; 71+ messages in thread
From: Rodrigo Siqueira @ 2019-07-19  1:21 UTC (permalink / raw)
  To: Liviu.Dudau; +Cc: igt-dev, Latvala, Petri, intel-gfx, daniel, nd, Brian.Starkey

On Thu, Jul 18, 2019 at 8:15 AM Liviu.Dudau@arm.com <Liviu.Dudau@arm.com> wrote:
>
> On Thu, Jul 18, 2019 at 09:56:39AM +0000, Ser, Simon wrote:
> > On Thu, 2019-07-18 at 10:49 +0100, Liviu.Dudau@arm.com wrote:
> > > On Wed, Jul 17, 2019 at 11:46:39AM +0000, Ser, Simon wrote:
> > > > Thanks for the clarification!
> > > >
> > > > On Tue, 2019-07-16 at 16:22 +0100, Liviu.Dudau@arm.com wrote:
> > > > > > > > +static void invalid_out_fence(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > > > +{
> > > > > > > > + int i, ret;
> > > > > > > > + int32_t out_fence;
> > > > > > > > + struct {
> > > > > > > > +         uint32_t fb_id;
> > > > > > > > +         bool ptr_valid;
> > > > > > > > +         int32_t *out_fence_ptr;
> > > > > > > > + } invalid_tests[] = {
> > > > > > > > +         {
> > > > > > > > +                 /* No output buffer, but the WRITEBACK_OUT_FENCE_PTR set. */
> > > > > > > > +                 .fb_id = 0,
> > > > > > > > +                 .ptr_valid = true,
> > > > > > > > +                 .out_fence_ptr = &out_fence,
> > > > > > > > +         },
> > > > > > > > +         {
> > > > > > > > +                 /* Invalid output buffer. */
> > > > > > > > +                 .fb_id = invalid_fb->fb_id,
> > > > > > > > +                 .ptr_valid = true,
> > > > > > > > +                 .out_fence_ptr = &out_fence,
> > > > > > > > +         },
> > > > > > >
> > > > > > > This doesn't belong in this function (invalid_out_fence), since this
> > > > > > > checks an invalid framebuffer, not an invalid fence. We should probably
> > > > > > > move it to writeback_fb_id (and rename that function to test_fb?).
> > > > >
> > > > > It tries to test that you can't trick the driver to do any work on a fence if
> > > > > the framebuffer is invalid, so the set of tests tries: no fb with valid fence,
> > > > > invalid fb with valid fence, valid fb but invalid fence and assumes that no
> > > > > fb with invalid fence is a NOP anyway.
> > > >
> > > > Yeah, that makes sense, it's just confusing to put it in a function
> > > > named invalid_out_fence. Here the out fence is valid, but the output
> > > > buffer isn't, so it should probably be moved away (or this function
> > > > should be renamed).
> > >
> > > Don't want to offend or anything, but this does sound like bikeshedding. You
> > > have a couple of parameters that you want to have a test for because they are
> > > linked together (output framebuffer and fence) and you go through the
> > > combination of possible bad options in the test. Not sure what name we can use
> > > for the function, other than maybe 'test_invalid_parameters'? Given that 2/3
> > > tests an invalid out fence, the name was thought to be relevant.
> > >
> > > Having invalid out buffer test separate into its own test brings no benefits, IMHO.
> >
> > Well, the issue is that I've been confused when reviewing the patch
> > series. I had trouble understanding what the test does and why. I also
> > had trouble to identify that do_writeback_test never submits a
> > writeback operation (see other e-mail).
> >
> > A name that is relevant "all the time, most of the time", is not
> > relevant at all in my opinion. It just tricks the reader into thinking
> > the test does one thing, while it also does something else.
> >
> > If it would be obvious, I wouldn't mind. But here IMHO it hurts
> > readability. So I'd prefer to rename the function.
>
> I take your comments as a valid point.
>
> Does "test_invalid_parameters" sound like a good name for the function? Is so,
> Rodrigo, can you please use that name in the next revision of the patch?

Sure, I'll do that.

Thanks

> >
> > If you think it's obvious, then maybe it's just me. I'd love to hear
> > from others if they have a different opinion.
> >
> > (As a side note, I agree I have a tendency to bikeshed, I try to mark
> > my bikesheddings behind "nit:" flags.)
>
> I've only said "it sounded like" :)
>
> Best regards,
> Liviu
>
> >
> > > Best regards,
> > > Liviu
> > >
> > > > > > > > +         {
> > > > > > > > +                 /* Invalid WRITEBACK_OUT_FENCE_PTR. */
> > > > > > > > +                 .fb_id = valid_fb->fb_id,
> > > > > > > > +                 .ptr_valid = false,
> > > > > > > > +                 .out_fence_ptr = (int32_t *)0x8,
> > > > > > > > +         },
> > > > > > > > + };
> > > > > > > > +
> > > > > > > > + for (i = 0; i < ARRAY_SIZE(invalid_tests); i++) {
> > > > > > > > +         ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +                                 invalid_tests[i].fb_id,
> > > > > > > > +                                 invalid_tests[i].out_fence_ptr,
> > > > > > > > +                                 invalid_tests[i].ptr_valid);
> > > > > > > > +         igt_assert(ret != 0);
> > > > > > >
> > > > > > > Maybe we can check for -ret == EINVAL?
> > > > > > >
> > > > > > > > + }
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +static void writeback_fb_id(igt_output_t *output, igt_fb_t *valid_fb, igt_fb_t *invalid_fb)
> > > > > > >
> > > > > > > invalid_fb doesn't seem to be used here. valid_fb seems to be set to
> > > > > > > the input framebuffer. It's probably not a good idea to use the same FB
> > > > > > > for input and writeback output.
> > > > > > >
> > > > > > > > +{
> > > > > > > > +
> > > > > > > > + int ret;
> > > > > > > > +
> > > > > > > > + /* Valid output buffer */
> > > > > > > > + ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +                         valid_fb->fb_id, NULL, false);
> > > > > > > > + igt_assert(ret == 0);
> > > > > > > > +
> > > > > > > > + /* Invalid object for WRITEBACK_FB_ID */
> > > > > > > > + ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +                         output->id, NULL, false);
> > > > > > > > + igt_assert(ret == -EINVAL);
> > > > > > > > +
> > > > > > > > + /* Zero WRITEBACK_FB_ID */
> > > > > > > > + ret = do_writeback_test(output, DRM_MODE_ATOMIC_ALLOW_MODESET,
> > > > > > > > +                         0, NULL, false);
> > > > > > > > + igt_assert(ret == 0);
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +igt_main
> > > > > > > > +{
> > > > > > > > + igt_display_t display;
> > > > > > > > + igt_output_t *output;
> > > > > > > > + igt_plane_t *plane;
> > > > > > > > + igt_fb_t input_fb;
> > > > > > > > + drmModeModeInfo mode;
> > > > > > > > + int ret;
> > > > > > > > +
> > > > > > > > + memset(&display, 0, sizeof(display));
> > > > > > > > +
> > > > > > > > + igt_fixture {
> > > > > > > > +         display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> > > > > > > > +         igt_display_require(&display, display.drm_fd);
> > > > > > > > +
> > > > > > > > +         kmstest_set_vt_graphics_mode();
> > > > > > > > +
> > > > > > > > +         igt_display_require(&display, display.drm_fd);
> > > > > > > > +
> > > > > > > > +         igt_require(display.is_atomic);
> > > > > > > > +
> > > > > > > > +         output = kms_writeback_get_output(&display);
> > > > > > > > +         igt_require(output);
> > > > > > > > +
> > > > > > > > +         if (output->use_override_mode)
> > > > > > > > +                 memcpy(&mode, &output->override_mode, sizeof(mode));
> > > > > > > > +         else
> > > > > > > > +                 memcpy(&mode, &output->config.default_mode, sizeof(mode));
> > > > > > > > +
> > > > > > > > +         plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> > > > > > > > +         igt_require(plane);
> > > > > > >
> > > > > > > Maybe we can assert on this?
> > > > > > >
> > > > > > > > +         ret = igt_create_fb(display.drm_fd, mode.hdisplay,
> > > > > > > > +                             mode.vdisplay,
> > > > > > > > +                             DRM_FORMAT_XRGB8888,
> > > > > > > > +                             igt_fb_mod_to_tiling(0),
> > > > > > >
> > > > > > > This is supposed to take a modifier. DRM_FORMAT_MOD_LINEAR would be
> > > > > > > better to make this clear.
> > > > >
> > > > > Agree. The patchset pre-dates the modifiers support (or has the same age, I
> > > > > forgot)
> > > > >
> > > > > > > (Applies to other lines of this patch)
> > > > > > >
> > > > > > > > +                             &input_fb);
> > > > > > > > +         igt_assert(ret >= 0);
> > > > > > > > +         igt_plane_set_fb(plane, &input_fb);
> > > > > > > > + }
> > > > > > > > +
> > > > > > > > + igt_subtest("writeback-pixel-formats") {
> > > > > > > > +         drmModePropertyBlobRes *formats_blob = get_writeback_formats_blob(output);
> > > > > > >
> > > > > > > Need to drmModeFreePropertyBlob this.
> > > > > > >
> > > > > > > > +         const char *valid_chars = "0123456 ABCGNRUVXY";
> > > > > > > > +         unsigned int i;
> > > > > > > > +         char *c;
> > > > > > > > +
> > > > > > > > +         /*
> > > > > > > > +          * We don't have a comprehensive list of formats, so just check
> > > > > > > > +          * that the blob length is sensible and that it doesn't contain
> > > > > > > > +          * any outlandish characters
> > > > > > > > +          */
> > > > > > > > +         igt_assert(!(formats_blob->length % 4));
> > > > > > > > +         c = formats_blob->data;
> > > > > > > > +         for (i = 0; i < formats_blob->length; i++)
> > > > > > > > +                 igt_assert_f(strchr(valid_chars, c[i]),
> > > > > > > > +                              "Unexpected character %c\n", c[i]);
> > > > > > >
> > > > > > > Honestly, I'm not a fan of this check. There's no guarantee that fourcc
> > > > > > > codes will be made from ASCII characters, in fact some formats already
> > > > > > > have non-printable chars in them. I don't want to have to update this
> > > > > > > test when a new fourcc format is added.
> > > > >
> > > > > Like the comments says, we don't have a full list of formats to check against.
> > > > > Suggestions on how to improve are welcome, but I don't think we should delay
> > > > > (any longer) the patchset due to this.
> > > >
> > > > Agreed.
> > > >
> > > > > Best regards,
> > > > > Liviu
>
> --
> ====================
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---------------
>     ¯\_(ツ)_/¯



-- 

Rodrigo Siqueira
https://siqueira.tech
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 71+ messages in thread

end of thread, other threads:[~2019-07-19  1:21 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-13  2:14 [PATCH V6 i-g-t 0/6] igt: Add support for testing writeback connectors Rodrigo Siqueira
2019-06-13  2:14 ` [igt-dev] " Rodrigo Siqueira
2019-06-13  2:16 ` [PATCH V6 i-g-t 1/6] lib/igt_kms: Add writeback support Brian Starkey
2019-06-13  2:16   ` [Intel-gfx] " Brian Starkey
2019-06-13 14:54   ` Liviu Dudau
2019-06-13 14:54     ` [igt-dev] " Liviu Dudau
2019-06-18 21:56     ` Rodrigo Siqueira
2019-06-18 21:56       ` [igt-dev] " Rodrigo Siqueira
2019-07-03 12:15       ` Ser, Simon
2019-07-03 12:15         ` Ser, Simon
2019-07-09 14:32         ` Rodrigo Siqueira
2019-07-09 14:32           ` Rodrigo Siqueira
2019-07-09 14:42           ` Ser, Simon
2019-07-09 14:42             ` Ser, Simon
2019-07-09 15:07             ` Rodrigo Siqueira
2019-07-09 15:07               ` Rodrigo Siqueira
2019-07-10  8:48   ` Ser, Simon
2019-07-10  8:48     ` Ser, Simon
2019-06-13  2:16 ` [PATCH V6 i-g-t 2/6] kms_writeback: Add initial writeback tests Brian Starkey
2019-06-13  2:16   ` [igt-dev] " Brian Starkey
2019-07-10 11:57   ` Ser, Simon
2019-07-10 11:57     ` Ser, Simon
2019-07-12  2:44     ` Rodrigo Siqueira
2019-07-12  2:44       ` Rodrigo Siqueira
2019-07-12 11:40       ` Ser, Simon
2019-07-12 11:40         ` Ser, Simon
2019-07-17  1:21         ` Rodrigo Siqueira
2019-07-17  1:21           ` Rodrigo Siqueira
2019-07-17 13:00           ` Ser, Simon
2019-07-17 13:00             ` Ser, Simon
2019-07-16 15:22       ` Liviu.Dudau
2019-07-16 15:22         ` Liviu.Dudau
2019-07-17 11:46         ` Ser, Simon
2019-07-17 11:46           ` [Intel-gfx] " Ser, Simon
2019-07-18  9:49           ` Liviu.Dudau
2019-07-18  9:49             ` Liviu.Dudau
2019-07-18  9:56             ` Ser, Simon
2019-07-18  9:56               ` Ser, Simon
2019-07-18 11:15               ` Liviu.Dudau
2019-07-18 11:15                 ` Liviu.Dudau
2019-07-18 11:46                 ` Ser, Simon
2019-07-18 11:46                   ` Ser, Simon
2019-07-19  1:21                 ` Rodrigo Siqueira
2019-07-19  1:21                   ` Rodrigo Siqueira
2019-06-13  2:17 ` [PATCH V6 i-g-t 3/6] lib: Add function to hash a framebuffer Brian Starkey
2019-06-13  2:17   ` [Intel-gfx] " Brian Starkey
2019-07-10 15:30   ` [igt-dev] " Ser, Simon
2019-07-10 15:30     ` Ser, Simon
2019-07-10 15:34     ` Ser, Simon
2019-07-10 15:34       ` Ser, Simon
2019-07-12  2:49       ` Rodrigo Siqueira
2019-07-12  2:49         ` Rodrigo Siqueira
2019-07-12 12:17         ` Ser, Simon
2019-07-12 12:17           ` Ser, Simon
2019-07-17  1:25           ` Rodrigo Siqueira
2019-07-17  1:25             ` Rodrigo Siqueira
2019-06-13  2:17 ` [PATCH V6 i-g-t 4/6] kms_writeback: Add writeback-check-output Brian Starkey
2019-06-13  2:17   ` [igt-dev] " Brian Starkey
2019-07-12 12:34   ` Ser, Simon
2019-07-12 12:34     ` Ser, Simon
2019-06-13  2:18 ` [PATCH V6 i-g-t 5/6] lib/igt_kms: Add igt_output_clone_pipe for cloning Brian Starkey
2019-06-13  2:18   ` [igt-dev] " Brian Starkey
2019-07-12 12:54   ` Ser, Simon
2019-07-12 12:54     ` Ser, Simon
2019-07-17  1:47     ` Rodrigo Siqueira
2019-07-17  1:47       ` Rodrigo Siqueira
2019-07-17 13:10       ` Ser, Simon
2019-07-17 13:10         ` Ser, Simon
2019-06-13  2:19 ` [PATCH V6 i-g-t 6/6] kms_writeback: Add tests using a cloned output Brian Starkey
2019-06-13  2:19   ` [igt-dev] " Brian Starkey
2019-06-13  3:38 ` [igt-dev] ✗ Fi.CI.BAT: failure for igt: Add support for testing writeback connectors (rev6) Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.