00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "utils.h"
00029 #include "vblank.h"
00030 #include "xmlpool.h"
00031
00032 #include "intel_context.h"
00033 #include "intel_screen.h"
00034 #include "intel_batchbuffer.h"
00035 #include "intel_swapbuffers.h"
00036
00037 #include "i830_dri.h"
00038 #include "ws_dri_bufpool.h"
00039
00040 #include "pipe/p_context.h"
00041 #include "pipe/p_screen.h"
00042 #include "pipe/p_inlines.h"
00043 #include "state_tracker/st_public.h"
00044 #include "state_tracker/st_cb_fbo.h"
00045
00046 static void
00047 intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle);
00048
00049 static void
00050 intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle)
00051 {
00052 struct pipe_screen *screen = intelScreen->base.screen;
00053 struct pipe_texture *texture;
00054 struct pipe_texture templat;
00055 struct pipe_surface *surface;
00056 struct pipe_buffer *buffer;
00057 unsigned pitch;
00058
00059 assert(intelScreen->front.cpp == 4);
00060
00061 buffer = intel_be_buffer_from_handle(&intelScreen->base,
00062 "front", handle);
00063
00064 if (!buffer)
00065 return;
00066
00067 intelScreen->front.buffer = dri_bo(buffer);
00068
00069 memset(&templat, 0, sizeof(templat));
00070 templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
00071 templat.target = PIPE_TEXTURE_2D;
00072 templat.last_level = 0;
00073 templat.depth[0] = 1;
00074 templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
00075 templat.width[0] = intelScreen->front.width;
00076 templat.height[0] = intelScreen->front.height;
00077 pf_get_block(templat.format, &templat.block);
00078 pitch = intelScreen->front.pitch;
00079
00080 texture = screen->texture_blanket(screen,
00081 &templat,
00082 &pitch,
00083 buffer);
00084
00085
00086 pipe_buffer_reference(screen, &buffer, NULL);
00087
00088 surface = screen->get_tex_surface(screen,
00089 texture,
00090 0,
00091 0,
00092 0,
00093 PIPE_BUFFER_USAGE_GPU_WRITE);
00094
00095 intelScreen->front.texture = texture;
00096 intelScreen->front.surface = surface;
00097 }
00098
00099 PUBLIC const char __driConfigOptions[] =
00100 DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE
00101 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
00102 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
00103 DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY
00104
00105 DRI_CONF_ALLOW_LARGE_TEXTURES(1)
00106 DRI_CONF_SECTION_END DRI_CONF_END;
00107
00108 const uint __driNConfigOptions = 3;
00109
00110 #ifdef USE_NEW_INTERFACE
00111 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
00112 #endif
00113
00114 extern const struct dri_extension card_extensions[];
00115
00116
00117
00118
00119 static void
00120 intelPrintDRIInfo(struct intel_screen * intelScreen,
00121 __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv)
00122 {
00123 fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n",
00124 intelScreen->front.size, intelScreen->front.offset,
00125 intelScreen->front.pitch);
00126 fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem);
00127 }
00128
00129
00130 #if 0
00131 static void
00132 intelPrintSAREA(const drmI830Sarea * sarea)
00133 {
00134 fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width,
00135 sarea->height);
00136 fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch);
00137 fprintf(stderr,
00138 "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n",
00139 sarea->front_offset, sarea->front_size,
00140 (unsigned) sarea->front_handle);
00141 fprintf(stderr,
00142 "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n",
00143 sarea->back_offset, sarea->back_size,
00144 (unsigned) sarea->back_handle);
00145 fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n",
00146 sarea->depth_offset, sarea->depth_size,
00147 (unsigned) sarea->depth_handle);
00148 fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n",
00149 sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle);
00150 fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation);
00151 fprintf(stderr,
00152 "SAREA: rotated offset: 0x%08x size: 0x%x\n",
00153 sarea->rotated_offset, sarea->rotated_size);
00154 fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch);
00155 }
00156 #endif
00157
00158
00163 void
00164 intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea)
00165 {
00166 struct intel_screen *intelScreen = intel_screen(sPriv);
00167
00168 if (intelScreen->front.map) {
00169 drmUnmap(intelScreen->front.map, intelScreen->front.size);
00170 intelScreen->front.map = NULL;
00171 }
00172
00173 if (intelScreen->front.buffer)
00174 driDeleteBuffers(1, &intelScreen->front.buffer);
00175
00176 intelScreen->front.width = sarea->width;
00177 intelScreen->front.height = sarea->height;
00178 intelScreen->front.offset = sarea->front_offset;
00179 intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp;
00180 intelScreen->front.size = sarea->front_size;
00181 intelScreen->front.handle = sarea->front_handle;
00182
00183 assert( sarea->front_size >=
00184 intelScreen->front.pitch * intelScreen->front.height );
00185
00186 #if 0
00187 if (!sarea->front_handle)
00188 return;
00189
00190 if (drmMap(sPriv->fd,
00191 sarea->front_handle,
00192 intelScreen->front.size,
00193 (drmAddress *) & intelScreen->front.map) != 0) {
00194 fprintf(stderr, "drmMap(frontbuffer) failed!\n");
00195 return;
00196 }
00197 #endif
00198
00199 #if 0
00200 if (intelScreen->staticPool) {
00201 driGenBuffers(intelScreen->staticPool, "static region", 1,
00202 &intelScreen->front.buffer, 64,
00203 DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE |
00204 DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0);
00205
00206 driBOSetStatic(intelScreen->front.buffer,
00207 intelScreen->front.offset,
00208 intelScreen->front.pitch * intelScreen->front.height,
00209 intelScreen->front.map, 0);
00210 }
00211 #else
00212 if (intelScreen->base.staticPool) {
00213 if (intelScreen->front.buffer) {
00214 driBOUnReference(intelScreen->front.buffer);
00215 pipe_surface_reference(&intelScreen->front.surface, NULL);
00216 pipe_texture_reference(&intelScreen->front.texture, NULL);
00217 }
00218 intelCreateSurface(intelScreen, &intelScreen->base.base, sarea->front_bo_handle);
00219 }
00220 #endif
00221 }
00222
00223
00224 boolean
00225 intelCreatePools(__DRIscreenPrivate * sPriv)
00226 {
00227
00228 struct intel_screen *intelScreen = intel_screen(sPriv);
00229
00230 if (intelScreen->havePools)
00231 return GL_TRUE;
00232
00233 intelScreen->havePools = GL_TRUE;
00234
00235 intelUpdateScreenRotation(sPriv, intelScreen->sarea);
00236
00237 return GL_TRUE;
00238 }
00239
00240 static const char *
00241 intel_get_name( struct pipe_winsys *winsys )
00242 {
00243 return "Intel/DRI/ttm";
00244 }
00245
00246
00247
00248
00249
00250
00251 static void
00252 intel_flush_frontbuffer( struct pipe_winsys *winsys,
00253 struct pipe_surface *surf,
00254 void *context_private)
00255 {
00256 struct intel_context *intel = (struct intel_context *) context_private;
00257 __DRIdrawablePrivate *dPriv = intel->driDrawable;
00258
00259 intelDisplaySurface(dPriv, surf, NULL);
00260 }
00261
00262 static boolean
00263 intelInitDriver(__DRIscreenPrivate * sPriv)
00264 {
00265 struct intel_screen *intelScreen;
00266 I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv;
00267
00268 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
00269 (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->
00270 getProcAddress("glxEnableExtension"));
00271 void *const psc = sPriv->psc->screenConfigs;
00272
00273 if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
00274 fprintf(stderr,
00275 "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n");
00276 return GL_FALSE;
00277 }
00278
00279
00280 intelScreen = CALLOC_STRUCT(intel_screen);
00281 if (!intelScreen)
00282 return GL_FALSE;
00283
00284
00285 driParseOptionInfo(&intelScreen->optionCache,
00286 __driConfigOptions, __driNConfigOptions);
00287
00288 sPriv->private = (void *) intelScreen;
00289
00290 intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) +
00291 gDRIPriv->sarea_priv_offset);
00292 intelScreen->deviceID = gDRIPriv->deviceID;
00293 intelScreen->front.cpp = gDRIPriv->cpp;
00294 intelScreen->drmMinor = sPriv->drmMinor;
00295
00296 assert(gDRIPriv->bitsPerPixel == 16 ||
00297 gDRIPriv->bitsPerPixel == 32);
00298
00299 intelUpdateScreenRotation(sPriv, intelScreen->sarea);
00300
00301 if (0)
00302 intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
00303
00304 if (glx_enable_extension != NULL) {
00305 (*glx_enable_extension) (psc, "GLX_SGI_swap_control");
00306 (*glx_enable_extension) (psc, "GLX_SGI_video_sync");
00307 (*glx_enable_extension) (psc, "GLX_MESA_swap_control");
00308 (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage");
00309 (*glx_enable_extension) (psc, "GLX_SGI_make_current_read");
00310 }
00311
00312 intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer;
00313 intelScreen->base.base.get_name = intel_get_name;
00314 intel_be_init_device(&intelScreen->base, sPriv->fd, intelScreen->deviceID);
00315
00316 return GL_TRUE;
00317 }
00318
00319
00320 static void
00321 intelDestroyScreen(__DRIscreenPrivate * sPriv)
00322 {
00323 struct intel_screen *intelScreen = intel_screen(sPriv);
00324
00325 intel_be_destroy_device(&intelScreen->base);
00326
00327
00328 FREE(intelScreen);
00329 sPriv->private = NULL;
00330 }
00331
00332
00336 static boolean
00337 intelCreateBuffer(__DRIscreenPrivate * driScrnPriv,
00338 __DRIdrawablePrivate * driDrawPriv,
00339 const __GLcontextModes * visual, boolean isPixmap)
00340 {
00341 if (isPixmap) {
00342 return GL_FALSE;
00343 }
00344 else {
00345 enum pipe_format colorFormat, depthFormat, stencilFormat;
00346 struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer);
00347
00348 if (!intelfb)
00349 return GL_FALSE;
00350
00351 if (visual->redBits == 5)
00352 colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
00353 else
00354 colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
00355
00356 if (visual->depthBits == 16)
00357 depthFormat = PIPE_FORMAT_Z16_UNORM;
00358 else if (visual->depthBits == 24)
00359 depthFormat = PIPE_FORMAT_S8Z24_UNORM;
00360 else
00361 depthFormat = PIPE_FORMAT_NONE;
00362
00363 if (visual->stencilBits == 8)
00364 stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
00365 else
00366 stencilFormat = PIPE_FORMAT_NONE;
00367
00368 intelfb->stfb = st_create_framebuffer(visual,
00369 colorFormat,
00370 depthFormat,
00371 stencilFormat,
00372 driDrawPriv->w,
00373 driDrawPriv->h,
00374 (void*) intelfb);
00375 if (!intelfb->stfb) {
00376 free(intelfb);
00377 return GL_FALSE;
00378 }
00379
00380 driDrawPriv->driverPrivate = (void *) intelfb;
00381 return GL_TRUE;
00382 }
00383 }
00384
00385 static void
00386 intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv)
00387 {
00388 struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv);
00389 assert(intelfb->stfb);
00390 st_unreference_framebuffer(&intelfb->stfb);
00391 free(intelfb);
00392 }
00393
00394
00398 static int
00399 intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
00400 {
00401 if ((dPriv == NULL) || (dPriv->driverPrivate == NULL)
00402 || (sInfo == NULL)) {
00403 return -1;
00404 }
00405
00406 return 0;
00407 }
00408
00409
00410 static void
00411 intelSetTexOffset(__DRIcontext *pDRICtx, int texname,
00412 unsigned long long offset, int depth, uint pitch)
00413 {
00414 abort();
00415 #if 0
00416 struct intel_context *intel = (struct intel_context*)
00417 ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate;
00418 struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname);
00419 struct st_texture_object *stObj = st_texture_object(tObj);
00420
00421 if (!stObj)
00422 return;
00423
00424 if (stObj->pt)
00425 st->pipe->texture_release(intel->st->pipe, &stObj->pt);
00426
00427 stObj->imageOverride = GL_TRUE;
00428 stObj->depthOverride = depth;
00429 stObj->pitchOverride = pitch;
00430
00431 if (offset)
00432 stObj->textureOffset = offset;
00433 #endif
00434 }
00435
00436
00437 static const struct __DriverAPIRec intelAPI = {
00438 .InitDriver = intelInitDriver,
00439 .DestroyScreen = intelDestroyScreen,
00440 .CreateContext = intelCreateContext,
00441 .DestroyContext = intelDestroyContext,
00442 .CreateBuffer = intelCreateBuffer,
00443 .DestroyBuffer = intelDestroyBuffer,
00444 .SwapBuffers = intelSwapBuffers,
00445 .MakeCurrent = intelMakeCurrent,
00446 .UnbindContext = intelUnbindContext,
00447 .GetSwapInfo = intelGetSwapInfo,
00448 .GetMSC = driGetMSC32,
00449 .WaitForMSC = driWaitForMSC32,
00450 .WaitForSBC = NULL,
00451 .SwapBuffersMSC = NULL,
00452 .CopySubBuffer = intelCopySubBuffer,
00453 .setTexOffset = intelSetTexOffset,
00454 };
00455
00456
00457 static __GLcontextModes *
00458 intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
00459 unsigned stencil_bits, boolean have_back_buffer)
00460 {
00461 __GLcontextModes *modes;
00462 __GLcontextModes *m;
00463 unsigned num_modes;
00464 unsigned depth_buffer_factor;
00465 unsigned back_buffer_factor;
00466 GLenum fb_format;
00467 GLenum fb_type;
00468
00469
00470
00471
00472 static const GLenum back_buffer_modes[] = {
00473 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
00474 };
00475
00476 uint8_t depth_bits_array[3];
00477 uint8_t stencil_bits_array[3];
00478 uint8_t msaa_samples_array[1];
00479
00480
00481 depth_bits_array[0] = 0;
00482 depth_bits_array[1] = depth_bits;
00483 depth_bits_array[2] = depth_bits;
00484 msaa_samples_array[0] = 0;
00485
00486
00487
00488
00489
00490 stencil_bits_array[0] = 0;
00491 stencil_bits_array[1] = 0;
00492 if (depth_bits == 24)
00493 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
00494
00495 stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits;
00496
00497 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
00498 back_buffer_factor = (have_back_buffer) ? 3 : 1;
00499
00500 num_modes = depth_buffer_factor * back_buffer_factor * 4;
00501
00502 if (pixel_bits == 16) {
00503 fb_format = GL_RGB;
00504 fb_type = GL_UNSIGNED_SHORT_5_6_5;
00505 }
00506 else {
00507 fb_format = GL_BGRA;
00508 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
00509 }
00510
00511 modes =
00512 (*dri_interface->createContextModes) (num_modes,
00513 sizeof(__GLcontextModes));
00514 m = modes;
00515 if (!driFillInModes(&m, fb_format, fb_type,
00516 depth_bits_array, stencil_bits_array,
00517 depth_buffer_factor, back_buffer_modes,
00518 back_buffer_factor, msaa_samples_array, 1, GLX_TRUE_COLOR)) {
00519 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
00520 __LINE__);
00521 return NULL;
00522 }
00523 if (!driFillInModes(&m, fb_format, fb_type,
00524 depth_bits_array, stencil_bits_array,
00525 depth_buffer_factor, back_buffer_modes,
00526 back_buffer_factor, msaa_samples_array, 1, GLX_DIRECT_COLOR)) {
00527 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
00528 __LINE__);
00529 return NULL;
00530 }
00531
00532
00533
00534 for (m = modes; m != NULL; m = m->next) {
00535 if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
00536 m->visualRating = GLX_SLOW_CONFIG;
00537 }
00538 }
00539
00540 return modes;
00541 }
00542
00543
00554 PUBLIC void *
00555 __driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn,
00556 __DRIscreen * psc,
00557 const __GLcontextModes * modes,
00558 const __DRIversion * ddx_version,
00559 const __DRIversion * dri_version,
00560 const __DRIversion * drm_version,
00561 const __DRIframebuffer * frame_buffer,
00562 drmAddress pSAREA, int fd,
00563 int internal_api_version,
00564 const __DRIinterfaceMethods * interface,
00565 __GLcontextModes ** driver_modes)
00566 {
00567 __DRIscreenPrivate *psp;
00568 static const __DRIversion ddx_expected = { 1, 7, 0 };
00569 static const __DRIversion dri_expected = { 4, 0, 0 };
00570 static const __DRIversion drm_expected = { 1, 7, 0 };
00571
00572 dri_interface = interface;
00573
00574 if (!driCheckDriDdxDrmVersions2("i915",
00575 dri_version, &dri_expected,
00576 ddx_version, &ddx_expected,
00577 drm_version, &drm_expected)) {
00578 return NULL;
00579 }
00580
00581 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
00582 ddx_version, dri_version, drm_version,
00583 frame_buffer, pSAREA, fd,
00584 internal_api_version, &intelAPI);
00585
00586 if (psp != NULL) {
00587 I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
00588 *driver_modes = intelFillInModes(dri_priv->cpp * 8,
00589 (dri_priv->cpp == 2) ? 16 : 24,
00590 (dri_priv->cpp == 2) ? 0 : 8, 1);
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 driInitExtensions(NULL, card_extensions, GL_FALSE);
00603 }
00604
00605 return (void *) psp;
00606 }
00607