diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-02-18 20:01:57 -0500 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2009-02-18 20:01:57 -0500 |
commit | adff8906c9899dde7711382577a63f4a726437ca (patch) | |
tree | a18fe94f53b979cc4db5ec9e5f57578c92bef669 /src | |
parent | cf85d4a1d43a3209c7ca9307aede2c2c243f7130 (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.c | 69 | ||||
-rw-r--r-- | src/r600_textured_videofuncs.c | 116 | ||||
-rw-r--r-- | src/r6xx_accel.c | 2 |
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); |