1 /**************************************************************************
3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4 Copyright © 2002 David Dawes
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sub license, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial portions
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
24 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Keith Whitwell <keith@tungstengraphics.com>
33 * David Dawes <dawes@xfree86.org>
47 #ifndef REMAP_RESERVED
48 #define REMAP_RESERVED 0
54 #include "xf86_OSproc.h"
56 #include "xf86PciInfo.h"
58 #include "xf86Cursor.h"
62 #include "xf86RandR12.h"
64 #include "xorg-server.h"
65 #include <pciaccess.h>
69 #define _XF86DRI_SERVER_
72 #include "intel_bufmgr.h"
75 #include "intel_driver.h"
83 * The X server gained an *almost* identical implementation in 1.9.
85 * Remove this duplicate code either in 2.16 (when we can depend upon 1.9)
86 * or the drivers are merged back into the xserver tree, whichever happens
91 /* classic doubly-link circular list */
93 struct list *next, *prev;
97 list_init(struct list *list)
99 list->next = list->prev = list;
103 __list_add(struct list *entry,
114 list_add(struct list *entry, struct list *head)
116 __list_add(entry, head, head->next);
120 __list_del(struct list *prev, struct list *next)
127 list_del(struct list *entry)
129 __list_del(entry->prev, entry->next);
134 list_is_empty(struct list *head)
136 return head->next == head;
140 /* XXX work around a broken define in list.h currently [ickle 20100713] */
144 #define container_of(ptr, type, member) \
145 ((type *)((char *)(ptr) - (char *) &((type *)0)->member))
149 #define list_entry(ptr, type, member) \
150 container_of(ptr, type, member)
153 #ifndef list_first_entry
154 #define list_first_entry(ptr, type, member) \
155 list_entry((ptr)->next, type, member)
159 #define list_foreach(pos, head) \
160 for (pos = (head)->next; pos != (head); pos = pos->next)
163 /* XXX list.h from xserver-1.9 uses a GCC-ism to avoid having to pass type */
164 #ifndef list_foreach_entry
165 #define list_foreach_entry(pos, type, head, member) \
166 for (pos = list_entry((head)->next, type, member);\
167 &pos->member != (head); \
168 pos = list_entry(pos->member.next, type, member))
171 /* remain compatible to xorg-server 1.6 */
172 #ifndef MONITOR_EDID_COMPLETE_RAWDATA
173 #define MONITOR_EDID_COMPLETE_RAWDATA EDID_COMPLETE_RAWDATA
176 struct intel_pixmap {
179 struct list flush, batch, in_flight;
181 uint16_t src_bound, dst_bound;
185 int8_t batch_write :1;
190 #if HAS_DEVPRIVATEKEYREC
191 extern DevPrivateKeyRec uxa_pixmap_index;
193 extern int uxa_pixmap_index;
196 static inline struct intel_pixmap *intel_get_pixmap_private(PixmapPtr pixmap)
198 #if HAS_DEVPRIVATEKEYREC
199 return dixGetPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
201 return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
205 static inline Bool intel_pixmap_is_busy(struct intel_pixmap *priv)
207 if (priv->busy == -1)
208 priv->busy = drm_intel_bo_busy(priv->bo);
212 static inline void intel_set_pixmap_private(PixmapPtr pixmap, struct intel_pixmap *intel)
214 dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, intel);
217 static inline Bool intel_pixmap_is_dirty(PixmapPtr pixmap)
219 return !list_is_empty(&intel_get_pixmap_private(pixmap)->flush);
222 static inline Bool intel_pixmap_tiled(PixmapPtr pixmap)
224 return intel_get_pixmap_private(pixmap)->tiling != I915_TILING_NONE;
227 dri_bo *intel_get_pixmap_bo(PixmapPtr pixmap);
228 void intel_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo);
240 /** enumeration of 3d consumers so some can maintain invariant state. */
254 typedef struct intel_screen_private {
258 #define RENDER_BATCH I915_EXEC_RENDER
259 #define BLT_BATCH I915_EXEC_BLT
260 unsigned int current_batch;
263 drm_intel_bo *front_buffer;
264 long front_pitch, front_tiling;
267 DamagePtr shadow_damage;
271 uint32_t batch_ptr[4096];
272 /** Byte offset in batch_ptr for the next dword to be emitted. */
273 unsigned int batch_used;
274 /** Position in batch_ptr at the start of the current BEGIN_BATCH */
275 unsigned int batch_emit_start;
276 /** Number of bytes to be emitted in the current BEGIN_BATCH. */
277 uint32_t batch_emitting;
279 /** Whether we're in a section of code that can't tolerate flushing */
280 Bool in_batch_atomic;
281 /** Ending batch_used that was verified by intel_start_batch_atomic() */
282 int batch_atomic_limit;
283 struct list batch_pixmaps;
284 struct list flush_pixmaps;
285 struct list in_flight;
294 CreateScreenResourcesProcPtr CreateScreenResources;
299 #define INTEL_TILING_FB 0x1
300 #define INTEL_TILING_2D 0x2
301 #define INTEL_TILING_3D 0x4
302 #define INTEL_TILING_ALL (~0)
304 Bool swapbuffers_wait;
305 Bool has_relaxed_fencing;
309 struct pci_device *PciInfo;
310 struct intel_chipset chipset;
314 CloseScreenProcPtr CloseScreen;
316 void (*context_switch) (struct intel_screen_private *intel,
318 void (*vertex_flush) (struct intel_screen_private *intel);
319 void (*batch_flush) (struct intel_screen_private *intel);
320 void (*batch_commit_notify) (struct intel_screen_private *intel);
322 uxa_driver_t *uxa_driver;
324 int accel_pixmap_offset_alignment;
328 int max_gtt_map_size;
331 Bool XvDisabled; /* Xv disabled in PreInit. */
332 Bool XvEnabled; /* Xv enabled for this generation. */
333 Bool XvPreferOverlay;
336 XF86VideoAdaptorPtr adaptor;
337 ScreenBlockHandlerProcPtr BlockHandler;
341 drm_intel_bo *gen4_vs_bo;
342 drm_intel_bo *gen4_sf_bo;
343 drm_intel_bo *gen4_wm_packed_bo;
344 drm_intel_bo *gen4_wm_planar_bo;
345 drm_intel_bo *gen4_cc_bo;
346 drm_intel_bo *gen4_cc_vp_bo;
347 drm_intel_bo *gen4_sampler_bo;
348 drm_intel_bo *gen4_sip_kernel_bo;
349 drm_intel_bo *wm_prog_packed_bo;
350 drm_intel_bo *wm_prog_planar_bo;
351 drm_intel_bo *gen6_blend_bo;
352 drm_intel_bo *gen6_depth_stencil_bo;
355 /* Render accel state */
356 float scale_units[2][2];
357 /** Transform pointers for src/mask, or NULL if identity */
358 PictTransform *transform[2];
360 PixmapPtr render_source, render_mask, render_dest;
361 PicturePtr render_source_picture, render_mask_picture, render_dest_picture;
362 CARD32 render_source_solid;
363 CARD32 render_mask_solid;
364 PixmapPtr render_current_dest;
365 Bool render_source_is_solid;
366 Bool render_mask_is_solid;
367 Bool needs_3d_invariant;
368 Bool needs_render_state_emit;
369 Bool needs_render_vertex_emit;
370 Bool needs_render_ca_pass;
372 /* i830 render accel state */
373 uint32_t render_dest_format;
374 uint32_t cblend, ablend, s8_blendctl;
376 /* i915 render accel state */
377 PixmapPtr texture[2];
378 uint32_t mapstate[6];
379 uint32_t samplerstate[6];
394 uint32_t prim_offset;
395 void (*prim_emit)(struct intel_screen_private *intel,
397 int maskX, int maskY,
400 int floats_per_vertex;
401 int last_floats_per_vertex;
402 uint16_t vertex_offset;
403 uint16_t vertex_count;
404 uint16_t vertex_index;
405 uint16_t vertex_used;
407 float vertex_ptr[4*1024];
410 uint8_t surface_data[16*1024];
411 uint16_t surface_used;
412 uint16_t surface_table;
413 uint32_t surface_reloc;
416 /* 965 render acceleration state */
417 struct gen4_render_state *gen4_render_state;
419 enum dri_type directRenderingType; /* DRI enabled this generation. */
421 Bool directRenderingOpen;
425 Bool use_pageflipping;
428 Bool has_kernel_flush;
432 /* Broken-out options. */
433 OptionInfoPtr Options;
435 /* Driver phase/state information */
438 enum last_3d last_3d;
441 * User option to print acceleration fallback info to the server log.
444 unsigned debug_flush;
446 struct udev_monitor *uevent_monitor;
447 InputHandlerProc uevent_handler;
449 } intel_screen_private;
452 DEBUG_FLUSH_BATCHES = 0x1,
453 DEBUG_FLUSH_CACHES = 0x2,
454 DEBUG_FLUSH_WAIT = 0x4,
457 extern Bool intel_mode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp);
458 extern void intel_mode_init(struct intel_screen_private *intel);
459 extern void intel_mode_remove_fb(intel_screen_private *intel);
460 extern void intel_mode_fini(intel_screen_private *intel);
462 extern int intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc);
463 extern int intel_crtc_id(xf86CrtcPtr crtc);
464 extern int intel_output_dpms_status(xf86OutputPtr output);
466 enum DRI2FrameEventType {
472 #if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1,7,99,3,0)
473 typedef void (*DRI2SwapEventPtr)(ClientPtr client, void *data, int type,
474 CARD64 ust, CARD64 msc, CARD64 sbc);
477 typedef struct _DRI2FrameEvent {
479 XID client_id; /* fake client ID to track client destruction */
481 enum DRI2FrameEventType type;
484 /* for swaps & flips only */
485 DRI2SwapEventPtr event_complete;
489 } DRI2FrameEventRec, *DRI2FrameEventPtr;
491 extern Bool intel_do_pageflip(intel_screen_private *intel,
493 DRI2FrameEventPtr flip_info, int ref_crtc_hw_id);
495 static inline intel_screen_private *
496 intel_get_screen_private(ScrnInfoPtr scrn)
498 return (intel_screen_private *)(scrn->driverPrivate);
501 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
502 #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1))
503 #define MIN(a,b) ((a) < (b) ? (a) : (b))
505 static inline unsigned long intel_pixmap_pitch(PixmapPtr pixmap)
507 return (unsigned long)pixmap->devKind;
510 /* Batchbuffer support macros and functions */
511 #include "intel_batchbuffer.h"
513 /* I830 specific functions */
514 extern void IntelEmitInvarientState(ScrnInfoPtr scrn);
515 extern void I830EmitInvarientState(ScrnInfoPtr scrn);
516 extern void I915EmitInvarientState(ScrnInfoPtr scrn);
518 extern void I830EmitFlush(ScrnInfoPtr scrn);
520 extern void I830InitVideo(ScreenPtr pScreen);
521 extern xf86CrtcPtr intel_covering_crtc(ScrnInfoPtr scrn, BoxPtr box,
522 xf86CrtcPtr desired, BoxPtr crtc_box_ret);
524 Bool I830DRI2ScreenInit(ScreenPtr pScreen);
525 void I830DRI2CloseScreen(ScreenPtr pScreen);
526 void I830DRI2FrameEventHandler(unsigned int frame, unsigned int tv_sec,
527 unsigned int tv_usec, DRI2FrameEventPtr flip_info);
528 void I830DRI2FlipEventHandler(unsigned int frame, unsigned int tv_sec,
529 unsigned int tv_usec, DRI2FrameEventPtr flip_info);
531 extern Bool intel_crtc_on(xf86CrtcPtr crtc);
532 int intel_crtc_to_pipe(xf86CrtcPtr crtc);
535 unsigned long intel_get_fence_size(intel_screen_private *intel, unsigned long size);
536 unsigned long intel_get_fence_pitch(intel_screen_private *intel, unsigned long pitch,
537 uint32_t tiling_mode);
538 void intel_set_gem_max_sizes(ScrnInfoPtr scrn);
540 drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn,
541 int w, int h, int cpp,
542 unsigned long *pitch,
546 Bool i830_check_composite(int op,
547 PicturePtr sourcec, PicturePtr mask, PicturePtr dest,
548 int width, int height);
549 Bool i830_check_composite_target(PixmapPtr pixmap);
550 Bool i830_check_composite_texture(ScreenPtr screen, PicturePtr picture);
551 Bool i830_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
552 PicturePtr dest, PixmapPtr sourcecPixmap,
553 PixmapPtr maskPixmap, PixmapPtr destPixmap);
554 void i830_composite(PixmapPtr dest, int srcX, int srcY,
555 int maskX, int maskY, int dstX, int dstY, int w, int h);
556 void i830_vertex_flush(intel_screen_private *intel);
559 Bool i915_check_composite(int op,
560 PicturePtr sourcec, PicturePtr mask, PicturePtr dest,
561 int width, int height);
562 Bool i915_check_composite_target(PixmapPtr pixmap);
563 Bool i915_check_composite_texture(ScreenPtr screen, PicturePtr picture);
564 Bool i915_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
565 PicturePtr dest, PixmapPtr sourcecPixmap,
566 PixmapPtr maskPixmap, PixmapPtr destPixmap);
567 void i915_composite(PixmapPtr dest, int srcX, int srcY,
568 int maskX, int maskY, int dstX, int dstY, int w, int h);
569 void i915_vertex_flush(intel_screen_private *intel);
570 void i915_batch_commit_notify(intel_screen_private *intel);
571 void i830_batch_commit_notify(intel_screen_private *intel);
573 unsigned int gen4_render_state_size(ScrnInfoPtr scrn);
574 void gen4_render_state_init(ScrnInfoPtr scrn);
575 void gen4_render_state_cleanup(ScrnInfoPtr scrn);
576 Bool i965_check_composite(int op,
577 PicturePtr sourcec, PicturePtr mask, PicturePtr dest,
578 int width, int height);
579 Bool i965_check_composite_texture(ScreenPtr screen, PicturePtr picture);
580 Bool i965_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
581 PicturePtr dest, PixmapPtr sourcecPixmap,
582 PixmapPtr maskPixmap, PixmapPtr destPixmap);
583 void i965_composite(PixmapPtr dest, int srcX, int srcY,
584 int maskX, int maskY, int dstX, int dstY, int w, int h);
586 void i965_vertex_flush(intel_screen_private *intel);
587 void i965_batch_flush(intel_screen_private *intel);
588 void i965_batch_commit_notify(intel_screen_private *intel);
590 Bool intel_transform_is_affine(PictTransformPtr t);
592 intel_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
593 float *x_out, float *y_out);
596 intel_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
597 float *x_out, float *y_out, float *z_out);
600 intel_debug_fallback(ScrnInfoPtr scrn, char *format, ...)
602 intel_screen_private *intel = intel_get_screen_private(scrn);
605 va_start(ap, format);
606 if (intel->fallback_debug) {
607 xf86DrvMsg(scrn->scrnIndex, X_INFO, "fallback: ");
608 LogVMessageVerb(X_INFO, 1, format, ap);
614 intel_check_pitch_2d(PixmapPtr pixmap)
616 uint32_t pitch = intel_pixmap_pitch(pixmap);
617 if (pitch > KB(32)) {
618 ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
619 intel_debug_fallback(scrn, "pitch exceeds 2d limit 32K\n");
625 /* For pre-965 chip only, as they have 8KB limit for 3D */
627 intel_check_pitch_3d(PixmapPtr pixmap)
629 uint32_t pitch = intel_pixmap_pitch(pixmap);
631 ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
632 intel_debug_fallback(scrn, "pitch exceeds 3d limit 8K\n");
639 * Little wrapper around drm_intel_bo_reloc to return the initial value you
640 * should stuff into the relocation entry.
642 * If only we'd done this before settling on the library API.
644 static inline uint32_t
645 intel_emit_reloc(drm_intel_bo * bo, uint32_t offset,
646 drm_intel_bo * target_bo, uint32_t target_offset,
647 uint32_t read_domains, uint32_t write_domain)
649 drm_intel_bo_emit_reloc(bo, offset, target_bo, target_offset,
650 read_domains, write_domain);
652 return target_bo->offset + target_offset;
655 static inline drm_intel_bo *intel_bo_alloc_for_data(intel_screen_private *intel,
662 bo = drm_intel_bo_alloc(intel->bufmgr, name, size, 4096);
664 drm_intel_bo_subdata(bo, 0, size, data);
668 void intel_debug_flush(ScrnInfoPtr scrn);
670 static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
672 ScreenPtr screen = drawable->pScreen;
674 if (drawable->type == DRAWABLE_PIXMAP)
675 return (PixmapPtr) drawable;
677 return screen->GetWindowPixmap((WindowPtr) drawable);
680 static inline Bool pixmap_is_scanout(PixmapPtr pixmap)
682 ScreenPtr screen = pixmap->drawable.pScreen;
684 return pixmap == screen->GetScreenPixmap(screen);
687 const OptionInfoRec *intel_uxa_available_options(int chipid, int busid);
689 Bool intel_uxa_init(ScreenPtr pScreen);
690 Bool intel_uxa_create_screen_resources(ScreenPtr pScreen);
691 void intel_uxa_block_handler(intel_screen_private *intel);
692 Bool intel_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table,
696 void intel_shadow_blt(intel_screen_private *intel);
697 void intel_shadow_create(struct intel_screen_private *intel);
699 #endif /* _I830_H_ */