1 #include "main/glheader.h"
2 #include "glapi/glthread.h"
3 #include <GL/internal/glcore.h>
5 #include "state_tracker/st_public.h"
6 #include "pipe/p_defines.h"
7 #include "pipe/p_context.h"
9 #include "nouveau_context.h"
10 #include "nouveau_dri.h"
11 #include "nouveau_local.h"
12 #include "nouveau_screen.h"
13 #include "nouveau_winsys_pipe.h"
15 #define need_GL_ARB_fragment_program
16 #define need_GL_ARB_multisample
17 #define need_GL_ARB_occlusion_query
18 #define need_GL_ARB_point_parameters
19 #define need_GL_ARB_texture_compression
20 #define need_GL_ARB_vertex_program
21 #define need_GL_ARB_vertex_buffer_object
22 #define need_GL_EXT_compiled_vertex_array
23 #define need_GL_EXT_fog_coord
24 #define need_GL_EXT_secondary_color
25 #define need_GL_EXT_framebuffer_object
26 #include "extension_helper.h"
28 const struct dri_extension common_extensions
[] =
33 const struct dri_extension nv40_extensions
[] =
35 { "GL_ARB_fragment_program", NULL
},
36 { "GL_ARB_multisample", GL_ARB_multisample_functions
},
37 { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions
},
38 { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions
},
39 { "GL_ARB_texture_border_clamp", NULL
},
40 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions
},
41 { "GL_ARB_texture_cube_map", NULL
},
42 { "GL_ARB_texture_env_add", NULL
},
43 { "GL_ARB_texture_env_combine", NULL
},
44 { "GL_ARB_texture_env_crossbar", NULL
},
45 { "GL_ARB_texture_env_dot3", NULL
},
46 { "GL_ARB_texture_mirrored_repeat", NULL
},
47 { "GL_ARB_texture_non_power_of_two", NULL
},
48 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions
},
49 { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions
},
50 { "GL_ATI_texture_env_combine3", NULL
},
51 { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions
},
52 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions
},
53 { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions
},
54 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions
},
55 { "GL_EXT_texture_edge_clamp", NULL
},
56 { "GL_EXT_texture_env_add", NULL
},
57 { "GL_EXT_texture_env_combine", NULL
},
58 { "GL_EXT_texture_env_dot3", NULL
},
59 { "GL_EXT_texture_mirror_clamp", NULL
},
60 { "GL_NV_texture_rectangle", NULL
},
65 static const struct dri_debug_control debug_control
[] = {
69 int __nouveau_debug
= 0;
73 nouveau_context_create(const __GLcontextModes
*glVis
,
74 __DRIcontextPrivate
*driContextPriv
,
75 void *sharedContextPrivate
)
77 __DRIscreenPrivate
*driScrnPriv
= driContextPriv
->driScreenPriv
;
78 struct nouveau_screen
*nv_screen
= driScrnPriv
->private;
79 struct nouveau_context
*nv
= CALLOC_STRUCT(nouveau_context
);
80 struct nouveau_device_priv
*nvdev
;
81 struct pipe_context
*pipe
= NULL
;
82 struct st_context
*st_share
= NULL
;
85 if (sharedContextPrivate
) {
86 st_share
= ((struct nouveau_context
*)sharedContextPrivate
)->st
;
89 if ((ret
= nouveau_device_get_param(nv_screen
->device
,
90 NOUVEAU_GETPARAM_CHIPSET_ID
,
92 NOUVEAU_ERR("Error determining chipset id: %d\n", ret
);
96 if ((ret
= nouveau_channel_alloc(nv_screen
->device
,
97 0x8003d001, 0x8003d002,
99 NOUVEAU_ERR("Error creating GPU channel: %d\n", ret
);
103 driContextPriv
->driverPrivate
= (void *)nv
;
104 nv
->nv_screen
= nv_screen
;
105 nv
->dri_screen
= driScrnPriv
;
107 nvdev
= nouveau_device(nv_screen
->device
);
108 nvdev
->ctx
= driContextPriv
->hHWContext
;
109 nvdev
->lock
= (drmLock
*)&driScrnPriv
->pSAREA
->lock
;
111 driParseConfigFiles(&nv
->dri_option_cache
, &nv_screen
->option_cache
,
112 nv
->dri_screen
->myNum
, "nouveau");
114 __nouveau_debug
= driParseDebugString(getenv("NOUVEAU_DEBUG"),
118 /*XXX: Hack up a fake region and buffer object for front buffer.
119 * This will go away with TTM, replaced with a simple reference
120 * of the front buffer handle passed to us by the DDX.
123 struct pipe_surface
*fb_surf
;
124 struct nouveau_bo_priv
*fb_bo
;
126 fb_bo
= calloc(1, sizeof(struct nouveau_bo_priv
));
127 fb_bo
->drm
.offset
= nv_screen
->front_offset
;
128 fb_bo
->drm
.flags
= NOUVEAU_MEM_FB
;
129 fb_bo
->drm
.size
= nv_screen
->front_pitch
*
130 nv_screen
->front_height
;
132 fb_bo
->base
.flags
= NOUVEAU_BO_PIN
| NOUVEAU_BO_VRAM
;
133 fb_bo
->base
.offset
= fb_bo
->drm
.offset
;
134 fb_bo
->base
.handle
= (unsigned long)fb_bo
;
135 fb_bo
->base
.size
= fb_bo
->drm
.size
;
136 fb_bo
->base
.device
= nv_screen
->device
;
138 fb_surf
= calloc(1, sizeof(struct pipe_surface
));
139 fb_surf
->cpp
= nv_screen
->front_cpp
;
140 fb_surf
->pitch
= nv_screen
->front_pitch
/ fb_surf
->cpp
;
141 fb_surf
->height
= nv_screen
->front_height
;
142 fb_surf
->refcount
= 1;
143 fb_surf
->buffer
= (void *)fb_bo
;
145 nv
->frontbuffer
= fb_surf
;
148 if ((ret
= nouveau_grobj_alloc(nv
->channel
, 0x00000000, 0x30,
150 NOUVEAU_ERR("Error creating NULL object: %d\n", ret
);
153 nv
->next_handle
= 0x80000000;
155 if ((ret
= nouveau_notifier_alloc(nv
->channel
, nv
->next_handle
++, 1,
156 &nv
->sync_notifier
))) {
157 NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret
);
161 if (nv
->chipset
< 0x50)
162 ret
= nouveau_surface_init_nv04(nv
);
164 ret
= nouveau_surface_init_nv50(nv
);
169 if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) {
170 pipe
= nouveau_pipe_create(nv
);
172 NOUVEAU_ERR("Couldn't create hw pipe\n");
176 NOUVEAU_MSG("Using softpipe\n");
177 pipe
= nouveau_create_softpipe(nv
);
179 NOUVEAU_ERR("Error creating pipe, bailing\n");
185 nv
->st
= st_create_context(pipe
, glVis
, st_share
);
190 nouveau_context_destroy(__DRIcontextPrivate
*driContextPriv
)
192 struct nouveau_context
*nv
= driContextPriv
->driverPrivate
;
196 st_flush(nv
->st
, PIPE_FLUSH_WAIT
);
197 st_destroy_context(nv
->st
);
199 nouveau_grobj_free(&nv
->NvCtxSurf2D
);
200 nouveau_grobj_free(&nv
->NvImageBlit
);
201 nouveau_channel_free(&nv
->channel
);
207 nouveau_context_bind(__DRIcontextPrivate
*driContextPriv
,
208 __DRIdrawablePrivate
*driDrawPriv
,
209 __DRIdrawablePrivate
*driReadPriv
)
211 struct nouveau_context
*nv
;
212 struct nouveau_framebuffer
*draw
, *read
;
214 if (!driContextPriv
) {
215 st_make_current(NULL
, NULL
, NULL
);
219 nv
= driContextPriv
->driverPrivate
;
220 draw
= driDrawPriv
->driverPrivate
;
221 read
= driReadPriv
->driverPrivate
;
223 st_make_current(nv
->st
, draw
->stfb
, read
->stfb
);
225 if ((nv
->dri_drawable
!= driDrawPriv
) ||
226 (nv
->last_stamp
!= driDrawPriv
->lastStamp
)) {
227 nv
->dri_drawable
= driDrawPriv
;
228 st_resize_framebuffer(draw
->stfb
, driDrawPriv
->w
,
230 nv
->last_stamp
= driDrawPriv
->lastStamp
;
233 if (driDrawPriv
!= driReadPriv
) {
234 st_resize_framebuffer(read
->stfb
, driReadPriv
->w
,
242 nouveau_context_unbind(__DRIcontextPrivate
*driContextPriv
)
244 struct nouveau_context
*nv
= driContextPriv
->driverPrivate
;