g3dvl: Use sobel filter for chroma interpolation
[mesa/nouveau-pmpeg.git] / src / gallium / state_trackers / gbm / gbm_drm.c
blobd4baf87096a76233d55b524b0f7d1d3f13fed7e7
1 /*
2 * Copyright © 2011 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
24 * Authors:
25 * Benjamin Franzke <benjaminfranzke@googlemail.com>
28 #include "util/u_memory.h"
29 #include "util/u_inlines.h"
31 #include "state_tracker/drm_driver.h"
33 #include <unistd.h>
34 #include <sys/types.h>
36 #include "gbm_gallium_drmint.h"
38 static INLINE enum pipe_format
39 gbm_format_to_gallium(enum gbm_bo_format format)
41 switch (format) {
42 case GBM_BO_FORMAT_XRGB8888:
43 return PIPE_FORMAT_B8G8R8X8_UNORM;
44 case GBM_BO_FORMAT_ARGB8888:
45 return PIPE_FORMAT_B8G8R8A8_UNORM;
46 default:
47 return PIPE_FORMAT_NONE;
50 return PIPE_FORMAT_NONE;
53 static INLINE uint
54 gbm_usage_to_gallium(uint usage)
56 uint resource_usage = 0;
58 if (usage & GBM_BO_USE_SCANOUT)
59 resource_usage |= PIPE_BIND_SCANOUT;
61 if (usage & GBM_BO_USE_RENDERING)
62 resource_usage |= PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
64 if (usage & GBM_BO_USE_CURSOR_64X64)
65 resource_usage |= PIPE_BIND_CURSOR;
67 return resource_usage;
70 static int
71 gbm_gallium_drm_is_format_supported(struct gbm_device *gbm,
72 enum gbm_bo_format format,
73 uint32_t usage)
75 struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
76 enum pipe_format pf;
78 pf = gbm_format_to_gallium(format);
79 if (pf == PIPE_FORMAT_NONE)
80 return 0;
82 if (!gdrm->screen->is_format_supported(gdrm->screen, PIPE_TEXTURE_2D, pf, 0,
83 gbm_usage_to_gallium(usage)))
84 return 0;
86 if (usage & GBM_BO_USE_SCANOUT && format != GBM_BO_FORMAT_XRGB8888)
87 return 0;
89 return 1;
92 static void
93 gbm_gallium_drm_bo_destroy(struct gbm_bo *_bo)
95 struct gbm_gallium_drm_bo *bo = gbm_gallium_drm_bo(_bo);
97 pipe_resource_reference(&bo->resource, NULL);
98 free(bo);
101 static struct gbm_bo *
102 gbm_gallium_drm_bo_create_from_egl_image(struct gbm_device *gbm,
103 void *egl_dpy, void *egl_image,
104 uint32_t width, uint32_t height,
105 uint32_t usage)
107 struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
108 struct gbm_gallium_drm_bo *bo;
109 struct winsys_handle whandle;
111 if (!gdrm->lookup_egl_image)
112 return NULL;
114 bo = CALLOC_STRUCT(gbm_gallium_drm_bo);
115 if (bo == NULL)
116 return NULL;
118 bo->resource = gdrm->lookup_egl_image(gdrm->lookup_egl_image_data,
119 egl_image);
120 if (bo->resource == NULL) {
121 FREE(bo);
122 return NULL;
125 bo->base.base.gbm = gbm;
126 bo->base.base.width = width;
127 bo->base.base.height = height;
129 memset(&whandle, 0, sizeof(whandle));
130 whandle.type = DRM_API_HANDLE_TYPE_KMS;
131 gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle);
133 bo->base.base.handle.u32 = whandle.handle;
134 bo->base.base.pitch = whandle.stride;
136 return &bo->base.base;
139 static struct gbm_bo *
140 gbm_gallium_drm_bo_create(struct gbm_device *gbm,
141 uint32_t width, uint32_t height,
142 enum gbm_bo_format format, uint32_t usage)
144 struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
145 struct gbm_gallium_drm_bo *bo;
146 struct pipe_resource templ;
147 struct winsys_handle whandle;
148 enum pipe_format pf;
150 bo = CALLOC_STRUCT(gbm_gallium_drm_bo);
151 if (bo == NULL)
152 return NULL;
154 bo->base.base.gbm = gbm;
155 bo->base.base.width = width;
156 bo->base.base.height = height;
158 pf = gbm_format_to_gallium(format);
159 if (pf == PIPE_FORMAT_NONE)
160 return NULL;
162 memset(&templ, 0, sizeof(templ));
163 templ.bind = gbm_usage_to_gallium(usage);
164 templ.format = pf;
165 templ.target = PIPE_TEXTURE_2D;
166 templ.last_level = 0;
167 templ.width0 = width;
168 templ.height0 = height;
169 templ.depth0 = 1;
170 templ.array_size = 1;
172 bo->resource = gdrm->screen->resource_create(gdrm->screen, &templ);
173 if (bo->resource == NULL) {
174 FREE(bo);
175 return NULL;
178 memset(&whandle, 0, sizeof(whandle));
179 whandle.type = DRM_API_HANDLE_TYPE_KMS;
180 gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle);
182 bo->base.base.handle.u32 = whandle.handle;
183 bo->base.base.pitch = whandle.stride;
185 return &bo->base.base;
188 static void
189 gbm_gallium_drm_destroy(struct gbm_device *gbm)
191 struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
193 gdrm->screen->destroy(gdrm->screen);
195 FREE(gdrm->base.driver_name);
197 FREE(gdrm);
200 struct gbm_device *
201 gbm_gallium_drm_device_create(int fd)
203 struct gbm_gallium_drm_device *gdrm;
204 int ret;
206 gdrm = calloc(1, sizeof *gdrm);
208 gdrm->base.base.fd = fd;
209 gdrm->base.base.bo_create = gbm_gallium_drm_bo_create;
210 gdrm->base.base.bo_create_from_egl_image =
211 gbm_gallium_drm_bo_create_from_egl_image;
212 gdrm->base.base.bo_destroy = gbm_gallium_drm_bo_destroy;
213 gdrm->base.base.is_format_supported = gbm_gallium_drm_is_format_supported;
214 gdrm->base.base.destroy = gbm_gallium_drm_destroy;
216 gdrm->base.type = GBM_DRM_DRIVER_TYPE_GALLIUM;
217 gdrm->base.base.name = "drm";
219 ret = gallium_screen_create(gdrm);
220 if (ret) {
221 free(gdrm);
222 return NULL;
225 return &gdrm->base.base;