[PATCH] tests/vmwgfx: Add test that draws triangle without using 3d commands.

Martin Krastev martin.krastev at broadcom.com
Mon Oct 14 13:39:10 UTC 2024


LGTM.

Reviewed-by: Martin Krastev <martin.krastev at broadcom.com>

Regards,
Martin

On Sat, Oct 5, 2024 at 1:31 AM Maaz Mombasawala
<maaz.mombasawala at broadcom.com> wrote:
>
> The vmwgfx driver can be used in VMs with 3d disabled, in which case 3d
> commands are not available, but buffers can still be created and used.
> Validate buffers on such vms with a test that uses cairo to draw a
> triangle on a vmwgfx mob and validate it with the same image in system
> memory.
>
> Signed-off-by: Maaz Mombasawala <maaz.mombasawala at broadcom.com>
> ---
>  lib/igt_vmwgfx.c       | 78 ++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_vmwgfx.h       |  3 ++
>  tests/vmwgfx/vmw_tri.c | 30 +++++++++++++---
>  3 files changed, 107 insertions(+), 4 deletions(-)
>
> diff --git a/lib/igt_vmwgfx.c b/lib/igt_vmwgfx.c
> index b62d7a326..74c13b52b 100644
> --- a/lib/igt_vmwgfx.c
> +++ b/lib/igt_vmwgfx.c
> @@ -1348,3 +1348,81 @@ bool vmw_is_format_supported(int drm_fd, SVGA3dDevCapIndex dev_cap_index)
>         result = vmw_format_get_caps(drm_fd, dev_cap_index);
>         return result.u & SVGA3D_FORMAT_POSITIVE;
>  }
> +
> +static void draw_triangle_2d(cairo_t *cr, int width, int height)
> +{
> +       cairo_pattern_t *r_pat, *g_pat, *b_pat;
> +
> +       cairo_rectangle(cr, 0, 0, width, height);
> +       cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
> +       cairo_fill(cr);
> +
> +       cairo_scale(cr, width, height);
> +
> +       cairo_move_to(cr, 0.5, 0.125);
> +       cairo_line_to(cr, 0.125, 0.875);
> +       cairo_line_to(cr, 0.875, 0.875);
> +       cairo_close_path(cr);
> +
> +       r_pat = cairo_pattern_create_linear(0.125, 0.875, 0.675, 0.475);
> +       cairo_pattern_add_color_stop_rgba(r_pat, 0, 1, 0, 0, 1);
> +       cairo_pattern_add_color_stop_rgba(r_pat, 1, 0, 0, 0, 0);
> +
> +       g_pat = cairo_pattern_create_linear(0.5, 0.125, 0.5, 0.875);
> +       cairo_pattern_add_color_stop_rgba(g_pat, 0, 0, 1, 0, 1);
> +       cairo_pattern_add_color_stop_rgba(g_pat, 1, 0, 0, 0, 0);
> +
> +       b_pat = cairo_pattern_create_linear(0.875, 0.875, 0.325, 0.475);
> +       cairo_pattern_add_color_stop_rgba(b_pat, 0, 0, 0, 1, 1);
> +       cairo_pattern_add_color_stop_rgba(b_pat, 1, 0, 0, 0, 0);
> +
> +       cairo_set_source(cr, r_pat);
> +       cairo_fill_preserve(cr);
> +       cairo_set_source(cr, g_pat);
> +       cairo_fill_preserve(cr);
> +       cairo_set_source(cr, b_pat);
> +       cairo_fill(cr);
> +
> +       cairo_pattern_destroy(r_pat);
> +       cairo_pattern_destroy(g_pat);
> +       cairo_pattern_destroy(b_pat);
> +}
> +
> +
> +/**
> + * Tests if mob can be used without invoking 3d commands.
> + */
> +void vmw_triangle_test_2d(int fd, struct vmw_mob *mob, const uint32 width,
> +                         const uint32 height, const uint32 stride)
> +{
> +       cairo_surface_t *mob_cr_srf, *mem_cr_srf;
> +       cairo_t *cr_mob, *cr_mem;
> +       void *data, *mob_data, *mem_data;
> +       const uint32 size = height * stride;
> +
> +       data = vmw_ioctl_mob_map(fd, mob);
> +       mob_cr_srf = cairo_image_surface_create_for_data(data,
> +               CAIRO_FORMAT_ARGB32, width, height, stride);
> +       cr_mob = cairo_create(mob_cr_srf);
> +       draw_triangle_2d(cr_mob, width, height);
> +
> +       mem_cr_srf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width,
> +               height);
> +       cr_mem = cairo_create(mem_cr_srf);
> +       draw_triangle_2d(cr_mem, width, height);
> +
> +       mob_data = cairo_image_surface_get_data(mob_cr_srf);
> +       mem_data = cairo_image_surface_get_data(mem_cr_srf);
> +
> +       igt_assert_f(mob_data != NULL, "No data in mob image.\n");
> +       igt_assert_f(mem_data != NULL, "No data in system memory image.\n");
> +
> +       igt_assert_f(memcmp(mob_data, mem_data, size) == 0,
> +                    "Mob and system memory images are not identical\n");
> +
> +       cairo_destroy(cr_mob);
> +       cairo_surface_destroy(mob_cr_srf);
> +       cairo_destroy(cr_mem);
> +       cairo_surface_destroy(mem_cr_srf);
> +       vmw_ioctl_mob_unmap(mob);
> +}
> diff --git a/lib/igt_vmwgfx.h b/lib/igt_vmwgfx.h
> index a630d201d..bfc591128 100644
> --- a/lib/igt_vmwgfx.h
> +++ b/lib/igt_vmwgfx.h
> @@ -257,4 +257,7 @@ SVGA3dDevCapResult vmw_format_get_caps(int drm_fd,
>
>  bool vmw_is_format_supported(int drm_fd, SVGA3dDevCapIndex dev_cap_index);
>
> +void vmw_triangle_test_2d(int fd, struct vmw_mob *mob, const uint32 width,
> +                         const uint32 height, const uint32 stride);
> +
>  #endif /* IGT_VMWGFX_H */
> diff --git a/tests/vmwgfx/vmw_tri.c b/tests/vmwgfx/vmw_tri.c
> index 61c4d5df8..1cb54707a 100644
> --- a/tests/vmwgfx/vmw_tri.c
> +++ b/tests/vmwgfx/vmw_tri.c
> @@ -189,15 +189,17 @@ igt_main
>         {
>                 vmw_svga_device_init(&device, vmw_svga_device_node_render);
>                 igt_require(device.drm_fd != -1);
> -
> -               cid = vmw_ioctl_context_create(device.drm_fd);
> -               igt_require(cid != SVGA3D_INVALID_ID);
>         }
>
>         igt_describe("Tests rendering of a trivial triangle.");
>         igt_subtest("tri")
>         {
> +               cid = vmw_ioctl_context_create(device.drm_fd);
> +               igt_require(cid != SVGA3D_INVALID_ID);
> +
>                 draw_triangle(&device, cid);
> +
> +               vmw_ioctl_context_destroy(device.drm_fd, cid);
>         }
>
>         /*
> @@ -207,12 +209,32 @@ igt_main
>         igt_describe("Tests rendering of a triangle with coherency.");
>         igt_subtest("tri-no-sync-coherent")
>         {
> +               cid = vmw_ioctl_context_create(device.drm_fd);
> +               igt_require(cid != SVGA3D_INVALID_ID);
> +
>                 draw_triangle_on_coherent_rt(&device, cid);
> +
> +               vmw_ioctl_context_destroy(device.drm_fd, cid);
> +       }
> +
> +       igt_describe("Tests drawing a triangle without 3d commands");
> +       igt_subtest("tri-2d")
> +       {
> +               struct vmw_mob *mob;
> +               const uint32 width = vmw_default_rect_size.width;
> +               const uint32 height = vmw_default_rect_size.height;
> +               const uint32 stride = width * 4;
> +               const uint32 size = height * stride;
> +
> +               mob = vmw_ioctl_mob_create(device.drm_fd, size);
> +
> +               vmw_triangle_test_2d(device.drm_fd, mob, width, height, stride);
> +
> +               vmw_ioctl_mob_close_handle(device.drm_fd, mob);
>         }
>
>         igt_fixture
>         {
> -               vmw_ioctl_context_destroy(device.drm_fd, cid);
>                 vmw_svga_device_fini(&device);
>         }
>  }
> --
> 2.43.0
>


More information about the igt-dev mailing list