blob: f3f3ac28ab700712abe809da4f384df05ec165ad [file] [log] [blame]
Zach Reiznerc09812f2015-01-12 16:49:49 -08001/*
2 * Copyright 2014 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
Zach Reizner7d849892016-02-24 17:30:27 -08007#include "bs_drm.h"
Zach Reiznerc09812f2015-01-12 16:49:49 -08008
9#define BUFFERS 2
10
Zach Reizner7d849892016-02-24 17:30:27 -080011struct framebuffer {
12 struct gbm_bo *bo;
13 uint32_t vgem_handle;
14 uint32_t id;
Zach Reiznerc09812f2015-01-12 16:49:49 -080015};
16
Zach Reizner7d849892016-02-24 17:30:27 -080017struct context {
18 int display_fd;
19 int vgem_fd;
20 uint32_t crtc_id;
21
22 struct framebuffer fbs[BUFFERS];
23};
24
25void disable_psr()
26{
Zach Reizner299fab72015-04-28 16:56:14 -070027 const char psr_path[] = "/sys/module/i915/parameters/enable_psr";
28 int psr_fd = open(psr_path, O_WRONLY);
29
30 if (psr_fd < 0)
31 return;
32
33 if (write(psr_fd, "0", 1) == -1) {
Zach Reizner7d849892016-02-24 17:30:27 -080034 bs_debug_error("failed to disable psr");
35 }
36 else {
37 printf("disabled psr");
Zach Reizner299fab72015-04-28 16:56:14 -070038 }
39
40 close(psr_fd);
41}
42
Zach Reizner7d849892016-02-24 17:30:27 -080043void do_fixes()
44{
Zach Reizner299fab72015-04-28 16:56:14 -070045 disable_psr();
46}
47
Zach Reiznerc09812f2015-01-12 16:49:49 -080048#define STEP_SKIP 0
49#define STEP_MMAP 1
50#define STEP_FAULT 2
51#define STEP_FLIP 3
52#define STEP_DRAW 4
53
54void show_sequence(const int *sequence)
55{
56 int sequence_subindex;
Zach Reizner7d849892016-02-24 17:30:27 -080057 printf("starting sequence: ");
Zach Reiznerc09812f2015-01-12 16:49:49 -080058 for (sequence_subindex = 0; sequence_subindex < 4; sequence_subindex++) {
59 switch (sequence[sequence_subindex]) {
Zach Reizner7d849892016-02-24 17:30:27 -080060 case STEP_SKIP:
61 break;
62 case STEP_MMAP:
63 printf("mmap ");
64 break;
65 case STEP_FAULT:
66 printf("fault ");
67 break;
68 case STEP_FLIP:
69 printf("flip ");
70 break;
71 case STEP_DRAW:
72 printf("draw ");
73 break;
74 default:
75 bs_debug_error("<unknown step %d> (aborting!)",
76 sequence[sequence_subindex]);
77 abort();
78 break;
Zach Reiznerc09812f2015-01-12 16:49:49 -080079 }
80 }
Zach Reizner7d849892016-02-24 17:30:27 -080081 printf("\n");
Zach Reiznerc09812f2015-01-12 16:49:49 -080082}
83
84void draw(struct context *ctx)
85{
Zach Reiznerc09812f2015-01-12 16:49:49 -080086 // Run the drawing routine with the key driver events in different
87 // sequences.
88 const int sequences[4][4] = {
89 { STEP_MMAP, STEP_FAULT, STEP_FLIP, STEP_DRAW },
Zach Reizner7d849892016-02-24 17:30:27 -080090 { STEP_MMAP, STEP_FLIP, STEP_DRAW, STEP_SKIP },
91 { STEP_MMAP, STEP_DRAW, STEP_FLIP, STEP_SKIP },
92 { STEP_FLIP, STEP_MMAP, STEP_DRAW, STEP_SKIP },
Zach Reiznerc09812f2015-01-12 16:49:49 -080093 };
94
95 int sequence_index = 0;
96 int sequence_subindex = 0;
97
98 int fb_idx = 1;
99
100 for (sequence_index = 0; sequence_index < 4; sequence_index++) {
101 show_sequence(sequences[sequence_index]);
Zach Reizner7d849892016-02-24 17:30:27 -0800102 for (int frame_index = 0; frame_index < 0x100; frame_index++) {
103 struct framebuffer *fb = &ctx->fbs[fb_idx];
104 size_t bo_stride = gbm_bo_get_stride(fb->bo);
105 size_t bo_size = bo_stride * gbm_bo_get_height(fb->bo);
Zach Reiznerc09812f2015-01-12 16:49:49 -0800106 uint32_t *bo_ptr;
107 volatile uint32_t *ptr;
108
109 for (sequence_subindex = 0; sequence_subindex < 4; sequence_subindex++) {
110 switch (sequences[sequence_index][sequence_subindex]) {
Zach Reizner7d849892016-02-24 17:30:27 -0800111 case STEP_MMAP:
112 bo_ptr = bs_dumb_mmap(ctx->vgem_fd, fb->vgem_handle,
113 bo_size);
114 ptr = bo_ptr;
115 break;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800116
Zach Reizner7d849892016-02-24 17:30:27 -0800117 case STEP_FAULT:
118 *ptr = 1234567;
119 break;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800120
Zach Reizner7d849892016-02-24 17:30:27 -0800121 case STEP_FLIP:
122 drmModePageFlip(ctx->display_fd, ctx->crtc_id,
123 ctx->fbs[fb_idx].id, 0, NULL);
124 break;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800125
Zach Reizner7d849892016-02-24 17:30:27 -0800126 case STEP_DRAW:
127 for (ptr = bo_ptr;
128 ptr < bo_ptr + (bo_size / sizeof(*bo_ptr));
129 ptr++) {
130 int y = ((void *)ptr - (void *)bo_ptr) /
131 bo_stride;
132 int x = ((void *)ptr - (void *)bo_ptr -
133 bo_stride * y) /
134 sizeof(*ptr);
135 x -= 100;
136 y -= 100;
137 *ptr = 0xff000000;
138 if (x * x + y * y <
139 frame_index * frame_index)
140 *ptr |= (frame_index % 0x100) << 8;
141 else
142 *ptr |= 0xff |
143 (sequence_index * 64 << 16);
144 }
145 break;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800146
Zach Reizner7d849892016-02-24 17:30:27 -0800147 case STEP_SKIP:
148 default:
149 break;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800150 }
151 }
152
153 munmap(bo_ptr, bo_size);
154
155 usleep(1e6 / 120); /* 120 Hz */
156
157 fb_idx = fb_idx ^ 1;
158 }
159 }
160}
161
162int main(int argc, char **argv)
163{
Zach Reizner7d849892016-02-24 17:30:27 -0800164 struct context ctx = { 0 };
Zach Reiznerc09812f2015-01-12 16:49:49 -0800165
Zach Reizner299fab72015-04-28 16:56:14 -0700166 do_fixes();
167
Zach Reizner7d849892016-02-24 17:30:27 -0800168 ctx.display_fd = bs_drm_open_main_display();
169 if (ctx.display_fd < 0) {
170 bs_debug_error("failed to open card for display");
171 return 1;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800172 }
173
Zach Reizner7d849892016-02-24 17:30:27 -0800174 ctx.vgem_fd = bs_drm_open_vgem();
175 if (ctx.vgem_fd < 0) {
176 bs_debug_error("failed to open vgem card");
177 return 1;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800178 }
179
Zach Reizner7d849892016-02-24 17:30:27 -0800180 struct gbm_device *gbm = gbm_create_device(ctx.display_fd);
181 if (!gbm) {
182 bs_debug_error("failed to create gbm device");
183 return 1;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800184 }
185
Zach Reizner7d849892016-02-24 17:30:27 -0800186 struct bs_drm_pipe pipe = { 0 };
187 if (!bs_drm_pipe_make(ctx.display_fd, &pipe)) {
188 bs_debug_error("failed to make pipe");
189 return 1;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800190 }
191
Zach Reizner7d849892016-02-24 17:30:27 -0800192 drmModeConnector *connector = drmModeGetConnector(ctx.display_fd, pipe.connector_id);
193 drmModeModeInfo *mode = &connector->modes[0];
194 ctx.crtc_id = pipe.crtc_id;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800195
Zach Reizner7d849892016-02-24 17:30:27 -0800196 printf("display size: %ux%u\n", mode->hdisplay, mode->vdisplay);
Zach Reiznerc09812f2015-01-12 16:49:49 -0800197
Zach Reizner7d849892016-02-24 17:30:27 -0800198 for (size_t fb_index = 0; fb_index < BUFFERS; ++fb_index) {
199 struct framebuffer *fb = &ctx.fbs[fb_index];
200 fb->bo = gbm_bo_create(gbm, mode->hdisplay, mode->vdisplay, GBM_FORMAT_XRGB8888,
201 GBM_BO_USE_SCANOUT);
Zach Reiznerc09812f2015-01-12 16:49:49 -0800202
Zach Reizner7d849892016-02-24 17:30:27 -0800203 if (!fb->bo) {
204 bs_debug_error("failed to create buffer object");
205 return 1;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800206 }
207
Zach Reizner7d849892016-02-24 17:30:27 -0800208 fb->id = bs_drm_fb_create_gbm(fb->bo);
209 if (fb->id == 0) {
210 bs_debug_error("failed to create fb");
211 return 1;
212 }
Zach Reiznerc09812f2015-01-12 16:49:49 -0800213
Zach Reizner7d849892016-02-24 17:30:27 -0800214 int drm_prime_fd = gbm_bo_get_fd(fb->bo);
Zach Reiznerc09812f2015-01-12 16:49:49 -0800215
216 if (drm_prime_fd < 0) {
Zach Reizner7d849892016-02-24 17:30:27 -0800217 bs_debug_error("failed to turn handle into fd");
218 return 1;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800219 }
220
Zach Reizner7d849892016-02-24 17:30:27 -0800221 int ret = drmPrimeFDToHandle(ctx.vgem_fd, drm_prime_fd, &fb->vgem_handle);
Zach Reiznerc09812f2015-01-12 16:49:49 -0800222 if (ret) {
Zach Reizner7d849892016-02-24 17:30:27 -0800223 bs_debug_error("failed to import handle");
224 return 1;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800225 }
226 }
227
Zach Reizner7d849892016-02-24 17:30:27 -0800228 if (drmModeSetCrtc(ctx.display_fd, pipe.crtc_id, ctx.fbs[0].id, 0, 0, &pipe.connector_id, 1,
229 mode)) {
230 bs_debug_error("failed to set CRTC");
231 return 1;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800232 }
233
234 draw(&ctx);
235
Zach Reizner7d849892016-02-24 17:30:27 -0800236 return 0;
Zach Reiznerc09812f2015-01-12 16:49:49 -0800237}