From: Mauro Rossi Date: Sat, 25 Jan 2020 20:34:29 +0000 (+0100) Subject: Add framebuffer HAL implementation based on drm_framebuffer (v3) X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fexternal-minigbm.git;a=commitdiff_plain;h=8dc3668acf93a587bffe9b315d71285618981c2f Add framebuffer HAL implementation based on drm_framebuffer (v3) (v1) original lambdadroid implementation (v2) changes in drv.h due to following commits: 48b4c08 ("minigbm: fix flags to align with GBM") 6e6dc49 ("minigbm: virtio: restrict formats supported without 3D") (v3) changes in drv.h due to aosp master branch minigbm implementation NOTE: #define BO_USE_FRAMEBUFFER (1ull << 19) as the fist available bit --- diff --git a/Android.bp b/Android.bp index 63a50f7..2911e0a 100644 --- a/Android.bp +++ b/Android.bp @@ -39,6 +39,7 @@ cc_defaults { "cros_gralloc/cros_gralloc_driver.cc", "cros_gralloc/cros_gralloc_helpers.cc", "cros_gralloc/gralloc0/gralloc0.cc", + "cros_gralloc/gralloc0/drm_framebuffer.c", ], cflags: [ @@ -47,7 +48,6 @@ cc_defaults { "-Wall", "-Wsign-compare", "-Wpointer-arith", - "-Wcast-qual", "-Wcast-align", "-Wno-unused-parameter", ], diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 8096b7f..9419bf8 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -26,6 +26,10 @@ cros_gralloc_driver::~cros_gralloc_driver() } } +int cros_gralloc_driver::get_fd() const { + return drv_get_fd(drv_); +} + int32_t cros_gralloc_driver::init() { /* @@ -74,6 +78,18 @@ int32_t cros_gralloc_driver::init() return -ENODEV; } +int cros_gralloc_driver::init_master() +{ + int fd = open(DRM_DIR_NAME "/card0", O_RDWR, 0); + if (fd >= 0) { + drv_ = drv_create(fd); + if (drv_) + return 0; + } + + return -ENODEV; +} + bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descriptor *descriptor) { struct combination *combo; diff --git a/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h index 45782c9..668f8ee 100644 --- a/cros_gralloc/cros_gralloc_driver.h +++ b/cros_gralloc/cros_gralloc_driver.h @@ -18,7 +18,10 @@ class cros_gralloc_driver cros_gralloc_driver(); ~cros_gralloc_driver(); + int get_fd() const; + int32_t init(); + int32_t init_master(); bool is_supported(const struct cros_gralloc_buffer_descriptor *descriptor); int32_t allocate(const struct cros_gralloc_buffer_descriptor *descriptor, buffer_handle_t *out_handle); diff --git a/cros_gralloc/cros_gralloc_handle.h b/cros_gralloc/cros_gralloc_handle.h index cd3edfe..f50bf21 100644 --- a/cros_gralloc/cros_gralloc_handle.h +++ b/cros_gralloc/cros_gralloc_handle.h @@ -7,7 +7,9 @@ #ifndef CROS_GRALLOC_HANDLE_H #define CROS_GRALLOC_HANDLE_H +#ifdef __cplusplus #include +#endif #include #define DRV_MAX_PLANES 4 @@ -31,6 +33,7 @@ struct cros_gralloc_handle { uint32_t pixel_stride; int32_t droid_format; int32_t usage; /* Android usage. */ + uint32_t fb_id; }; typedef const struct cros_gralloc_handle *cros_gralloc_handle_t; diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index 12daf4b..1daba8d 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -44,7 +44,7 @@ uint32_t cros_gralloc_convert_format(int format) return DRM_FORMAT_NONE; } -cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle) +extern "C" cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle) { auto hnd = reinterpret_cast(handle); if (!hnd || hnd->magic != cros_gralloc_magic) diff --git a/cros_gralloc/cros_gralloc_helpers.h b/cros_gralloc/cros_gralloc_helpers.h index a55eebc..cd21ca1 100644 --- a/cros_gralloc/cros_gralloc_helpers.h +++ b/cros_gralloc/cros_gralloc_helpers.h @@ -20,7 +20,7 @@ constexpr uint32_t handle_data_size = uint32_t cros_gralloc_convert_format(int32_t format); -cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle); +extern "C" cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle); int32_t cros_gralloc_sync_wait(int32_t acquire_fence); diff --git a/cros_gralloc/gralloc0/drm_framebuffer.c b/cros_gralloc/gralloc0/drm_framebuffer.c new file mode 100644 index 0000000..509833e --- /dev/null +++ b/cros_gralloc/gralloc0/drm_framebuffer.c @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2017 lambdadroid (https://github.com/lambdadroid) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#define LOG_TAG "drm-fb" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "drm_framebuffer.h" + +#include "../cros_gralloc_handle.h" + +#define SWAP_INTERVAL 1 + +struct drm_framebuffer { + struct framebuffer_device_t device; + + int fd; + uint32_t connector_id, crtc_id; + drmModeModeInfo mode; + + uint32_t current_fb, next_fb; + drmEventContext evctx; +}; + +extern cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle); + +static drmModeConnectorPtr fb0_find_connector(int fd, drmModeResPtr res) +{ + drmModeConnectorPtr connector; + int i; + + connector = NULL; + for (i = 0; i < res->count_connectors; ++i) { + connector = drmModeGetConnector(fd, res->connectors[i]); + if (connector->connection == DRM_MODE_CONNECTED) { + break; + } + + drmModeFreeConnector(connector); + connector = NULL; + } + + return connector; +} + +static uint32_t fb0_find_crtc(int fd, drmModeResPtr res, drmModeConnectorPtr connector) +{ + drmModeEncoderPtr encoder; + int i; + + encoder = drmModeGetEncoder(fd, connector->encoders[0]); + for (i = 0; i < res->count_crtcs; ++i) { + if (encoder->possible_crtcs & (1 << i)) { + drmModeFreeEncoder(encoder); + return res->crtcs[i]; + } + } + + drmModeFreeEncoder(encoder); + return 0; +} + +static drmModeModeInfoPtr fb0_find_preferred_mode(drmModeConnectorPtr connector) +{ + int i; + drmModeModeInfoPtr mode = NULL; + + for (i = 0; i < connector->count_modes; ++i) { + mode = &connector->modes[i]; + if (mode->type & DRM_MODE_TYPE_PREFERRED) { + break; + } + } + + return mode; +} + +static void fb0_handle_page_flip( + __unused int fd, __unused unsigned int sequence, + __unused unsigned int tv_sec, __unused unsigned int tv_usec, + __unused void *data) +{ + struct drm_framebuffer *fb = data; + fb->current_fb = fb->next_fb; + fb->next_fb = 0; +} + +static int fb0_init(struct drm_framebuffer *fb) +{ + drmModeResPtr res; + drmModeConnectorPtr connector; + drmModeModeInfoPtr mode; + + res = drmModeGetResources(fb->fd); + + connector = fb0_find_connector(fb->fd, res); + if (!connector) { + ALOGE("No connector found"); + drmModeFreeResources(res); + return -ENODEV; + } + + fb->connector_id = connector->connector_id; + + fb->crtc_id = fb0_find_crtc(fb->fd, res, connector); + drmModeFreeResources(res); + if (!fb->crtc_id) { + ALOGE("No CRTC found"); + return -ENODEV; + } + + ALOGI("Connector: %d, CRTC: %d", fb->connector_id, fb->crtc_id); + + mode = fb0_find_preferred_mode(connector); + if (!mode) { + ALOGE("No preferred mode found"); + drmModeFreeConnector(connector); + return -ENODEV; + } + + fb->mode = *mode; + fb->current_fb = 0; + fb->next_fb = 0; + + *(uint32_t*) &fb->device.flags = 0; + *(uint32_t*) &fb->device.width = mode->hdisplay; + *(uint32_t*) &fb->device.height = mode->vdisplay; + *(int*) &fb->device.stride = mode->vdisplay; + *(int*) &fb->device.format = HAL_PIXEL_FORMAT_RGBA_8888; + *(float*) &fb->device.xdpi = mode->hdisplay * 25.4 / connector->mmWidth; + *(float*) &fb->device.ydpi = mode->vdisplay * 25.4 / connector->mmHeight; + *(float*) &fb->device.fps = mode->vrefresh; + *(int*) &fb->device.minSwapInterval = SWAP_INTERVAL; + *(int*) &fb->device.maxSwapInterval = SWAP_INTERVAL; + + memset(&fb->evctx, 0, sizeof(fb->evctx)); + fb->evctx.version = DRM_EVENT_CONTEXT_VERSION; + fb->evctx.page_flip_handler = fb0_handle_page_flip; + + drmModeFreeConnector(connector); + return 0; +} + +static void fb0_await_page_flip(struct drm_framebuffer *fb) +{ + if (fb->next_fb) { + /* There is another flip pending */ + drmHandleEvent(fb->fd, &fb->evctx); + if (fb->next_fb) { + ALOGE("drmHandleEvent returned without flipping"); + fb->current_fb = fb->next_fb; + fb->next_fb = 0; + } + } +} + +static int fb0_page_flip(struct drm_framebuffer *fb, int fb_id) +{ + int ret; + + /* Finish current page flip */ + fb0_await_page_flip(fb); + + ret = drmModePageFlip(fb->fd, fb->crtc_id, fb_id, + DRM_MODE_PAGE_FLIP_EVENT, fb); + if (ret) { + ALOGE("Failed to perform page flip: %d", ret); + if (errno != -EBUSY) { + fb->current_fb = 0; + } + return errno; + } else { + fb->next_fb = fb_id; + } + + return 0; +} + +static int fb0_enable_crtc(struct drm_framebuffer *fb, uint32_t fb_id) +{ + int ret = drmModeSetCrtc(fb->fd, fb->crtc_id, fb_id, 0, 0, + &fb->connector_id, 1, &fb->mode); + if (ret) { + ALOGE("Failed to enable CRTC: %d", ret); + } else { + fb->current_fb = fb_id; + } + + return ret; +} + +static int fb0_disable_crtc(struct drm_framebuffer *fb) +{ + int ret; + + /* Finish current page flip */ + fb0_await_page_flip(fb); + + ret = drmModeSetCrtc(fb->fd, fb->crtc_id, 0, 0, 0, NULL, 0, NULL); + if (ret) { + ALOGE("Failed to disable CRTC: %d", ret); + } else { + fb->current_fb = 0; + } + + return ret; +} + +static int fb0_post(struct framebuffer_device_t *fbdev, buffer_handle_t buffer) +{ + struct drm_framebuffer *fb = (struct drm_framebuffer *) fbdev; + cros_gralloc_handle_t handle = cros_gralloc_convert_handle(buffer); + uint32_t fb_id; + + if (!handle) { + return -EINVAL; + } + + fb_id = handle->fb_id; + if (!fb_id) { + ALOGE("Cannot post because handle does not have a framebuffer"); + return -EINVAL; + } + + if (fb->current_fb == fb_id) { + /* Already current */ + return 0; + } + + if (fb->current_fb) { + return fb0_page_flip(fb, fb_id); + } else { + return fb0_enable_crtc(fb, fb_id); + } +} + +static int fb0_enable_screen(struct framebuffer_device_t *fbdev, int enable) +{ + struct drm_framebuffer *fb = (struct drm_framebuffer *) fbdev; + ALOGI("Updating screen state: %d", enable); + + /* Only need to disable screen here, will be re-enabled with next post */ + if (!enable && fb->current_fb) { + return fb0_disable_crtc(fb); + } else { + return 0; + } +} + +static int fb0_composition_complete(__unused struct framebuffer_device_t *dev) +{ + //glFlush(); + return 0; +} + +static int fb0_set_swap_interval( + __unused struct framebuffer_device_t *window, int interval) +{ + if (interval != SWAP_INTERVAL) { + return -EINVAL; + } + return 0; +} + +static int fb0_close(struct hw_device_t *dev) +{ + free(dev); + return 0; +} + +int drm_framebuffer_init(int fd, struct drm_framebuffer **fb_out) +{ + struct drm_framebuffer *fb; + int ret; + + fb = calloc(1, sizeof(*fb)); + if (!fb) { + return -ENOMEM; + } + + fb->fd = fd; + ret = fb0_init(fb); + if (ret) { + free(fb); + return ret; + } + + fb->device.common.tag = HARDWARE_DEVICE_TAG; + fb->device.common.version = 0; + fb->device.common.close = fb0_close; + + fb->device.setSwapInterval = fb0_set_swap_interval; + fb->device.post = fb0_post; + fb->device.compositionComplete = fb0_composition_complete; + fb->device.enableScreen = fb0_enable_screen; + + *fb_out = fb; + return 0; +} + + +static uint32_t convert_android_to_drm_fb_format(uint32_t format) +{ + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + /* Avoid using alpha bits for the framebuffer. + * They are not supported on older Intel GPUs for primary planes. */ + case HAL_PIXEL_FORMAT_RGBX_8888: + return DRM_FORMAT_XBGR8888; + case HAL_PIXEL_FORMAT_RGB_888: + return DRM_FORMAT_BGR888; + case HAL_PIXEL_FORMAT_RGB_565: + return DRM_FORMAT_BGR565; + case HAL_PIXEL_FORMAT_BGRA_8888: + return DRM_FORMAT_ARGB8888; + default: + ALOGE("Unsupported framebuffer format: %u", format); + return 0; + } +} + +static int fb0_add_fb(struct drm_framebuffer *fb, cros_gralloc_handle_t handle, uint32_t handle_id) +{ + uint32_t pitches[4] = { handle->strides[0], 0, 0, 0 }; + uint32_t offsets[4] = { 0, 0, 0, 0 }; + uint32_t handles[4] = { handle_id, 0, 0, 0 }; + + return drmModeAddFB2(fb->fd, handle->width, handle->height, + convert_android_to_drm_fb_format(handle->droid_format), + handles, pitches, offsets, (uint32_t*) &handle->fb_id, 0); +} + +void drm_framebuffer_import(struct drm_framebuffer *fb, buffer_handle_t buffer) +{ + cros_gralloc_handle_t handle = cros_gralloc_convert_handle(buffer); + uint32_t handle_id; + + /* Ignore buffers that are not intended for usage with the framebuffer */ + if (!(handle->usage & GRALLOC_USAGE_HW_FB)) { + return; + } + + /* Lookup the handle for the prime fd. + * (The buffer should have already been imported by the gralloc HAL) */ + if (drmPrimeFDToHandle(fb->fd, handle->fds[0], &handle_id)) { + ALOGE("Failed to get handle from prime fd: %d", errno); + return; + } + + /* Add a framebuffer to the handle */ + if (fb0_add_fb(fb, handle, handle_id)) { + ALOGE("Failed to add framebuffer to handle: %d", errno); + } +} diff --git a/cros_gralloc/gralloc0/drm_framebuffer.h b/cros_gralloc/gralloc0/drm_framebuffer.h new file mode 100644 index 0000000..8234e36 --- /dev/null +++ b/cros_gralloc/gralloc0/drm_framebuffer.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 lambdadroid (https://github.com/lambdadroid) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _DRM_FRAMEBUFFER_H_ +#define _DRM_FRAMEBUFFER_H_ + +#include +#include + +__BEGIN_DECLS + +struct drm_framebuffer; + +int drm_framebuffer_init(int fd, struct drm_framebuffer **fb); +void drm_framebuffer_import(struct drm_framebuffer *fb, buffer_handle_t handle); + +__END_DECLS + +#endif /* _DRM_FRAMEBUFFER_H_ */ diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index 96593b8..20b61cf 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -9,11 +9,13 @@ #include #include #include +#include "drm_framebuffer.h" struct gralloc0_module { gralloc_module_t base; std::unique_ptr alloc; std::unique_ptr driver; + struct drm_framebuffer *fb; bool initialized; std::mutex initialization_mutex; }; @@ -57,7 +59,7 @@ static uint64_t gralloc0_convert_usage(int usage) /* HWC wants to use display hardware, but can defer to OpenGL. */ use_flags |= BO_USE_SCANOUT | BO_USE_TEXTURE; if (usage & GRALLOC_USAGE_HW_FB) - use_flags |= BO_USE_NONE; + use_flags |= BO_USE_FRAMEBUFFER; if (usage & GRALLOC_USAGE_EXTERNAL_DISP) /* * This flag potentially covers external display for the normal drivers (i915, @@ -142,7 +144,8 @@ static int gralloc0_close(struct hw_device_t *dev) return 0; } -static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc) +static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc, + bool framebuffer = false) { std::lock_guard lock(mod->initialization_mutex); @@ -150,7 +153,7 @@ static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc) return 0; mod->driver = std::make_unique(); - if (mod->driver->init()) { + if (framebuffer ? mod->driver->init_master() : mod->driver->init()) { drv_log("Failed to initialize driver.\n"); return -ENODEV; } @@ -165,15 +168,58 @@ static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc) mod->alloc->common.close = gralloc0_close; } + if (framebuffer) { + int ret = drm_framebuffer_init(mod->driver->get_fd(), &mod->fb); + if (ret) + return ret; + } + mod->initialized = true; return 0; } +static int gralloc0_open_fb0(struct gralloc0_module *mod, struct hw_device_t **dev) +{ + int ret; + + if (!mod->initialized) { + ret = gralloc0_init(mod, true, true); + if (ret) + return ret; + } + + if (!mod->fb) { + /* + * On Pie and above the FB HAL is opened before the Gralloc HAL. + * This has the advantage that we can open the DRM card node in this case, + * and open the render node in all other cases. + * + * On earlier Android versions this is not the case, so we need to make + * sure the FB HAL was actually initialized. + * + * TODO: Currently it does not attempt to set master on the opened render + * node. That means it will only work with DRM authentication disabled. + */ + std::lock_guard lock(mod->initialization_mutex); + drv_log("FB HAL opened after Gralloc HAL, we might not be DRM master!\n"); + + ret = drm_framebuffer_init(mod->driver->get_fd(), &mod->fb); + if (ret) + return ret; + } + + *dev = (struct hw_device_t *) mod->fb; + return 0; +} + static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct hw_device_t **dev) { auto const_module = reinterpret_cast(mod); auto module = const_cast(const_module); + if (!strcmp(name, GRALLOC_HARDWARE_FB0)) + return gralloc0_open_fb0(module, dev); + if (module->initialized) { *dev = &module->alloc->common; return 0; @@ -200,7 +246,10 @@ static int gralloc0_register_buffer(struct gralloc_module_t const *module, buffe if (gralloc0_init(mod, false)) return -ENODEV; - return mod->driver->retain(handle); + int ret = mod->driver->retain(handle); + if (ret == 0 && mod->fb) + drm_framebuffer_import(mod->fb, handle); + return ret; } static int gralloc0_unregister_buffer(struct gralloc_module_t const *module, buffer_handle_t handle) diff --git a/drv.h b/drv.h index d27e845..f73ba3d 100644 --- a/drv.h +++ b/drv.h @@ -38,6 +38,7 @@ extern "C" { #define BO_USE_RENDERSCRIPT (1ull << 16) #define BO_USE_TEXTURE (1ull << 17) #define BO_USE_HW_VIDEO_DECODER (1ull << 18) +#define BO_USE_FRAMEBUFFER (1ull << 19) /* Map flags */ diff --git a/drv_priv.h b/drv_priv.h index 719cd35..acb8242 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -79,7 +79,7 @@ struct backend { // clang-format off #define BO_USE_RENDER_MASK BO_USE_LINEAR | BO_USE_PROTECTED | BO_USE_RENDERING | \ BO_USE_RENDERSCRIPT | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | \ - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY | BO_USE_TEXTURE + BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY | BO_USE_TEXTURE | BO_USE_FRAMEBUFFER #define BO_USE_TEXTURE_MASK BO_USE_LINEAR | BO_USE_PROTECTED | BO_USE_RENDERSCRIPT | \ BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | \ diff --git a/i915.c b/i915.c index a88db6a..8c37e9d 100644 --- a/i915.c +++ b/i915.c @@ -171,6 +171,9 @@ static int i915_add_combinations(struct driver *drv) ARRAY_SIZE(tileable_texture_source_formats), &metadata, texture_use_flags); + /* TODO: Y tiling does not seem to work for framebuffers */ + render_use_flags &= ~BO_USE_FRAMEBUFFER; + metadata.tiling = I915_TILING_Y; metadata.priority = 3; metadata.modifier = I915_FORMAT_MOD_Y_TILED;