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_resource
*pt
= NULL
;
23 struct pipe_resource tmpl
;
24 struct winsys_handle whandle
;
25 unsigned bind
= (PIPE_BIND_SCANOUT
|
26 PIPE_BIND_RENDER_TARGET
|
27 PIPE_BIND_BLIT_DESTINATION
|
28 PIPE_BIND_BLIT_SOURCE
);
30 memset(&tmpl
, 0, sizeof(tmpl
));
32 tmpl
.target
= PIPE_TEXTURE_2D
;
37 tmpl
.height0
= height
;
39 memset(&whandle
, 0, sizeof(whandle
));
40 whandle
.stride
= pitch
;
41 whandle
.handle
= handle
;
43 pt
= pscreen
->resource_from_handle(pscreen
, &tmpl
, &whandle
);
47 ps
= pscreen
->get_tex_surface(pscreen
, pt
, 0, 0, 0, bind
);
49 /* we don't need the texture from this point on */
50 pipe_resource_reference(&pt
, NULL
);
54 static struct pipe_surface
*
55 nouveau_dri1_front_surface(struct pipe_context
*pipe
)
57 return nouveau_winsys_screen(pipe
->screen
)->front
;
60 static struct dri1_api nouveau_dri1_api
= {
61 nouveau_dri1_front_surface
,
65 nouveau_drm_destroy_winsys(struct pipe_winsys
*s
)
67 struct nouveau_winsys
*nv_winsys
= nouveau_winsys(s
);
68 struct nouveau_screen
*nv_screen
= nouveau_screen(nv_winsys
->pscreen
);
69 nouveau_device_close(&nv_screen
->device
);
73 static struct pipe_screen
*
74 nouveau_drm_create_screen(struct drm_api
*api
, int fd
,
75 struct drm_create_screen_arg
*arg
)
77 struct dri1_create_screen_arg
*dri1
= (void *)arg
;
78 struct nouveau_winsys
*nvws
;
79 struct pipe_winsys
*ws
;
80 struct nouveau_device
*dev
= NULL
;
81 struct pipe_screen
*(*init
)(struct pipe_winsys
*,
82 struct nouveau_device
*);
85 ret
= nouveau_device_open_existing(&dev
, 0, fd
, 0);
89 switch (dev
->chipset
& 0xf0) {
93 init
= nvfx_screen_create
;
99 init
= nv50_screen_create
;
102 debug_printf("%s: unknown chipset nv%02x\n", __func__
,
107 nvws
= CALLOC_STRUCT(nouveau_winsys
);
109 nouveau_device_close(&dev
);
113 ws
->destroy
= nouveau_drm_destroy_winsys
;
115 nvws
->pscreen
= init(ws
, dev
);
116 if (!nvws
->pscreen
) {
121 if (arg
&& arg
->mode
== DRM_CREATE_DRI1
) {
122 struct nouveau_dri
*nvdri
= dri1
->ddx_info
;
123 enum pipe_format format
;
125 if (nvdri
->bpp
== 16)
126 format
= PIPE_FORMAT_B5G6R5_UNORM
;
128 format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
130 nvws
->front
= dri_surface_from_handle(api
, nvws
->pscreen
,
132 format
, nvdri
->width
,
137 debug_printf("%s: error referencing front buffer\n",
143 dri1
->api
= &nouveau_dri1_api
;
146 return nvws
->pscreen
;
149 static struct drm_api nouveau_drm_api_hooks
= {
151 .driver_name
= "nouveau",
152 .create_screen
= nouveau_drm_create_screen
,
158 return &nouveau_drm_api_hooks
;