1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
32 #include "intel_context.h"
33 #include "intel_screen.h"
34 #include "intel_batchbuffer.h"
35 //#include "intel_batchpool.h"
36 #include "intel_swapbuffers.h"
37 #include "intel_winsys.h"
40 #include "ws_dri_bufpool.h"
42 #include "pipe/p_context.h"
43 #include "state_tracker/st_public.h"
44 #include "state_tracker/st_cb_fbo.h"
48 PUBLIC
const char __driConfigOptions
[] =
49 DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE
50 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS
)
51 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0
)
52 DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY
53 DRI_CONF_FORCE_S3TC_ENABLE(false)
54 DRI_CONF_ALLOW_LARGE_TEXTURES(1)
55 DRI_CONF_SECTION_END DRI_CONF_END
;
57 const uint __driNConfigOptions
= 4;
59 #ifdef USE_NEW_INTERFACE
60 static PFNGLXCREATECONTEXTMODES create_context_modes
= NULL
;
61 #endif /*USE_NEW_INTERFACE */
63 extern const struct dri_extension card_extensions
[];
69 intelPrintDRIInfo(struct intel_screen
* intelScreen
,
70 __DRIscreenPrivate
* sPriv
, I830DRIPtr gDRIPriv
)
72 fprintf(stderr
, "*** Front size: 0x%x offset: 0x%x pitch: %d\n",
73 intelScreen
->front
.size
, intelScreen
->front
.offset
,
74 intelScreen
->front
.pitch
);
75 fprintf(stderr
, "*** Memory : 0x%x\n", gDRIPriv
->mem
);
81 intelPrintSAREA(const drmI830Sarea
* sarea
)
83 fprintf(stderr
, "SAREA: sarea width %d height %d\n", sarea
->width
,
85 fprintf(stderr
, "SAREA: pitch: %d\n", sarea
->pitch
);
87 "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n",
88 sarea
->front_offset
, sarea
->front_size
,
89 (unsigned) sarea
->front_handle
);
91 "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n",
92 sarea
->back_offset
, sarea
->back_size
,
93 (unsigned) sarea
->back_handle
);
94 fprintf(stderr
, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n",
95 sarea
->depth_offset
, sarea
->depth_size
,
96 (unsigned) sarea
->depth_handle
);
97 fprintf(stderr
, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n",
98 sarea
->tex_offset
, sarea
->tex_size
, (unsigned) sarea
->tex_handle
);
99 fprintf(stderr
, "SAREA: rotation: %d\n", sarea
->rotation
);
101 "SAREA: rotated offset: 0x%08x size: 0x%x\n",
102 sarea
->rotated_offset
, sarea
->rotated_size
);
103 fprintf(stderr
, "SAREA: rotated pitch: %d\n", sarea
->rotated_pitch
);
109 * Use the information in the sarea to update the screen parameters
110 * related to screen rotation. Needs to be called locked.
113 intelUpdateScreenRotation(__DRIscreenPrivate
* sPriv
, drmI830Sarea
* sarea
)
115 struct intel_screen
*intelScreen
= intel_screen(sPriv
);
117 if (intelScreen
->front
.map
) {
118 drmUnmap(intelScreen
->front
.map
, intelScreen
->front
.size
);
119 intelScreen
->front
.map
= NULL
;
122 if (intelScreen
->front
.buffer
)
123 driDeleteBuffers(1, &intelScreen
->front
.buffer
);
125 intelScreen
->front
.width
= sarea
->width
;
126 intelScreen
->front
.height
= sarea
->height
;
127 intelScreen
->front
.offset
= sarea
->front_offset
;
128 intelScreen
->front
.pitch
= sarea
->pitch
* intelScreen
->front
.cpp
;
129 intelScreen
->front
.size
= sarea
->front_size
;
130 intelScreen
->front
.handle
= sarea
->front_handle
;
132 assert( sarea
->front_size
>=
133 intelScreen
->front
.pitch
* intelScreen
->front
.height
);
135 #if 0 /* JB not important */
136 if (!sarea
->front_handle
)
139 if (drmMap(sPriv
->fd
,
141 intelScreen
->front
.size
,
142 (drmAddress
*) & intelScreen
->front
.map
) != 0) {
143 fprintf(stderr
, "drmMap(frontbuffer) failed!\n");
149 if (intelScreen
->staticPool
) {
150 driGenBuffers(intelScreen
->staticPool
, "static region", 1,
151 &intelScreen
->front
.buffer
, 64,
152 DRM_BO_FLAG_MEM_TT
| DRM_BO_FLAG_NO_MOVE
|
153 DRM_BO_FLAG_READ
| DRM_BO_FLAG_WRITE
, 0);
155 driBOSetStatic(intelScreen
->front
.buffer
,
156 intelScreen
->front
.offset
,
157 intelScreen
->front
.pitch
* intelScreen
->front
.height
,
158 intelScreen
->front
.map
, 0);
161 if (intelScreen
->staticPool
) {
162 if (intelScreen
->front
.buffer
)
163 driBOUnReference(intelScreen
->front
.buffer
);
164 driGenBuffers(intelScreen
->staticPool
, "front", 1, &intelScreen
->front
.buffer
, 0, 0, 0);
165 driBOSetReferenced(intelScreen
->front
.buffer
, sarea
->front_bo_handle
);
172 intelCreatePools(__DRIscreenPrivate
* sPriv
)
174 //unsigned batchPoolSize = 1024*1024;
175 struct intel_screen
*intelScreen
= intel_screen(sPriv
);
177 if (intelScreen
->havePools
)
180 #if 0 /* ZZZ JB fix this */
181 intelScreen
->staticPool
= driDRMStaticPoolInit(sPriv
->fd
);
182 if (!intelScreen
->staticPool
)
185 batchPoolSize
/= BATCH_SZ
;
186 intelScreen
->batchPool
= driBatchPoolInit(sPriv
->fd
,
189 DRM_BO_FLAG_MEM_LOCAL
,
192 if (!intelScreen
->batchPool
) {
193 fprintf(stderr
, "Failed to initialize batch pool - possible incorrect agpgart installed\n");
197 intelScreen
->staticPool
= driDRMPoolInit(sPriv
->fd
);
198 intelScreen
->batchPool
= driSlabPoolInit(sPriv
->fd
,
203 4096, //intelScreen->maxBatchSize,
207 intelScreen
->havePools
= GL_TRUE
;
209 intelUpdateScreenRotation(sPriv
, intelScreen
->sarea
);
216 intelInitDriver(__DRIscreenPrivate
* sPriv
)
218 struct intel_screen
*intelScreen
;
219 I830DRIPtr gDRIPriv
= (I830DRIPtr
) sPriv
->pDevPriv
;
221 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension
=
222 (PFNGLXSCRENABLEEXTENSIONPROC
) (*dri_interface
->
223 getProcAddress("glxEnableExtension"));
224 void *const psc
= sPriv
->psc
->screenConfigs
;
226 if (sPriv
->devPrivSize
!= sizeof(I830DRIRec
)) {
228 "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n");
232 /* Allocate the private area */
233 intelScreen
= CALLOC_STRUCT(intel_screen
);
237 /* parse information in __driConfigOptions */
238 driParseOptionInfo(&intelScreen
->optionCache
,
239 __driConfigOptions
, __driNConfigOptions
);
241 sPriv
->private = (void *) intelScreen
;
243 intelScreen
->sarea
= (drmI830Sarea
*) (((GLubyte
*) sPriv
->pSAREA
) +
244 gDRIPriv
->sarea_priv_offset
);
245 intelScreen
->deviceID
= gDRIPriv
->deviceID
;
246 intelScreen
->front
.cpp
= gDRIPriv
->cpp
;
247 intelScreen
->drmMinor
= sPriv
->drmMinor
;
249 assert(gDRIPriv
->bitsPerPixel
== 16 ||
250 gDRIPriv
->bitsPerPixel
== 32);
252 intelUpdateScreenRotation(sPriv
, intelScreen
->sarea
);
255 intelPrintDRIInfo(intelScreen
, sPriv
, gDRIPriv
);
257 if (glx_enable_extension
!= NULL
) {
258 (*glx_enable_extension
) (psc
, "GLX_SGI_swap_control");
259 (*glx_enable_extension
) (psc
, "GLX_SGI_video_sync");
260 (*glx_enable_extension
) (psc
, "GLX_MESA_swap_control");
261 (*glx_enable_extension
) (psc
, "GLX_MESA_swap_frame_usage");
262 (*glx_enable_extension
) (psc
, "GLX_SGI_make_current_read");
268 intelScreen
->mgr
= driFenceMgrTTMInit(sPriv
->fd
);
269 if (!intelScreen
->mgr
) {
270 fprintf(stderr
, "Failed to create fence manager.\n");
274 intelScreen
->fMan
= driInitFreeSlabManager(10, 10);
275 if (!intelScreen
->fMan
) {
276 fprintf(stderr
, "Failed to create free slab manager.\n");
280 if (!intelCreatePools(sPriv
))
284 intelScreen
->winsys
= intel_create_pipe_winsys(sPriv
->fd
, intelScreen
->fMan
);
291 intelDestroyScreen(__DRIscreenPrivate
* sPriv
)
293 struct intel_screen
*intelScreen
= intel_screen(sPriv
);
295 /* intelUnmapScreenRegions(intelScreen); */
297 if (intelScreen
->havePools
) {
298 driPoolTakeDown(intelScreen
->staticPool
);
299 driPoolTakeDown(intelScreen
->batchPool
);
302 sPriv
->private = NULL
;
307 * This is called when we need to set up GL rendering to a new X window.
310 intelCreateBuffer(__DRIscreenPrivate
* driScrnPriv
,
311 __DRIdrawablePrivate
* driDrawPriv
,
312 const __GLcontextModes
* visual
, boolean isPixmap
)
315 return GL_FALSE
; /* not implemented */
318 enum pipe_format colorFormat
, depthFormat
, stencilFormat
;
319 struct intel_framebuffer
*intelfb
= CALLOC_STRUCT(intel_framebuffer
);
324 if (visual
->redBits
== 5)
325 colorFormat
= PIPE_FORMAT_R5G6B5_UNORM
;
327 colorFormat
= PIPE_FORMAT_A8R8G8B8_UNORM
;
329 if (visual
->depthBits
== 16)
330 depthFormat
= PIPE_FORMAT_Z16_UNORM
;
331 else if (visual
->depthBits
== 24)
332 depthFormat
= PIPE_FORMAT_S8Z24_UNORM
;
334 depthFormat
= PIPE_FORMAT_NONE
;
336 if (visual
->stencilBits
== 8)
337 stencilFormat
= PIPE_FORMAT_S8Z24_UNORM
;
339 stencilFormat
= PIPE_FORMAT_NONE
;
341 intelfb
->stfb
= st_create_framebuffer(visual
,
348 if (!intelfb
->stfb
) {
353 driDrawPriv
->driverPrivate
= (void *) intelfb
;
359 intelDestroyBuffer(__DRIdrawablePrivate
* driDrawPriv
)
361 struct intel_framebuffer
*intelfb
= intel_framebuffer(driDrawPriv
);
362 assert(intelfb
->stfb
);
363 st_unreference_framebuffer(&intelfb
->stfb
);
369 * Get information about previous buffer swaps.
372 intelGetSwapInfo(__DRIdrawablePrivate
* dPriv
, __DRIswapInfo
* sInfo
)
374 if ((dPriv
== NULL
) || (dPriv
->driverPrivate
== NULL
)
375 || (sInfo
== NULL
)) {
384 intelSetTexOffset(__DRIcontext
*pDRICtx
, int texname
,
385 unsigned long long offset
, int depth
, uint pitch
)
389 struct intel_context
*intel
= (struct intel_context
*)
390 ((__DRIcontextPrivate
*)pDRICtx
->private)->driverPrivate
;
391 struct gl_texture_object
*tObj
= _mesa_lookup_texture(&intel
->ctx
, texname
);
392 struct st_texture_object
*stObj
= st_texture_object(tObj
);
398 st
->pipe
->texture_release(intel
->st
->pipe
, &stObj
->pt
);
400 stObj
->imageOverride
= GL_TRUE
;
401 stObj
->depthOverride
= depth
;
402 stObj
->pitchOverride
= pitch
;
405 stObj
->textureOffset
= offset
;
410 static const struct __DriverAPIRec intelAPI
= {
411 .InitDriver
= intelInitDriver
,
412 .DestroyScreen
= intelDestroyScreen
,
413 .CreateContext
= intelCreateContext
,
414 .DestroyContext
= intelDestroyContext
,
415 .CreateBuffer
= intelCreateBuffer
,
416 .DestroyBuffer
= intelDestroyBuffer
,
417 .SwapBuffers
= intelSwapBuffers
,
418 .MakeCurrent
= intelMakeCurrent
,
419 .UnbindContext
= intelUnbindContext
,
420 .GetSwapInfo
= intelGetSwapInfo
,
421 .GetMSC
= driGetMSC32
,
422 .WaitForMSC
= driWaitForMSC32
,
424 .SwapBuffersMSC
= NULL
,
425 .CopySubBuffer
= intelCopySubBuffer
,
426 .setTexOffset
= intelSetTexOffset
,
430 static __GLcontextModes
*
431 intelFillInModes(unsigned pixel_bits
, unsigned depth_bits
,
432 unsigned stencil_bits
, boolean have_back_buffer
)
434 __GLcontextModes
*modes
;
437 unsigned depth_buffer_factor
;
438 unsigned back_buffer_factor
;
442 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
443 * support pageflipping at all.
445 static const GLenum back_buffer_modes
[] = {
446 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
, GLX_SWAP_COPY_OML
449 u_int8_t depth_bits_array
[3];
450 u_int8_t stencil_bits_array
[3];
453 depth_bits_array
[0] = 0;
454 depth_bits_array
[1] = depth_bits
;
455 depth_bits_array
[2] = depth_bits
;
457 /* Just like with the accumulation buffer, always provide some modes
458 * with a stencil buffer. It will be a sw fallback, but some apps won't
461 stencil_bits_array
[0] = 0;
462 stencil_bits_array
[1] = 0;
463 if (depth_bits
== 24)
464 stencil_bits_array
[1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
466 stencil_bits_array
[2] = (stencil_bits
== 0) ? 8 : stencil_bits
;
468 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 3 : 1;
469 back_buffer_factor
= (have_back_buffer
) ? 3 : 1;
471 num_modes
= depth_buffer_factor
* back_buffer_factor
* 4;
473 if (pixel_bits
== 16) {
475 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
479 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
483 (*dri_interface
->createContextModes
) (num_modes
,
484 sizeof(__GLcontextModes
));
486 if (!driFillInModes(&m
, fb_format
, fb_type
,
487 depth_bits_array
, stencil_bits_array
,
488 depth_buffer_factor
, back_buffer_modes
,
489 back_buffer_factor
, GLX_TRUE_COLOR
)) {
490 fprintf(stderr
, "[%s:%u] Error creating FBConfig!\n", __func__
,
494 if (!driFillInModes(&m
, fb_format
, fb_type
,
495 depth_bits_array
, stencil_bits_array
,
496 depth_buffer_factor
, back_buffer_modes
,
497 back_buffer_factor
, GLX_DIRECT_COLOR
)) {
498 fprintf(stderr
, "[%s:%u] Error creating FBConfig!\n", __func__
,
503 /* Mark the visual as slow if there are "fake" stencil bits.
505 for (m
= modes
; m
!= NULL
; m
= m
->next
) {
506 if ((m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
)) {
507 m
->visualRating
= GLX_SLOW_CONFIG
;
516 * This is the bootstrap function for the driver. libGL supplies all of the
517 * requisite information about the system, and the driver initializes itself.
518 * This routine also fills in the linked list pointed to by \c driver_modes
519 * with the \c __GLcontextModes that the driver can support for windows or
522 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
526 __driCreateNewScreen_20050727(__DRInativeDisplay
* dpy
, int scrn
,
528 const __GLcontextModes
* modes
,
529 const __DRIversion
* ddx_version
,
530 const __DRIversion
* dri_version
,
531 const __DRIversion
* drm_version
,
532 const __DRIframebuffer
* frame_buffer
,
533 drmAddress pSAREA
, int fd
,
534 int internal_api_version
,
535 const __DRIinterfaceMethods
* interface
,
536 __GLcontextModes
** driver_modes
)
538 __DRIscreenPrivate
*psp
;
539 static const __DRIversion ddx_expected
= { 1, 7, 0 };
540 static const __DRIversion dri_expected
= { 4, 0, 0 };
541 static const __DRIversion drm_expected
= { 1, 7, 0 };
543 dri_interface
= interface
;
545 if (!driCheckDriDdxDrmVersions2("i915",
546 dri_version
, &dri_expected
,
547 ddx_version
, &ddx_expected
,
548 drm_version
, &drm_expected
)) {
552 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
553 ddx_version
, dri_version
, drm_version
,
554 frame_buffer
, pSAREA
, fd
,
555 internal_api_version
, &intelAPI
);
558 I830DRIPtr dri_priv
= (I830DRIPtr
) psp
->pDevPriv
;
559 *driver_modes
= intelFillInModes(dri_priv
->cpp
* 8,
560 (dri_priv
->cpp
== 2) ? 16 : 24,
561 (dri_priv
->cpp
== 2) ? 0 : 8, 1);
563 /* Calling driInitExtensions here, with a NULL context pointer,
564 * does not actually enable the extensions. It just makes sure
565 * that all the dispatch offsets for all the extensions that
566 * *might* be enables are known. This is needed because the
567 * dispatch offsets need to be known when _mesa_context_create
568 * is called, but we can't enable the extensions until we have a
571 * Hello chicken. Hello egg. How are you two today?
573 driInitExtensions(NULL
, card_extensions
, GL_FALSE
);