[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