summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore84
-rw-r--r--Makefile.am10
-rw-r--r--configure.ac13
-rw-r--r--man/radeon.man8
-rw-r--r--src/.gitignore3
-rw-r--r--src/Makefile.am2
-rw-r--r--src/atombios_output.c40
-rw-r--r--src/drmmode_display.c32
-rw-r--r--src/r600_exa.c269
-rw-r--r--src/r600_state.h4
-rw-r--r--src/r600_textured_videofuncs.c76
-rw-r--r--src/r6xx_accel.c206
-rw-r--r--src/radeon.h33
-rw-r--r--src/radeon_atombios.c32
-rw-r--r--src/radeon_dri2.c46
-rw-r--r--src/radeon_dri2.h2
-rw-r--r--src/radeon_exa.c18
-rw-r--r--src/radeon_exa_render.c9
-rw-r--r--src/radeon_kms.c72
-rw-r--r--src/radeon_modes.c2
-rw-r--r--src/radeon_output.c2
-rw-r--r--src/radeon_textured_video.c2
-rw-r--r--src/radeon_textured_videofuncs.c45
-rw-r--r--src/radeon_vbo.c206
-rw-r--r--src/radeon_vbo.h62
-rw-r--r--src/simple_list.h202
26 files changed, 997 insertions, 483 deletions
diff --git a/.gitignore b/.gitignore
index 45acc17b..fc236a32 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,36 +1,80 @@
-*~
-*.la
-*.lo
-.#*
-.deps
-.libs
-Makefile
-Makefile.in
+#
+# X.Org module default exclusion patterns
+# The next section if for module specific patterns
+#
+# Do not edit the following section
+# GNU Build System (Autotools)
aclocal.m4
-ati.4
-ati.4x
-autom4te.cache
+autom4te.cache/
+autoscan.log
+ChangeLog
compile
config.guess
config.h
config.h.in
config.log
+config-ml.in
+config.py
config.status
+config.status.lineno
config.sub
configure
-configure.lineno
-cscope.files
-cscope.out
+configure.scan
depcomp
+.deps/
+INSTALL
install-sh
+.libs/
libtool
+libtool.m4
ltmain.sh
+lt~obsolete.m4
+ltoptions.m4
+ltsugar.m4
+ltversion.m4
+Makefile
+Makefile.in
+mdate-sh
missing
-r128.4
-r128.4x
-radeon.4
-radeon.4x
-stamp-h1
-*cscope*
+mkinstalldirs
+*.pc
+py-compile
+stamp-h?
+symlink-tree
+texinfo.tex
+ylwrap
+
+# Do not edit the following section
+# Edit Compile Debug Document Distribute
+*~
+*.[0-9]
+*.[0-9]x
+*.bak
+*.bin
+core
+*.dll
+*.exe
+*-ISO*.bdf
+*-JIS*.bdf
+*-KOI8*.bdf
+*.kld
+*.ko
+*.ko.cmd
+*.lai
+*.l[oa]
+*.[oa]
+*.obj
+*.patch
+*.so
+*.pcf.gz
+*.pdb
+*.tar.bz2
+*.tar.gz
+#
+# Add & Override patterns for xf86-video-ati
+#
+# Edit the following section as needed
+# For example, !report.pc overrides *.pc. See 'man gitignore'
+#
shave
shave-libtool
diff --git a/Makefile.am b/Makefile.am
index e76bf118..4c278ba7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -18,15 +18,15 @@
# 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.
-AUTOMAKE_OPTIONS = foreign
SUBDIRS = src man
+MAINTAINERCLEANFILES = ChangeLog INSTALL
-EXTRA_DIST = ChangeLog
-CLEANFILES = ChangeLog
+.PHONY: ChangeLog INSTALL
-.PHONY: ChangeLog
+INSTALL:
+ $(INSTALL_CMD)
ChangeLog:
$(CHANGELOG_CMD)
-dist-hook: ChangeLog
+dist-hook: ChangeLog INSTALL
diff --git a/configure.ac b/configure.ac
index 162c8394..6b3c4c6c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,13 +29,15 @@ AC_INIT([xf86-video-ati],
AC_CONFIG_SRCDIR([Makefile.am])
AM_CONFIG_HEADER([config.h])
-# Require xorg-macros: XORG_RELEASE_VERSION XORG_CHANGELOG
-m4_ifndef([XORG_MACROS_VERSION], [AC_FATAL([must install xorg-macros 1.2 or later before running autoconf/autogen])])
-XORG_MACROS_VERSION(1.2)
+# Require xorg-macros: XORG_DEFAULT_OPTIONS
+m4_ifndef([XORG_MACROS_VERSION],
+ [m4_fatal([must install xorg-macros 1.3 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.3)
+XORG_DEFAULT_OPTIONS
AC_CONFIG_AUX_DIR(.)
-AM_INIT_AUTOMAKE([dist-bzip2])
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
AC_SYS_LARGEFILE
AM_MAINTAINER_MODE
@@ -363,10 +365,7 @@ AC_SUBST([moduledir])
DRIVER_NAME=ati
AC_SUBST([DRIVER_NAME])
-XORG_MANPAGE_SECTIONS
-XORG_RELEASE_VERSION
XORG_CHECK_LINUXDOC
-XORG_CHANGELOG
AC_MSG_NOTICE(
[The atimisc sub-driver has been split out to xf86-video-mach64:]
diff --git a/man/radeon.man b/man/radeon.man
index 47fa9f5e..0ea866fe 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -606,6 +606,14 @@ The default is
This option enables modesetting on R/RV4xx chips using atombios.
The default is
.B off.
+.TP
+.BI "Option \*qEXAPixmaps\*q \*q" boolean \*q
+(KMS Only) Under kernel modesetting to avoid thrashing pixmaps in/out
+of VRAM on low memory cards, we use a heuristic based on VRAM amount,
+to determine whether to allow EXA to use VRAM for non-essential pixmaps.
+This option allows us to override the heurisitc.
+The default is
+.B on with > 32MB VRAM, off with < 32MB.
.SH TEXTURED VIDEO ATTRIBUTES
The driver supports the following X11 Xv attributes for Textured Video.
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 00000000..9147dc10
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1,3 @@
+# Add & Override for this directory and it's subdirectories
+modes
+parser
diff --git a/src/Makefile.am b/src/Makefile.am
index 93f237cb..a431d2e5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -66,7 +66,7 @@ XMODE_SRCS=\
modes/xf86DiDGA.c
if XF86DRM_MODE
-RADEON_KMS_SRCS=radeon_dri2.c radeon_kms.c drmmode_display.c
+RADEON_KMS_SRCS=radeon_dri2.c radeon_kms.c drmmode_display.c radeon_vbo.c
endif
if USE_EXA
diff --git a/src/atombios_output.c b/src/atombios_output.c
index eb643ce4..8047b534 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -1316,21 +1316,29 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
- if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
- index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
- else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
- index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
- else
+ if (IS_DCE32_VARIANT)
index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
+ else {
+ if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
+ index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
+ else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
+ index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
+ else
+ index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
+ }
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
- if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
- index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
- else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
- index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
- else
+ if (IS_DCE32_VARIANT)
index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
+ else {
+ if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
+ index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
+ else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
+ index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
+ else
+ index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
+ }
break;
}
@@ -1556,6 +1564,18 @@ atombios_apply_output_quirks(xf86OutputPtr output, DisplayModePtr mode)
if (IS_AVIVO_VARIANT && (mode->Flags & V_INTERLACE))
OUTREG(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN);
}
+
+ if (IS_DCE32_VARIANT && (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT))) {
+ radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+ if (radeon_encoder == NULL)
+ return;
+ /* XXX: need to sort out why transmitter control table sometimes sets this to a
+ * different golden value.
+ */
+ if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY2) {
+ OUTREG(0x7ec4, 0x00824002);
+ }
+ }
}
void
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 29c3ff17..38f73735 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -204,6 +204,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
int crtc_id = 0;
int i;
int pitch = pScrn->displayWidth * info->CurrentLayout.pixel_bytes;
+ Bool ret;
if (info->accelOn == FALSE)
return;
@@ -228,8 +229,10 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
if (!dst)
goto out_free_src;
- info->accel_state->exa->PrepareCopy (src, dst,
- -1, -1, GXcopy, FB_ALLONES);
+ ret = info->accel_state->exa->PrepareCopy (src, dst,
+ -1, -1, GXcopy, FB_ALLONES);
+ if (!ret)
+ goto out_free_src;
info->accel_state->exa->Copy (dst, 0, 0, 0, 0,
pScrn->virtualX, pScrn->virtualY);
info->accel_state->exa->DoneCopy (dst);
@@ -1017,11 +1020,13 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
int cpp = info->CurrentLayout.pixel_bytes;
struct radeon_bo *front_bo;
uint32_t tiling_flags = 0;
+ PixmapPtr ppix = screen->GetScreenPixmap(screen);
+ void *fb_shadow;
if (scrn->virtualX == width && scrn->virtualY == height)
return TRUE;
- front_bo = radeon_get_pixmap_bo(screen->GetScreenPixmap(screen));
+ front_bo = info->front_bo;
radeon_cs_flush_indirect(scrn);
if (front_bo)
@@ -1073,9 +1078,23 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
if (ret)
goto fail;
- radeon_set_pixmap_bo(screen->GetScreenPixmap(screen), info->front_bo);
- screen->ModifyPixmapHeader(screen->GetScreenPixmap(screen),
- width, height, -1, -1, pitch * cpp, NULL);
+ if (!info->r600_shadow_fb) {
+ radeon_set_pixmap_bo(screen->GetScreenPixmap(screen), info->front_bo);
+ screen->ModifyPixmapHeader(screen->GetScreenPixmap(screen),
+ width, height, -1, -1, pitch * cpp, NULL);
+ } else {
+ if (radeon_bo_map(info->front_bo, 1))
+ goto fail;
+ fb_shadow = xcalloc(1, screen_size);
+ if (fb_shadow == NULL)
+ goto fail;
+ xfree(info->fb_shadow);
+ info->fb_shadow = fb_shadow;
+ screen->ModifyPixmapHeader(screen->GetScreenPixmap(screen),
+ width, height, -1, -1, pitch * cpp,
+ info->fb_shadow);
+ }
+ scrn->pixmapPrivate.ptr = ppix->devPrivate.ptr;
// xf86DrvMsg(scrn->scrnIndex, X_INFO, "New front buffer at 0x%lx\n",
// info->front_bo-);
@@ -1095,6 +1114,7 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
if (old_front)
radeon_bo_unref(old_front);
+ radeon_kms_update_vram_limit(scrn, screen_size);
return TRUE;
fail:
diff --git a/src/r600_exa.c b/src/r600_exa.c
index ca1a1fae..634e6cac 100644
--- a/src/r600_exa.c
+++ b/src/r600_exa.c
@@ -38,7 +38,7 @@
#include "r600_shader.h"
#include "r600_reg.h"
#include "r600_state.h"
-
+#include "radeon_vbo.h"
#define RADEON_TRACE_FALL 0
#define RADEON_TRACE_DRAW 0
@@ -217,15 +217,9 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
pPix->drawable.bitsPerPixel, exaGetPixmapPitch(pPix));
#endif
+ radeon_vbo_check(pScrn, 16);
r600_cp_start(pScrn);
- /* Init */
-#if defined(XF86DRM_MODE)
- if (info->cs)
- accel_state->XInited3D = FALSE;
-#endif
- start_3d(pScrn, accel_state->ib);
-
set_default_state(pScrn, accel_state->ib);
set_generic_scissor(pScrn, accel_state->ib, 0, 0, pPix->drawable.width, pPix->drawable.height);
@@ -367,16 +361,9 @@ static void
R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
{
ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
- RADEONInfoPtr info = RADEONPTR(pScrn);
- struct radeon_accel_state *accel_state = info->accel_state;
float *vb;
- if (((accel_state->vb_index + 3) * 8) > accel_state->vb_total) {
- R600DoneSolid(pPix);
- r600_cp_start(pScrn);
- }
-
- vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*8);
+ vb = radeon_vbo_space(pScrn, 8);
vb[0] = (float)x1;
vb[1] = (float)y1;
@@ -387,70 +374,15 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
vb[4] = (float)x2;
vb[5] = (float)y2;
- accel_state->vb_index += 3;
-
+ radeon_vbo_commit(pScrn);
}
static void
R600DoneSolid(PixmapPtr pPix)
{
ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
- RADEONInfoPtr info = RADEONPTR(pScrn);
- struct radeon_accel_state *accel_state = info->accel_state;
- draw_config_t draw_conf;
- vtx_resource_t vtx_res;
- CLEAR (draw_conf);
- CLEAR (vtx_res);
-
- if (accel_state->vb_index == 0) {
- R600IBDiscard(pScrn, accel_state->ib);
- r600_vb_discard(pScrn);
- return;
- }
-
- accel_state->vb_size = accel_state->vb_index * 8;
-
- /* flush vertex cache */
- if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
- (info->ChipFamily == CHIP_FAMILY_RV620) ||
- (info->ChipFamily == CHIP_FAMILY_RS780) ||
- (info->ChipFamily == CHIP_FAMILY_RS880) ||
- (info->ChipFamily == CHIP_FAMILY_RV710))
- cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit,
- accel_state->vb_size, accel_state->vb_mc_addr,
- accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
- else
- cp_set_surface_sync(pScrn, accel_state->ib, VC_ACTION_ENA_bit,
- accel_state->vb_size, accel_state->vb_mc_addr,
- accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
-
- /* Vertex buffer setup */
- vtx_res.id = SQ_VTX_RESOURCE_vs;
- vtx_res.vtx_size_dw = 8 / 4;
- vtx_res.vtx_num_entries = accel_state->vb_size / 4;
- vtx_res.mem_req_size = 1;
- vtx_res.vb_addr = accel_state->vb_mc_addr;
- vtx_res.bo = accel_state->vb_bo;
- set_vtx_resource (pScrn, accel_state->ib, &vtx_res);
-
- /* Draw */
- draw_conf.prim_type = DI_PT_RECTLIST;
- draw_conf.vgt_draw_initiator = DI_SRC_SEL_AUTO_INDEX;
- draw_conf.num_instances = 1;
- draw_conf.num_indices = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
- draw_conf.index_type = DI_INDEX_SIZE_16_BIT;
-
- draw_auto(pScrn, accel_state->ib, &draw_conf);
-
- wait_3d_idle_clean(pScrn, accel_state->ib);
-
- /* sync dst surface */
- cp_set_surface_sync(pScrn, accel_state->ib, (CB_ACTION_ENA_bit | CB0_DEST_BASE_ENA_bit),
- accel_state->dst_size, accel_state->dst_mc_addr,
- accel_state->dst_bo, RADEON_GEM_DOMAIN_VRAM, 0);
-
- R600CPFlushIndirect(pScrn, accel_state->ib);
+ r600_finish_op(pScrn, 8);
}
static void
@@ -491,15 +423,9 @@ R600DoPrepareCopy(ScrnInfoPtr pScrn,
accel_state->dst_bpp = dst_bpp;
accel_state->dst_bo = dst_bo;
+ radeon_vbo_check(pScrn, 16);
r600_cp_start(pScrn);
- /* Init */
-#if defined(XF86DRM_MODE)
- if (info->cs)
- accel_state->XInited3D = FALSE;
-#endif
- start_3d(pScrn, accel_state->ib);
-
set_default_state(pScrn, accel_state->ib);
set_generic_scissor(pScrn, accel_state->ib, 0, 0, dst_width, dst_height);
@@ -651,66 +577,13 @@ R600DoPrepareCopy(ScrnInfoPtr pScrn,
SEL_CENTROID_bit));
EREG(accel_state->ib, SPI_INTERP_CONTROL_0, 0);
END_BATCH();
+
}
static void
R600DoCopy(ScrnInfoPtr pScrn)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- struct radeon_accel_state *accel_state = info->accel_state;
- draw_config_t draw_conf;
- vtx_resource_t vtx_res;
-
- CLEAR (draw_conf);
- CLEAR (vtx_res);
-
- if (accel_state->vb_index == 0) {
- R600IBDiscard(pScrn, accel_state->ib);
- r600_vb_discard(pScrn);
- return;
- }
-
- accel_state->vb_size = accel_state->vb_index * 16;
-
- /* flush vertex cache */
- if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
- (info->ChipFamily == CHIP_FAMILY_RV620) ||
- (info->ChipFamily == CHIP_FAMILY_RS780) ||
- (info->ChipFamily == CHIP_FAMILY_RS880) ||
- (info->ChipFamily == CHIP_FAMILY_RV710))
- cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit,
- accel_state->vb_size, accel_state->vb_mc_addr,
- accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
- else
- cp_set_surface_sync(pScrn, accel_state->ib, VC_ACTION_ENA_bit,
- accel_state->vb_size, accel_state->vb_mc_addr,
- accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
-
- /* Vertex buffer setup */
- vtx_res.id = SQ_VTX_RESOURCE_vs;
- vtx_res.vtx_size_dw = 16 / 4;
- vtx_res.vtx_num_entries = accel_state->vb_size / 4;
- vtx_res.mem_req_size = 1;
- vtx_res.vb_addr = accel_state->vb_mc_addr;
- vtx_res.bo = accel_state->vb_bo;
- set_vtx_resource (pScrn, accel_state->ib, &vtx_res);
-
- draw_conf.prim_type = DI_PT_RECTLIST;
- draw_conf.vgt_draw_initiator = DI_SRC_SEL_AUTO_INDEX;
- draw_conf.num_instances = 1;
- draw_conf.num_indices = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
- draw_conf.index_type = DI_INDEX_SIZE_16_BIT;
-
- draw_auto(pScrn, accel_state->ib, &draw_conf);
-
- wait_3d_idle_clean(pScrn, accel_state->ib);
-
- /* sync dst surface */
- cp_set_surface_sync(pScrn, accel_state->ib, (CB_ACTION_ENA_bit | CB0_DEST_BASE_ENA_bit),
- accel_state->dst_size, accel_state->dst_mc_addr,
- accel_state->dst_bo, RADEON_GEM_DOMAIN_VRAM, 0);
-
- R600CPFlushIndirect(pScrn, accel_state->ib);
+ r600_finish_op(pScrn, 16);
}
static void
@@ -719,16 +592,9 @@ R600AppendCopyVertex(ScrnInfoPtr pScrn,
int dstX, int dstY,
int w, int h)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- struct radeon_accel_state *accel_state = info->accel_state;
float *vb;
- if (((accel_state->vb_index + 3) * 16) > accel_state->vb_total) {
- R600DoCopy(pScrn);
- r600_cp_start(pScrn);
- }
-
- vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*16);
+ vb = radeon_vbo_space(pScrn, 16);
vb[0] = (float)dstX;
vb[1] = (float)dstY;
@@ -745,7 +611,7 @@ R600AppendCopyVertex(ScrnInfoPtr pScrn,
vb[10] = (float)(srcX + w);
vb[11] = (float)(srcY + h);
- accel_state->vb_index += 3;
+ radeon_vbo_commit(pScrn);
}
static Bool
@@ -757,7 +623,6 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst,
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
struct radeon_accel_state *accel_state = info->accel_state;
- int ret;
if (!R600CheckBPP(pSrc->drawable.bitsPerPixel))
RADEON_FALLBACK(("R600CheckDatatype src failed\n"));
@@ -809,6 +674,8 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst,
#if defined(XF86DRM_MODE)
if (info->cs) {
+ int ret;
+
radeon_cs_space_reset_bos(info->cs);
radeon_cs_space_add_persistent_bo(info->cs, accel_state->shaders_bo,
RADEON_GEM_DOMAIN_VRAM, 0);
@@ -845,7 +712,6 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst,
RADEON_GEM_DOMAIN_VRAM,
0);
if (accel_state->copy_area_bo == NULL) {
- R600IBDiscard(pScrn, accel_state->ib);
return FALSE;
}
radeon_cs_space_add_persistent_bo(info->cs, accel_state->copy_area_bo,
@@ -853,7 +719,6 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst,
if (radeon_cs_space_check(info->cs)) {
radeon_bo_unref(accel_state->copy_area_bo);
accel_state->copy_area_bo = NULL;
- R600IBDiscard(pScrn, accel_state->ib);
return FALSE;
}
accel_state->copy_area = (void*)accel_state->copy_area_bo;
@@ -1654,7 +1519,6 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
uint32_t blendcntl, dst_format;
cb_config_t cb_conf;
shader_config_t vs_conf, ps_conf;
- int ret;
/* return FALSE; */
@@ -1681,6 +1545,8 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
#if defined(XF86DRM_MODE)
if (info->cs) {
+ int ret;
+
accel_state->dst_mc_addr = 0;
accel_state->dst_bo = radeon_get_pixmap_bo(pDst);
accel_state->src_bo[0] = radeon_get_pixmap_bo(pSrc);
@@ -1717,14 +1583,12 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture,
CLEAR (vs_conf);
CLEAR (ps_conf);
- r600_cp_start(pScrn);
+ if (pMask)
+ radeon_vbo_check(pScrn, 24);
+ else
+ radeon_vbo_check(pScrn, 16);
- /* Init */
-#if defined(XF86DRM_MODE)
- if (info->cs)
- accel_state->XInited3D = FALSE;
-#endif
- start_3d(pScrn, accel_state->ib);
+ r600_cp_start(pScrn);
set_default_state(pScrn, accel_state->ib);
@@ -1906,12 +1770,8 @@ static void R600Composite(PixmapPtr pDst,
srcX, srcY, maskX, maskY,dstX, dstY, w, h); */
if (accel_state->msk_pic) {
- if (((accel_state->vb_index + 3) * 24) > accel_state->vb_total) {
- R600DoneComposite(pDst);
- r600_cp_start(pScrn);
- }
- vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*24);
+ vb = radeon_vbo_space(pScrn, 24);
vb[0] = (float)dstX;
vb[1] = (float)dstY;
@@ -1934,13 +1794,11 @@ static void R600Composite(PixmapPtr pDst,
vb[16] = (float)(maskX + w);
vb[17] = (float)(maskY + h);
+ radeon_vbo_commit(pScrn);
+
} else {
- if (((accel_state->vb_index + 3) * 16) > accel_state->vb_total) {
- R600DoneComposite(pDst);
- r600_cp_start(pScrn);
- }
- vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*16);
+ vb = radeon_vbo_space(pScrn, 16);
vb[0] = (float)dstX;
vb[1] = (float)dstY;
@@ -1956,9 +1814,10 @@ static void R600Composite(PixmapPtr pDst,
vb[9] = (float)(dstY + h);
vb[10] = (float)(srcX + w);
vb[11] = (float)(srcY + h);
+
+ radeon_vbo_commit(pScrn);
}
- accel_state->vb_index += 3;
}
@@ -1967,68 +1826,11 @@ static void R600DoneComposite(PixmapPtr pDst)
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
struct radeon_accel_state *accel_state = info->accel_state;
- draw_config_t draw_conf;
- vtx_resource_t vtx_res;
-
- CLEAR (draw_conf);
- CLEAR (vtx_res);
-
- if (accel_state->vb_index == 0) {
- R600IBDiscard(pScrn, accel_state->ib);
- r600_vb_discard(pScrn);
- return;
- }
-
- /* Vertex buffer setup */
- if (accel_state->msk_pic) {
- accel_state->vb_size = accel_state->vb_index * 24;
- vtx_res.id = SQ_VTX_RESOURCE_vs;
- vtx_res.vtx_size_dw = 24 / 4;
- vtx_res.vtx_num_entries = accel_state->vb_size / 4;
- vtx_res.mem_req_size = 1;
- vtx_res.vb_addr = accel_state->vb_mc_addr;
- vtx_res.bo = accel_state->vb_bo;
- } else {
- accel_state->vb_size = accel_state->vb_index * 16;
- vtx_res.id = SQ_VTX_RESOURCE_vs;
- vtx_res.vtx_size_dw = 16 / 4;
- vtx_res.vtx_num_entries = accel_state->vb_size / 4;
- vtx_res.mem_req_size = 1;
- vtx_res.vb_addr = accel_state->vb_mc_addr;
- vtx_res.bo = accel_state->vb_bo;
- }
- /* flush vertex cache */
- if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
- (info->ChipFamily == CHIP_FAMILY_RV620) ||
- (info->ChipFamily == CHIP_FAMILY_RS780) ||
- (info->ChipFamily == CHIP_FAMILY_RS880) ||
- (info->ChipFamily == CHIP_FAMILY_RV710))
- cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit,
- accel_state->vb_size, accel_state->vb_mc_addr,
- accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
- else
- cp_set_surface_sync(pScrn, accel_state->ib, VC_ACTION_ENA_bit,
- accel_state->vb_size, accel_state->vb_mc_addr,
- accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
-
- set_vtx_resource(pScrn, accel_state->ib, &vtx_res);
-
- draw_conf.prim_type = DI_PT_RECTLIST;
- draw_conf.vgt_draw_initiator = DI_SRC_SEL_AUTO_INDEX;
- draw_conf.num_instances = 1;
- draw_conf.num_indices = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
- draw_conf.index_type = DI_INDEX_SIZE_16_BIT;
+ int vtx_size;
- draw_auto(pScrn, accel_state->ib, &draw_conf);
-
- wait_3d_idle_clean(pScrn, accel_state->ib);
-
- cp_set_surface_sync(pScrn, accel_state->ib, (CB_ACTION_ENA_bit | CB0_DEST_BASE_ENA_bit),
- accel_state->dst_size, accel_state->dst_mc_addr,
- accel_state->dst_bo, RADEON_GEM_DOMAIN_VRAM, 0);
-
- R600CPFlushIndirect(pScrn, accel_state->ib);
+ vtx_size = accel_state->msk_pic ? 24 : 16;
+ r600_finish_op(pScrn, vtx_size);
}
Bool
@@ -2336,6 +2138,9 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w,
3, 0xffffffff);
R600AppendCopyVertex(pScrn, x, y, 0, 0, w, h);
R600DoCopy(pScrn);
+
+ if (info->cs)
+ radeon_cs_flush_indirect(pScrn);
r = radeon_bo_map(scratch, 0);
if (r) {
@@ -2575,9 +2380,9 @@ R600DrawInit(ScreenPtr pScreen)
#ifdef EXA_HANDLES_PIXMAPS
if (info->cs) {
info->accel_state->exa->flags |= EXA_HANDLES_PIXMAPS;
-//#ifdef EXA_MIXED_PIXMAPS
-// info->accel_state->exa->flags |= EXA_MIXED_PIXMAPS;
-//#endif
+#ifdef EXA_MIXED_PIXMAPS
+ info->accel_state->exa->flags |= EXA_MIXED_PIXMAPS;
+#endif
}
#endif
#endif
@@ -2621,7 +2426,11 @@ R600DrawInit(ScreenPtr pScreen)
info->accel_state->src_bo[1] = NULL;
info->accel_state->dst_bo = NULL;
info->accel_state->copy_area_bo = NULL;
- info->accel_state->vb_bo = NULL;
+ info->accel_state->vb_start_op = -1;
+
+#ifdef XF86DRM_MODE
+ radeon_vbo_init_lists(pScrn);
+#endif
if (!R600AllocShaders(pScrn, pScreen))
return FALSE;
diff --git a/src/r600_state.h b/src/r600_state.h
index 46c18f9d..0ee480bc 100644
--- a/src/r600_state.h
+++ b/src/r600_state.h
@@ -206,7 +206,7 @@ do { \
} \
} while (0)
#else
-#define BEGIN_BATCH(n) do {} while(0)
+#define BEGIN_BATCH(n) do {(void)info;} while(0)
#define END_BATCH() do {} while(0)
#define RELOC_BATCH(bo, wd, rd) do {} while(0)
#define E32(ib, dword) \
@@ -326,6 +326,7 @@ void
r600_vb_discard(ScrnInfoPtr pScrn);
int
r600_cp_start(ScrnInfoPtr pScrn);
+void r600_finish_op(ScrnInfoPtr pScrn, int vtx_size);
extern Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index);
extern void RADEONFinishAccess_CS(PixmapPtr pPix, int index);
@@ -334,4 +335,5 @@ extern void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv);
extern struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix);
extern Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix);
+
#endif
diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c
index 7598429f..69deb815 100644
--- a/src/r600_textured_videofuncs.c
+++ b/src/r600_textured_videofuncs.c
@@ -45,6 +45,8 @@
#include "damage.h"
+#include "radeon_vbo.h"
+
/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces
note the difference to the parameters used in overlay are due
to 10bit vs. float calcs */
@@ -57,61 +59,7 @@ static REF_TRANSFORM trans[2] =
static void
R600DoneTexturedVideo(ScrnInfoPtr pScrn)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- struct radeon_accel_state *accel_state = info->accel_state;
- draw_config_t draw_conf;
- vtx_resource_t vtx_res;
-
- CLEAR (draw_conf);
- CLEAR (vtx_res);
-
- if (accel_state->vb_index == 0) {
- R600IBDiscard(pScrn, accel_state->ib);
- r600_vb_discard(pScrn);
- return;
- }
-
- accel_state->vb_size = accel_state->vb_index * 16;
-
- /* flush vertex cache */
- if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
- (info->ChipFamily == CHIP_FAMILY_RV620) ||
- (info->ChipFamily == CHIP_FAMILY_RS780) ||
- (info->ChipFamily == CHIP_FAMILY_RS880) ||
- (info->ChipFamily == CHIP_FAMILY_RV710))
- cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit,
- accel_state->vb_size, accel_state->vb_mc_addr,
- accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
- else
- cp_set_surface_sync(pScrn, accel_state->ib, VC_ACTION_ENA_bit,
- accel_state->vb_size, accel_state->vb_mc_addr,
- accel_state->vb_bo, RADEON_GEM_DOMAIN_GTT, 0);
-
- /* Vertex buffer setup */
- vtx_res.id = SQ_VTX_RESOURCE_vs;
- vtx_res.vtx_size_dw = 16 / 4;
- vtx_res.vtx_num_entries = accel_state->vb_size / 4;
- vtx_res.mem_req_size = 1;
- vtx_res.vb_addr = accel_state->vb_mc_addr;
- vtx_res.bo = accel_state->vb_bo;
- set_vtx_resource (pScrn, accel_state->ib, &vtx_res);
-
- draw_conf.prim_type = DI_PT_RECTLIST;
- draw_conf.vgt_draw_initiator = DI_SRC_SEL_AUTO_INDEX;
- draw_conf.num_instances = 1;
- draw_conf.num_indices = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
- draw_conf.index_type = DI_INDEX_SIZE_16_BIT;
-
- draw_auto(pScrn, accel_state->ib, &draw_conf);
-
- wait_3d_idle_clean(pScrn, accel_state->ib);
-
- /* sync destination surface */
- cp_set_surface_sync(pScrn, accel_state->ib, (CB_ACTION_ENA_bit | CB0_DEST_BASE_ENA_bit),
- accel_state->dst_size, accel_state->dst_mc_addr,
- accel_state->dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
-
- R600CPFlushIndirect(pScrn, accel_state->ib);
+ r600_finish_op(pScrn, 16);
}
void
@@ -260,15 +208,9 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
dstyoff = 0;
#endif
+ radeon_vbo_check(pScrn, 16);
r600_cp_start(pScrn);
- /* Init */
-#if defined(XF86DRM_MODE)
- if (info->cs)
- accel_state->XInited3D = FALSE;
-#endif
- start_3d(pScrn, accel_state->ib);
-
set_default_state(pScrn, accel_state->ib);
set_generic_scissor(pScrn, accel_state->ib, 0, 0, pPixmap->drawable.width, pPixmap->drawable.height);
@@ -595,12 +537,6 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
int dstX, dstY, dstw, dsth;
float *vb;
- if (((accel_state->vb_index + 3) * 16) > accel_state->vb_total) {
- R600DoneTexturedVideo(pScrn);
- r600_cp_start(pScrn);
- }
-
- vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_index*16);
dstX = pBox->x1 + dstxoff;
dstY = pBox->y1 + dstyoff;
@@ -617,6 +553,8 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
srcw = (pPriv->src_w * dstw) / pPriv->dst_w;
srch = (pPriv->src_h * dsth) / pPriv->dst_h;
+ vb = radeon_vbo_space(pScrn, 16);
+
vb[0] = (float)dstX;
vb[1] = (float)dstY;
vb[2] = (float)srcX;
@@ -632,7 +570,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
vb[10] = (float)(srcX + srcw);
vb[11] = (float)(srcY + srch);
- accel_state->vb_index += 3;
+ radeon_vbo_commit(pScrn);
pBox++;
}
diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c
index dd74d468..0ca942ef 100644
--- a/src/r6xx_accel.c
+++ b/src/r6xx_accel.c
@@ -38,29 +38,11 @@
#include "r600_state.h"
#include "radeon_drm.h"
+#include "radeon_vbo.h"
-#if defined(XF86DRM_MODE)
-void r600_cs_flush_indirect(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- int ret;
-
- if (!info->cs->cdw)
- return;
-
- if (info->accel_state->vb_ptr) {
- radeon_bo_unmap(info->accel_state->vb_bo);
- info->accel_state->vb_ptr = NULL;
- }
-
- radeon_cs_emit(info->cs);
- radeon_cs_erase(info->cs);
-
- ret = radeon_cs_space_check(info->cs);
- if (ret)
- ErrorF("space check failed in flush\n");
-}
-#endif
+/* we try and batch operations together under KMS -
+ but it doesn't work yet without misrendering */
+#define KMS_MULTI_OP 1
/* Flush the indirect buffer to the kernel for submission to the card */
void R600CPFlushIndirect(ScrnInfoPtr pScrn, drmBufPtr ib)
@@ -72,7 +54,7 @@ void R600CPFlushIndirect(ScrnInfoPtr pScrn, drmBufPtr ib)
#if defined(XF86DRM_MODE)
if (info->cs) {
- r600_cs_flush_indirect(pScrn);
+ radeon_cs_flush_indirect(pScrn);
return;
}
#endif
@@ -106,12 +88,21 @@ void R600IBDiscard(ScrnInfoPtr pScrn, drmBufPtr ib)
int ret;
RADEONInfoPtr info = RADEONPTR(pScrn);
if (info->cs) {
+ if (info->accel_state->ib_reset_op) {
+ /* if we have data just reset the CS and ignore the operation */
+ info->cs->cdw = info->accel_state->ib_reset_op;
+ info->accel_state->ib_reset_op = 0;
+ return;
+ }
if (info->accel_state->vb_ptr) {
- radeon_bo_unmap(info->accel_state->vb_bo);
info->accel_state->vb_ptr = NULL;
- }
+ }
+
+ info->accel_state->vb_offset = 0;
+ info->accel_state->vb_start_op = -1;
+
if (CS_FULL(info->cs)) {
- r600_cs_flush_indirect(pScrn);
+ radeon_cs_flush_indirect(pScrn);
return;
}
radeon_cs_erase(info->cs);
@@ -738,15 +729,15 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib)
RADEONInfoPtr info = RADEONPTR(pScrn);
struct radeon_accel_state *accel_state = info->accel_state;
- memset(&tex_res, 0, sizeof(tex_resource_t));
- memset(&fs_conf, 0, sizeof(shader_config_t));
-
if (accel_state->XInited3D)
return;
+ memset(&tex_res, 0, sizeof(tex_resource_t));
+ memset(&fs_conf, 0, sizeof(shader_config_t));
+
accel_state->XInited3D = TRUE;
- wait_3d_idle(pScrn, ib);
+ start_3d(pScrn, accel_state->ib);
// ASIC specific setup, see drm
BEGIN_BATCH(15);
@@ -1178,44 +1169,27 @@ r600_vb_get(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
struct radeon_accel_state *accel_state = info->accel_state;
-#if defined(XF86DRM_MODE)
- int ret;
- if (info->cs) {
- if (accel_state->vb_bo == NULL) {
- accel_state->vb_mc_addr = 0;
- accel_state->vb_bo = radeon_bo_open(info->bufmgr, 0, 16 * 1024,
- 0, RADEON_GEM_DOMAIN_GTT, 0);
- if (accel_state->vb_bo == NULL)
- return FALSE;
- accel_state->vb_total = 16 * 1024;
- }
- if (!accel_state->vb_ptr) {
- ret = radeon_bo_map(accel_state->vb_bo, 1);
- if (ret) {
- FatalError("failed to vb %d\n", ret);
- return FALSE;
- }
- accel_state->vb_ptr = accel_state->vb_bo->ptr;
- }
- } else
-#endif
- {
- accel_state->vb_mc_addr = info->gartLocation + info->dri->bufStart +
- (accel_state->ib->idx*accel_state->ib->total)+
- (accel_state->ib->total / 2);
- accel_state->vb_total = (accel_state->ib->total / 2);
- accel_state->vb_ptr = (pointer)((char*)accel_state->ib->address +
- (accel_state->ib->total / 2));
- }
- accel_state->vb_index = 0;
+
+ accel_state->vb_mc_addr = info->gartLocation + info->dri->bufStart +
+ (accel_state->ib->idx*accel_state->ib->total)+
+ (accel_state->ib->total / 2);
+ accel_state->vb_total = (accel_state->ib->total / 2);
+ accel_state->vb_ptr = (pointer)((char*)accel_state->ib->address +
+ (accel_state->ib->total / 2));
+ accel_state->vb_offset = 0;
return TRUE;
}
void
r600_vb_discard(ScrnInfoPtr pScrn)
{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ info->accel_state->vb_start_op = -1;
}
+
+
int
r600_cp_start(ScrnInfoPtr pScrn)
{
@@ -1224,13 +1198,11 @@ r600_cp_start(ScrnInfoPtr pScrn)
#if defined(XF86DRM_MODE)
if (info->cs) {
- if (!r600_vb_get(pScrn))
- return -1;
- if (accel_state->vb_bo)
- radeon_cs_space_add_persistent_bo(info->cs, accel_state->vb_bo,
- RADEON_GEM_DOMAIN_GTT, 0);
-
- radeon_cs_space_check(info->cs);
+ if (CS_FULL(info->cs)) {
+ radeon_cs_flush_indirect(pScrn);
+ }
+ accel_state->ib_reset_op = info->cs->cdw;
+ accel_state->vb_start_op = accel_state->vb_offset;
} else
#endif
{
@@ -1238,6 +1210,106 @@ r600_cp_start(ScrnInfoPtr pScrn)
if (!r600_vb_get(pScrn)) {
return -1;
}
+ accel_state->vb_start_op = accel_state->vb_offset;
}
return 0;
}
+
+void r600_finish_op(ScrnInfoPtr pScrn, int vtx_size)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+ draw_config_t draw_conf;
+ vtx_resource_t vtx_res;
+
+ if (accel_state->vb_start_op == -1)
+ return;
+
+ CLEAR (draw_conf);
+ CLEAR (vtx_res);
+
+ if (accel_state->vb_offset == accel_state->vb_start_op) {
+ R600IBDiscard(pScrn, accel_state->ib);
+ r600_vb_discard(pScrn);
+ return;
+ }
+
+ /* flush vertex cache */
+ if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
+ (info->ChipFamily == CHIP_FAMILY_RV620) ||
+ (info->ChipFamily == CHIP_FAMILY_RS780) ||
+ (info->ChipFamily == CHIP_FAMILY_RS880) ||
+ (info->ChipFamily == CHIP_FAMILY_RV710))
+ cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit,
+ accel_state->vb_offset, accel_state->vb_mc_addr,
+ accel_state->vb_bo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ else
+ cp_set_surface_sync(pScrn, accel_state->ib, VC_ACTION_ENA_bit,
+ accel_state->vb_offset, accel_state->vb_mc_addr,
+ accel_state->vb_bo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+
+ /* Vertex buffer setup */
+ accel_state->vb_size = accel_state->vb_offset - accel_state->vb_start_op;
+ vtx_res.id = SQ_VTX_RESOURCE_vs;
+ vtx_res.vtx_size_dw = vtx_size / 4;
+ vtx_res.vtx_num_entries = accel_state->vb_size / 4;
+ vtx_res.mem_req_size = 1;
+ vtx_res.vb_addr = accel_state->vb_mc_addr + accel_state->vb_start_op;
+ vtx_res.bo = accel_state->vb_bo;
+ set_vtx_resource (pScrn, accel_state->ib, &vtx_res);
+
+ /* Draw */
+ draw_conf.prim_type = DI_PT_RECTLIST;
+ draw_conf.vgt_draw_initiator = DI_SRC_SEL_AUTO_INDEX;
+ draw_conf.num_instances = 1;
+ draw_conf.num_indices = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
+ draw_conf.index_type = DI_INDEX_SIZE_16_BIT;
+
+ draw_auto(pScrn, accel_state->ib, &draw_conf);
+
+ wait_3d_idle_clean(pScrn, accel_state->ib);
+
+ /* sync dst surface */
+ cp_set_surface_sync(pScrn, accel_state->ib, (CB_ACTION_ENA_bit | CB0_DEST_BASE_ENA_bit),
+ accel_state->dst_size, accel_state->dst_mc_addr,
+ accel_state->dst_bo, RADEON_GEM_DOMAIN_VRAM, 0);
+
+ wait_3d_idle_clean(pScrn, accel_state->ib);
+
+ accel_state->vb_start_op = -1;
+ accel_state->ib_reset_op = 0;
+
+#if KMS_MULTI_OP
+ if (!info->cs)
+#endif
+ R600CPFlushIndirect(pScrn, accel_state->ib);
+}
+
+void r600_vb_no_space(ScrnInfoPtr pScrn, int vert_size)
+{
+#ifdef XF86DRM_MODE
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+
+ if (info->cs) {
+ if (accel_state->vb_bo) {
+ if (accel_state->vb_start_op != accel_state->vb_offset) {
+ r600_finish_op(pScrn, vert_size);
+ accel_state->ib_reset_op = info->cs->cdw;
+ }
+
+ /* release the current VBO */
+ radeon_vbo_put(pScrn);
+ }
+
+ /* get a new one */
+ radeon_vbo_get(pScrn);
+ return;
+ }
+#endif
+
+ r600_finish_op(pScrn, vert_size);
+ r600_cp_start(pScrn);
+}
diff --git a/src/radeon.h b/src/radeon.h
index fc43df69..c9f388ad 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -100,6 +100,7 @@
#include "picturestr.h"
#endif
+#include "simple_list.h"
#include "atipcirename.h"
#ifndef MAX
@@ -173,6 +174,7 @@ typedef enum {
OPTION_PCIAPER_SIZE,
#ifdef USE_EXA
OPTION_ACCEL_DFS,
+ OPTION_EXA_PIXMAPS,
#endif
#endif
OPTION_IGNORE_EDID,
@@ -382,6 +384,12 @@ typedef enum {
(info->ChipFamily == CHIP_FAMILY_RV560) || \
(info->ChipFamily == CHIP_FAMILY_RV570))
+#define IS_R400_3D ((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))
+
#define IS_R300_3D ((info->ChipFamily == CHIP_FAMILY_R300) || \
(info->ChipFamily == CHIP_FAMILY_RV350) || \
(info->ChipFamily == CHIP_FAMILY_R350) || \
@@ -645,6 +653,14 @@ struct radeon_dri {
};
#endif
+#define DMA_BO_FREE_TIME 1000
+
+struct radeon_dma_bo {
+ struct radeon_dma_bo *next, *prev;
+ struct radeon_bo *bo;
+ int expire_counter;
+};
+
struct radeon_accel_state {
/* common accel data */
int fifo_slots; /* Free slots in the FIFO (64 max) */
@@ -696,12 +712,22 @@ struct radeon_accel_state {
Bool vsync;
drmBufPtr ib;
- int vb_index;
+ int vb_offset;
uint64_t vb_mc_addr;
int vb_total;
void *vb_ptr;
uint32_t vb_size;
- struct radeon_bo *vb_bo;
+ uint32_t vb_op_vert_size;
+ int32_t vb_start_op;
+ /* where to discard IB from if we cancel operation */
+ uint32_t ib_reset_op;
+ struct radeon_bo *vb_bo;
+#ifdef XF86DRM_MODE
+ struct radeon_dma_bo bo_free;
+ struct radeon_dma_bo bo_wait;
+ struct radeon_dma_bo bo_reserved;
+ Bool use_vbos;
+#endif
// shader storage
ExaOffscreenArea *shaders;
@@ -888,6 +914,8 @@ typedef struct {
Bool accelOn;
Bool useEXA;
#ifdef USE_EXA
+ Bool exa_pixmaps;
+ Bool exa_force_create;
XF86ModReqInfo exaReq;
#endif
#ifdef USE_XAA
@@ -1287,6 +1315,7 @@ 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, int new_fb_size);
#endif
struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix);
void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo);
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index ee99da27..72fbe214 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -901,6 +901,7 @@ rhdAtomCVGetTimings(atomBiosHandlePtr handle, AtomBiosRequestID func,
DisplayModePtr new = NULL;
DisplayModePtr first = NULL;
int i;
+ uint16_t size;
data->modes = NULL;
@@ -908,12 +909,11 @@ rhdAtomCVGetTimings(atomBiosHandlePtr handle, AtomBiosRequestID func,
if (!rhdAtomGetTableRevisionAndSize(
(ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->ComponentVideoInfo.base),
- &frev,&crev,NULL)) {
+ &crev,&frev,&size)) {
return ATOM_FAILED;
}
switch (frev) {
-
case 1:
switch (func) {
case ATOMBIOS_GET_CV_MODES:
@@ -947,6 +947,11 @@ rhdAtomCVGetTimings(atomBiosHandlePtr handle, AtomBiosRequestID func,
switch (func) {
case ATOMBIOS_GET_CV_MODES:
for (i = 0; i < MAX_SUPPORTED_CV_STANDARDS; i++) {
+ /* my rv730 table has only room for one mode */
+ if ((void *)&atomDataPtr->ComponentVideoInfo.ComponentVideoInfo_v21->aModeTimings[i] -
+ atomDataPtr->ComponentVideoInfo.base > size)
+ break;
+
new = rhdAtomDTDTimings(handle,
&atomDataPtr->ComponentVideoInfo
.ComponentVideoInfo_v21->aModeTimings[i]);
@@ -1977,6 +1982,7 @@ RADEONGetATOMLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
radeon_native_mode_ptr native_mode = &lvds->native_mode;
atomDataTablesPtr atomDataPtr;
uint8_t crev, frev;
+ uint16_t misc;
atomDataPtr = info->atomBIOS->atomDataPtr;
@@ -1997,6 +2003,17 @@ RADEONGetATOMLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
native_mode->VBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVBlanking_Time);
native_mode->VOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncOffset);
native_mode->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncWidth);
+ misc = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.susModeMiscInfo.usAccess);
+ if (misc & ATOM_VSYNC_POLARITY)
+ native_mode->Flags |= V_NVSYNC;
+ if (misc & ATOM_HSYNC_POLARITY)
+ native_mode->Flags |= V_NHSYNC;
+ if (misc & ATOM_COMPOSITESYNC)
+ native_mode->Flags |= V_CSYNC;
+ if (misc & ATOM_INTERLACE)
+ native_mode->Flags |= V_INTERLACE;
+ if (misc & ATOM_DOUBLE_CLOCK_MODE)
+ native_mode->Flags |= V_DBLSCAN;
lvds->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->usOffDelayInMs);
lvds->lvds_misc = atomDataPtr->LVDS_Info.LVDS_Info->ucLVDS_Misc;
lvds->lvds_ss_id = atomDataPtr->LVDS_Info.LVDS_Info->ucSS_Id;
@@ -2011,6 +2028,17 @@ RADEONGetATOMLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
native_mode->VBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVBlanking_Time);
native_mode->VOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncOffset);
native_mode->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncWidth);
+ misc = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.susModeMiscInfo.usAccess);
+ if (misc & ATOM_VSYNC_POLARITY)
+ native_mode->Flags |= V_NVSYNC;
+ if (misc & ATOM_HSYNC_POLARITY)
+ native_mode->Flags |= V_NHSYNC;
+ if (misc & ATOM_COMPOSITESYNC)
+ native_mode->Flags |= V_CSYNC;
+ if (misc & ATOM_INTERLACE)
+ native_mode->Flags |= V_INTERLACE;
+ if (misc & ATOM_DOUBLE_CLOCK_MODE)
+ native_mode->Flags |= V_DBLSCAN;
lvds->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->usOffDelayInMs);
lvds->lvds_misc = atomDataPtr->LVDS_Info.LVDS_Info_v12->ucLVDS_Misc;
lvds->lvds_ss_id = atomDataPtr->LVDS_Info.LVDS_Info_v12->ucSS_Id;
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index db46d27a..103972f5 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -65,6 +65,8 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
int count)
{
ScreenPtr pScreen = drawable->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
BufferPtr buffers;
struct dri2_buffer_priv *privates;
PixmapPtr pixmap, depth_pixmap;
@@ -120,7 +122,9 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
if (attachments[i] == DRI2BufferDepth) {
depth_pixmap = pixmap;
}
+ info->exa_force_create = TRUE;
exaMoveInPixmap(pixmap);
+ info->exa_force_create = FALSE;
driver_priv = exaGetPixmapDriverPrivate(pixmap);
r = radeon_gem_get_kernel_name(driver_priv->bo, &buffers[i].name);
if (r)
@@ -143,6 +147,8 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
unsigned int format)
{
ScreenPtr pScreen = drawable->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
BufferPtr buffers;
struct dri2_buffer_priv *privates;
PixmapPtr pixmap, depth_pixmap;
@@ -198,7 +204,9 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
if (attachment == DRI2BufferDepth) {
depth_pixmap = pixmap;
}
+ info->exa_force_create = TRUE;
exaMoveInPixmap(pixmap);
+ info->exa_force_create = FALSE;
driver_priv = exaGetPixmapDriverPrivate(pixmap);
r = radeon_gem_get_kernel_name(driver_priv->bo, &buffers->name);
if (r)
@@ -322,45 +330,13 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
DRI2InfoRec dri2_info = { 0 };
- int fd;
- char *bus_id;
- char *tmp_bus_id;
- int cmp;
- int i;
if (!info->useEXA) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI2 requires EXA\n");
return FALSE;
}
- /* The whole drmOpen thing is a fiasco and we need to find a way
- * back to just using open(2). For now, however, lets just make
- * things worse with even more ad hoc directory walking code to
- * discover the device file name. */
- bus_id = DRICreatePCIBusID(info->PciInfo);
- for (i = 0; i < DRM_MAX_MINOR; i++) {
- sprintf(info->dri2.device_name, DRM_DEV_NAME, DRM_DIR_NAME, i);
- fd = open(info->dri2.device_name, O_RDWR);
- if (fd < 0)
- continue;
-
- tmp_bus_id = drmGetBusid(fd);
- close(fd);
- if (tmp_bus_id == NULL)
- continue;
-
- cmp = strcmp(tmp_bus_id, bus_id);
- drmFree(tmp_bus_id);
- if (cmp == 0)
- break;
- }
- xfree(bus_id);
-
- if (i == DRM_MAX_MINOR) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "DRI2: failed to open drm device\n");
- return FALSE;
- }
+ info->dri2.device_name = drmGetDeviceNameFromFd(info->dri2.drm_fd);
if ( (info->ChipFamily >= CHIP_FAMILY_R600) ) {
dri2_info.driverName = R600_DRIVER_NAME;
@@ -389,7 +365,11 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
void radeon_dri2_close_screen(ScreenPtr pScreen)
{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
DRI2CloseScreen(pScreen);
+ drmFree(info->dri2.device_name);
}
#endif
diff --git a/src/radeon_dri2.h b/src/radeon_dri2.h
index 899a6261..c391e739 100644
--- a/src/radeon_dri2.h
+++ b/src/radeon_dri2.h
@@ -30,7 +30,7 @@
struct radeon_dri2 {
int drm_fd;
Bool enabled;
- char device_name[64];
+ char *device_name;
};
#ifdef RADEON_DRI2
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 99a93a4e..bff6ec05 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -391,6 +391,14 @@ void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align)
RADEONInfoPtr info = RADEONPTR(pScrn);
struct radeon_exa_pixmap_priv *new_priv;
+#ifdef EXA_MIXED_PIXMAPS
+ if (info->accel_state->exa->flags & EXA_MIXED_PIXMAPS) {
+ if (size != 0 && !info->exa_force_create &&
+ info->exa_pixmaps == FALSE)
+ return NULL;
+ }
+#endif
+
new_priv = xcalloc(1, sizeof(struct radeon_exa_pixmap_priv));
if (!new_priv)
return NULL;
@@ -421,7 +429,15 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
uint32_t size;
uint32_t tiling = 0;
int pixmap_align = 0;
-
+
+#ifdef EXA_MIXED_PIXMAPS
+ if (info->accel_state->exa->flags & EXA_MIXED_PIXMAPS) {
+ if (width != 0 && height != 0 && !info->exa_force_create &&
+ info->exa_pixmaps == FALSE)
+ return NULL;
+ }
+#endif
+
if (usage_hint) {
if (info->allowColorTiling) {
if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MACRO)
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index b7457057..c1448900 100644
--- a/src/radeon_exa_render.c
+++ b/src/radeon_exa_render.c
@@ -1348,8 +1348,13 @@ static Bool R300CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
} else {
max_tex_w = 2048;
max_tex_h = 2048;
- max_dst_w = 4021;
- max_dst_h = 4021;
+ if (IS_R400_3D) {
+ max_dst_w = 4021;
+ max_dst_h = 4021;
+ } else {
+ max_dst_w = 2560;
+ max_dst_h = 2560;
+ }
}
if (pSrcPixmap->drawable.width > max_tex_w ||
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 8e46a8a2..c06b8328 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -41,7 +41,6 @@
#include "atipciids.h"
-
#ifdef XF86DRM_MODE
#include "radeon_chipset_gen.h"
@@ -52,6 +51,8 @@
#include "radeon_bo_gem.h"
#include "radeon_cs_gem.h"
+#include "radeon_vbo.h"
+
static Bool radeon_setup_kernel_mem(ScreenPtr pScreen);
const OptionInfoRec RADEONOptions_KMS[] = {
@@ -67,29 +68,48 @@ const OptionInfoRec RADEONOptions_KMS[] = {
{ OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_TVSTD, "TVStandard", OPTV_STRING, {0}, FALSE },
{ OPTION_EXA_VSYNC, "EXAVSync", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_EXA_PIXMAPS, "EXAPixmaps", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
void radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
int ret;
if (!info->cs->cdw)
return;
+
+ if (info->accel_state->vb_ptr)
+ info->accel_state->vb_ptr = NULL;
+
+ /* release the current VBO so we don't block on mapping it later */
+ if (info->accel_state->vb_offset && info->accel_state->vb_bo) {
+ radeon_vbo_put(pScrn);
+ info->accel_state->vb_start_op = -1;
+ }
+
radeon_cs_emit(info->cs);
radeon_cs_erase(info->cs);
- ret = radeon_cs_space_check(info->cs);
+ if (accel_state->use_vbos)
+ radeon_vbo_flush_bos(pScrn);
+
+ ret = radeon_cs_space_check_with_bo(info->cs,
+ accel_state->vb_bo,
+ RADEON_GEM_DOMAIN_GTT, 0);
if (ret)
ErrorF("space check failed in flush\n");
if (info->reemit_current2d && info->state_2d.op)
- info->reemit_current2d(pScrn, info->state_2d.op);
+ info->reemit_current2d(pScrn, info->state_2d.op);
+
if (info->dri2.enabled) {
- info->accel_state->XInited3D = FALSE;
- info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
+ info->accel_state->XInited3D = FALSE;
+ info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
}
+
}
void radeon_ddx_cs_start(ScrnInfoPtr pScrn,
@@ -450,6 +470,16 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
(unsigned long long)mminfo.vram_visible);
}
}
+
+ info->exa_pixmaps = xf86ReturnOptValBool(info->Options,
+ OPTION_EXA_PIXMAPS,
+ (info->vram_size > (32 * 1024 * 1024)));
+ if (info->exa_pixmaps)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "EXA: Driver will allow EXA pixmaps in VRAM\n");
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "EXA: Driver will not allow EXA pixmaps in VRAM\n");
RADEONSetPitch(pScrn);
/* Set display resolution */
@@ -520,12 +550,18 @@ static Bool RADEONCloseScreen_KMS(int scrnIndex, ScreenPtr pScreen)
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"RADEONCloseScreen\n");
+ if (info->cs)
+ radeon_cs_flush_indirect(pScrn);
+
if (info->accel_state->exa) {
exaDriverFini(pScreen);
xfree(info->accel_state->exa);
info->accel_state->exa = NULL;
}
+ if (info->accel_state->use_vbos)
+ radeon_vbo_free_lists(pScrn);
+
drmDropMaster(info->dri->drmFD);
if (info->cursor) xf86DestroyCursorInfoRec(info->cursor);
@@ -946,13 +982,31 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", info->front_bo->size/1024);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Remaining VRAM size (used for pixmaps): %dK\n", remain_size_bytes/1024);
+ radeon_kms_update_vram_limit(pScrn, screen_size);
+ return TRUE;
+}
- /* set the emit limit at 90% of VRAM */
- remain_size_bytes = (remain_size_bytes / 10) * 9;
+void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, int new_fb_size)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int remain_size_bytes;
+ int total_size_bytes;
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ if (info->cursor_bo[c] != NULL) {
+ total_size_bytes += (64 * 4 * 64);
+ }
+ }
+ total_size_bytes += new_fb_size;
+ remain_size_bytes = info->vram_size - new_fb_size;
+ remain_size_bytes = (remain_size_bytes / 10) * 9;
radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_VRAM, remain_size_bytes);
- return TRUE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VRAM usage limit set to %dK\n", remain_size_bytes / 1024);
}
+
#endif
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index ec60cc9b..3e3d4c80 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -158,7 +158,7 @@ static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
new->VSyncEnd = new->VSyncStart + native_mode->VSyncWidth;
new->Clock = native_mode->DotClock;
- new->Flags = 0;
+ new->Flags = native_mode->Flags;
if (new) {
new->type = M_T_DRIVER | M_T_PREFERRED;
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 71803340..107955d5 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -154,7 +154,7 @@ void RADEONPrintPortMap(ScrnInfoPtr pScrn)
if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
ErrorF(" TV1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id]);
if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
- ErrorF(" CV: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id]);
+ ErrorF(" CV: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CV_INDEX]->encoder_id]);
ErrorF(" DDC reg: 0x%x\n",(unsigned int)radeon_output->ddc_i2c.mask_clk_reg);
}
diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c
index 39c75749..7396f6f0 100644
--- a/src/radeon_textured_video.c
+++ b/src/radeon_textured_video.c
@@ -349,7 +349,9 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
#ifdef USE_EXA
if (info->useEXA) {
/* Force the pixmap into framebuffer so we can draw to it. */
+ info->exa_force_create = TRUE;
exaMoveInPixmap(pPriv->pPixmap);
+ info->exa_force_create = FALSE;
}
#endif
diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c
index c7d9b028..bd3fa174 100644
--- a/src/radeon_textured_videofuncs.c
+++ b/src/radeon_textured_videofuncs.c
@@ -344,12 +344,17 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
FINISH_ACCEL();
}
- BEGIN_ACCEL(2);
- OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
- OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, (((pPixmap->drawable.width) << RADEON_RE_WIDTH_SHIFT) |
- ((pPixmap->drawable.height) << RADEON_RE_HEIGHT_SHIFT)));
- FINISH_ACCEL();
-
+ {
+ int scissor_w, scissor_h;
+ scissor_w = MIN(pPixmap->drawable.width, 2047);
+ scissor_h = MIN(pPixmap->drawable.height, 2047);
+
+ BEGIN_ACCEL(2);
+ OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
+ OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, ((scissor_w << RADEON_RE_WIDTH_SHIFT) |
+ (scissor_h << RADEON_RE_HEIGHT_SHIFT)));
+ FINISH_ACCEL();
+ }
if (pPriv->vsync) {
xf86CrtcPtr crtc;
if (pPriv->desired_crtc)
@@ -382,7 +387,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
* We render a single, large triangle and use the scissor
* functionality to restrict it to the desired rectangle.
* Due to guardband limits on r3xx/r4xx, we can only use
- * the single triangle up to 4021 pixels; above that we
+ * the single triangle up to 2560/4021 pixels; above that we
* render as a quad.
*/
@@ -907,10 +912,15 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
FINISH_ACCEL();
}
- BEGIN_ACCEL(2);
- OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
- OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, (((pPixmap->drawable.width) << RADEON_RE_WIDTH_SHIFT) |
- ((pPixmap->drawable.height) << RADEON_RE_HEIGHT_SHIFT)));
+ {
+ int scissor_w, scissor_h;
+ scissor_w = MIN(pPixmap->drawable.width, 2047);
+ scissor_h = MIN(pPixmap->drawable.height, 2047);
+ BEGIN_ACCEL(2);
+ OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
+ OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, ((scissor_w << RADEON_RE_WIDTH_SHIFT) |
+ (scissor_h << RADEON_RE_HEIGHT_SHIFT)));
+ }
FINISH_ACCEL();
if (pPriv->vsync) {
@@ -945,7 +955,7 @@ FUNC_NAME(R200DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
* We render a single, large triangle and use the scissor
* functionality to restrict it to the desired rectangle.
* Due to guardband limits on r3xx/r4xx, we can only use
- * the single triangle up to 4021 pixels; above that we
+ * the single triangle up to 2560/4021 pixels; above that we
* render as a quad.
*/
@@ -2321,7 +2331,7 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
* We render a single, large triangle and use the scissor
* functionality to restrict it to the desired rectangle.
* Due to guardband limits on r3xx/r4xx, we can only use
- * the single triangle up to 4021 pixels; above that we
+ * the single triangle up to 2560/4021 pixels; above that we
* render as a quad.
*/
@@ -2349,8 +2359,13 @@ FUNC_NAME(R300DisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
ErrorF("src: %d, %d, %d, %d\n", srcX, srcY, srcw, srch);
#endif
- if ((dstw+dsth) > 4021)
- use_quad = TRUE;
+ if (IS_R400_3D) {
+ if ((dstw+dsth) > 4021)
+ use_quad = TRUE;
+ } else {
+ if ((dstw+dsth) > 2560)
+ use_quad = TRUE;
+ }
/*
* Set up the scissor area to that of the output size.
*/
diff --git a/src/radeon_vbo.c b/src/radeon_vbo.c
new file mode 100644
index 00000000..ad650b2d
--- /dev/null
+++ b/src/radeon_vbo.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * 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
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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:
+ * Dave Airlie <airlied@redhat.com>
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include "radeon.h"
+#include "radeon_bo.h"
+#include "radeon_cs.h"
+
+#define VBO_SIZE (16*1024)
+
+/* KMS vertex buffer support - for R600 only but could be used on previous gpus */
+
+#ifdef XF86DRM_MODE
+
+static struct radeon_bo *radeon_vbo_get_bo(ScrnInfoPtr pScrn);
+
+void radeon_vbo_put(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+
+ if (accel_state->vb_bo) {
+ radeon_bo_unmap(accel_state->vb_bo);
+ radeon_bo_unref(accel_state->vb_bo);
+ accel_state->vb_bo = NULL;
+ accel_state->vb_total = 0;
+ }
+
+ accel_state->vb_offset = 0;
+}
+
+void radeon_vbo_get(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+
+ accel_state->vb_bo = radeon_vbo_get_bo(pScrn);
+
+ accel_state->vb_total = VBO_SIZE;
+ accel_state->vb_offset = 0;
+ accel_state->vb_start_op = accel_state->vb_offset;
+}
+
+/* these functions could migrate to libdrm and
+ be shared with the radeon 3D driver */
+static int radeon_bo_is_idle(struct radeon_bo *bo)
+{
+ uint32_t domain;
+ int ret = radeon_bo_is_busy(bo, &domain);
+ return ret != -EBUSY;
+}
+
+void radeon_vbo_init_lists(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+
+ accel_state->use_vbos = TRUE;
+ make_empty_list(&accel_state->bo_free);
+ make_empty_list(&accel_state->bo_wait);
+ make_empty_list(&accel_state->bo_reserved);
+}
+
+void radeon_vbo_free_lists(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+ struct radeon_dma_bo *dma_bo, *temp;
+
+ foreach_s(dma_bo, temp, &accel_state->bo_free) {
+ remove_from_list(dma_bo);
+ radeon_bo_unref(dma_bo->bo);
+ xfree(dma_bo);
+ }
+
+ foreach_s(dma_bo, temp, &accel_state->bo_wait) {
+ remove_from_list(dma_bo);
+ radeon_bo_unref(dma_bo->bo);
+ xfree(dma_bo);
+ }
+
+ foreach_s(dma_bo, temp, &accel_state->bo_reserved) {
+ remove_from_list(dma_bo);
+ radeon_bo_unref(dma_bo->bo);
+ xfree(dma_bo);
+ }
+}
+
+void radeon_vbo_flush_bos(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+ struct radeon_dma_bo *dma_bo, *temp;
+ const int expire_at = ++accel_state->bo_free.expire_counter + DMA_BO_FREE_TIME;
+ const int time = accel_state->bo_free.expire_counter;
+
+ foreach_s(dma_bo, temp, &accel_state->bo_wait) {
+ if (dma_bo->expire_counter == time) {
+ ErrorF("leaking dma buffer\n");
+ while ((dma_bo->bo = radeon_bo_unref(dma_bo->bo))) {}
+ remove_from_list(dma_bo);
+ xfree(dma_bo);
+ continue;
+ }
+
+ if (!radeon_bo_is_idle(dma_bo->bo))
+ continue;
+
+ remove_from_list(dma_bo);
+ dma_bo->expire_counter = expire_at;
+ insert_at_tail(&accel_state->bo_free, dma_bo);
+ }
+
+ /* move reserved to wait list */
+ foreach_s(dma_bo, temp, &accel_state->bo_reserved) {
+ remove_from_list(dma_bo);
+ dma_bo->expire_counter = expire_at;
+ insert_at_tail(&accel_state->bo_wait, dma_bo);
+ }
+
+ /* free bos that have been unused */
+ foreach_s(dma_bo, temp, &accel_state->bo_free) {
+ if (dma_bo->expire_counter != time)
+ break;
+ /* always keep one hanging around at end */
+ if (at_end(&accel_state->bo_free, dma_bo)) {
+ dma_bo->expire_counter = time + DMA_BO_FREE_TIME;
+ break;
+ }
+
+ remove_from_list(dma_bo);
+ radeon_bo_unref(dma_bo->bo);
+ xfree(dma_bo);
+ }
+}
+
+static struct radeon_bo *radeon_vbo_get_bo(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+ struct radeon_dma_bo *dma_bo = NULL;
+ struct radeon_bo *bo;
+
+ if (is_empty_list(&accel_state->bo_free)) {
+ dma_bo = xcalloc(1, sizeof(struct radeon_dma_bo));
+ if (!dma_bo)
+ return NULL;
+
+again_alloc:
+ dma_bo->bo = radeon_bo_open(info->bufmgr, 0, VBO_SIZE,
+ 0, RADEON_GEM_DOMAIN_GTT, 0);
+
+ if (!dma_bo->bo) {
+ ErrorF("failure to allocate DMA BO\n");
+ return NULL;
+ }
+ insert_at_head(&accel_state->bo_reserved, dma_bo);
+ } else {
+ dma_bo = last_elem(&accel_state->bo_free);
+ remove_from_list(dma_bo);
+ insert_at_head(&accel_state->bo_reserved, dma_bo);
+ }
+
+ /* need a space check */
+ if (radeon_cs_space_check_with_bo(info->cs,
+ first_elem(&accel_state->bo_reserved)->bo,
+ RADEON_GEM_DOMAIN_GTT, 0))
+ fprintf(stderr,"failed to revalidated\n");
+
+ if (is_empty_list(&accel_state->bo_reserved)) {
+ goto again_alloc;
+ }
+
+ bo = first_elem(&accel_state->bo_reserved)->bo;
+ radeon_bo_ref(bo);
+ return bo;
+}
+
+#endif
diff --git a/src/radeon_vbo.h b/src/radeon_vbo.h
new file mode 100644
index 00000000..a8c70b30
--- /dev/null
+++ b/src/radeon_vbo.h
@@ -0,0 +1,62 @@
+
+#ifndef RADEON_VBO_H
+#define RADEON_VBO_H
+
+extern void r600_vb_no_space(ScrnInfoPtr pScrn, int vert_size);
+extern void radeon_vbo_init_lists(ScrnInfoPtr pScrn);
+extern void radeon_vbo_free_lists(ScrnInfoPtr pScrn);
+extern void radeon_vbo_flush_bos(ScrnInfoPtr pScrn);
+extern void radeon_vbo_get(ScrnInfoPtr pScrn);
+extern void radeon_vbo_put(ScrnInfoPtr pScrn);
+
+static inline void radeon_vbo_check(ScrnInfoPtr pScrn, int vert_size)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+
+ if ((accel_state->vb_offset + (3 * vert_size)) > accel_state->vb_total) {
+ r600_vb_no_space(pScrn, vert_size);
+ }
+}
+
+static inline void *
+radeon_vbo_space(ScrnInfoPtr pScrn, int vert_size)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+ void *vb;
+
+ /* we've ran out of space in the vertex buffer - need to get a
+ new one */
+ if ((accel_state->vb_offset + (3 * vert_size)) > accel_state->vb_total) {
+ r600_vb_no_space(pScrn, vert_size);
+ }
+ accel_state->vb_op_vert_size = vert_size;
+#if defined(XF86DRM_MODE)
+ if (info->cs) {
+ int ret;
+ struct radeon_bo *bo = accel_state->vb_bo;
+
+ if (!bo->ptr) {
+ ret = radeon_bo_map(bo, 1);
+ if (ret) {
+ FatalError("Failed to map vb %d\n", ret);
+ return NULL;
+ }
+ }
+ vb = (pointer)((char *)bo->ptr + accel_state->vb_offset);
+ } else
+#endif
+ vb = (pointer)((char *)accel_state->vb_ptr + accel_state->vb_offset);
+ return vb;
+}
+
+static inline void radeon_vbo_commit(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_accel_state *accel_state = info->accel_state;
+
+ accel_state->vb_offset += 3 * accel_state->vb_op_vert_size;
+}
+
+#endif
diff --git a/src/simple_list.h b/src/simple_list.h
new file mode 100644
index 00000000..ff7f8882
--- /dev/null
+++ b/src/simple_list.h
@@ -0,0 +1,202 @@
+/**
+ * \file simple_list.h
+ * Simple macros for type-safe, intrusive lists.
+ *
+ * Intended to work with a list sentinal which is created as an empty
+ * list. Insert & delete are O(1).
+ *
+ * \author
+ * (C) 1997, Keith Whitwell
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2001 Brian Paul 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
+ * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL 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.
+ */
+
+
+#ifndef _SIMPLE_LIST_H
+#define _SIMPLE_LIST_H
+
+struct simple_node {
+ struct simple_node *next;
+ struct simple_node *prev;
+};
+
+/**
+ * Remove an element from list.
+ *
+ * \param elem element to remove.
+ */
+#define remove_from_list(elem) \
+do { \
+ (elem)->next->prev = (elem)->prev; \
+ (elem)->prev->next = (elem)->next; \
+} while (0)
+
+/**
+ * Insert an element to the list head.
+ *
+ * \param list list.
+ * \param elem element to insert.
+ */
+#define insert_at_head(list, elem) \
+do { \
+ (elem)->prev = list; \
+ (elem)->next = (list)->next; \
+ (list)->next->prev = elem; \
+ (list)->next = elem; \
+} while(0)
+
+/**
+ * Insert an element to the list tail.
+ *
+ * \param list list.
+ * \param elem element to insert.
+ */
+#define insert_at_tail(list, elem) \
+do { \
+ (elem)->next = list; \
+ (elem)->prev = (list)->prev; \
+ (list)->prev->next = elem; \
+ (list)->prev = elem; \
+} while(0)
+
+/**
+ * Move an element to the list head.
+ *
+ * \param list list.
+ * \param elem element to move.
+ */
+#define move_to_head(list, elem) \
+do { \
+ remove_from_list(elem); \
+ insert_at_head(list, elem); \
+} while (0)
+
+/**
+ * Move an element to the list tail.
+ *
+ * \param list list.
+ * \param elem element to move.
+ */
+#define move_to_tail(list, elem) \
+do { \
+ remove_from_list(elem); \
+ insert_at_tail(list, elem); \
+} while (0)
+
+/**
+ * Make a empty list empty.
+ *
+ * \param sentinal list (sentinal element).
+ */
+#define make_empty_list(sentinal) \
+do { \
+ (sentinal)->next = sentinal; \
+ (sentinal)->prev = sentinal; \
+} while (0)
+
+/**
+ * Get list first element.
+ *
+ * \param list list.
+ *
+ * \return pointer to first element.
+ */
+#define first_elem(list) ((list)->next)
+
+/**
+ * Get list last element.
+ *
+ * \param list list.
+ *
+ * \return pointer to last element.
+ */
+#define last_elem(list) ((list)->prev)
+
+/**
+ * Get next element.
+ *
+ * \param elem element.
+ *
+ * \return pointer to next element.
+ */
+#define next_elem(elem) ((elem)->next)
+
+/**
+ * Get previous element.
+ *
+ * \param elem element.
+ *
+ * \return pointer to previous element.
+ */
+#define prev_elem(elem) ((elem)->prev)
+
+/**
+ * Test whether element is at end of the list.
+ *
+ * \param list list.
+ * \param elem element.
+ *
+ * \return non-zero if element is at end of list, or zero otherwise.
+ */
+#define at_end(list, elem) ((elem) == (list))
+
+/**
+ * Test if a list is empty.
+ *
+ * \param list list.
+ *
+ * \return non-zero if list empty, or zero otherwise.
+ */
+#define is_empty_list(list) ((list)->next == (list))
+
+/**
+ * Walk through the elements of a list.
+ *
+ * \param ptr pointer to the current element.
+ * \param list list.
+ *
+ * \note It should be followed by a { } block or a single statement, as in a \c
+ * for loop.
+ */
+#define foreach(ptr, list) \
+ for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next )
+
+/**
+ * Walk through the elements of a list.
+ *
+ * Same as #foreach but lets you unlink the current value during a list
+ * traversal. Useful for freeing a list, element by element.
+ *
+ * \param ptr pointer to the current element.
+ * \param t temporary pointer.
+ * \param list list.
+ *
+ * \note It should be followed by a { } block or a single statement, as in a \c
+ * for loop.
+ */
+#define foreach_s(ptr, t, list) \
+ for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next)
+
+#endif