1 #include "pipe/p_context.h"
2 #include "pipe/p_state.h"
3 #include "util/u_format.h"
4 #include "util/u_memory.h"
5 #include "util/u_inlines.h"
7 #include "nouveau_drm_api.h"
9 #include "nouveau_drmif.h"
10 #include "nouveau_channel.h"
11 #include "nouveau_bo.h"
13 #include "nouveau/nouveau_winsys.h"
14 #include "nouveau/nouveau_screen.h"
16 static struct pipe_surface
*
17 dri_surface_from_handle(struct drm_api
*api
, struct pipe_screen
*pscreen
,
18 unsigned handle
, enum pipe_format format
,
19 unsigned width
, unsigned height
, unsigned pitch
)
21 struct pipe_surface
*ps
= NULL
;
22 struct pipe_texture
*pt
= NULL
;
23 struct pipe_texture tmpl
;
24 struct winsys_handle whandle
;
26 memset(&tmpl
, 0, sizeof(tmpl
));
27 tmpl
.tex_usage
= PIPE_TEXTURE_USAGE_SCANOUT
;
28 tmpl
.target
= PIPE_TEXTURE_2D
;
33 tmpl
.height0
= height
;
35 memset(&whandle
, 0, sizeof(whandle
));
36 whandle
.stride
= pitch
;
37 whandle
.handle
= handle
;
39 pt
= pscreen
->texture_from_handle(pscreen
, &tmpl
, &whandle
);
43 ps
= pscreen
->get_tex_surface(pscreen
, pt
, 0, 0, 0,
44 PIPE_BUFFER_USAGE_GPU_READ
|
45 PIPE_BUFFER_USAGE_GPU_WRITE
);
47 /* we don't need the texture from this point on */
48 pipe_texture_reference(&pt
, NULL
);
52 static struct pipe_surface
*
53 nouveau_dri1_front_surface(struct pipe_context
*pipe
)
55 return nouveau_winsys_screen(pipe
->screen
)->front
;
58 static struct dri1_api nouveau_dri1_api
= {
59 nouveau_dri1_front_surface
,
63 nouveau_drm_destroy_winsys(struct pipe_winsys
*s
)
65 struct nouveau_winsys
*nv_winsys
= nouveau_winsys(s
);
66 struct nouveau_screen
*nv_screen
= nouveau_screen(nv_winsys
->pscreen
);
67 nouveau_device_close(&nv_screen
->device
);
71 static struct pipe_screen
*
72 nouveau_drm_create_screen(struct drm_api
*api
, int fd
,
73 struct drm_create_screen_arg
*arg
)
75 struct dri1_create_screen_arg
*dri1
= (void *)arg
;
76 struct nouveau_winsys
*nvws
;
77 struct pipe_winsys
*ws
;
78 struct nouveau_device
*dev
= NULL
;
79 struct pipe_screen
*(*init
)(struct pipe_winsys
*,
80 struct nouveau_device
*);
83 ret
= nouveau_device_open_existing(&dev
, 0, fd
, 0);
87 switch (dev
->chipset
& 0xf0) {
91 init
= nvfx_screen_create
;
97 init
= nv50_screen_create
;
100 debug_printf("%s: unknown chipset nv%02x\n", __func__
,
105 nvws
= CALLOC_STRUCT(nouveau_winsys
);
107 nouveau_device_close(&dev
);
111 ws
->destroy
= nouveau_drm_destroy_winsys
;
113 nvws
->pscreen
= init(ws
, dev
);
114 if (!nvws
->pscreen
) {
119 if (arg
&& arg
->mode
== DRM_CREATE_DRI1
) {
120 struct nouveau_dri
*nvdri
= dri1
->ddx_info
;
121 enum pipe_format format
;
123 if (nvdri
->bpp
== 16)
124 format
= PIPE_FORMAT_B5G6R5_UNORM
;
126 format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
128 nvws
->front
= dri_surface_from_handle(api
, nvws
->pscreen
,
130 format
, nvdri
->width
,
135 debug_printf("%s: error referencing front buffer\n",
141 dri1
->api
= &nouveau_dri1_api
;
144 return nvws
->pscreen
;
147 struct drm_api drm_api_hooks
= {
149 .driver_name
= "nouveau",
150 .create_screen
= nouveau_drm_create_screen
,
155 return &drm_api_hooks
;