5 #include "pipe/p_context.h"
6 #include "state_tracker/st_public.h"
7 #include "state_tracker/st_cb_fbo.h"
9 #include "nouveau_context.h"
10 #include "nouveau_drm.h"
11 #include "nouveau_dri.h"
12 #include "nouveau_local.h"
13 #include "nouveau_screen.h"
14 #include "nouveau_swapbuffers.h"
16 #if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11
17 #error nouveau_drm.h version does not match expected version
20 /* Extension stuff, enabling of extensions handled by Gallium's GL state
21 * tracker. But, we still need to define the entry points we want.
23 #define need_GL_ARB_fragment_program
24 #define need_GL_ARB_multisample
25 #define need_GL_ARB_occlusion_query
26 #define need_GL_ARB_point_parameters
27 #define need_GL_ARB_shader_objects
28 #define need_GL_ARB_texture_compression
29 #define need_GL_ARB_vertex_program
30 #define need_GL_ARB_vertex_shader
31 #define need_GL_ARB_vertex_buffer_object
32 #define need_GL_EXT_compiled_vertex_array
33 #define need_GL_EXT_fog_coord
34 #define need_GL_EXT_secondary_color
35 #define need_GL_EXT_framebuffer_object
36 #define need_GL_VERSION_2_0
37 #define need_GL_VERSION_2_1
38 #include "extension_helper.h"
40 const struct dri_extension card_extensions
[] =
42 { "GL_ARB_multisample", GL_ARB_multisample_functions
},
43 { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions
},
44 { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions
},
45 { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions
},
46 { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions
},
47 { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions
},
48 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions
},
49 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions
},
50 { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions
},
51 { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions
},
52 { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions
},
53 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions
},
54 { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions
},
55 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions
},
59 PUBLIC
const char __driConfigOptions
[] =
62 static const GLuint __driNConfigOptions
= 0;
64 extern const struct dri_extension common_extensions
[];
65 extern const struct dri_extension nv40_extensions
[];
68 nouveau_screen_create(__DRIscreenPrivate
*driScrnPriv
)
70 struct nouveau_dri
*nv_dri
= driScrnPriv
->pDevPriv
;
71 struct nouveau_screen
*nv_screen
;
74 if (driScrnPriv
->devPrivSize
!= sizeof(struct nouveau_dri
)) {
75 NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n");
79 nv_screen
= CALLOC_STRUCT(nouveau_screen
);
82 nv_screen
->driScrnPriv
= driScrnPriv
;
83 driScrnPriv
->private = (void *)nv_screen
;
85 driParseOptionInfo(&nv_screen
->option_cache
,
86 __driConfigOptions
, __driNConfigOptions
);
88 if ((ret
= nouveau_device_open_existing(&nv_screen
->device
, 0,
89 driScrnPriv
->fd
, 0))) {
90 NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret
);
94 nv_screen
->front_offset
= nv_dri
->front_offset
;
95 nv_screen
->front_pitch
= nv_dri
->front_pitch
* (nv_dri
->bpp
/ 8);
96 nv_screen
->front_cpp
= nv_dri
->bpp
/ 8;
97 nv_screen
->front_height
= nv_dri
->height
;
103 nouveau_screen_destroy(__DRIscreenPrivate
*driScrnPriv
)
105 struct nouveau_screen
*nv_screen
= driScrnPriv
->private;
107 driScrnPriv
->private = NULL
;
112 nouveau_create_buffer(__DRIscreenPrivate
* driScrnPriv
,
113 __DRIdrawablePrivate
* driDrawPriv
,
114 const __GLcontextModes
*glVis
, GLboolean pixmapBuffer
)
116 struct nouveau_framebuffer
*nvfb
;
117 enum pipe_format colour
, depth
, stencil
;
122 nvfb
= CALLOC_STRUCT(nouveau_framebuffer
);
126 if (glVis
->redBits
== 5)
127 colour
= PIPE_FORMAT_R5G6B5_UNORM
;
129 colour
= PIPE_FORMAT_A8R8G8B8_UNORM
;
131 if (glVis
->depthBits
== 16)
132 depth
= PIPE_FORMAT_Z16_UNORM
;
133 else if (glVis
->depthBits
== 24)
134 depth
= PIPE_FORMAT_Z24S8_UNORM
;
136 depth
= PIPE_FORMAT_NONE
;
138 if (glVis
->stencilBits
== 8)
139 stencil
= PIPE_FORMAT_Z24S8_UNORM
;
141 stencil
= PIPE_FORMAT_NONE
;
143 nvfb
->stfb
= st_create_framebuffer(glVis
, colour
, depth
, stencil
,
144 driDrawPriv
->w
, driDrawPriv
->h
,
151 driDrawPriv
->driverPrivate
= (void *)nvfb
;
156 nouveau_destroy_buffer(__DRIdrawablePrivate
* driDrawPriv
)
158 struct nouveau_framebuffer
*nvfb
;
160 nvfb
= (struct nouveau_framebuffer
*)driDrawPriv
->driverPrivate
;
161 st_unreference_framebuffer(&nvfb
->stfb
);
165 static struct __DriverAPIRec
167 .InitDriver
= nouveau_screen_create
,
168 .DestroyScreen
= nouveau_screen_destroy
,
169 .CreateContext
= nouveau_context_create
,
170 .DestroyContext
= nouveau_context_destroy
,
171 .CreateBuffer
= nouveau_create_buffer
,
172 .DestroyBuffer
= nouveau_destroy_buffer
,
173 .SwapBuffers
= nouveau_swap_buffers
,
174 .MakeCurrent
= nouveau_context_bind
,
175 .UnbindContext
= nouveau_context_unbind
,
180 .SwapBuffersMSC
= NULL
,
181 .CopySubBuffer
= nouveau_copy_sub_buffer
,
185 static __GLcontextModes
*
186 nouveau_fill_in_modes(unsigned pixel_bits
, unsigned depth_bits
,
187 unsigned stencil_bits
, GLboolean have_back_buffer
)
189 __GLcontextModes
* modes
;
190 __GLcontextModes
* m
;
192 unsigned depth_buffer_factor
;
193 unsigned back_buffer_factor
;
196 static const struct {
199 } fb_format_array
[] = {
200 { GL_RGB
, GL_UNSIGNED_SHORT_5_6_5
},
201 { GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
},
202 { GL_BGR
, GL_UNSIGNED_INT_8_8_8_8_REV
},
205 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
206 * support pageflipping at all.
208 static const GLenum back_buffer_modes
[] = {
209 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
, GLX_SWAP_COPY_OML
212 uint8_t depth_bits_array
[4] = { 0, 16, 24, 24 };
213 uint8_t stencil_bits_array
[4] = { 0, 0, 0, 8 };
214 uint8_t msaa_samples_array
[1] = { 0 };
216 depth_buffer_factor
= 4;
217 back_buffer_factor
= (have_back_buffer
) ? 3 : 1;
219 num_modes
= ((pixel_bits
==16) ? 1 : 2) *
220 depth_buffer_factor
* back_buffer_factor
* 4;
221 modes
= (*dri_interface
->createContextModes
)(num_modes
,
222 sizeof(__GLcontextModes
));
225 for (i
=((pixel_bits
==16)?0:1);i
<((pixel_bits
==16)?1:3);i
++) {
226 if (!driFillInModes(&m
, fb_format_array
[i
].format
,
227 fb_format_array
[i
].type
,
233 msaa_samples_array
, 1,
235 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
236 __func__
, __LINE__
);
240 if (!driFillInModes(&m
, fb_format_array
[i
].format
,
241 fb_format_array
[i
].type
,
247 msaa_samples_array
, 1,
249 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
250 __func__
, __LINE__
);
258 __driCreateNewScreen_20050727(__DRInativeDisplay
*dpy
, int scrn
,
259 __DRIscreen
*psc
, const __GLcontextModes
* modes
,
260 const __DRIversion
* ddx_version
,
261 const __DRIversion
* dri_version
,
262 const __DRIversion
* drm_version
,
263 const __DRIframebuffer
* frame_buffer
,
264 void * pSAREA
, int fd
, int internal_api_version
,
265 const __DRIinterfaceMethods
* interface
,
266 __GLcontextModes
** driver_modes
)
268 __DRIscreenPrivate
*psp
;
269 static const __DRIversion ddx_expected
=
270 { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL
};
271 static const __DRIversion dri_expected
= { 4, 0, 0 };
272 static const __DRIversion drm_expected
=
273 { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL
};
274 struct nouveau_dri
*nv_dri
= NULL
;
276 dri_interface
= interface
;
278 if (!driCheckDriDdxDrmVersions2("nouveau",
279 dri_version
, &dri_expected
,
280 ddx_version
, &ddx_expected
,
281 drm_version
, &drm_expected
)) {
285 if (drm_expected
.patch
!= drm_version
->patch
) {
286 fprintf(stderr
, "Incompatible DRM patch level.\n"
287 "Expected: %d\n" "Current : %d\n",
288 drm_expected
.patch
, drm_version
->patch
);
292 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
293 ddx_version
, dri_version
, drm_version
,
294 frame_buffer
, pSAREA
, fd
,
295 internal_api_version
,
299 nv_dri
= psp
->pDevPriv
;
301 *driver_modes
= nouveau_fill_in_modes(nv_dri
->bpp
,
302 (nv_dri
->bpp
== 16) ? 16 : 24,
303 (nv_dri
->bpp
== 16) ? 0 : 8,
306 driInitExtensions(NULL
, card_extensions
, GL_FALSE
);