mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-10 17:36:11 +00:00
lib: refactor kmstest_create_fb
Factor out parts that will be used by an upcoming patch adding kmstest_create_fb2. Also call the fb paint functions directly, there is not much point in passing a function pointer for that. Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com>
This commit is contained in:
parent
bfb0cdd668
commit
f68d964c57
188
lib/drmtest.c
188
lib/drmtest.c
@ -39,6 +39,7 @@
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <linux/kd.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "drmtest.h"
|
||||
#include "i915_drm.h"
|
||||
@ -788,16 +789,14 @@ void drmtest_cleanup_aperture_trashers(void)
|
||||
}
|
||||
|
||||
/* helpers to create nice-looking framebuffers */
|
||||
static cairo_surface_t *
|
||||
paint_allocate_surface(int fd, int width, int height, int depth, int bpp,
|
||||
bool tiled,
|
||||
struct kmstest_fb *fb_info)
|
||||
static int create_bo_for_fb(int fd, int width, int height, int bpp,
|
||||
bool tiled, uint32_t *gem_handle_ret,
|
||||
unsigned *size_ret, unsigned *stride_ret)
|
||||
{
|
||||
cairo_format_t format;
|
||||
struct drm_i915_gem_set_tiling set_tiling;
|
||||
uint32_t gem_handle;
|
||||
int size;
|
||||
unsigned stride;
|
||||
uint32_t *fb_ptr;
|
||||
|
||||
if (tiled) {
|
||||
int v;
|
||||
@ -823,49 +822,24 @@ paint_allocate_surface(int fd, int width, int height, int depth, int bpp,
|
||||
size = stride * height;
|
||||
}
|
||||
|
||||
switch (depth) {
|
||||
case 16:
|
||||
format = CAIRO_FORMAT_RGB16_565;
|
||||
break;
|
||||
case 24:
|
||||
format = CAIRO_FORMAT_RGB24;
|
||||
break;
|
||||
#if 0
|
||||
case 30:
|
||||
format = CAIRO_FORMAT_RGB30;
|
||||
break;
|
||||
#endif
|
||||
case 32:
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "bad depth %d\n", depth);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert (bpp >= depth);
|
||||
|
||||
fb_info->gem_handle = gem_create(fd, size);
|
||||
gem_handle = gem_create(fd, size);
|
||||
|
||||
if (tiled) {
|
||||
set_tiling.handle = fb_info->gem_handle;
|
||||
set_tiling.handle = gem_handle;
|
||||
set_tiling.tiling_mode = I915_TILING_X;
|
||||
set_tiling.stride = stride;
|
||||
if (ioctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling)) {
|
||||
fprintf(stderr, "set tiling failed: %s (stride=%d, size=%d)\n",
|
||||
strerror(errno), stride, size);
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fb_ptr = gem_mmap(fd, fb_info->gem_handle, size, PROT_READ | PROT_WRITE);
|
||||
*stride_ret = stride;
|
||||
*size_ret = size;
|
||||
*gem_handle_ret = gem_handle;
|
||||
|
||||
fb_info->stride = stride;
|
||||
fb_info->size = size;
|
||||
|
||||
return cairo_image_surface_create_for_data((unsigned char *)fb_ptr,
|
||||
format, width, height,
|
||||
stride);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -981,23 +955,8 @@ paint_marker(cairo_t *cr, int x, int y)
|
||||
kmstest_cairo_printf_line(cr, align, 0, "(%d, %d)", x, y);
|
||||
}
|
||||
|
||||
unsigned int kmstest_create_fb(int fd, int width, int height, int bpp,
|
||||
int depth, bool tiled,
|
||||
struct kmstest_fb *fb_info,
|
||||
kmstest_paint_func paint_func,
|
||||
void *func_arg)
|
||||
void kmstest_paint_test_pattern(cairo_t *cr, int width, int height)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_status_t status;
|
||||
cairo_t *cr;
|
||||
unsigned int fb_id;
|
||||
|
||||
surface = paint_allocate_surface(fd, width, height, depth, bpp,
|
||||
tiled, fb_info);
|
||||
assert(surface);
|
||||
|
||||
cr = cairo_create(surface);
|
||||
|
||||
paint_test_patterns(cr, width, height);
|
||||
|
||||
cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
|
||||
@ -1008,27 +967,112 @@ unsigned int kmstest_create_fb(int fd, int width, int height, int bpp,
|
||||
paint_marker(cr, 0, height);
|
||||
paint_marker(cr, width, height);
|
||||
|
||||
if (paint_func)
|
||||
paint_func(cr, width, height, func_arg);
|
||||
|
||||
status = cairo_status(cr);
|
||||
assert(!status);
|
||||
cairo_destroy(cr);
|
||||
|
||||
do_or_die(drmModeAddFB(fd, width, height, depth, bpp,
|
||||
fb_info->stride,
|
||||
fb_info->gem_handle, &fb_id));
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
|
||||
fb_info->fb_id = fb_id;
|
||||
|
||||
return fb_id;
|
||||
assert(!cairo_status(cr));
|
||||
}
|
||||
|
||||
void kmstest_remove_fb(int fd, int fb_id)
|
||||
#define DF(did, cid, _bpp, _depth) \
|
||||
{ DRM_FORMAT_##did, CAIRO_FORMAT_##cid, # did, _bpp, _depth }
|
||||
static struct format_desc_struct {
|
||||
uint32_t drm_id;
|
||||
cairo_format_t cairo_id;
|
||||
const char *name;
|
||||
int bpp;
|
||||
int depth;
|
||||
} format_desc[] = {
|
||||
DF(RGB565, RGB16_565, 16, 16),
|
||||
DF(RGB888, INVALID, 24, 24),
|
||||
DF(XRGB8888, RGB24, 32, 24),
|
||||
DF(XRGB2101010, RGB30, 32, 30),
|
||||
DF(ARGB8888, ARGB32, 32, 32),
|
||||
};
|
||||
#undef DF
|
||||
|
||||
#define for_each_format(f) \
|
||||
for (f = format_desc; f - format_desc < ARRAY_SIZE(format_desc); f++)
|
||||
|
||||
static uint32_t bpp_depth_to_drm_format(int bpp, int depth)
|
||||
{
|
||||
do_or_die(drmModeRmFB(fd, fb_id));
|
||||
struct format_desc_struct *f;
|
||||
|
||||
for_each_format(f)
|
||||
if (f->bpp == bpp && f->depth == depth)
|
||||
return f->drm_id;
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Return fb_id on success, 0 on error */
|
||||
unsigned int kmstest_create_fb(int fd, int width, int height, int bpp,
|
||||
int depth, bool tiled, struct kmstest_fb *fb)
|
||||
{
|
||||
memset(fb, 0, sizeof(*fb));
|
||||
|
||||
if (create_bo_for_fb(fd, width, height, bpp, tiled, &fb->gem_handle,
|
||||
&fb->size, &fb->stride) < 0)
|
||||
return 0;
|
||||
|
||||
if (drmModeAddFB(fd, width, height, depth, bpp, fb->stride,
|
||||
fb->gem_handle, &fb->fb_id) < 0) {
|
||||
gem_close(fd, fb->gem_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fb->width = width;
|
||||
fb->height = height;
|
||||
fb->drm_format = bpp_depth_to_drm_format(bpp, depth);
|
||||
|
||||
return fb->fb_id;
|
||||
}
|
||||
|
||||
static cairo_format_t drm_format_to_cairo(uint32_t drm_format)
|
||||
{
|
||||
struct format_desc_struct *f;
|
||||
|
||||
for_each_format(f)
|
||||
if (f->drm_id == drm_format)
|
||||
return f->cairo_id;
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
static cairo_t *create_cairo_ctx(int fd, struct kmstest_fb *fb)
|
||||
{
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *surface;
|
||||
cairo_format_t cformat;
|
||||
void *fb_ptr;
|
||||
|
||||
cformat = drm_format_to_cairo(fb->drm_format);
|
||||
fb_ptr = gem_mmap(fd, fb->gem_handle, fb->size, PROT_READ | PROT_WRITE);
|
||||
surface = cairo_image_surface_create_for_data((unsigned char *)fb_ptr,
|
||||
cformat, fb->width,
|
||||
fb->height, fb->stride);
|
||||
assert(surface);
|
||||
cr = cairo_create(surface);
|
||||
cairo_surface_destroy(surface);
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
cairo_t *kmstest_get_cairo_ctx(int fd, struct kmstest_fb *fb)
|
||||
{
|
||||
|
||||
if (!fb->cairo_ctx)
|
||||
fb->cairo_ctx = create_cairo_ctx(fd, fb);
|
||||
|
||||
gem_set_domain(fd, fb->gem_handle, I915_GEM_DOMAIN_CPU,
|
||||
I915_GEM_DOMAIN_CPU);
|
||||
|
||||
return fb->cairo_ctx;
|
||||
}
|
||||
|
||||
void kmstest_remove_fb(int fd, struct kmstest_fb *fb)
|
||||
{
|
||||
if (fb->cairo_ctx)
|
||||
cairo_destroy(fb->cairo_ctx);
|
||||
do_or_die(drmModeRmFB(fd, fb->fb_id));
|
||||
gem_close(fd, fb->gem_handle);
|
||||
}
|
||||
|
||||
struct type_name {
|
||||
|
@ -119,8 +119,13 @@ void kmstest_free_connector_config(struct kmstest_connector_config *config);
|
||||
struct kmstest_fb {
|
||||
uint32_t fb_id;
|
||||
uint32_t gem_handle;
|
||||
uint32_t drm_format;
|
||||
int width;
|
||||
int height;
|
||||
int depth;
|
||||
unsigned stride;
|
||||
unsigned size;
|
||||
cairo_t *cairo_ctx;
|
||||
};
|
||||
|
||||
enum kmstest_text_align {
|
||||
@ -136,14 +141,12 @@ int kmstest_cairo_printf_line(cairo_t *cr, enum kmstest_text_align align,
|
||||
double yspacing, const char *fmt, ...)
|
||||
__attribute__((format (printf, 4, 5)));
|
||||
|
||||
typedef void (*kmstest_paint_func)(cairo_t *cr, int width, int height, void *priv);
|
||||
|
||||
unsigned int kmstest_create_fb(int fd, int width, int height, int bpp,
|
||||
int depth, bool tiled,
|
||||
struct kmstest_fb *fb_info,
|
||||
kmstest_paint_func paint_func,
|
||||
void *func_arg);
|
||||
void kmstest_remove_fb(int fd, int fb_id);
|
||||
struct kmstest_fb *fb_info);
|
||||
void kmstest_remove_fb(int fd, struct kmstest_fb *fb_info);
|
||||
cairo_t *kmstest_get_cairo_ctx(int fd, struct kmstest_fb *fb);
|
||||
void kmstest_paint_test_pattern(cairo_t *cr, int width, int height);
|
||||
void kmstest_dump_mode(drmModeModeInfo *mode);
|
||||
int kmstest_get_pipe_from_crtc_id(int fd, int crtc_id);
|
||||
const char *kmstest_encoder_type_str(int type);
|
||||
|
@ -844,10 +844,13 @@ static void connector_find_preferred_mode(uint32_t connector_id, int crtc_idx,
|
||||
o->mode_valid = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
paint_flip_mode(cairo_t *cr, int width, int height, void *priv)
|
||||
static void paint_flip_mode(struct kmstest_fb *fb, bool odd_frame)
|
||||
{
|
||||
bool odd_frame = (bool) priv;
|
||||
cairo_t *cr = kmstest_get_cairo_ctx(drm_fd, fb);
|
||||
int width = fb->width;
|
||||
int height = fb->height;
|
||||
|
||||
kmstest_paint_test_pattern(cr, width, height);
|
||||
|
||||
if (odd_frame)
|
||||
cairo_rectangle(cr, width/4, height/2, width/4, height/8);
|
||||
@ -856,6 +859,8 @@ paint_flip_mode(cairo_t *cr, int width, int height, void *priv)
|
||||
|
||||
cairo_set_source_rgb(cr, 1, 1, 1);
|
||||
cairo_fill(cr);
|
||||
|
||||
assert(!cairo_status(cr));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -991,20 +996,21 @@ static void run_test_on_crtc(struct test_output *o, int crtc_idx, int duration)
|
||||
o->fb_width *= 2;
|
||||
|
||||
o->fb_ids[0] = kmstest_create_fb(drm_fd, o->fb_width, o->fb_height,
|
||||
o->bpp, o->depth, false, &o->fb_info[0],
|
||||
paint_flip_mode, (void *)false);
|
||||
o->bpp, o->depth, false, &o->fb_info[0]);
|
||||
o->fb_ids[1] = kmstest_create_fb(drm_fd, o->fb_width, o->fb_height,
|
||||
o->bpp, o->depth, false, &o->fb_info[1],
|
||||
paint_flip_mode, (void *)true);
|
||||
o->bpp, o->depth, false, &o->fb_info[1]);
|
||||
o->fb_ids[2] = kmstest_create_fb(drm_fd, o->fb_width, o->fb_height,
|
||||
o->bpp, o->depth, true, &o->fb_info[2],
|
||||
paint_flip_mode, (void *)true);
|
||||
o->bpp, o->depth, true, &o->fb_info[2]);
|
||||
|
||||
if (!o->fb_ids[0] || !o->fb_ids[1] || !o->fb_ids[2]) {
|
||||
fprintf(stderr, "failed to create fbs\n");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
paint_flip_mode(&o->fb_info[0], false);
|
||||
paint_flip_mode(&o->fb_info[1], true);
|
||||
paint_flip_mode(&o->fb_info[2], true);
|
||||
|
||||
set_y_tiling(o, 2);
|
||||
|
||||
kmstest_dump_mode(&o->mode);
|
||||
@ -1044,9 +1050,9 @@ static void run_test_on_crtc(struct test_output *o, int crtc_idx, int duration)
|
||||
fprintf(stdout, "\n%s on crtc %d, connector %d: PASSED\n\n",
|
||||
o->test_name, o->crtc, o->id);
|
||||
|
||||
kmstest_remove_fb(drm_fd, o->fb_ids[2]);
|
||||
kmstest_remove_fb(drm_fd, o->fb_ids[1]);
|
||||
kmstest_remove_fb(drm_fd, o->fb_ids[0]);
|
||||
kmstest_remove_fb(drm_fd, &o->fb_info[2]);
|
||||
kmstest_remove_fb(drm_fd, &o->fb_info[1]);
|
||||
kmstest_remove_fb(drm_fd, &o->fb_info[0]);
|
||||
|
||||
last_connector = NULL;
|
||||
|
||||
|
@ -258,15 +258,18 @@ static void paint_image(cairo_t *cr, const char *file)
|
||||
cairo_surface_destroy(image);
|
||||
}
|
||||
|
||||
static void
|
||||
paint_output_info(cairo_t *cr, int l_width, int l_height, void *priv)
|
||||
static void paint_output_info(struct connector *c, struct kmstest_fb *fb)
|
||||
{
|
||||
struct connector *c = priv;
|
||||
cairo_t *cr = kmstest_get_cairo_ctx(drm_fd, fb);
|
||||
int l_width = fb->width;
|
||||
int l_height = fb->height;
|
||||
double str_width;
|
||||
double x, y, top_y;
|
||||
double max_width;
|
||||
int i;
|
||||
|
||||
kmstest_paint_test_pattern(cr, l_width, l_height);
|
||||
|
||||
cairo_select_font_face(cr, "Helvetica",
|
||||
CAIRO_FONT_SLANT_NORMAL,
|
||||
CAIRO_FONT_WEIGHT_NORMAL);
|
||||
@ -308,6 +311,8 @@ paint_output_info(cairo_t *cr, int l_width, int l_height, void *priv)
|
||||
|
||||
if (qr_code)
|
||||
paint_image(cr, "./pass.png");
|
||||
|
||||
assert(!cairo_status(cr));
|
||||
}
|
||||
|
||||
static void sighandler(int signo)
|
||||
@ -362,8 +367,8 @@ set_mode(struct connector *c)
|
||||
height = c->mode.vdisplay;
|
||||
|
||||
fb_id = kmstest_create_fb(drm_fd, width, height, bpp, depth,
|
||||
enable_tiling, &fb_info,
|
||||
paint_output_info, c);
|
||||
enable_tiling, &fb_info);
|
||||
paint_output_info(c, &fb_info);
|
||||
|
||||
fb_ptr = gem_mmap(drm_fd, fb_info.gem_handle,
|
||||
fb_info.size, PROT_READ | PROT_WRITE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user