summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-02-18 20:01:57 -0500
committerAlex Deucher <alexdeucher@gmail.com>2009-02-18 20:01:57 -0500
commitadff8906c9899dde7711382577a63f4a726437ca (patch)
treea18fe94f53b979cc4db5ec9e5f57578c92bef669 /src
parentcf85d4a1d43a3209c7ca9307aede2c2c243f7130 (diff)
R6xx/R7xx EXA/Xv: properly deal with running out of vertex buffer space
As noted by mhopf, if VGT_MAX/MIN_INDX, etc. regs change, you need to re-emit CB blocks to avoid a hang. So, just set the VGT_MAX_INDX to a reasonably large value in the default state and don't touch them when drawing. When we run out of VB space, just draw the current buffer, grab a new one, and continue.
Diffstat (limited to 'src')
-rw-r--r--src/r600_exa.c69
-rw-r--r--src/r600_textured_videofuncs.c116
-rw-r--r--src/r6xx_accel.c2
3 files changed, 87 insertions, 100 deletions
diff --git a/src/r600_exa.c b/src/r600_exa.c
index 5b17dcba..a252fb62 100644
--- a/src/r600_exa.c
+++ b/src/r600_exa.c
@@ -79,6 +79,13 @@ uint32_t RADEON_ROP[16] = {
RADEON_ROP3_ONE, /* GXset */
};
+static void
+R600DoneSolid(PixmapPtr pPix);
+
+static void
+R600DoneComposite(PixmapPtr pDst);
+
+
static Bool
R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
{
@@ -260,13 +267,16 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
RADEONInfoPtr info = RADEONPTR(pScrn);
struct radeon_accel_state *accel_state = info->accel_state;
struct r6xx_solid_vertex vertex[3];
- struct r6xx_solid_vertex *solid_vb = (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+ struct r6xx_solid_vertex *solid_vb;
if (((accel_state->vb_index + 3) * 8) > (accel_state->ib->total / 2)) {
- ErrorF("Solid: Ran out of VB space!\n");
- return;
+ R600DoneSolid(pPix);
+ accel_state->vb_index = 0;
+ accel_state->ib = RADEONCPGetBuffer(pScrn);
}
+ solid_vb = (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+
vertex[0].x = (float)x1;
vertex[0].y = (float)y1;
@@ -335,13 +345,6 @@ R600DoneSolid(PixmapPtr pPix)
draw_conf.num_indices = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
draw_conf.index_type = DI_INDEX_SIZE_16_BIT;
- ereg (accel_state->ib, VGT_INSTANCE_STEP_RATE_0, 0); /* ? */
- ereg (accel_state->ib, VGT_INSTANCE_STEP_RATE_1, 0);
-
- ereg (accel_state->ib, VGT_MAX_VTX_INDX, draw_conf.num_indices);
- ereg (accel_state->ib, VGT_MIN_VTX_INDX, 0);
- ereg (accel_state->ib, VGT_INDX_OFFSET, 0);
-
draw_auto(pScrn, accel_state->ib, &draw_conf);
wait_3d_idle_clean(pScrn, accel_state->ib);
@@ -581,13 +584,6 @@ R600DoCopy(ScrnInfoPtr pScrn)
draw_conf.num_indices = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
draw_conf.index_type = DI_INDEX_SIZE_16_BIT;
- ereg (accel_state->ib, VGT_INSTANCE_STEP_RATE_0, 0); /* ? */
- ereg (accel_state->ib, VGT_INSTANCE_STEP_RATE_1, 0);
-
- ereg (accel_state->ib, VGT_MAX_VTX_INDX, draw_conf.num_indices);
- ereg (accel_state->ib, VGT_MIN_VTX_INDX, 0);
- ereg (accel_state->ib, VGT_INDX_OFFSET, 0);
-
draw_auto(pScrn, accel_state->ib, &draw_conf);
wait_3d_idle_clean(pScrn, accel_state->ib);
@@ -611,17 +607,9 @@ R600AppendCopyVertex(ScrnInfoPtr pScrn,
struct r6xx_copy_vertex vertex[3];
if (((accel_state->vb_index + 3) * 16) > (accel_state->ib->total / 2)) {
- //ErrorF("Copy: Ran out of VB space!\n");
- // emit the old VB
R600DoCopy(pScrn);
- // start a new one
- R600DoPrepareCopy(pScrn,
- accel_state->src_pitch[0], accel_state->src_width[0], accel_state->src_height[0],
- accel_state->src_mc_addr[0], accel_state->src_bpp[0],
- accel_state->dst_pitch, accel_state->dst_height,
- accel_state->dst_mc_addr, accel_state->dst_bpp,
- accel_state->rop, accel_state->planemask);
-
+ accel_state->vb_index = 0;
+ accel_state->ib = RADEONCPGetBuffer(pScrn);
}
copy_vb = (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
@@ -1950,16 +1938,18 @@ static void R600Composite(PixmapPtr pDst,
}
if (accel_state->has_mask) {
- struct r6xx_comp_mask_vertex *comp_vb =
- (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+ struct r6xx_comp_mask_vertex *comp_vb;
struct r6xx_comp_mask_vertex vertex[3];
xPointFixed maskTopLeft, maskTopRight, maskBottomLeft, maskBottomRight;
if (((accel_state->vb_index + 3) * 24) > (accel_state->ib->total / 2)) {
- ErrorF("Composite: Ran out of VB space!\n");
- return;
+ R600DoneComposite(pDst);
+ accel_state->vb_index = 0;
+ accel_state->ib = RADEONCPGetBuffer(pScrn);
}
+ comp_vb = (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+
maskTopLeft.x = IntToxFixed(maskX);
maskTopLeft.y = IntToxFixed(maskY);
maskTopRight.x = IntToxFixed(maskX + w);
@@ -2012,15 +2002,17 @@ static void R600Composite(PixmapPtr pDst,
comp_vb[accel_state->vb_index++] = vertex[2];
} else {
- struct r6xx_comp_vertex *comp_vb =
- (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+ struct r6xx_comp_vertex *comp_vb;
struct r6xx_comp_vertex vertex[3];
if (((accel_state->vb_index + 3) * 16) > (accel_state->ib->total / 2)) {
- ErrorF("Composite: Ran out of VB space!\n");
- return;
+ R600DoneComposite(pDst);
+ accel_state->vb_index = 0;
+ accel_state->ib = RADEONCPGetBuffer(pScrn);
}
+ comp_vb = (pointer)((char*)accel_state->ib->address + (accel_state->ib->total / 2));
+
vertex[0].x = (float)dstX;
vertex[0].y = (float)dstY;
vertex[0].src_s = xFixedToFloat(srcTopLeft.x) / accel_state->texW[0];
@@ -2106,13 +2098,6 @@ static void R600DoneComposite(PixmapPtr pDst)
draw_conf.num_indices = vtx_res.vtx_num_entries / vtx_res.vtx_size_dw;
draw_conf.index_type = DI_INDEX_SIZE_16_BIT;
- ereg (accel_state->ib, VGT_INSTANCE_STEP_RATE_0, 0); /* ? */
- ereg (accel_state->ib, VGT_INSTANCE_STEP_RATE_1, 0);
-
- ereg (accel_state->ib, VGT_MAX_VTX_INDX, draw_conf.num_indices);
- ereg (accel_state->ib, VGT_MIN_VTX_INDX, 0);
- ereg (accel_state->ib, VGT_INDX_OFFSET, 0);
-
draw_auto(pScrn, accel_state->ib, &draw_conf);
wait_3d_idle_clean(pScrn, accel_state->ib);
diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c
index aca64125..c2b0e753 100644
--- a/src/r600_textured_videofuncs.c
+++ b/src/r600_textured_videofuncs.c
@@ -44,6 +44,61 @@
#include "damage.h"
+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);
+ return;
+ }
+
+ 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_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_RV710))
+ cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit,
+ accel_state->vb_size, accel_state->vb_mc_addr);
+ else
+ cp_set_surface_sync(pScrn, accel_state->ib, VC_ACTION_ENA_bit,
+ accel_state->vb_size, accel_state->vb_mc_addr);
+
+ /* 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;
+ 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);
+
+ R600CPFlushIndirect(pScrn, accel_state->ib);
+}
void
R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
@@ -58,8 +113,6 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
tex_resource_t tex_res;
tex_sampler_t tex_samp;
shader_config_t vs_conf, ps_conf;
- draw_config_t draw_conf;
- vtx_resource_t vtx_res;
int uv_offset;
static float ps_alu_consts[] = {
@@ -80,8 +133,6 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
CLEAR (tex_samp);
CLEAR (vs_conf);
CLEAR (ps_conf);
- CLEAR (draw_conf);
- CLEAR (vtx_res);
accel_state->dst_pitch = exaGetPixmapPitch(pPixmap) / (pPixmap->drawable.bitsPerPixel / 8);
accel_state->src_pitch[0] = pPriv->src_pitch;
@@ -415,8 +466,9 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
struct r6xx_copy_vertex vertex[3];
if (((accel_state->vb_index + 3) * 16) > (accel_state->ib->total / 2)) {
- ErrorF("Xv: Ran out of VB space!\n");
- break;
+ R600DoneTexturedVideo(pScrn);
+ accel_state->vb_index = 0;
+ accel_state->ib = RADEONCPGetBuffer(pScrn);
}
dstX = pBox->x1 + dstxoff;
@@ -461,57 +513,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
pBox++;
}
- if (accel_state->vb_index == 0) {
- R600IBDiscard(pScrn, accel_state->ib);
- DamageDamageRegion(pPriv->pDraw, &pPriv->clip);
- return;
- }
-
- 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_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_RV710))
- cp_set_surface_sync(pScrn, accel_state->ib, TC_ACTION_ENA_bit,
- accel_state->vb_size, accel_state->vb_mc_addr);
- else
- cp_set_surface_sync(pScrn, accel_state->ib, VC_ACTION_ENA_bit,
- accel_state->vb_size, accel_state->vb_mc_addr);
-
- /* 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;
- 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;
-
- ereg (accel_state->ib, VGT_INSTANCE_STEP_RATE_0, 0); /* ? */
- ereg (accel_state->ib, VGT_INSTANCE_STEP_RATE_1, 0);
-
- ereg (accel_state->ib, VGT_MAX_VTX_INDX, draw_conf.num_indices);
- ereg (accel_state->ib, VGT_MIN_VTX_INDX, 0);
- ereg (accel_state->ib, VGT_INDX_OFFSET, 0);
-
- 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);
-
- R600CPFlushIndirect(pScrn, accel_state->ib);
+ R600DoneTexturedVideo(pScrn);
DamageDamageRegion(pPriv->pDraw, &pPriv->clip);
}
diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c
index bebab883..267a7b01 100644
--- a/src/r6xx_accel.c
+++ b/src/r6xx_accel.c
@@ -1058,7 +1058,7 @@ set_default_state(ScrnInfoPtr pScrn, drmBufPtr ib)
fs_setup(pScrn, ib, &fs_conf);
// VGT
- ereg (ib, VGT_MAX_VTX_INDX, 0);
+ ereg (ib, VGT_MAX_VTX_INDX, 2048); /* XXX set to a reasonably large number of indices */
ereg (ib, VGT_MIN_VTX_INDX, 0);
ereg (ib, VGT_INDX_OFFSET, 0);
ereg (ib, VGT_INSTANCE_STEP_RATE_0, 0);