[PATCH] tests/vmwgfx: Add test that draws triangle without using 3d commands.
Maaz Mombasawala
maaz.mombasawala at broadcom.com
Fri Oct 4 22:30:53 UTC 2024
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