mirror of
https://github.com/X11Libre/xf86-video-ati.git
synced 2026-03-24 01:24:43 +00:00
Inspired by amdgpu. This avoids various issues due to a GEM handle lifetime conflict between us and Mesa with current glamor. Bugzilla: https://bugs.freedesktop.org/105381 Tested-by: Konstantin Kharlamov <hi-angel@yandex.ru> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
1057 lines
28 KiB
C
1057 lines
28 KiB
C
/*
|
|
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
|
|
* VA Linux Systems Inc., Fremont, California.
|
|
*
|
|
* All Rights Reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
* a copy of this software and associated documentation files (the
|
|
* "Software"), to deal in the Software without restriction, including
|
|
* without limitation on the rights to use, copy, modify, merge,
|
|
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
* and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the
|
|
* next paragraph) shall be included in all copies or substantial
|
|
* portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
|
|
* THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
/*
|
|
* Authors:
|
|
* Kevin E. Martin <martin@xfree86.org>
|
|
* Rickard E. Faith <faith@valinux.com>
|
|
* Alan Hourihane <alanh@fairlite.demon.co.uk>
|
|
*
|
|
*/
|
|
|
|
#ifndef _RADEON_H_
|
|
#define _RADEON_H_
|
|
|
|
#include <stdlib.h> /* For abs() */
|
|
#include <unistd.h> /* For usleep() */
|
|
#include <sys/time.h> /* For gettimeofday() */
|
|
|
|
#include "config.h"
|
|
|
|
#include "xf86str.h"
|
|
#include "compiler.h"
|
|
|
|
/* PCI support */
|
|
#include "xf86Pci.h"
|
|
|
|
#include "exa.h"
|
|
|
|
/* Exa and Cursor Support */
|
|
#include "xf86Cursor.h"
|
|
|
|
/* DDC support */
|
|
#include "xf86DDC.h"
|
|
|
|
/* Xv support */
|
|
#include "xf86xv.h"
|
|
|
|
#include "radeon_probe.h"
|
|
|
|
/* DRI support */
|
|
#include "xf86drm.h"
|
|
#include "radeon_drm.h"
|
|
|
|
#ifndef RADEON_GEM_NO_CPU_ACCESS
|
|
#define RADEON_GEM_NO_CPU_ACCESS (1 << 4)
|
|
#endif
|
|
|
|
#ifdef DAMAGE
|
|
#include "damage.h"
|
|
#include "globals.h"
|
|
#endif
|
|
|
|
#include "xf86Crtc.h"
|
|
#include "X11/Xatom.h"
|
|
|
|
#include "radeon_bo.h"
|
|
#include "radeon_cs.h"
|
|
#include "radeon_dri2.h"
|
|
#include "drmmode_display.h"
|
|
#include "radeon_surface.h"
|
|
#include "radeon_bo_helper.h"
|
|
|
|
/* Render support */
|
|
#ifdef RENDER
|
|
#include "picturestr.h"
|
|
#endif
|
|
|
|
#include "compat-api.h"
|
|
|
|
#include "simple_list.h"
|
|
#include "atipcirename.h"
|
|
|
|
struct _SyncFence;
|
|
|
|
#ifndef HAVE_REGIONDUPLICATE
|
|
|
|
static inline RegionPtr
|
|
RegionDuplicate(RegionPtr pOld)
|
|
{
|
|
RegionPtr pNew;
|
|
|
|
pNew = RegionCreate(&pOld->extents, 0);
|
|
if (!pNew)
|
|
return NULL;
|
|
if (!RegionCopy(pNew, pOld)) {
|
|
RegionDestroy(pNew);
|
|
return NULL;
|
|
}
|
|
return pNew;
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifndef MAX
|
|
#define MAX(a,b) ((a)>(b)?(a):(b))
|
|
#endif
|
|
#ifndef MIN
|
|
#define MIN(a,b) ((a)>(b)?(b):(a))
|
|
#endif
|
|
|
|
#if HAVE_BYTESWAP_H
|
|
#include <byteswap.h>
|
|
#elif defined(USE_SYS_ENDIAN_H)
|
|
#include <sys/endian.h>
|
|
#else
|
|
#define bswap_16(value) \
|
|
((((value) & 0xff) << 8) | ((value) >> 8))
|
|
|
|
#define bswap_32(value) \
|
|
(((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \
|
|
(uint32_t)bswap_16((uint16_t)((value) >> 16)))
|
|
|
|
#define bswap_64(value) \
|
|
(((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) \
|
|
<< 32) | \
|
|
(uint64_t)bswap_32((uint32_t)((value) >> 32)))
|
|
#endif
|
|
|
|
#if X_BYTE_ORDER == X_BIG_ENDIAN
|
|
#define le32_to_cpu(x) bswap_32(x)
|
|
#define le16_to_cpu(x) bswap_16(x)
|
|
#define cpu_to_le32(x) bswap_32(x)
|
|
#define cpu_to_le16(x) bswap_16(x)
|
|
#else
|
|
#define le32_to_cpu(x) (x)
|
|
#define le16_to_cpu(x) (x)
|
|
#define cpu_to_le32(x) (x)
|
|
#define cpu_to_le16(x) (x)
|
|
#endif
|
|
|
|
/* Provide substitutes for gcc's __FUNCTION__ on other compilers */
|
|
#if !defined(__GNUC__) && !defined(__FUNCTION__)
|
|
# define __FUNCTION__ __func__ /* C99 */
|
|
#endif
|
|
|
|
typedef enum {
|
|
OPTION_ACCEL,
|
|
OPTION_SW_CURSOR,
|
|
OPTION_PAGE_FLIP,
|
|
OPTION_EXA_PIXMAPS,
|
|
OPTION_COLOR_TILING,
|
|
OPTION_COLOR_TILING_2D,
|
|
#ifdef RENDER
|
|
OPTION_RENDER_ACCEL,
|
|
OPTION_SUBPIXEL_ORDER,
|
|
#endif
|
|
OPTION_ACCELMETHOD,
|
|
OPTION_EXA_VSYNC,
|
|
OPTION_ZAPHOD_HEADS,
|
|
OPTION_SWAPBUFFERS_WAIT,
|
|
OPTION_DELETE_DP12,
|
|
OPTION_DRI3,
|
|
OPTION_DRI,
|
|
OPTION_SHADOW_PRIMARY,
|
|
OPTION_TEAR_FREE,
|
|
} RADEONOpts;
|
|
|
|
|
|
static inline ScreenPtr
|
|
radeon_master_screen(ScreenPtr screen)
|
|
{
|
|
if (screen->current_master)
|
|
return screen->current_master;
|
|
|
|
return screen;
|
|
}
|
|
|
|
static inline ScreenPtr
|
|
radeon_dirty_master(PixmapDirtyUpdatePtr dirty)
|
|
{
|
|
return radeon_master_screen(dirty->slave_dst->drawable.pScreen);
|
|
}
|
|
|
|
static inline DrawablePtr
|
|
radeon_dirty_src_drawable(PixmapDirtyUpdatePtr dirty)
|
|
{
|
|
#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC
|
|
return dirty->src;
|
|
#else
|
|
return &dirty->src->drawable;
|
|
#endif
|
|
}
|
|
|
|
static inline Bool
|
|
radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap)
|
|
{
|
|
return radeon_dirty_src_drawable(dirty) == &pixmap->drawable;
|
|
}
|
|
|
|
|
|
#define RADEON_VSYNC_TIMEOUT 20000 /* Maximum wait for VSYNC (in usecs) */
|
|
|
|
/* Buffer are aligned on 4096 byte boundaries */
|
|
#define RADEON_GPU_PAGE_SIZE 4096
|
|
#define RADEON_BUFFER_ALIGN (RADEON_GPU_PAGE_SIZE - 1)
|
|
|
|
|
|
#define xFixedToFloat(f) (((float) (f)) / 65536)
|
|
|
|
#define RADEON_LOGLEVEL_DEBUG 4
|
|
|
|
/* for Xv, outputs */
|
|
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
|
|
|
|
/* Other macros */
|
|
#define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
|
|
#define RADEONPTR(pScrn) ((RADEONInfoPtr)(pScrn)->driverPrivate)
|
|
|
|
#define IS_RV100_VARIANT ((info->ChipFamily == CHIP_FAMILY_RV100) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV200) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RS100) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RS200) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV250) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV280) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RS300))
|
|
|
|
|
|
#define IS_R300_VARIANT ((info->ChipFamily == CHIP_FAMILY_R300) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV350) || \
|
|
(info->ChipFamily == CHIP_FAMILY_R350) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV380) || \
|
|
(info->ChipFamily == CHIP_FAMILY_R420) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV410) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RS400) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RS480))
|
|
|
|
#define IS_AVIVO_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV515))
|
|
|
|
#define IS_DCE3_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV620))
|
|
|
|
#define IS_DCE32_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV730))
|
|
|
|
#define IS_DCE4_VARIANT ((info->ChipFamily >= CHIP_FAMILY_CEDAR))
|
|
|
|
#define IS_DCE41_VARIANT ((info->ChipFamily >= CHIP_FAMILY_PALM))
|
|
|
|
#define IS_DCE5_VARIANT ((info->ChipFamily >= CHIP_FAMILY_BARTS))
|
|
|
|
#define IS_EVERGREEN_3D (info->ChipFamily >= CHIP_FAMILY_CEDAR)
|
|
|
|
#define IS_R600_3D (info->ChipFamily >= CHIP_FAMILY_R600)
|
|
|
|
#define IS_R500_3D ((info->ChipFamily == CHIP_FAMILY_RV515) || \
|
|
(info->ChipFamily == CHIP_FAMILY_R520) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV530) || \
|
|
(info->ChipFamily == CHIP_FAMILY_R580) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV560) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV570))
|
|
|
|
/* RS6xx, RS740 are technically R4xx as well, but the
|
|
* clipping hardware seems to follow the r3xx restrictions
|
|
*/
|
|
#define IS_R400_3D ((info->ChipFamily == CHIP_FAMILY_R420) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV410))
|
|
|
|
#define IS_R300_3D ((info->ChipFamily == CHIP_FAMILY_R300) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV350) || \
|
|
(info->ChipFamily == CHIP_FAMILY_R350) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV380) || \
|
|
(info->ChipFamily == CHIP_FAMILY_R420) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV410) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RS690) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RS600) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RS740) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RS400) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RS480))
|
|
|
|
#define IS_R200_3D ((info->ChipFamily == CHIP_FAMILY_RV250) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RV280) || \
|
|
(info->ChipFamily == CHIP_FAMILY_RS300) || \
|
|
(info->ChipFamily == CHIP_FAMILY_R200))
|
|
|
|
#define CURSOR_WIDTH 64
|
|
#define CURSOR_HEIGHT 64
|
|
|
|
#define CURSOR_WIDTH_CIK 128
|
|
#define CURSOR_HEIGHT_CIK 128
|
|
|
|
#ifdef USE_GLAMOR
|
|
|
|
struct radeon_pixmap {
|
|
uint_fast32_t gpu_read;
|
|
uint_fast32_t gpu_write;
|
|
|
|
struct radeon_buffer *bo;
|
|
struct drmmode_fb *fb;
|
|
|
|
uint32_t tiling_flags;
|
|
|
|
/* GEM handle for glamor-only pixmaps shared via DRI3 */
|
|
Bool handle_valid;
|
|
uint32_t handle;
|
|
};
|
|
|
|
extern DevPrivateKeyRec glamor_pixmap_index;
|
|
|
|
static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap)
|
|
{
|
|
return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
|
|
}
|
|
|
|
static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv)
|
|
{
|
|
dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_index, priv);
|
|
}
|
|
|
|
#endif /* USE_GLAMOR */
|
|
|
|
|
|
struct radeon_exa_pixmap_priv {
|
|
struct radeon_buffer *bo;
|
|
struct drmmode_fb *fb;
|
|
uint32_t tiling_flags;
|
|
struct radeon_surface surface;
|
|
Bool bo_mapped;
|
|
Bool shared;
|
|
};
|
|
|
|
#define RADEON_2D_EXA_COPY 1
|
|
#define RADEON_2D_EXA_SOLID 2
|
|
|
|
struct radeon_2d_state {
|
|
int op; //
|
|
uint32_t dst_pitch_offset;
|
|
uint32_t src_pitch_offset;
|
|
uint32_t dp_gui_master_cntl;
|
|
uint32_t dp_cntl;
|
|
uint32_t dp_write_mask;
|
|
uint32_t dp_brush_frgd_clr;
|
|
uint32_t dp_brush_bkgd_clr;
|
|
uint32_t dp_src_frgd_clr;
|
|
uint32_t dp_src_bkgd_clr;
|
|
uint32_t default_sc_bottom_right;
|
|
uint32_t dst_domain;
|
|
struct radeon_bo *dst_bo;
|
|
struct radeon_bo *src_bo;
|
|
};
|
|
|
|
#define DMA_BO_FREE_TIME 1000
|
|
|
|
struct radeon_dma_bo {
|
|
struct radeon_dma_bo *next, *prev;
|
|
struct radeon_bo *bo;
|
|
int expire_counter;
|
|
};
|
|
|
|
struct r600_accel_object {
|
|
uint32_t pitch;
|
|
uint32_t width;
|
|
uint32_t height;
|
|
int bpp;
|
|
uint32_t domain;
|
|
struct radeon_bo *bo;
|
|
uint32_t tiling_flags;
|
|
struct radeon_surface *surface;
|
|
};
|
|
|
|
struct radeon_vbo_object {
|
|
int vb_offset;
|
|
int vb_total;
|
|
uint32_t vb_size;
|
|
uint32_t vb_op_vert_size;
|
|
int32_t vb_start_op;
|
|
struct radeon_bo *vb_bo;
|
|
unsigned verts_per_op;
|
|
};
|
|
|
|
struct radeon_accel_state {
|
|
|
|
/* Saved values for ScreenToScreenCopy */
|
|
int xdir;
|
|
int ydir;
|
|
|
|
/* render accel */
|
|
unsigned short texW[2];
|
|
unsigned short texH[2];
|
|
Bool XInited3D; /* X itself has the 3D context */
|
|
int num_gb_pipes;
|
|
Bool has_tcl;
|
|
Bool allowHWDFS;
|
|
|
|
/* EXA */
|
|
ExaDriverPtr exa;
|
|
int exaSyncMarker;
|
|
int exaMarkerSynced;
|
|
int engineMode;
|
|
#define EXA_ENGINEMODE_UNKNOWN 0
|
|
#define EXA_ENGINEMODE_2D 1
|
|
#define EXA_ENGINEMODE_3D 2
|
|
|
|
int composite_op;
|
|
PicturePtr dst_pic;
|
|
PicturePtr msk_pic;
|
|
PicturePtr src_pic;
|
|
PixmapPtr dst_pix;
|
|
PixmapPtr msk_pix;
|
|
PixmapPtr src_pix;
|
|
Bool is_transform[2];
|
|
PictTransform *transform[2];
|
|
/* Whether we are tiling horizontally and vertically */
|
|
Bool need_src_tile_x;
|
|
Bool need_src_tile_y;
|
|
/* Size of tiles ... set to 65536x65536 if not tiling in that direction */
|
|
Bool src_tile_width;
|
|
Bool src_tile_height;
|
|
uint32_t *draw_header;
|
|
unsigned vtx_count;
|
|
unsigned num_vtx;
|
|
Bool vsync;
|
|
|
|
struct radeon_vbo_object vbo;
|
|
struct radeon_vbo_object cbuf;
|
|
|
|
/* where to discard IB from if we cancel operation */
|
|
uint32_t ib_reset_op;
|
|
struct radeon_dma_bo bo_free;
|
|
struct radeon_dma_bo bo_wait;
|
|
struct radeon_dma_bo bo_reserved;
|
|
Bool use_vbos;
|
|
void (*finish_op)(ScrnInfoPtr, int);
|
|
// shader storage
|
|
struct radeon_bo *shaders_bo;
|
|
uint32_t solid_vs_offset;
|
|
uint32_t solid_ps_offset;
|
|
uint32_t copy_vs_offset;
|
|
uint32_t copy_ps_offset;
|
|
uint32_t comp_vs_offset;
|
|
uint32_t comp_ps_offset;
|
|
uint32_t xv_vs_offset;
|
|
uint32_t xv_ps_offset;
|
|
// shader consts
|
|
uint32_t solid_vs_const_offset;
|
|
uint32_t solid_ps_const_offset;
|
|
uint32_t copy_vs_const_offset;
|
|
uint32_t copy_ps_const_offset;
|
|
uint32_t comp_vs_const_offset;
|
|
uint32_t comp_ps_const_offset;
|
|
uint32_t comp_mask_ps_const_offset;
|
|
uint32_t xv_vs_const_offset;
|
|
uint32_t xv_ps_const_offset;
|
|
|
|
//size/addr stuff
|
|
struct r600_accel_object src_obj[2];
|
|
struct r600_accel_object dst_obj;
|
|
uint32_t src_size[2];
|
|
uint32_t dst_size;
|
|
|
|
uint32_t vs_size;
|
|
uint64_t vs_mc_addr;
|
|
uint32_t ps_size;
|
|
uint64_t ps_mc_addr;
|
|
|
|
// solid/copy
|
|
void *copy_area;
|
|
struct radeon_bo *copy_area_bo;
|
|
Bool same_surface;
|
|
int rop;
|
|
uint32_t planemask;
|
|
uint32_t fg;
|
|
|
|
// composite
|
|
Bool component_alpha;
|
|
Bool src_alpha;
|
|
// vline
|
|
xf86CrtcPtr vline_crtc;
|
|
int vline_y1;
|
|
int vline_y2;
|
|
|
|
Bool force;
|
|
};
|
|
|
|
struct radeon_client_priv {
|
|
uint_fast32_t needs_flush;
|
|
};
|
|
|
|
struct radeon_device_priv {
|
|
CursorPtr cursor;
|
|
Bool sprite_visible;
|
|
};
|
|
|
|
extern DevScreenPrivateKeyRec radeon_device_private_key;
|
|
|
|
typedef struct {
|
|
EntityInfoPtr pEnt;
|
|
pciVideoPtr PciInfo;
|
|
int Chipset;
|
|
RADEONChipFamily ChipFamily;
|
|
|
|
Bool (*CloseScreen)(ScreenPtr pScreen);
|
|
|
|
void (*BlockHandler)(BLOCKHANDLER_ARGS_DECL);
|
|
|
|
void (*CreateFence) (ScreenPtr pScreen, struct _SyncFence *pFence,
|
|
Bool initially_triggered);
|
|
|
|
int pix24bpp; /* Depth of pixmap for 24bpp fb */
|
|
Bool dac6bits; /* Use 6 bit DAC? */
|
|
|
|
int pixel_bytes;
|
|
|
|
Bool directRenderingEnabled;
|
|
struct radeon_dri2 dri2;
|
|
|
|
/* accel */
|
|
Bool RenderAccel; /* Render */
|
|
Bool allowColorTiling;
|
|
Bool allowColorTiling2D;
|
|
int callback_event_type;
|
|
uint_fast32_t gpu_flushed;
|
|
uint_fast32_t gpu_synced;
|
|
struct radeon_accel_state *accel_state;
|
|
PixmapPtr fbcon_pixmap;
|
|
Bool accelOn;
|
|
Bool use_glamor;
|
|
Bool shadow_primary;
|
|
int tear_free;
|
|
Bool exa_pixmaps;
|
|
Bool exa_force_create;
|
|
XF86ModReqInfo exaReq;
|
|
Bool is_fast_fb; /* use direct mapping for fast fb access */
|
|
|
|
unsigned int xv_max_width;
|
|
unsigned int xv_max_height;
|
|
|
|
/* general */
|
|
OptionInfoPtr Options;
|
|
|
|
DisplayModePtr currentMode;
|
|
|
|
CreateScreenResourcesProcPtr CreateScreenResources;
|
|
CreateWindowProcPtr CreateWindow;
|
|
WindowExposuresProcPtr WindowExposures;
|
|
miPointerSpriteFuncPtr SpriteFuncs;
|
|
|
|
/* Number of SW cursors currently visible on this screen */
|
|
int sprites_visible;
|
|
|
|
Bool IsSecondary;
|
|
|
|
Bool r600_shadow_fb;
|
|
void *fb_shadow;
|
|
|
|
void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB
|
|
struct radeon_2d_state state_2d;
|
|
struct radeon_buffer *front_buffer;
|
|
struct radeon_bo_manager *bufmgr;
|
|
struct radeon_cs_manager *csm;
|
|
struct radeon_cs *cs;
|
|
|
|
struct radeon_bo *cursor_bo[32];
|
|
uint64_t vram_size;
|
|
uint64_t gart_size;
|
|
drmmode_rec drmmode;
|
|
Bool drmmode_inited;
|
|
/* r6xx+ tile config */
|
|
Bool have_tiling_info;
|
|
uint32_t tile_config;
|
|
int group_bytes;
|
|
int num_channels;
|
|
int num_banks;
|
|
int r7xx_bank_op;
|
|
struct radeon_surface_manager *surf_man;
|
|
struct radeon_surface front_surface;
|
|
|
|
/* Xv bicubic filtering */
|
|
struct radeon_bo *bicubic_bo;
|
|
|
|
/* kms pageflipping */
|
|
Bool allowPageFlip;
|
|
|
|
/* Perform vsync'ed SwapBuffers? */
|
|
Bool swapBuffersWait;
|
|
|
|
/* cursor size */
|
|
int cursor_w;
|
|
int cursor_h;
|
|
|
|
/* If bit n of this field is set, xf86_config->crtc[n] currently can't
|
|
* use the HW cursor
|
|
*/
|
|
unsigned hwcursor_disabled;
|
|
|
|
#ifdef USE_GLAMOR
|
|
struct gbm_device *gbm;
|
|
|
|
struct {
|
|
CreateGCProcPtr SavedCreateGC;
|
|
RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr, int, int,
|
|
int, int, int, int);
|
|
void (*SavedPolyFillRect)(DrawablePtr, GCPtr, int, xRectangle*);
|
|
CloseScreenProcPtr SavedCloseScreen;
|
|
GetImageProcPtr SavedGetImage;
|
|
GetSpansProcPtr SavedGetSpans;
|
|
CreatePixmapProcPtr SavedCreatePixmap;
|
|
DestroyPixmapProcPtr SavedDestroyPixmap;
|
|
CopyWindowProcPtr SavedCopyWindow;
|
|
ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
|
|
BitmapToRegionProcPtr SavedBitmapToRegion;
|
|
#ifdef RENDER
|
|
CompositeProcPtr SavedComposite;
|
|
TrianglesProcPtr SavedTriangles;
|
|
GlyphsProcPtr SavedGlyphs;
|
|
TrapezoidsProcPtr SavedTrapezoids;
|
|
AddTrapsProcPtr SavedAddTraps;
|
|
UnrealizeGlyphProcPtr SavedUnrealizeGlyph;
|
|
#endif
|
|
SharePixmapBackingProcPtr SavedSharePixmapBacking;
|
|
SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking;
|
|
} glamor;
|
|
#endif /* USE_GLAMOR */
|
|
|
|
xf86CrtcFuncsRec drmmode_crtc_funcs;
|
|
} RADEONInfoRec, *RADEONInfoPtr;
|
|
|
|
/* radeon_accel.c */
|
|
extern Bool RADEONAccelInit(ScreenPtr pScreen);
|
|
extern void RADEONEngineInit(ScrnInfoPtr pScrn);
|
|
extern void RADEONCopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap);
|
|
extern void RADEONInit3DEngine(ScrnInfoPtr pScrn);
|
|
extern int radeon_cs_space_remaining(ScrnInfoPtr pScrn);
|
|
|
|
/* radeon_bo_helper.c */
|
|
extern Bool
|
|
radeon_surface_initialize(RADEONInfoPtr info, struct radeon_surface *surface,
|
|
int width, int height, int cpp, uint32_t tiling_flags,
|
|
int usage_hint);
|
|
|
|
extern Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle);
|
|
|
|
/* radeon_commonfuncs.c */
|
|
extern void RADEONWaitForVLine(ScrnInfoPtr pScrn, PixmapPtr pPix,
|
|
xf86CrtcPtr crtc, int start, int stop);
|
|
|
|
|
|
/* radeon_exa.c */
|
|
extern unsigned eg_tile_split(unsigned tile_split);
|
|
extern Bool radeon_transform_is_affine_or_scaled(PictTransformPtr t);
|
|
|
|
/* radeon_exa_funcs.c */
|
|
extern Bool RADEONDrawInit(ScreenPtr pScreen);
|
|
extern Bool R600DrawInit(ScreenPtr pScreen);
|
|
extern Bool R600LoadShaders(ScrnInfoPtr pScrn);
|
|
extern Bool EVERGREENDrawInit(ScreenPtr pScreen);
|
|
|
|
/* radeon_exa.c */
|
|
extern Bool RADEONGetDatatypeBpp(int bpp, uint32_t *type);
|
|
extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
|
|
uint32_t *pitch_offset);
|
|
|
|
/* radeon_dri3.c */
|
|
Bool radeon_dri3_screen_init(ScreenPtr screen);
|
|
|
|
/* radeon_kms.c */
|
|
Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id,
|
|
PixmapPtr src_pix, BoxRec extents);
|
|
void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion
|
|
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0)
|
|
, RegionPtr pBSRegion
|
|
#endif
|
|
);
|
|
|
|
/* radeon_present.c */
|
|
Bool radeon_present_screen_init(ScreenPtr screen);
|
|
|
|
/* radeon_sync.c */
|
|
extern Bool radeon_sync_init(ScreenPtr screen);
|
|
extern void radeon_sync_close(ScreenPtr screen);
|
|
|
|
/* radeon_video.c */
|
|
extern void RADEONInitVideo(ScreenPtr pScreen);
|
|
extern void RADEONResetVideo(ScrnInfoPtr pScrn);
|
|
extern Bool radeon_load_bicubic_texture(ScrnInfoPtr pScrn);
|
|
extern xf86CrtcPtr radeon_pick_best_crtc(ScrnInfoPtr pScrn,
|
|
Bool consider_disabled,
|
|
int x1, int x2, int y1, int y2);
|
|
|
|
extern void radeon_cs_flush_indirect(ScrnInfoPtr pScrn);
|
|
extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn,
|
|
int num, const char *file,
|
|
const char *func, int line);
|
|
void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size);
|
|
extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn);
|
|
|
|
static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix)
|
|
{
|
|
struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
|
|
|
|
return &driver_priv->surface;
|
|
}
|
|
|
|
uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix);
|
|
|
|
static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_buffer *bo)
|
|
{
|
|
ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen);
|
|
RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
|
|
#ifdef USE_GLAMOR
|
|
RADEONInfoPtr info = RADEONPTR(scrn);
|
|
|
|
if (info->use_glamor) {
|
|
struct radeon_pixmap *priv;
|
|
|
|
priv = radeon_get_pixmap_private(pPix);
|
|
if (priv == NULL && bo == NULL)
|
|
return TRUE;
|
|
|
|
if (priv) {
|
|
if (priv->bo) {
|
|
if (priv->bo == bo)
|
|
return TRUE;
|
|
|
|
radeon_buffer_unref(&priv->bo);
|
|
}
|
|
|
|
drmmode_fb_reference(pRADEONEnt->fd, &priv->fb, NULL);
|
|
|
|
if (!bo) {
|
|
free(priv);
|
|
priv = NULL;
|
|
}
|
|
}
|
|
|
|
if (bo) {
|
|
if (!priv) {
|
|
priv = calloc(1, sizeof (struct radeon_pixmap));
|
|
if (!priv)
|
|
return FALSE;
|
|
}
|
|
|
|
radeon_buffer_ref(bo);
|
|
priv->bo = bo;
|
|
}
|
|
|
|
radeon_set_pixmap_private(pPix, priv);
|
|
radeon_get_pixmap_tiling_flags(pPix);
|
|
return TRUE;
|
|
} else
|
|
#endif /* USE_GLAMOR */
|
|
{
|
|
struct radeon_exa_pixmap_priv *driver_priv;
|
|
|
|
driver_priv = exaGetPixmapDriverPrivate(pPix);
|
|
if (driver_priv) {
|
|
uint32_t pitch;
|
|
|
|
radeon_buffer_unref(&driver_priv->bo);
|
|
drmmode_fb_reference(pRADEONEnt->fd, &driver_priv->fb, NULL);
|
|
|
|
radeon_buffer_ref(bo);
|
|
driver_priv->bo = bo;
|
|
|
|
radeon_bo_get_tiling(bo->bo.radeon, &driver_priv->tiling_flags,
|
|
&pitch);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
static inline struct radeon_buffer *radeon_get_pixmap_bo(PixmapPtr pPix)
|
|
{
|
|
#ifdef USE_GLAMOR
|
|
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
|
|
|
|
if (info->use_glamor) {
|
|
struct radeon_pixmap *priv;
|
|
priv = radeon_get_pixmap_private(pPix);
|
|
return priv ? priv->bo : NULL;
|
|
} else
|
|
#endif
|
|
{
|
|
struct radeon_exa_pixmap_priv *driver_priv;
|
|
driver_priv = exaGetPixmapDriverPrivate(pPix);
|
|
return driver_priv ? driver_priv->bo : NULL;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static inline Bool radeon_get_pixmap_shared(PixmapPtr pPix)
|
|
{
|
|
#ifdef USE_GLAMOR
|
|
RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
|
|
|
|
if (info->use_glamor) {
|
|
ErrorF("glamor sharing todo\n");
|
|
return FALSE;
|
|
} else
|
|
#endif
|
|
{
|
|
struct radeon_exa_pixmap_priv *driver_priv;
|
|
driver_priv = exaGetPixmapDriverPrivate(pPix);
|
|
return driver_priv->shared;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static inline struct drmmode_fb*
|
|
radeon_fb_create(ScrnInfoPtr scrn, int drm_fd, uint32_t width, uint32_t height,
|
|
uint32_t pitch, uint32_t handle)
|
|
{
|
|
struct drmmode_fb *fb = malloc(sizeof(*fb));
|
|
|
|
if (!fb)
|
|
return NULL;
|
|
|
|
fb->refcnt = 1;
|
|
if (drmModeAddFB(drm_fd, width, height, scrn->depth, scrn->bitsPerPixel,
|
|
pitch, handle, &fb->handle) == 0)
|
|
return fb;
|
|
|
|
free(fb);
|
|
return NULL;
|
|
}
|
|
|
|
static inline struct drmmode_fb**
|
|
radeon_pixmap_get_fb_ptr(PixmapPtr pix)
|
|
{
|
|
ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
|
|
RADEONInfoPtr info = RADEONPTR(scrn);
|
|
|
|
#ifdef USE_GLAMOR
|
|
if (info->use_glamor) {
|
|
struct radeon_pixmap *priv = radeon_get_pixmap_private(pix);
|
|
|
|
if (!priv)
|
|
return NULL;
|
|
|
|
return &priv->fb;
|
|
} else
|
|
#endif
|
|
if (info->accelOn)
|
|
{
|
|
struct radeon_exa_pixmap_priv *driver_priv =
|
|
exaGetPixmapDriverPrivate(pix);
|
|
|
|
if (!driver_priv)
|
|
return NULL;
|
|
|
|
return &driver_priv->fb;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static inline struct drmmode_fb*
|
|
radeon_pixmap_get_fb(PixmapPtr pix)
|
|
{
|
|
struct drmmode_fb **fb_ptr = radeon_pixmap_get_fb_ptr(pix);
|
|
|
|
if (!fb_ptr)
|
|
return NULL;
|
|
|
|
if (!*fb_ptr) {
|
|
uint32_t handle;
|
|
|
|
if (radeon_get_pixmap_handle(pix, &handle)) {
|
|
ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
|
|
RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
|
|
|
|
*fb_ptr = radeon_fb_create(scrn, pRADEONEnt->fd, pix->drawable.width,
|
|
pix->drawable.height, pix->devKind,
|
|
handle);
|
|
}
|
|
}
|
|
|
|
return *fb_ptr;
|
|
}
|
|
|
|
|
|
#define CP_PACKET0(reg, n) \
|
|
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
|
|
#define CP_PACKET1(reg0, reg1) \
|
|
(RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
|
|
#define CP_PACKET2() \
|
|
(RADEON_CP_PACKET2)
|
|
#define CP_PACKET3(pkt, n) \
|
|
(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
|
|
|
|
|
|
#define RADEON_VERBOSE 0
|
|
|
|
#define BEGIN_RING(n) do { \
|
|
if (RADEON_VERBOSE) { \
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
|
|
"BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\
|
|
} \
|
|
radeon_ddx_cs_start(pScrn, n, __FILE__, __func__, __LINE__); \
|
|
} while (0)
|
|
|
|
#define ADVANCE_RING() do { \
|
|
radeon_cs_end(info->cs, __FILE__, __func__, __LINE__); \
|
|
} while (0)
|
|
|
|
#define OUT_RING(x) do { \
|
|
if (RADEON_VERBOSE) { \
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
|
|
" OUT_RING(0x%08x)\n", (unsigned int)(x)); \
|
|
} \
|
|
radeon_cs_write_dword(info->cs, (x)); \
|
|
} while (0)
|
|
|
|
#define OUT_RING_REG(reg, val) \
|
|
do { \
|
|
OUT_RING(CP_PACKET0(reg, 0)); \
|
|
OUT_RING(val); \
|
|
} while (0)
|
|
|
|
#define OUT_RING_RELOC(x, read_domains, write_domain) \
|
|
do { \
|
|
int _ret; \
|
|
_ret = radeon_cs_write_reloc(info->cs, x, read_domains, write_domain, 0); \
|
|
if (_ret) ErrorF("reloc emit failure %d\n", _ret); \
|
|
} while(0)
|
|
|
|
|
|
#define FLUSH_RING() \
|
|
do { \
|
|
if (RADEON_VERBOSE) \
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
|
|
"FLUSH_RING in %s\n", __FUNCTION__); \
|
|
radeon_cs_flush_indirect(pScrn); \
|
|
} while (0)
|
|
|
|
#define CS_FULL(cs) ((cs)->cdw > 15 * 1024)
|
|
|
|
#define RADEON_SWITCH_TO_2D() \
|
|
do { \
|
|
uint32_t flush = 0; \
|
|
switch (info->accel_state->engineMode) { \
|
|
case EXA_ENGINEMODE_UNKNOWN: \
|
|
flush = 1; \
|
|
break; \
|
|
case EXA_ENGINEMODE_3D: \
|
|
flush = CS_FULL(info->cs); \
|
|
break; \
|
|
case EXA_ENGINEMODE_2D: \
|
|
flush = CS_FULL(info->cs); \
|
|
break; \
|
|
} \
|
|
if (flush) { \
|
|
radeon_cs_flush_indirect(pScrn); \
|
|
} \
|
|
info->accel_state->engineMode = EXA_ENGINEMODE_2D; \
|
|
} while (0);
|
|
|
|
#define RADEON_SWITCH_TO_3D() \
|
|
do { \
|
|
uint32_t flush = 0; \
|
|
switch (info->accel_state->engineMode) { \
|
|
case EXA_ENGINEMODE_UNKNOWN: \
|
|
flush = 1; \
|
|
break; \
|
|
case EXA_ENGINEMODE_2D: \
|
|
flush = CS_FULL(info->cs); \
|
|
break; \
|
|
case EXA_ENGINEMODE_3D: \
|
|
flush = CS_FULL(info->cs); \
|
|
break; \
|
|
} \
|
|
if (flush) { \
|
|
radeon_cs_flush_indirect(pScrn); \
|
|
} \
|
|
if (!info->accel_state->XInited3D) \
|
|
RADEONInit3DEngine(pScrn); \
|
|
info->accel_state->engineMode = EXA_ENGINEMODE_3D; \
|
|
} while (0);
|
|
|
|
/* Memory mapped register access macros */
|
|
|
|
#define BEGIN_ACCEL_RELOC(n, r) do { \
|
|
int _nqw = (n) + (r); \
|
|
BEGIN_RING(2*_nqw); \
|
|
} while (0)
|
|
|
|
#define EMIT_OFFSET(reg, value, pPix, rd, wd) do { \
|
|
driver_priv = exaGetPixmapDriverPrivate(pPix); \
|
|
OUT_RING_REG((reg), (value)); \
|
|
OUT_RING_RELOC(driver_priv->bo->bo.radeon, (rd), (wd)); \
|
|
} while(0)
|
|
|
|
#define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0)
|
|
#define EMIT_WRITE_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, 0, RADEON_GEM_DOMAIN_VRAM)
|
|
|
|
#define OUT_TEXTURE_REG(reg, offset, bo) do { \
|
|
OUT_RING_REG((reg), (offset)); \
|
|
OUT_RING_RELOC((bo), RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); \
|
|
} while(0)
|
|
|
|
#define EMIT_COLORPITCH(reg, value, pPix) do { \
|
|
driver_priv = exaGetPixmapDriverPrivate(pPix); \
|
|
OUT_RING_REG((reg), value); \
|
|
OUT_RING_RELOC(driver_priv->bo->bo.radeon, 0, RADEON_GEM_DOMAIN_VRAM); \
|
|
} while(0)
|
|
|
|
static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn)
|
|
{
|
|
if (pScrn->pScreen)
|
|
exaWaitSync(pScrn->pScreen);
|
|
}
|
|
|
|
enum {
|
|
RADEON_CREATE_PIXMAP_SCANOUT = 0x02000000,
|
|
RADEON_CREATE_PIXMAP_DRI2 = 0x04000000,
|
|
RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE = 0x08000000,
|
|
RADEON_CREATE_PIXMAP_TILING_MACRO = 0x10000000,
|
|
RADEON_CREATE_PIXMAP_TILING_MICRO = 0x20000000,
|
|
RADEON_CREATE_PIXMAP_DEPTH = 0x40000000, /* for r200 */
|
|
RADEON_CREATE_PIXMAP_SZBUFFER = 0x80000000, /* for eg */
|
|
};
|
|
|
|
#define RADEON_CREATE_PIXMAP_TILING_FLAGS \
|
|
(RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE | \
|
|
RADEON_CREATE_PIXMAP_TILING_MACRO | \
|
|
RADEON_CREATE_PIXMAP_TILING_MICRO | \
|
|
RADEON_CREATE_PIXMAP_DEPTH | \
|
|
RADEON_CREATE_PIXMAP_SZBUFFER)
|
|
|
|
|
|
/* Compute log base 2 of val. */
|
|
static __inline__ int
|
|
RADEONLog2(int val)
|
|
{
|
|
return 31 - __builtin_clz(val);
|
|
}
|
|
|
|
#define RADEON_TILING_MASK 0xff
|
|
#define RADEON_TILING_LINEAR 0x0
|
|
|
|
#endif /* _RADEON_H_ */
|