1 #include <pipe/p_defines.h>
2 #include <pipe/p_context.h>
3 #include <pipe/p_screen.h>
4 #include <util/u_memory.h>
5 #include "nouveau_context.h"
6 #include "nouveau_dri.h"
7 #include "nouveau_local.h"
8 #include "nouveau_screen.h"
9 #include "nouveau_winsys_pipe.h"
12 nouveau_channel_context_destroy(struct nouveau_channel_context
*nvc
)
14 nouveau_channel_free(&nvc
->channel
);
19 static struct nouveau_channel_context
*
20 nouveau_channel_context_create(struct nouveau_device
*dev
)
22 struct nouveau_channel_context
*nvc
;
25 nvc
= CALLOC_STRUCT(nouveau_channel_context
);
29 if ((ret
= nouveau_channel_alloc(dev
, 0x8003d001, 0x8003d002,
31 NOUVEAU_ERR("Error creating GPU channel: %d\n", ret
);
32 nouveau_channel_context_destroy(nvc
);
36 nvc
->next_handle
= 0x77000000;
41 nouveau_context_init(struct nouveau_screen
*nv_screen
,
42 drm_context_t hHWContext
, drmLock
*sarea_lock
,
43 struct nouveau_context
*nv_share
,
44 struct nouveau_context
*nv
)
46 struct pipe_context
*pipe
= NULL
;
47 struct nouveau_channel_context
*nvc
= NULL
;
48 struct nouveau_device
*dev
= nv_screen
->device
;
51 switch (dev
->chipset
& 0xf0) {
68 NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev
->chipset
);
72 nv
->nv_screen
= nv_screen
;
75 struct nouveau_device_priv
*nvdev
= nouveau_device(dev
);
77 nvdev
->ctx
= hHWContext
;
78 nvdev
->lock
= sarea_lock
;
81 /* Attempt to share a single channel between multiple contexts from
88 /*XXX: temporary - disable multi-context/single-channel on pre-NV4x */
89 switch (dev
->chipset
& 0xf0) {
104 nvc
= nouveau_channel_context_create(dev
);
106 NOUVEAU_ERR("Failed initialising GPU context\n");
109 nv_screen
->nvc
= nvc
;
115 /* Find a free slot for a pipe context, allocate a new one if needed */
117 for (i
= 0; i
< nvc
->nr_pctx
; i
++) {
118 if (nvc
->pctx
[i
] == NULL
) {
124 if (nv
->pctx_id
< 0) {
125 nv
->pctx_id
= nvc
->nr_pctx
++;
128 sizeof(struct pipe_context
*) * nvc
->nr_pctx
);
132 if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) {
133 struct pipe_screen
*pscreen
;
135 pipe
= nouveau_pipe_create(nv
);
137 NOUVEAU_ERR("Couldn't create hw pipe\n");
138 pscreen
= nvc
->pscreen
;
140 nv
->cap
.hw_vertex_buffer
=
141 pscreen
->get_param(pscreen
, NOUVEAU_CAP_HW_VTXBUF
);
142 nv
->cap
.hw_index_buffer
=
143 pscreen
->get_param(pscreen
, NOUVEAU_CAP_HW_IDXBUF
);
147 NOUVEAU_MSG("Using softpipe\n");
148 pipe
= nouveau_create_softpipe(nv
);
150 NOUVEAU_ERR("Error creating pipe, bailing\n");
156 struct pipe_texture
*fb_tex
;
157 struct pipe_surface
*fb_surf
;
158 struct nouveau_pipe_buffer
*fb_buf
;
159 enum pipe_format format
;
161 fb_buf
= calloc(1, sizeof(struct nouveau_pipe_buffer
));
162 fb_buf
->base
.refcount
= 1;
163 fb_buf
->base
.usage
= PIPE_BUFFER_USAGE_PIXEL
;
165 nouveau_bo_fake(dev
, nv_screen
->front_offset
, NOUVEAU_BO_VRAM
,
166 nv_screen
->front_pitch
*nv_screen
->front_height
,
169 if (nv_screen
->front_cpp
== 4)
170 format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
172 format
= PIPE_FORMAT_R5G6B5_UNORM
;
174 fb_surf
= nouveau_surface_buffer_ref(nv
, &fb_buf
->base
, format
,
175 nv_screen
->front_pitch
/
176 nv_screen
->front_cpp
,
177 nv_screen
->front_height
,
178 nv_screen
->front_pitch
,
181 nv
->frontbuffer
= fb_surf
;
182 nv
->frontbuffer_texture
= fb_tex
;
190 nouveau_context_cleanup(struct nouveau_context
*nv
)
192 struct nouveau_channel_context
*nvc
= nv
->nvc
;
196 if (nv
->pctx_id
>= 0) {
197 nvc
->pctx
[nv
->pctx_id
] = NULL
;
198 if (--nvc
->refcount
<= 0) {
199 nouveau_channel_context_destroy(nvc
);
200 nv
->nv_screen
->nvc
= NULL
;
204 /* XXX: Who cleans up the pipe? */