3 #include "framebuffer.h"
5 #include "renderbuffer.h"
6 #include "simple_list.h"
11 #include "pipe/p_context.h"
12 #include "state_tracker/st_public.h"
13 #include "state_tracker/st_cb_fbo.h"
15 #include "nouveau_context.h"
16 #include "nouveau_device.h"
17 #include "nouveau_drm.h"
18 #include "nouveau_dri.h"
19 #include "nouveau_local.h"
20 #include "nouveau_screen.h"
21 #include "nouveau_swapbuffers.h"
23 #if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10
24 #error nouveau_drm.h version does not match expected version
27 PUBLIC
const char __driConfigOptions
[] =
30 static const GLuint __driNConfigOptions
= 0;
32 extern const struct dri_extension common_extensions
[];
33 extern const struct dri_extension nv40_extensions
[];
36 nouveau_screen_create(__DRIscreenPrivate
*driScrnPriv
)
38 struct nouveau_dri
*nv_dri
= driScrnPriv
->pDevPriv
;
39 struct nouveau_screen
*nv_screen
;
42 if (driScrnPriv
->devPrivSize
!= sizeof(struct nouveau_dri
)) {
43 NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n");
47 nv_screen
= CALLOC_STRUCT(nouveau_screen
);
50 nv_screen
->driScrnPriv
= driScrnPriv
;
51 driScrnPriv
->private = (void *)nv_screen
;
53 driParseOptionInfo(&nv_screen
->option_cache
,
54 __driConfigOptions
, __driNConfigOptions
);
56 if ((ret
= nouveau_device_open_existing(&nv_screen
->device
, 0,
57 driScrnPriv
->fd
, 0))) {
58 NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret
);
62 nv_screen
->front_offset
= nv_dri
->front_offset
;
63 nv_screen
->front_pitch
= nv_dri
->front_pitch
* (nv_dri
->bpp
/ 8);
69 nouveau_screen_destroy(__DRIscreenPrivate
*driScrnPriv
)
71 struct nouveau_screen
*nv_screen
= driScrnPriv
->private;
73 driScrnPriv
->private = NULL
;
78 nouveau_create_buffer(__DRIscreenPrivate
* driScrnPriv
,
79 __DRIdrawablePrivate
* driDrawPriv
,
80 const __GLcontextModes
*glVis
, GLboolean pixmapBuffer
)
82 struct nouveau_framebuffer
*nvfb
;
87 nvfb
= CALLOC_STRUCT(nouveau_framebuffer
);
91 nvfb
->stfb
= st_create_framebuffer(glVis
, GL_TRUE
, (void*)nvfb
);
97 driDrawPriv
->driverPrivate
= (void *)nvfb
;
102 nouveau_destroy_buffer(__DRIdrawablePrivate
* driDrawPriv
)
104 struct nouveau_framebuffer
*nvfb
;
106 nvfb
= (struct nouveau_framebuffer
*)driDrawPriv
;
107 st_unreference_framebuffer(&nvfb
->stfb
);
111 static struct __DriverAPIRec
113 .InitDriver
= nouveau_screen_create
,
114 .DestroyScreen
= nouveau_screen_destroy
,
115 .CreateContext
= nouveau_context_create
,
116 .DestroyContext
= nouveau_context_destroy
,
117 .CreateBuffer
= nouveau_create_buffer
,
118 .DestroyBuffer
= nouveau_destroy_buffer
,
119 .SwapBuffers
= nouveau_swap_buffers
,
120 .MakeCurrent
= nouveau_context_bind
,
121 .UnbindContext
= nouveau_context_unbind
,
126 .SwapBuffersMSC
= NULL
,
127 .CopySubBuffer
= nouveau_copy_sub_buffer
,
131 static __GLcontextModes
*
132 nouveau_fill_in_modes(unsigned pixel_bits
, unsigned depth_bits
,
133 unsigned stencil_bits
, GLboolean have_back_buffer
)
135 __GLcontextModes
* modes
;
136 __GLcontextModes
* m
;
138 unsigned depth_buffer_factor
;
139 unsigned back_buffer_factor
;
142 static const struct {
145 } fb_format_array
[] = {
146 { GL_RGB
, GL_UNSIGNED_SHORT_5_6_5
},
147 { GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
},
148 { GL_BGR
, GL_UNSIGNED_INT_8_8_8_8_REV
},
151 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
152 * support pageflipping at all.
154 static const GLenum back_buffer_modes
[] = {
155 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
, GLX_SWAP_COPY_OML
158 u_int8_t depth_bits_array
[4] = { 0, 16, 24 };
159 u_int8_t stencil_bits_array
[4] = { 0, 0, 8 };
161 depth_buffer_factor
= 4;
162 back_buffer_factor
= (have_back_buffer
) ? 3 : 1;
164 num_modes
= ((pixel_bits
==16) ? 1 : 2) *
165 depth_buffer_factor
* back_buffer_factor
* 4;
166 modes
= (*dri_interface
->createContextModes
)(num_modes
,
167 sizeof(__GLcontextModes
));
170 for (i
=((pixel_bits
==16)?0:1);i
<((pixel_bits
==16)?1:3);i
++) {
171 if (!driFillInModes(&m
, fb_format_array
[i
].format
,
172 fb_format_array
[i
].type
,
179 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
180 __func__
, __LINE__
);
184 if (!driFillInModes(&m
, fb_format_array
[i
].format
,
185 fb_format_array
[i
].type
,
192 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
193 __func__
, __LINE__
);
201 __driCreateNewScreen_20050727(__DRInativeDisplay
*dpy
, int scrn
,
202 __DRIscreen
*psc
, const __GLcontextModes
* modes
,
203 const __DRIversion
* ddx_version
,
204 const __DRIversion
* dri_version
,
205 const __DRIversion
* drm_version
,
206 const __DRIframebuffer
* frame_buffer
,
207 void * pSAREA
, int fd
, int internal_api_version
,
208 const __DRIinterfaceMethods
* interface
,
209 __GLcontextModes
** driver_modes
)
211 __DRIscreenPrivate
*psp
;
212 static const __DRIversion ddx_expected
= { 1, 2, 0 };
213 static const __DRIversion dri_expected
= { 4, 0, 0 };
214 static const __DRIversion drm_expected
=
215 { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL
};
216 struct nouveau_dri
*nv_dri
= NULL
;
218 dri_interface
= interface
;
220 if (!driCheckDriDdxDrmVersions2("nouveau",
221 dri_version
, &dri_expected
,
222 ddx_version
, &ddx_expected
,
223 drm_version
, &drm_expected
)) {
227 if (drm_expected
.patch
!= drm_version
->patch
) {
228 fprintf(stderr
, "Incompatible DRM patch level.\n"
229 "Expected: %d\n" "Current : %d\n",
230 drm_expected
.patch
, drm_version
->patch
);
234 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
235 ddx_version
, dri_version
, drm_version
,
236 frame_buffer
, pSAREA
, fd
,
237 internal_api_version
,
241 nv_dri
= psp
->pDevPriv
;
243 *driver_modes
= nouveau_fill_in_modes(nv_dri
->bpp
,
244 (nv_dri
->bpp
== 16) ? 16 : 24,
245 (nv_dri
->bpp
== 16) ? 0 : 8,
248 driInitExtensions(NULL
, common_extensions
, GL_FALSE
);
249 driInitExtensions(NULL
, nv40_extensions
, GL_FALSE
);