summaryrefslogtreecommitdiff
path: root/tests/kms_addfb_basic.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2018-09-05 10:41:18 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2018-09-06 15:19:48 +0100
commit129394b79b182c5566b316ba3282cdb2cd4e661b (patch)
tree7f6d2df4b96c5238ce276e5ff7ff823c7bc605b6 /tests/kms_addfb_basic.c
parent94b4e204473a7d9f49e536c8877a4a5636e0d1b2 (diff)
igt/kms_addfb_basic: Exercise legacy interface to addfb2
The legacy interface passes in a single handle, and instead of providing the pixel_format fourcc, passes in a bpp/depth combination that the kernel translates into a fourcc. If that is an illegal combination, the kernel should be reporting EINVAL rather than pass an unknown framebuffer to the drivers. As the number of possible permutations of bpp/depth (both are strictly u32 parameters) is huge, we simply fuzz the interface for 1s. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'tests/kms_addfb_basic.c')
-rw-r--r--tests/kms_addfb_basic.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/tests/kms_addfb_basic.c b/tests/kms_addfb_basic.c
index 7d8852f0..ce48d24f 100644
--- a/tests/kms_addfb_basic.c
+++ b/tests/kms_addfb_basic.c
@@ -38,9 +38,35 @@
#include "drm.h"
#include "drm_fourcc.h"
+#include "igt_rand.h"
+
uint32_t gem_bo;
uint32_t gem_bo_small;
+static int legacy_addfb(int fd, struct drm_mode_fb_cmd *arg)
+{
+ int err;
+
+ err = 0;
+ if (igt_ioctl(fd, DRM_IOCTL_MODE_ADDFB, arg))
+ err = -errno;
+
+ errno = 0;
+ return err;
+}
+
+static int rmfb(int fd, uint32_t id)
+{
+ int err;
+
+ err = 0;
+ if (igt_ioctl(fd, DRM_IOCTL_MODE_RMFB, &id))
+ err = -errno;
+
+ errno = 0;
+ return err;
+}
+
static void invalid_tests(int fd)
{
struct local_drm_mode_fb_cmd2 f = {};
@@ -113,6 +139,108 @@ static void invalid_tests(int fd)
igt_assert(f.modifier[0] == 0);
}
+ igt_subtest("legacy-format") {
+ struct {
+ /* drm_mode_legacy_fb_format() */
+ int bpp, depth;
+ int expect;
+ } known_formats[] = {
+ { 8, 8 }, /* c8 (palette) */
+ { 16, 15 }, /* x1r5g5b5 */
+ { 16, 16 }, /* r5g6b5 or a1r5g5b5! */
+ { 24, 24 }, /* r8g8b8 */
+ { 32, 24 }, /* x8r8g8b8 */
+ { 32, 30 }, /* x2r10g10b10 */
+ { 32, 32 }, /* a8r8g8b8 or a2r10g10b10! */
+ };
+ struct drm_mode_fb_cmd arg = {
+ .handle = f.handles[0],
+ .width = f.width,
+ .height = f.height,
+ .pitch = f.pitches[0],
+ };
+ uint32_t prng = 0x12345678;
+ unsigned long timeout = 1;
+ unsigned long count = 0;
+
+ /*
+ * First confirm the kernel recognises our known_formats;
+ * some may be invalid for different devices.
+ */
+ for (int i = 0; i < ARRAY_SIZE(known_formats); i++) {
+ arg.bpp = known_formats[i].bpp;
+ arg.depth = known_formats[i].depth;
+ known_formats[i].expect = legacy_addfb(fd, &arg);
+ igt_debug("{bpp:%d, depth:%d} -> expect:%d\n",
+ arg.bpp, arg.depth, known_formats[i].expect);
+ if (arg.fb_id) {
+ igt_assert_eq(rmfb(fd, arg.fb_id), 0);
+ arg.fb_id = 0;
+ }
+ }
+
+ igt_until_timeout(timeout) {
+ int expect = -EINVAL;
+ int err;
+
+ arg.bpp = hars_petruska_f54_1_random(&prng);
+ arg.depth = hars_petruska_f54_1_random(&prng);
+ for (int start = 0, end = ARRAY_SIZE(known_formats);
+ start < end; ) {
+ int mid = start + (end - start) / 2;
+ typeof(*known_formats) *tbl = &known_formats[mid];
+
+ if (arg.bpp < tbl->bpp) {
+ end = mid;
+ } else if (arg.bpp > tbl->bpp) {
+ start = mid + 1;
+ } else {
+ if (arg.depth < tbl->depth) {
+ end = mid;
+ } else if (arg.depth > tbl->depth) {
+ start = mid + 1;
+ } else {
+ expect = tbl->expect;
+ break;
+ }
+ }
+ }
+
+ err = legacy_addfb(fd, &arg);
+ igt_assert_f(err == expect,
+ "Expected %d with {bpp:%d, depth:%d}, got %d instead\n",
+ expect, arg.bpp, arg.depth, err);
+ if (arg.fb_id) {
+ igt_assert_eq(rmfb(fd, arg.fb_id), 0);
+ arg.fb_id = 0;
+ }
+
+ count++;
+ }
+
+ /* After all the abuse, confirm the known_formats */
+ for (int i = 0; i < ARRAY_SIZE(known_formats); i++) {
+ int err;
+
+ arg.bpp = known_formats[i].bpp;
+ arg.depth = known_formats[i].depth;
+
+ err = legacy_addfb(fd, &arg);
+ igt_assert_f(err == known_formats[i].expect,
+ "Expected %d with {bpp:%d, depth:%d}, got %d instead\n",
+ known_formats[i].expect,
+ arg.bpp, arg.depth,
+ err);
+ if (arg.fb_id) {
+ igt_assert_eq(rmfb(fd, arg.fb_id), 0);
+ arg.fb_id = 0;
+ }
+ }
+
+ igt_info("Successfully fuzzed %lu {bpp, depth} variations\n",
+ count);
+ }
+
igt_fixture {
gem_close(fd, gem_bo);
gem_close(fd, gem_bo_small);