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_create_buffer(__DRIscreenPrivate
* driScrnPriv
,
69 __DRIdrawablePrivate
* driDrawPriv
,
70 const __GLcontextModes
*glVis
, GLboolean pixmapBuffer
)
72 struct nouveau_framebuffer
*nvfb
;
73 enum pipe_format colour
, depth
, stencil
;
78 nvfb
= CALLOC_STRUCT(nouveau_framebuffer
);
82 if (glVis
->redBits
== 5)
83 colour
= PIPE_FORMAT_R5G6B5_UNORM
;
85 colour
= PIPE_FORMAT_A8R8G8B8_UNORM
;
87 if (glVis
->depthBits
== 16)
88 depth
= PIPE_FORMAT_Z16_UNORM
;
89 else if (glVis
->depthBits
== 24)
90 depth
= PIPE_FORMAT_Z24S8_UNORM
;
92 depth
= PIPE_FORMAT_NONE
;
94 if (glVis
->stencilBits
== 8)
95 stencil
= PIPE_FORMAT_Z24S8_UNORM
;
97 stencil
= PIPE_FORMAT_NONE
;
99 nvfb
->stfb
= st_create_framebuffer(glVis
, colour
, depth
, stencil
,
100 driDrawPriv
->w
, driDrawPriv
->h
,
107 driDrawPriv
->driverPrivate
= (void *)nvfb
;
112 nouveau_destroy_buffer(__DRIdrawablePrivate
* driDrawPriv
)
114 struct nouveau_framebuffer
*nvfb
;
116 nvfb
= (struct nouveau_framebuffer
*)driDrawPriv
->driverPrivate
;
117 st_unreference_framebuffer(nvfb
->stfb
);
121 static __DRIconfig
**
122 nouveau_fill_in_modes(__DRIscreenPrivate
*psp
,
123 unsigned pixel_bits
, unsigned depth_bits
,
124 unsigned stencil_bits
, GLboolean have_back_buffer
)
126 __DRIconfig
**configs
;
127 unsigned depth_buffer_factor
;
128 unsigned back_buffer_factor
;
132 static const GLenum back_buffer_modes
[] = {
133 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
,
136 uint8_t depth_bits_array
[3];
137 uint8_t stencil_bits_array
[3];
138 uint8_t msaa_samples_array
[1];
140 depth_bits_array
[0] = 0;
141 depth_bits_array
[1] = depth_bits
;
142 depth_bits_array
[2] = depth_bits
;
144 /* Just like with the accumulation buffer, always provide some modes
145 * with a stencil buffer. It will be a sw fallback, but some apps won't
148 stencil_bits_array
[0] = 0;
149 stencil_bits_array
[1] = 0;
150 if (depth_bits
== 24)
151 stencil_bits_array
[1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
152 stencil_bits_array
[2] = (stencil_bits
== 0) ? 8 : stencil_bits
;
154 msaa_samples_array
[0] = 0;
156 depth_buffer_factor
=
157 ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 3 : 1;
158 back_buffer_factor
= (have_back_buffer
) ? 3 : 1;
160 if (pixel_bits
== 16) {
162 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
166 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
169 configs
= driCreateConfigs(fb_format
, fb_type
,
170 depth_bits_array
, stencil_bits_array
,
171 depth_buffer_factor
, back_buffer_modes
,
172 back_buffer_factor
, msaa_samples_array
, 1);
173 if (configs
== NULL
) {
174 fprintf(stderr
, "[%s:%u] Error creating FBConfig!\n",
182 static const __DRIconfig
**
183 nouveau_screen_create(__DRIscreenPrivate
*psp
)
185 struct nouveau_dri
*nv_dri
= psp
->pDevPriv
;
186 struct nouveau_screen
*nv_screen
;
187 static const __DRIversion ddx_expected
=
188 { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL
};
189 static const __DRIversion dri_expected
= { 4, 0, 0 };
190 static const __DRIversion drm_expected
=
191 { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL
};
194 if (!driCheckDriDdxDrmVersions2("nouveau",
195 &psp
->dri_version
, &dri_expected
,
196 &psp
->ddx_version
, &ddx_expected
,
197 &psp
->drm_version
, &drm_expected
)) {
201 if (drm_expected
.patch
!= psp
->drm_version
.patch
) {
202 fprintf(stderr
, "Incompatible DRM patch level.\n"
203 "Expected: %d\n" "Current : %d\n",
204 drm_expected
.patch
, psp
->drm_version
.patch
);
208 driInitExtensions(NULL
, card_extensions
, GL_FALSE
);
210 if (psp
->devPrivSize
!= sizeof(struct nouveau_dri
)) {
211 NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n");
215 nv_screen
= CALLOC_STRUCT(nouveau_screen
);
218 nv_screen
->driScrnPriv
= psp
;
219 psp
->private = (void *)nv_screen
;
221 driParseOptionInfo(&nv_screen
->option_cache
,
222 __driConfigOptions
, __driNConfigOptions
);
224 if ((ret
= nouveau_device_open_existing(&nv_screen
->device
, 0,
226 NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret
);
230 nv_screen
->front_offset
= nv_dri
->front_offset
;
231 nv_screen
->front_pitch
= nv_dri
->front_pitch
* (nv_dri
->bpp
/ 8);
232 nv_screen
->front_cpp
= nv_dri
->bpp
/ 8;
233 nv_screen
->front_height
= nv_dri
->height
;
235 return (const __DRIconfig
**)
236 nouveau_fill_in_modes(psp
, nv_dri
->bpp
,
237 (nv_dri
->bpp
== 16) ? 16 : 24,
238 (nv_dri
->bpp
== 16) ? 0 : 8, 1);
242 nouveau_screen_destroy(__DRIscreenPrivate
*driScrnPriv
)
244 struct nouveau_screen
*nv_screen
= driScrnPriv
->private;
246 driScrnPriv
->private = NULL
;
250 const struct __DriverAPIRec
252 .InitScreen
= nouveau_screen_create
,
253 .DestroyScreen
= nouveau_screen_destroy
,
254 .CreateContext
= nouveau_context_create
,
255 .DestroyContext
= nouveau_context_destroy
,
256 .CreateBuffer
= nouveau_create_buffer
,
257 .DestroyBuffer
= nouveau_destroy_buffer
,
258 .SwapBuffers
= nouveau_swap_buffers
,
259 .MakeCurrent
= nouveau_context_bind
,
260 .UnbindContext
= nouveau_context_unbind
,
261 .CopySubBuffer
= nouveau_copy_sub_buffer
,
263 .InitScreen2
= NULL
, /* one day, I promise! */