5 #include <pipe/p_context.h>
6 #include <state_tracker/st_public.h>
7 #include <state_tracker/st_cb_fbo.h>
8 #include <nouveau_drm.h>
9 #include "../common/nouveau_dri.h"
10 #include "../common/nouveau_local.h"
11 #include "nouveau_context_dri.h"
12 #include "nouveau_screen_dri.h"
13 #include "nouveau_swapbuffers.h"
15 #if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11
16 #error nouveau_drm.h version does not match expected version
19 /* Extension stuff, enabling of extensions handled by Gallium's GL state
20 * tracker. But, we still need to define the entry points we want.
22 #define need_GL_ARB_fragment_program
23 #define need_GL_ARB_multisample
24 #define need_GL_ARB_occlusion_query
25 #define need_GL_ARB_point_parameters
26 #define need_GL_ARB_shader_objects
27 #define need_GL_ARB_texture_compression
28 #define need_GL_ARB_vertex_program
29 #define need_GL_ARB_vertex_shader
30 #define need_GL_ARB_vertex_buffer_object
31 #define need_GL_EXT_compiled_vertex_array
32 #define need_GL_EXT_fog_coord
33 #define need_GL_EXT_secondary_color
34 #define need_GL_EXT_framebuffer_object
35 #define need_GL_VERSION_2_0
36 #define need_GL_VERSION_2_1
37 #include "extension_helper.h"
39 const struct dri_extension card_extensions
[] =
41 { "GL_ARB_multisample", GL_ARB_multisample_functions
},
42 { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions
},
43 { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions
},
44 { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions
},
45 { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions
},
46 { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions
},
47 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions
},
48 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions
},
49 { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions
},
50 { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions
},
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
},
58 PUBLIC
const char __driConfigOptions
[] =
61 static const GLuint __driNConfigOptions
= 0;
63 extern const struct dri_extension common_extensions
[];
64 extern const struct dri_extension nv40_extensions
[];
67 nouveau_create_buffer(__DRIscreenPrivate
* driScrnPriv
,
68 __DRIdrawablePrivate
* driDrawPriv
,
69 const __GLcontextModes
*glVis
, GLboolean pixmapBuffer
)
71 struct nouveau_framebuffer
*nvfb
;
72 enum pipe_format colour
, depth
, stencil
;
77 nvfb
= CALLOC_STRUCT(nouveau_framebuffer
);
81 if (glVis
->redBits
== 5)
82 colour
= PIPE_FORMAT_R5G6B5_UNORM
;
84 colour
= PIPE_FORMAT_A8R8G8B8_UNORM
;
86 if (glVis
->depthBits
== 16)
87 depth
= PIPE_FORMAT_Z16_UNORM
;
88 else if (glVis
->depthBits
== 24)
89 depth
= PIPE_FORMAT_Z24S8_UNORM
;
91 depth
= PIPE_FORMAT_NONE
;
93 if (glVis
->stencilBits
== 8)
94 stencil
= PIPE_FORMAT_Z24S8_UNORM
;
96 stencil
= PIPE_FORMAT_NONE
;
98 nvfb
->stfb
= st_create_framebuffer(glVis
, colour
, depth
, stencil
,
99 driDrawPriv
->w
, driDrawPriv
->h
,
106 driDrawPriv
->driverPrivate
= (void *)nvfb
;
111 nouveau_destroy_buffer(__DRIdrawablePrivate
* driDrawPriv
)
113 struct nouveau_framebuffer
*nvfb
;
115 nvfb
= (struct nouveau_framebuffer
*)driDrawPriv
->driverPrivate
;
116 st_unreference_framebuffer(nvfb
->stfb
);
120 static __DRIconfig
**
121 nouveau_fill_in_modes(__DRIscreenPrivate
*psp
,
122 unsigned pixel_bits
, unsigned depth_bits
,
123 unsigned stencil_bits
, GLboolean have_back_buffer
)
125 __DRIconfig
**configs
;
126 unsigned depth_buffer_factor
;
127 unsigned back_buffer_factor
;
131 static const GLenum back_buffer_modes
[] = {
132 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
,
135 uint8_t depth_bits_array
[3];
136 uint8_t stencil_bits_array
[3];
137 uint8_t msaa_samples_array
[1];
139 depth_bits_array
[0] = 0;
140 depth_bits_array
[1] = depth_bits
;
141 depth_bits_array
[2] = depth_bits
;
143 /* Just like with the accumulation buffer, always provide some modes
144 * with a stencil buffer. It will be a sw fallback, but some apps won't
147 stencil_bits_array
[0] = 0;
148 stencil_bits_array
[1] = 0;
149 if (depth_bits
== 24)
150 stencil_bits_array
[1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
151 stencil_bits_array
[2] = (stencil_bits
== 0) ? 8 : stencil_bits
;
153 msaa_samples_array
[0] = 0;
155 depth_buffer_factor
=
156 ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 3 : 1;
157 back_buffer_factor
= (have_back_buffer
) ? 3 : 1;
159 if (pixel_bits
== 16) {
161 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
165 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
168 configs
= driCreateConfigs(fb_format
, fb_type
,
169 depth_bits_array
, stencil_bits_array
,
170 depth_buffer_factor
, back_buffer_modes
,
171 back_buffer_factor
, msaa_samples_array
, 1);
172 if (configs
== NULL
) {
173 fprintf(stderr
, "[%s:%u] Error creating FBConfig!\n",
181 static const __DRIconfig
**
182 nouveau_screen_create(__DRIscreenPrivate
*psp
)
184 struct nouveau_dri
*nv_dri
= psp
->pDevPriv
;
185 struct nouveau_screen_dri
*nv_screen
;
186 static const __DRIversion ddx_expected
=
187 { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL
};
188 static const __DRIversion dri_expected
= { 4, 0, 0 };
189 static const __DRIversion drm_expected
=
190 { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL
};
192 if (!driCheckDriDdxDrmVersions2("nouveau",
193 &psp
->dri_version
, &dri_expected
,
194 &psp
->ddx_version
, &ddx_expected
,
195 &psp
->drm_version
, &drm_expected
)) {
199 if (drm_expected
.patch
!= psp
->drm_version
.patch
) {
200 fprintf(stderr
, "Incompatible DRM patch level.\n"
201 "Expected: %d\n" "Current : %d\n",
202 drm_expected
.patch
, psp
->drm_version
.patch
);
206 driInitExtensions(NULL
, card_extensions
, GL_FALSE
);
208 if (psp
->devPrivSize
!= sizeof(struct nouveau_dri
)) {
209 NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n");
213 nv_screen
= CALLOC_STRUCT(nouveau_screen_dri
);
217 driParseOptionInfo(&nv_screen
->option_cache
,
218 __driConfigOptions
, __driNConfigOptions
);
220 if (nouveau_screen_init(nv_dri
, psp
->fd
, &nv_screen
->base
)) {
225 nv_screen
->driScrnPriv
= psp
;
226 psp
->private = (void *)nv_screen
;
228 return (const __DRIconfig
**)
229 nouveau_fill_in_modes(psp
, nv_dri
->bpp
,
230 (nv_dri
->bpp
== 16) ? 16 : 24,
231 (nv_dri
->bpp
== 16) ? 0 : 8, 1);
235 nouveau_screen_destroy(__DRIscreenPrivate
*driScrnPriv
)
237 struct nouveau_screen_dri
*nv_screen
= driScrnPriv
->private;
239 driScrnPriv
->private = NULL
;
240 nouveau_screen_cleanup(&nv_screen
->base
);
244 const struct __DriverAPIRec
246 .InitScreen
= nouveau_screen_create
,
247 .DestroyScreen
= nouveau_screen_destroy
,
248 .CreateContext
= nouveau_context_create
,
249 .DestroyContext
= nouveau_context_destroy
,
250 .CreateBuffer
= nouveau_create_buffer
,
251 .DestroyBuffer
= nouveau_destroy_buffer
,
252 .SwapBuffers
= nouveau_swap_buffers
,
253 .MakeCurrent
= nouveau_context_bind
,
254 .UnbindContext
= nouveau_context_unbind
,
255 .CopySubBuffer
= nouveau_copy_sub_buffer
,
257 .InitScreen2
= NULL
, /* one day, I promise! */