1 #include "util/u_memory.h"
3 #include "nouveau_drm_api.h"
4 #include "nouveau_winsys_pipe.h"
6 #include "nouveau_drmif.h"
7 #include "nouveau_channel.h"
8 #include "nouveau_bo.h"
10 static struct pipe_screen
*
11 nouveau_drm_create_screen(int fd
, int pciid
)
13 struct pipe_winsys
*ws
;
14 struct nouveau_winsys
*nvws
;
15 struct nouveau_device
*dev
= NULL
;
16 struct pipe_screen
*(*init
)(struct pipe_winsys
*,
17 struct nouveau_winsys
*);
20 ret
= nouveau_device_open_existing(&dev
, 0, fd
, 0);
24 switch (dev
->chipset
& 0xf0) {
26 init
= nv04_screen_create
;
29 init
= nv10_screen_create
;
32 init
= nv20_screen_create
;
35 init
= nv30_screen_create
;
39 init
= nv40_screen_create
;
44 init
= nv50_screen_create
;
47 debug_printf("%s: unknown chipset nv%02x\n", __func__
,
52 ws
= nouveau_pipe_winsys_new(dev
);
54 nouveau_device_close(&dev
);
58 nvws
= nouveau_winsys_new(ws
);
64 nouveau_pipe_winsys(ws
)->pscreen
= init(ws
, nvws
);
65 if (!nouveau_pipe_winsys(ws
)->pscreen
) {
70 return nouveau_pipe_winsys(ws
)->pscreen
;
73 static struct pipe_context
*
74 nouveau_drm_create_context(struct pipe_screen
*pscreen
)
76 struct nouveau_pipe_winsys
*nvpws
= nouveau_screen(pscreen
);
77 struct pipe_context
*(*init
)(struct pipe_screen
*, unsigned);
78 unsigned chipset
= nvpws
->channel
->device
->chipset
;
81 switch (chipset
& 0xf0) {
104 debug_printf("%s: unknown chipset nv%02x\n", __func__
, chipset
);
108 /* Find a free slot for a pipe context, allocate a new one if needed */
109 for (i
= 0; i
< nvpws
->nr_pctx
; i
++) {
110 if (nvpws
->pctx
[i
] == NULL
)
114 if (i
== nvpws
->nr_pctx
) {
116 nvpws
->pctx
= realloc(nvpws
->pctx
,
117 sizeof(*nvpws
->pctx
) * nvpws
->nr_pctx
);
120 nvpws
->pctx
[i
] = init(pscreen
, i
);
121 return nvpws
->pctx
[i
];
125 nouveau_drm_pb_from_pt(struct pipe_texture
*pt
, struct pipe_buffer
**ppb
,
131 static struct pipe_buffer
*
132 nouveau_drm_pb_from_handle(struct pipe_screen
*pscreen
, const char *name
,
135 struct nouveau_pipe_winsys
*nvpws
= nouveau_screen(pscreen
);
136 struct nouveau_device
*dev
= nvpws
->channel
->device
;
137 struct nouveau_pipe_buffer
*nvpb
;
140 nvpb
= CALLOC_STRUCT(nouveau_pipe_buffer
);
144 ret
= nouveau_bo_handle_ref(dev
, handle
, &nvpb
->bo
);
146 debug_printf("%s: ref name 0x%08x failed with %d\n",
147 __func__
, handle
, ret
);
152 pipe_reference_init(&nvpb
->base
.reference
, 1);
153 nvpb
->base
.screen
= pscreen
;
154 nvpb
->base
.alignment
= 0;
155 nvpb
->base
.usage
= PIPE_BUFFER_USAGE_GPU_READ_WRITE
|
156 PIPE_BUFFER_USAGE_CPU_READ_WRITE
;
157 nvpb
->base
.size
= nvpb
->bo
->size
;
162 nouveau_drm_handle_from_pb(struct pipe_screen
*pscreen
, struct pipe_buffer
*pb
,
165 struct nouveau_pipe_buffer
*nvpb
= nouveau_pipe_buffer(pb
);
170 *handle
= nvpb
->bo
->handle
;
175 nouveau_drm_name_from_pb(struct pipe_screen
*pscreen
, struct pipe_buffer
*pb
,
178 struct nouveau_pipe_buffer
*nvpb
= nouveau_pipe_buffer(pb
);
183 return nouveau_bo_handle_get(nvpb
->bo
, handle
) == 0;
186 struct drm_api drm_api_hooks
= {
187 .create_screen
= nouveau_drm_create_screen
,
188 .create_context
= nouveau_drm_create_context
,
189 .buffer_from_texture
= nouveau_drm_pb_from_pt
,
190 .buffer_from_handle
= nouveau_drm_pb_from_handle
,
191 .handle_from_buffer
= nouveau_drm_handle_from_pb
,
192 .global_handle_from_buffer
= nouveau_drm_name_from_pb
,