drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn, int width, int height, int cpp, int *out_stride, uint32_t *out_tiling) { intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t tiling; int stride, size; drm_intel_bo *bo; intel_set_gem_max_sizes(scrn); if (intel->tiling & INTEL_TILING_FB) tiling = I915_TILING_X; else tiling = I915_TILING_NONE; retry: size = intel_compute_size(intel, width, height, intel->cpp*8, 0, &tiling, &stride); if (!intel_check_display_stride(scrn, stride, tiling)) { if (tiling != I915_TILING_NONE) { tiling = I915_TILING_NONE; goto retry; } xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Front buffer stride %d kB " "exceeds display limit\n", stride / 1024); return NULL; } bo = drm_intel_bo_alloc(intel->bufmgr, "front buffer", size, 0); if (bo == NULL) return FALSE; if (tiling != I915_TILING_NONE) drm_intel_bo_set_tiling(bo, &tiling, stride); xf86DrvMsg(scrn->scrnIndex, X_INFO, "Allocated new frame buffer %dx%d stride %d, %s\n", width, height, stride, tiling == I915_TILING_NONE ? "untiled" : "tiled"); drm_intel_bo_disable_reuse(bo); *out_stride = stride; *out_tiling = tiling; return bo; }
static Bool drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) { ScrnInfoPtr scrn = crtc->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; int saved_x, saved_y; Rotation saved_rotation; DisplayModeRec saved_mode; uint32_t *output_ids; int output_count = 0; int ret = TRUE; int i; int fb_id; drmModeModeInfo kmode; unsigned int pitch = scrn->displayWidth * intel->cpp; if (drmmode->fb_id == 0) { ret = drmModeAddFB(drmmode->fd, scrn->virtualX, scrn->virtualY, scrn->depth, scrn->bitsPerPixel, pitch, intel->front_buffer->handle, &drmmode->fb_id); if (ret < 0) { ErrorF("failed to add fb\n"); return FALSE; } } saved_mode = crtc->mode; saved_x = crtc->x; saved_y = crtc->y; saved_rotation = crtc->rotation; crtc->mode = *mode; crtc->x = x; crtc->y = y; crtc->rotation = rotation; output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); if (!output_ids) { ret = FALSE; goto done; } for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; drmmode_output_private_ptr drmmode_output; if (output->crtc != crtc) continue; drmmode_output = output->driver_private; output_ids[output_count] = drmmode_output->mode_output->connector_id; output_count++; } #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,5,99,0,0) if (!xf86CrtcRotate(crtc, mode, rotation)) goto done; #else if (!xf86CrtcRotate(crtc)) goto done; #endif #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0) crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, crtc->gamma_blue, crtc->gamma_size); #endif drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); fb_id = drmmode->fb_id; if (drmmode_crtc->rotate_fb_id) { fb_id = drmmode_crtc->rotate_fb_id; x = 0; y = 0; } ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, fb_id, x, y, output_ids, output_count, &kmode); if (ret) xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "failed to set mode: %s", strerror(-ret)); else ret = TRUE; /* Turn on any outputs on this crtc that may have been disabled */ for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; if (output->crtc != crtc) continue; drmmode_output_dpms(output, DPMSModeOn); } intel_set_gem_max_sizes(scrn); if (scrn->pScreen) xf86_reload_cursors(scrn->pScreen); done: if (!ret) { crtc->x = saved_x; crtc->y = saved_y; crtc->rotation = saved_rotation; crtc->mode = saved_mode; } return ret; }