1 #include "main/glheader.h"
2 #include "glapi/glthread.h"
3 #include <GL/internal/glcore.h>
6 #include "state_tracker/st_public.h"
7 #include "pipe/p_defines.h"
8 #include "pipe/p_context.h"
10 #include "nouveau_context.h"
11 #include "nouveau_dri.h"
12 #include "nouveau_local.h"
13 #include "nouveau_screen.h"
14 #include "nouveau_winsys_pipe.h"
17 static const struct dri_debug_control debug_control
[] = {
21 int __nouveau_debug
= 0;
25 nouveau_context_create(const __GLcontextModes
*glVis
,
26 __DRIcontextPrivate
*driContextPriv
,
27 void *sharedContextPrivate
)
29 __DRIscreenPrivate
*driScrnPriv
= driContextPriv
->driScreenPriv
;
30 struct nouveau_screen
*nv_screen
= driScrnPriv
->private;
31 struct nouveau_context
*nv
= CALLOC_STRUCT(nouveau_context
);
32 struct nouveau_device_priv
*nvdev
;
33 struct pipe_context
*pipe
= NULL
;
34 struct st_context
*st_share
= NULL
;
37 if (sharedContextPrivate
) {
38 st_share
= ((struct nouveau_context
*)sharedContextPrivate
)->st
;
41 if ((ret
= nouveau_device_get_param(nv_screen
->device
,
42 NOUVEAU_GETPARAM_CHIPSET_ID
,
44 NOUVEAU_ERR("Error determining chipset id: %d\n", ret
);
48 if ((ret
= nouveau_channel_alloc(nv_screen
->device
,
49 0x8003d001, 0x8003d002,
51 NOUVEAU_ERR("Error creating GPU channel: %d\n", ret
);
55 driContextPriv
->driverPrivate
= (void *)nv
;
56 nv
->nv_screen
= nv_screen
;
57 nv
->dri_screen
= driScrnPriv
;
59 nvdev
= nouveau_device(nv_screen
->device
);
60 nvdev
->ctx
= driContextPriv
->hHWContext
;
61 nvdev
->lock
= (drmLock
*)&driScrnPriv
->pSAREA
->lock
;
63 driParseConfigFiles(&nv
->dri_option_cache
, &nv_screen
->option_cache
,
64 nv
->dri_screen
->myNum
, "nouveau");
66 __nouveau_debug
= driParseDebugString(getenv("NOUVEAU_DEBUG"),
70 /*XXX: Hack up a fake region and buffer object for front buffer.
71 * This will go away with TTM, replaced with a simple reference
72 * of the front buffer handle passed to us by the DDX.
75 struct pipe_surface
*fb_surf
;
76 struct nouveau_pipe_buffer
*fb_buf
;
77 struct nouveau_bo_priv
*fb_bo
;
79 fb_bo
= calloc(1, sizeof(struct nouveau_bo_priv
));
80 fb_bo
->drm
.offset
= nv_screen
->front_offset
;
81 fb_bo
->drm
.flags
= NOUVEAU_MEM_FB
;
82 fb_bo
->drm
.size
= nv_screen
->front_pitch
*
83 nv_screen
->front_height
;
85 fb_bo
->base
.flags
= NOUVEAU_BO_PIN
| NOUVEAU_BO_VRAM
;
86 fb_bo
->base
.offset
= fb_bo
->drm
.offset
;
87 fb_bo
->base
.handle
= (unsigned long)fb_bo
;
88 fb_bo
->base
.size
= fb_bo
->drm
.size
;
89 fb_bo
->base
.device
= nv_screen
->device
;
91 fb_buf
= calloc(1, sizeof(struct nouveau_pipe_buffer
));
92 fb_buf
->bo
= &fb_bo
->base
;
94 fb_surf
= calloc(1, sizeof(struct pipe_surface
));
95 fb_surf
->cpp
= nv_screen
->front_cpp
;
96 fb_surf
->pitch
= nv_screen
->front_pitch
/ fb_surf
->cpp
;
97 fb_surf
->height
= nv_screen
->front_height
;
98 fb_surf
->refcount
= 1;
99 fb_surf
->buffer
= &fb_buf
->base
;
101 nv
->frontbuffer
= fb_surf
;
104 if ((ret
= nouveau_grobj_alloc(nv
->channel
, 0x00000000, 0x30,
106 NOUVEAU_ERR("Error creating NULL object: %d\n", ret
);
109 nv
->next_handle
= 0x80000000;
111 if ((ret
= nouveau_notifier_alloc(nv
->channel
, nv
->next_handle
++, 1,
112 &nv
->sync_notifier
))) {
113 NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret
);
117 if (nv
->chipset
< 0x50)
118 ret
= nouveau_surface_init_nv04(nv
);
120 ret
= nouveau_surface_init_nv50(nv
);
125 if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) {
126 pipe
= nouveau_pipe_create(nv
);
128 NOUVEAU_ERR("Couldn't create hw pipe\n");
132 NOUVEAU_MSG("Using softpipe\n");
133 pipe
= nouveau_create_softpipe(nv
);
135 NOUVEAU_ERR("Error creating pipe, bailing\n");
141 nv
->st
= st_create_context(pipe
, glVis
, st_share
);
146 nouveau_context_destroy(__DRIcontextPrivate
*driContextPriv
)
148 struct nouveau_context
*nv
= driContextPriv
->driverPrivate
;
152 st_flush(nv
->st
, PIPE_FLUSH_WAIT
);
153 st_destroy_context(nv
->st
);
155 nouveau_grobj_free(&nv
->NvCtxSurf2D
);
156 nouveau_grobj_free(&nv
->NvImageBlit
);
157 nouveau_channel_free(&nv
->channel
);
163 nouveau_context_bind(__DRIcontextPrivate
*driContextPriv
,
164 __DRIdrawablePrivate
*driDrawPriv
,
165 __DRIdrawablePrivate
*driReadPriv
)
167 struct nouveau_context
*nv
;
168 struct nouveau_framebuffer
*draw
, *read
;
170 if (!driContextPriv
) {
171 st_make_current(NULL
, NULL
, NULL
);
175 nv
= driContextPriv
->driverPrivate
;
176 draw
= driDrawPriv
->driverPrivate
;
177 read
= driReadPriv
->driverPrivate
;
179 st_make_current(nv
->st
, draw
->stfb
, read
->stfb
);
181 if ((nv
->dri_drawable
!= driDrawPriv
) ||
182 (nv
->last_stamp
!= driDrawPriv
->lastStamp
)) {
183 nv
->dri_drawable
= driDrawPriv
;
184 st_resize_framebuffer(draw
->stfb
, driDrawPriv
->w
,
186 nv
->last_stamp
= driDrawPriv
->lastStamp
;
189 if (driDrawPriv
!= driReadPriv
) {
190 st_resize_framebuffer(read
->stfb
, driReadPriv
->w
,
198 nouveau_context_unbind(__DRIcontextPrivate
*driContextPriv
)
200 struct nouveau_context
*nv
= driContextPriv
->driverPrivate
;