Merge commit 'origin/gallium-master-merge'
[mesa.git] / src / gallium / winsys / drm / nouveau / common / nouveau_winsys.c
1 #include "util/u_memory.h"
2
3 #include "nouveau_context.h"
4 #include "nouveau_screen.h"
5 #include "nouveau_winsys_pipe.h"
6
7 #include "nouveau/nouveau_winsys.h"
8
9 static int
10 nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count,
11 struct nouveau_notifier **notify)
12 {
13 struct nouveau_context *nv = nvws->nv;
14
15 return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++,
16 count, notify);
17 }
18
19 static int
20 nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass,
21 struct nouveau_grobj **grobj)
22 {
23 struct nouveau_context *nv = nvws->nv;
24 struct nouveau_channel *chan = nv->nvc->channel;
25 int ret;
26
27 ret = nouveau_grobj_alloc(chan, nv->nvc->next_handle++,
28 grclass, grobj);
29 if (ret)
30 return ret;
31
32 BEGIN_RING(chan, *grobj, 0x0000, 1);
33 OUT_RING (chan, (*grobj)->handle);
34 (*grobj)->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
35 return 0;
36 }
37
38 static int
39 nouveau_pipe_push_reloc(struct nouveau_winsys *nvws, void *ptr,
40 struct pipe_buffer *buf, uint32_t data,
41 uint32_t flags, uint32_t vor, uint32_t tor)
42 {
43 struct nouveau_bo *bo = nouveau_pipe_buffer(buf)->bo;
44
45 return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, bo,
46 data, flags, vor, tor);
47 }
48
49 static int
50 nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size,
51 struct pipe_fence_handle **fence)
52 {
53 if (fence)
54 *fence = NULL;
55
56 return nouveau_pushbuf_flush(nvws->channel, size);
57 }
58
59 static struct nouveau_bo *
60 nouveau_pipe_get_bo(struct pipe_buffer *pb)
61 {
62 return nouveau_pipe_buffer(pb)->bo;
63 }
64
65 struct pipe_context *
66 nouveau_pipe_create(struct nouveau_context *nv)
67 {
68 struct nouveau_channel_context *nvc = nv->nvc;
69 struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys);
70 struct pipe_screen *(*hws_create)(struct pipe_winsys *,
71 struct nouveau_winsys *);
72 struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned);
73 struct pipe_winsys *ws;
74 unsigned chipset = nv->nv_screen->device->chipset;
75
76 if (!nvws)
77 return NULL;
78
79 switch (chipset & 0xf0) {
80 case 0x00:
81 hws_create = nv04_screen_create;
82 hw_create = nv04_create;
83 break;
84 case 0x10:
85 hws_create = nv10_screen_create;
86 hw_create = nv10_create;
87 break;
88 case 0x20:
89 hws_create = nv20_screen_create;
90 hw_create = nv20_create;
91 break;
92 case 0x30:
93 hws_create = nv30_screen_create;
94 hw_create = nv30_create;
95 break;
96 case 0x40:
97 case 0x60:
98 hws_create = nv40_screen_create;
99 hw_create = nv40_create;
100 break;
101 case 0x50:
102 case 0x80:
103 case 0x90:
104 hws_create = nv50_screen_create;
105 hw_create = nv50_create;
106 break;
107 default:
108 NOUVEAU_ERR("Unknown chipset NV%02x\n", chipset);
109 return NULL;
110 }
111
112 nvws->nv = nv;
113 nvws->channel = nv->nvc->channel;
114
115 nvws->res_init = nouveau_resource_init;
116 nvws->res_alloc = nouveau_resource_alloc;
117 nvws->res_free = nouveau_resource_free;
118
119 nvws->push_reloc = nouveau_pipe_push_reloc;
120 nvws->push_flush = nouveau_pipe_push_flush;
121
122 nvws->grobj_alloc = nouveau_pipe_grobj_alloc;
123 nvws->grobj_free = nouveau_grobj_free;
124
125 nvws->notifier_alloc = nouveau_pipe_notifier_alloc;
126 nvws->notifier_free = nouveau_notifier_free;
127 nvws->notifier_reset = nouveau_notifier_reset;
128 nvws->notifier_status = nouveau_notifier_status;
129 nvws->notifier_retval = nouveau_notifier_return_val;
130 nvws->notifier_wait = nouveau_notifier_wait_status;
131
132 nvws->get_bo = nouveau_pipe_get_bo;
133
134 ws = nouveau_create_pipe_winsys(nv);
135
136 if (!nvc->pscreen)
137 nvc->pscreen = hws_create(ws, nvws);
138 nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id);
139 return nvc->pctx[nv->pctx_id];
140 }
141