[igt-dev] [PATCH i-g-t] tests/kms_prime: Add subtests to validate hybrid GPU
Karthik B S
karthik.b.s at intel.com
Thu Jul 21 05:34:53 UTC 2022
On 7/21/2022 3:39 AM, Navare, Manasi wrote:
> All the tests here look good,
> For D3 hot validation, I think Anshuman has sent a patch adding a
> subtest to kms_prime, could you reviewthat patch and may be we can
> combine that here or add D3 hot and cold validation later through
> Anshuman's patch.
Hi Manasi,
Thank you for the review.
I will review Anshuman's patch. That patch sits on top of this. So we
could get this merged first if this looks good and add it later as a
separate patch once that is reviewed?
Thanks,
Karthik.B.S
>
> Manasi
>
> On Tue, Jul 19, 2022 at 09:09:09AM +0530, Karthik B S wrote:
>> Add subtests to validate the Hybrid Graphics config with 2 GPUs active.
>>
>> 1.basic-crc-hybrid: Render on one GPU and export to second GPU for
>> scanout.
>>
>> 2.basic-modeset-hybrid: Render+scanout on one GPU when second GPU is
>> active.
>>
>> 3.D3hot: Validate PCI state of dGPU is D3 Hot when dGPU is idle and
>> scanout is on iGPU.
>>
>> 4.basic-crc-vgem: The existing subtest which uses DRIVER_VGEM
>> as the virtual second GPU. This is the legacy
>> subtest which runs even on non-hybrid configurations.
>>
>> Signed-off-by: Karthik B S <karthik.b.s at intel.com>
>> ---
>> tests/kms_prime.c | 214 ++++++++++++++++++++++++++++++++++++++++------
>> 1 file changed, 188 insertions(+), 26 deletions(-)
>>
>> diff --git a/tests/kms_prime.c b/tests/kms_prime.c
>> index 1ad4b3a6..4b1a3274 100644
>> --- a/tests/kms_prime.c
>> +++ b/tests/kms_prime.c
>> @@ -23,11 +23,20 @@
>>
>> #include "igt.h"
>> #include "igt_device.h"
>> +#include "igt_debugfs.h"
>> +#include "igt_sysfs.h"
>> +#include <fcntl.h>
>>
>> #include <sys/ioctl.h>
>> #include <sys/poll.h>
>> #include <time.h>
>>
>> +#define KMS_HELPER "/sys/module/drm_kms_helper/parameters/"
>> +#define KMS_POLL_DISABLE 0
>> +
>> +bool kms_poll_saved_state;
>> +bool kms_poll_disabled;
>> +
>> struct dumb_bo {
>> uint32_t handle;
>> uint32_t width, height;
>> @@ -141,10 +150,31 @@ static void prepare_fb(int importer_fd, struct dumb_bo *scratch, struct igt_fb *
>> static void import_fb(int importer_fd, struct igt_fb *fb,
>> int dmabuf_fd, uint32_t pitch)
>> {
>> - uint32_t offsets[4] = {}, pitches[4] = {}, handles[4] = {};
>> + uint32_t offsets[4] = {}, pitches[4] = {}, handles[4] = {}, temp_buf_handle;
>> int ret;
>>
>> - fb->gem_handle = prime_fd_to_handle(importer_fd, dmabuf_fd);
>> + if (is_i915_device(importer_fd)) {
>> + if (gem_has_lmem(importer_fd)) {
>> + uint64_t ahnd = get_reloc_ahnd(importer_fd, 0);
>> + igt_info("Importer is dGPU\n");
>> + temp_buf_handle = prime_fd_to_handle(importer_fd, dmabuf_fd);
>> + igt_assert(temp_buf_handle > 0);
>> + fb->gem_handle = igt_create_bo_with_dimensions(importer_fd, fb->width, fb->height,
>> + fb->drm_format, fb->modifier, pitch, NULL, NULL, NULL);
>> + igt_assert(fb->gem_handle > 0);
>> +
>> + igt_blitter_src_copy(importer_fd, ahnd, 0, temp_buf_handle, 0, pitch, fb->modifier, 0, 0, fb->size,
>> + fb->width, fb->height, 32, fb->gem_handle, 0, pitch, fb->modifier, 0, 0, fb->size);
>> +
>> + gem_sync(importer_fd, fb->gem_handle);
>> + gem_close(importer_fd, temp_buf_handle);
>> + put_ahnd(ahnd);
>> + } else {
>> + fb->gem_handle = prime_fd_to_handle(importer_fd, dmabuf_fd);
>> + }
>> + } else {
>> + fb->gem_handle = prime_fd_to_handle(importer_fd, dmabuf_fd);
>> + }
>>
>> handles[0] = fb->gem_handle;
>> pitches[0] = pitch;
>> @@ -154,7 +184,6 @@ static void import_fb(int importer_fd, struct igt_fb *fb,
>> DRM_FORMAT_XRGB8888,
>> handles, pitches, offsets,
>> &fb->fb_id, 0);
>> -
>> igt_assert(ret == 0);
>> }
>>
>> @@ -217,11 +246,9 @@ static void test_crc(int exporter_fd, int importer_fd)
>> import_fb(importer_fd, &fb, dmabuf_fd, scratch.pitch);
>> close(dmabuf_fd);
>>
>> -
>> colors[i].prime_crc.name = "prime";
>> collect_crc_for_fb(importer_fd, &fb, &display, output,
>> pipe_crc, colors[i].color, &colors[i].prime_crc);
>> -
>> igt_create_color_fb(importer_fd,
>> mode->hdisplay, mode->vdisplay,
>> DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR,
>> @@ -258,35 +285,170 @@ static void test_crc(int exporter_fd, int importer_fd)
>> igt_display_fini(&display);
>> }
>>
>> -igt_main
>> +static void test_basic_modeset(int drm_fd)
>> {
>> - igt_fixture
>> - kmstest_set_vt_graphics_mode();
>> + igt_display_t display;
>> + igt_output_t *output;
>> + enum pipe pipe;
>> + drmModeModeInfo *mode;
>> + struct igt_fb fb;
>> +
>> + igt_device_set_master(drm_fd);
>> + igt_display_require(&display, drm_fd);
>> +
>> + output = setup_display(drm_fd, &display, &pipe);
>> + mode = igt_output_get_mode(output);
>> + igt_assert(mode);
>> +
>> + igt_create_pattern_fb(drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888,
>> + DRM_FORMAT_MOD_LINEAR, &fb);
>> +
>> + set_fb(&fb, &display, output);
>> + igt_remove_fb(drm_fd, &fb);
>> + igt_display_fini(&display);
>> +}
>> +
>> +static bool has_connected_output(int drm_fd)
>> +{
>> + igt_display_t display;
>> + igt_output_t *output;
>> +
>> + igt_device_set_master(drm_fd);
>> + igt_display_require(&display, drm_fd);
>> +
>> + for_each_connected_output(&display, output)
>> + return true;
>> +
>> + return false;
>> +}
>> +
>> +static void validate_d3_hot(int drm_fd)
>> +{
>> + igt_assert(igt_debugfs_search(drm_fd, "i915_runtime_pm_status", "GPU idle: yes"));
>> + igt_assert(igt_debugfs_search(drm_fd, "i915_runtime_pm_status", "PCI device power state: D3hot [3]"));
>> +}
>> +
>> +static void kms_poll_state_restore(void)
>> +{
>> + int sysfs_fd;
>> +
>> + igt_assert((sysfs_fd = open(KMS_HELPER, O_RDONLY)) >= 0);
>> + igt_sysfs_set_boolean(sysfs_fd, "poll", kms_poll_saved_state);
>> + close(sysfs_fd);
>>
>> - igt_describe("Make a dumb color buffer, export to another device and"
>> - " compare the CRCs with a buffer native to that device");
>> - igt_subtest_with_dynamic("basic-crc") {
>> - int first_fd = -1;
>> - int second_fd = -1;
>> +}
>> +
>> +static void kms_poll_disable(void)
>> +{
>> + int sysfs_fd;
>> +
>> + igt_require((sysfs_fd = open(KMS_HELPER, O_RDONLY)) >= 0);
>> + kms_poll_saved_state = igt_sysfs_get_boolean(sysfs_fd, "poll");
>> + igt_sysfs_set_boolean(sysfs_fd, "poll", KMS_POLL_DISABLE);
>> + kms_poll_disabled = true;
>> + close(sysfs_fd);
>> +}
>> +
>> +igt_main
>> +{
>> + int first_fd = -1;
>> + int second_fd_vgem = -1;
>> + int second_fd_hybrid = -1;
>> + bool first_output, second_output;
>>
>> + igt_fixture {
>> + kmstest_set_vt_graphics_mode();
>> /* ANY = anything that is not VGEM */
>> - first_fd = __drm_open_driver_another(0, DRIVER_ANY | DRIVER_VGEM);
>> + first_fd = __drm_open_driver_another(0, DRIVER_ANY);
>> igt_require(first_fd >= 0);
>> + first_output = has_connected_output(first_fd);
>> + }
>>
>> - second_fd = __drm_open_driver_another(1, DRIVER_ANY | DRIVER_VGEM);
>> - igt_require(second_fd >= 0);
>> + igt_describe("Hybrid GPU subtests");
>> + igt_subtest_group {
>> + igt_fixture {
>> + second_fd_hybrid = __drm_open_driver_another(1, DRIVER_ANY);
>> + igt_require(second_fd_hybrid >= 0);
>> + second_output = has_connected_output(second_fd_hybrid);
>> + }
>>
>> - if (has_prime_export(first_fd) &&
>> - has_prime_import(second_fd))
>> - igt_dynamic("first-to-second")
>> - test_crc(first_fd, second_fd);
>> + igt_describe("Hybrid GPU: Make a dumb color buffer, export to another device and"
>> + " compare the CRCs with a buffer native to that device");
>> + igt_subtest_with_dynamic("basic-crc-hybrid") {
>> + if (has_prime_export(first_fd) &&
>> + has_prime_import(second_fd_hybrid) && second_output)
>> + igt_dynamic("first-to-second")
>> + test_crc(first_fd, second_fd_hybrid);
>> +
>> + if (has_prime_import(first_fd) &&
>> + has_prime_export(second_fd_hybrid) && first_output)
>> + igt_dynamic("second-to-first")
>> + test_crc(second_fd_hybrid, first_fd);
>> + }
>>
>> - if (has_prime_import(first_fd) &&
>> - has_prime_export(second_fd))
>> - igt_dynamic("second-to-first")
>> - test_crc(second_fd, first_fd);
>> + igt_describe("Basic modeset on the one device when the other device is active");
>> + igt_subtest_with_dynamic("basic-modeset-hybrid") {
>> + igt_require(second_fd_hybrid >= 0);
>> + if (first_output) {
>> + igt_dynamic("first")
>> + test_basic_modeset(first_fd);
>> + }
>>
>> - close(first_fd);
>> - close(second_fd);
>> + if (second_output) {
>> + igt_dynamic("second")
>> + test_basic_modeset(second_fd_hybrid);
>> + }
>> + }
>> +
>> + igt_describe("Validate pci state of dGPU when dGPU is idle and scanout is on iGPU");
>> + igt_subtest("D3hot") {
>> + igt_require_f(is_i915_device(second_fd_hybrid), "i915 device required\n");
>> + igt_require_f(gem_has_lmem(second_fd_hybrid), "Second GPU is not dGPU\n");
>> + igt_require_f(first_output, "No display connected to iGPU\n");
>> + igt_require_f(!second_output, "Display connected to dGPU\n");
>> +
>> + kms_poll_disable();
>> +
>> + igt_set_timeout(10, "Wait for dGPU to enter D3hot before starting the subtest");
>> + while (!igt_debugfs_search(second_fd_hybrid,
>> + "i915_runtime_pm_status",
>> + "PCI device power state: D3hot [3]"));
>> + igt_reset_timeout();
>> +
>> + test_basic_modeset(first_fd);
>> + validate_d3_hot(second_fd_hybrid);
>> + }
>> +
>> + igt_fixture {
>> + if (kms_poll_disabled)
>> + kms_poll_state_restore();
>> +
>> + close(second_fd_hybrid);
>> + }
>> }
>> +
>> + igt_describe("VGEM subtests");
>> + igt_subtest_group {
>> + igt_fixture {
>> + second_fd_vgem = __drm_open_driver_another(1, DRIVER_VGEM);
>> + igt_require(second_fd_vgem >= 0);
>> + if (is_i915_device(first_fd))
>> + igt_require(!gem_has_lmem(first_fd));
>> + }
>> +
>> + igt_describe("Make a dumb color buffer, export to another device and"
>> + " compare the CRCs with a buffer native to that device");
>> + igt_subtest_with_dynamic("basic-crc-vgem") {
>> + if (has_prime_import(first_fd) &&
>> + has_prime_export(second_fd_vgem) && first_output)
>> + igt_dynamic("second-to-first")
>> + test_crc(second_fd_vgem, first_fd);
>> + }
>> +
>> + igt_fixture
>> + close(second_fd_vgem);
>> + }
>> +
>> + igt_fixture
>> + close(first_fd);
>> }
>> --
>> 2.22.0
>>
More information about the igt-dev
mailing list