+static int
+dri_screen_create_swrast(struct gbm_dri_device *dri)
+{
+ int ret;
+
+ dri->driver_name = strdup("swrast");
+ if (dri->driver_name == NULL)
+ return -1;
+
+ ret = dri_load_driver_swrast(dri);
+ if (ret) {
+ fprintf(stderr, "failed to load swrast driver\n");
+ return ret;
+ }
+
+ dri->loader_extensions = gbm_dri_screen_extensions;
+
+ if (dri->swrast == NULL)
+ return -1;
+
+ if (dri->swrast->base.version >= 4) {
+ dri->screen = dri->swrast->createNewScreen2(0, dri->loader_extensions,
+ dri->driver_extensions,
+ &dri->driver_configs, dri);
+ } else {
+ dri->screen = dri->swrast->createNewScreen(0, dri->loader_extensions,
+ &dri->driver_configs, dri);
+ }
+ if (dri->screen == NULL)
+ return -1;
+
+ dri->lookup_image = NULL;
+ dri->lookup_user_data = NULL;
+
+ return 0;
+}
+
+static int
+dri_screen_create(struct gbm_dri_device *dri)
+{
+ char *driver_name;
+
+ driver_name = loader_get_driver_for_fd(dri->base.fd);
+ if (!driver_name)
+ return -1;
+
+ return dri_screen_create_dri2(dri, driver_name);
+}
+
+static int
+dri_screen_create_sw(struct gbm_dri_device *dri)
+{
+ char *driver_name;
+ int ret;
+
+ driver_name = strdup("kms_swrast");
+ if (!driver_name)
+ return -errno;
+
+ ret = dri_screen_create_dri2(dri, driver_name);
+ if (ret == 0)
+ return ret;
+
+ return dri_screen_create_swrast(dri);
+}
+
+static const struct gbm_dri_visual gbm_dri_visuals_table[] = {
+ {
+ GBM_FORMAT_R8, __DRI_IMAGE_FORMAT_R8,
+ { 0x000000ff, 0x00000000, 0x00000000, 0x00000000 },
+ },
+ {
+ GBM_FORMAT_GR88, __DRI_IMAGE_FORMAT_GR88,
+ { 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000 },
+ },
+ {
+ GBM_FORMAT_ARGB1555, __DRI_IMAGE_FORMAT_ARGB1555,
+ { 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 },
+ },
+ {
+ GBM_FORMAT_RGB565, __DRI_IMAGE_FORMAT_RGB565,
+ { 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 },
+ },
+ {
+ GBM_FORMAT_XRGB8888, __DRI_IMAGE_FORMAT_XRGB8888,
+ { 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 },
+ },
+ {
+ GBM_FORMAT_ARGB8888, __DRI_IMAGE_FORMAT_ARGB8888,
+ { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
+ },
+ {
+ GBM_FORMAT_XBGR8888, __DRI_IMAGE_FORMAT_XBGR8888,
+ { 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 },
+ },
+ {
+ GBM_FORMAT_ABGR8888, __DRI_IMAGE_FORMAT_ABGR8888,
+ { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
+ },
+ {
+ GBM_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XRGB2101010,
+ { 0x3ff00000, 0x000ffc00, 0x000003ff, 0x00000000 },
+ },
+ {
+ GBM_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ARGB2101010,
+ { 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 },
+ },
+ {
+ GBM_FORMAT_XBGR2101010, __DRI_IMAGE_FORMAT_XBGR2101010,
+ { 0x000003ff, 0x000ffc00, 0x3ff00000, 0x00000000 },
+ },
+ {
+ GBM_FORMAT_ABGR2101010, __DRI_IMAGE_FORMAT_ABGR2101010,
+ { 0x000003ff, 0x000ffc00, 0x3ff00000, 0xc0000000 },
+ },
+};
+
+static int
+gbm_format_to_dri_format(uint32_t gbm_format)
+{
+ int i;
+
+ gbm_format = gbm_format_canonicalize(gbm_format);
+ for (i = 0; i < ARRAY_SIZE(gbm_dri_visuals_table); i++) {
+ if (gbm_dri_visuals_table[i].gbm_format == gbm_format)
+ return gbm_dri_visuals_table[i].dri_image_format;
+ }
+
+ return 0;
+}
+
+static uint32_t
+gbm_dri_to_gbm_format(int dri_format)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(gbm_dri_visuals_table); i++) {
+ if (gbm_dri_visuals_table[i].dri_image_format == dri_format)
+ return gbm_dri_visuals_table[i].gbm_format;
+ }
+
+ return 0;
+}
+