diff options
-rw-r--r-- | src/r600_exa.c | 237 | ||||
-rw-r--r-- | src/r600_state.h | 24 | ||||
-rw-r--r-- | src/r600_textured_videofuncs.c | 73 | ||||
-rw-r--r-- | src/r6xx_accel.c | 108 | ||||
-rw-r--r-- | src/radeon.h | 3 | ||||
-rw-r--r-- | src/radeon_kms.c | 2 |
6 files changed, 135 insertions, 312 deletions
diff --git a/src/r600_exa.c b/src/r600_exa.c index 1405db78..174037d5 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -219,9 +219,6 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) r600_cp_start(pScrn); - /* Init */ - 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); @@ -355,7 +352,6 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) ErrorF("PM: 0x%08x\n", pm); #endif - accel_state->vb_start_op = accel_state->vb_offset; return TRUE; } @@ -368,14 +364,7 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2) struct radeon_accel_state *accel_state = info->accel_state; float *vb; - if ((accel_state->vb_offset + (3 * 8)) > accel_state->vb_total) { - R600DoneSolid(pPix); - if (info->cs) - radeon_cs_flush_indirect(pScrn); - r600_cp_start(pScrn); - } - - vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_offset); + vb = r600_vb_space(pScrn, 8); vb[0] = (float)x1; vb[1] = (float)y1; @@ -386,71 +375,15 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2) vb[4] = (float)x2; vb[5] = (float)y2; - accel_state->vb_offset += (3*8); - + r600_vb_update(accel_state, 8); } 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_offset == accel_state->vb_start_op) { - R600IBDiscard(pScrn, accel_state->ib); - r600_vb_discard(pScrn); - return; - } - - accel_state->vb_size = accel_state->vb_offset; - - /* 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 */ - accel_state->vb_size -= accel_state->vb_start_op; - 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 + 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); - - r600_finish_op(pScrn); + r600_finish_op(pScrn, 8); } static void @@ -493,9 +426,6 @@ R600DoPrepareCopy(ScrnInfoPtr pScrn, r600_cp_start(pScrn); - /* Init */ - 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); @@ -648,69 +578,12 @@ R600DoPrepareCopy(ScrnInfoPtr pScrn, EREG(accel_state->ib, SPI_INTERP_CONTROL_0, 0); END_BATCH(); - accel_state->vb_start_op = accel_state->vb_offset; } 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_offset == accel_state->vb_start_op) { - R600IBDiscard(pScrn, accel_state->ib); - r600_vb_discard(pScrn); - return; - } - - accel_state->vb_size = accel_state->vb_offset; - - /* 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 */ - accel_state->vb_size -= accel_state->vb_start_op; - - 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 + accel_state->vb_start_op; - 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); - - r600_finish_op(pScrn); + r600_finish_op(pScrn, 16); } static void @@ -723,14 +596,7 @@ R600AppendCopyVertex(ScrnInfoPtr pScrn, struct radeon_accel_state *accel_state = info->accel_state; float *vb; - if ((accel_state->vb_offset + (3 * 16)) > accel_state->vb_total) { - R600DoCopy(pScrn); - if (info->cs) - radeon_cs_flush_indirect(pScrn); - r600_cp_start(pScrn); - } - - vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_offset); + vb = r600_vb_space(pScrn, 16); vb[0] = (float)dstX; vb[1] = (float)dstY; @@ -747,7 +613,7 @@ R600AppendCopyVertex(ScrnInfoPtr pScrn, vb[10] = (float)(srcX + w); vb[11] = (float)(srcY + h); - accel_state->vb_offset += (3 * 16); + r600_vb_update(accel_state, 16); } static Bool @@ -1719,9 +1585,6 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, r600_cp_start(pScrn); - /* Init */ - start_3d(pScrn, accel_state->ib); - set_default_state(pScrn, accel_state->ib); set_generic_scissor(pScrn, accel_state->ib, 0, 0, pDst->drawable.width, pDst->drawable.height); @@ -1884,8 +1747,6 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, EREG(accel_state->ib, SPI_INTERP_CONTROL_0, 0); END_BATCH(); - accel_state->vb_start_op = accel_state->vb_offset; - return TRUE; } @@ -1904,14 +1765,8 @@ static void R600Composite(PixmapPtr pDst, srcX, srcY, maskX, maskY,dstX, dstY, w, h); */ if (accel_state->msk_pic) { - if ((accel_state->vb_offset + (3 * 24)) > accel_state->vb_total) { - R600DoneComposite(pDst); - if (info->cs) - radeon_cs_flush_indirect(pScrn); - r600_cp_start(pScrn); - } - vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_offset); + vb = r600_vb_space(pScrn, 24); vb[0] = (float)dstX; vb[1] = (float)dstY; @@ -1934,16 +1789,10 @@ static void R600Composite(PixmapPtr pDst, vb[16] = (float)(maskX + w); vb[17] = (float)(maskY + h); - accel_state->vb_offset += 3 * 24; + r600_vb_update(accel_state, 24); } else { - if ((accel_state->vb_offset + (3 * 16)) > accel_state->vb_total) { - R600DoneComposite(pDst); - if (info->cs) - radeon_cs_flush_indirect(pScrn); - r600_cp_start(pScrn); - } - vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_offset); + vb = r600_vb_space(pScrn, 16); vb[0] = (float)dstX; vb[1] = (float)dstY; @@ -1959,8 +1808,8 @@ static void R600Composite(PixmapPtr pDst, vb[9] = (float)(dstY + h); vb[10] = (float)(srcX + w); vb[11] = (float)(srcY + h); - accel_state->vb_offset += 3 * 16; + r600_vb_update(accel_state, 16); } @@ -1971,68 +1820,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_offset == accel_state->vb_start_op) { - R600IBDiscard(pScrn, accel_state->ib); - r600_vb_discard(pScrn); - return; - } - - accel_state->vb_size = accel_state->vb_offset; - /* 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); - - accel_state->vb_size -= accel_state->vb_start_op; - - /* Vertex buffer setup */ - if (accel_state->msk_pic) { - 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 + accel_state->vb_start_op; - vtx_res.bo = accel_state->vb_bo; - } else { - 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 + accel_state->vb_start_op; - 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); + int vtx_size; - 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); + vtx_size = accel_state->msk_pic ? 24 : 16; - r600_finish_op(pScrn); + r600_finish_op(pScrn, vtx_size); } Bool @@ -2628,7 +2420,8 @@ 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_bo[0] = NULL; + info->accel_state->vb_bo[1] = NULL; if (!R600AllocShaders(pScrn, pScreen)) return FALSE; diff --git a/src/r600_state.h b/src/r600_state.h index b2d2433a..6cd47dcc 100644 --- a/src/r600_state.h +++ b/src/r600_state.h @@ -326,8 +326,7 @@ void r600_vb_discard(ScrnInfoPtr pScrn); int r600_cp_start(ScrnInfoPtr pScrn); -void -r600_finish_op(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); @@ -336,4 +335,25 @@ extern void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv); extern struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix); extern Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix); + +static inline float * +r600_vb_space(ScrnInfoPtr pScrn, int vert_size) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + float *vb; + + if ((accel_state->vb_offset + (3 * vert_size)) > accel_state->vb_total) { + r600_finish_op(pScrn, vert_size); + if (info->cs) + radeon_cs_flush_indirect(pScrn); + r600_cp_start(pScrn); + } + vb = (pointer)((char *)accel_state->vb_ptr + accel_state->vb_offset); + return vb; +} + +#define r600_vb_update(accel_state, vert_size) do { (accel_state)->vb_offset += (3 * (vert_size)); } while(0) + + #endif diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c index bf0511ef..b962ae7a 100644 --- a/src/r600_textured_videofuncs.c +++ b/src/r600_textured_videofuncs.c @@ -57,62 +57,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_offset == accel_state->vb_start_op) { - R600IBDiscard(pScrn, accel_state->ib); - r600_vb_discard(pScrn); - return; - } - - accel_state->vb_size = accel_state->vb_offset; - - /* 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 */ - accel_state->vb_size -= accel_state->vb_start_op; - 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 + accel_state->vb_start_op; - 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); - - r600_finish_op(pScrn); + r600_finish_op(pScrn, 16); } void @@ -263,9 +208,6 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) r600_cp_start(pScrn); - /* Init */ - 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); @@ -561,8 +503,6 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) EREG(accel_state->ib, SPI_INTERP_CONTROL_0, 0); END_BATCH(); - accel_state->vb_start_op = accel_state->vb_offset; - vs_alu_consts[0] = 1.0 / pPriv->w; vs_alu_consts[1] = 1.0 / pPriv->h; vs_alu_consts[2] = 0.0; @@ -594,14 +534,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) int dstX, dstY, dstw, dsth; float *vb; - if ((accel_state->vb_offset + (3 * 16)) > accel_state->vb_total) { - R600DoneTexturedVideo(pScrn); - if (info->cs) - radeon_cs_flush_indirect(pScrn); - r600_cp_start(pScrn); - } - - vb = (pointer)((char*)accel_state->vb_ptr+accel_state->vb_offset); + vb = r600_vb_space(pScrn, 16); dstX = pBox->x1 + dstxoff; dstY = pBox->y1 + dstyoff; @@ -633,7 +566,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) vb[10] = (float)(srcX + srcw); vb[11] = (float)(srcY + srch); - accel_state->vb_offset += 3 * 16; + r600_vb_update(accel_state, 16); pBox++; } diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c index 0ca44adb..69e17e49 100644 --- a/src/r6xx_accel.c +++ b/src/r6xx_accel.c @@ -39,6 +39,16 @@ #include "radeon_drm.h" +/* we try and batch operations together under KMS - + but it doesn't work yet without misrendering */ +#define KMS_MULTI_OP 0 + +#if KMS_MULTI_OP +#define VBO_SIZE (16*1024) +#else +#define VBO_SIZE (4*1024) +#endif + /* Flush the indirect buffer to the kernel for submission to the card */ void R600CPFlushIndirect(ScrnInfoPtr pScrn, drmBufPtr ib) { @@ -90,7 +100,7 @@ void R600IBDiscard(ScrnInfoPtr pScrn, drmBufPtr ib) return; } if (info->accel_state->vb_ptr) { - radeon_bo_unmap(info->accel_state->vb_bo); + radeon_bo_unmap(info->accel_state->vb_bo[info->accel_state->vb_bo_index]); info->accel_state->vb_ptr = NULL; info->accel_state->vb_offset = 0; info->accel_state->vb_start_op = 0; @@ -723,15 +733,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); @@ -1166,21 +1176,29 @@ r600_vb_get(ScrnInfoPtr pScrn) #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, + if (accel_state->vb_bo[0] == NULL) { + accel_state->vb_bo[0] = radeon_bo_open(info->bufmgr, 0, VBO_SIZE, 0, RADEON_GEM_DOMAIN_GTT, 0); - if (accel_state->vb_bo == NULL) + if (accel_state->vb_bo[0] == NULL) + return FALSE; + accel_state->vb_mc_addr = 0; + accel_state->vb_total = VBO_SIZE; + accel_state->vb_bo_index = 1; + } + if (accel_state->vb_bo[1] == NULL) { + accel_state->vb_bo[1] = radeon_bo_open(info->bufmgr, 0, VBO_SIZE, + 0, RADEON_GEM_DOMAIN_GTT, 0); + if (accel_state->vb_bo[1] == NULL) return FALSE; - accel_state->vb_total = 16 * 1024; } if (!accel_state->vb_ptr) { - ret = radeon_bo_map(accel_state->vb_bo, 1); + accel_state->vb_bo_index = !(accel_state->vb_bo_index); + ret = radeon_bo_map(accel_state->vb_bo[accel_state->vb_bo_index], 1); if (ret) { FatalError("failed to vb %d\n", ret); return FALSE; } - accel_state->vb_ptr = accel_state->vb_bo->ptr; + accel_state->vb_ptr = accel_state->vb_bo[accel_state->vb_bo_index]->ptr; } } else #endif @@ -1215,12 +1233,13 @@ r600_cp_start(ScrnInfoPtr pScrn) } if (!r600_vb_get(pScrn)) return -1; - if (accel_state->vb_bo) - radeon_cs_space_add_persistent_bo(info->cs, accel_state->vb_bo, + if (accel_state->vb_bo[accel_state->vb_bo_index]) + radeon_cs_space_add_persistent_bo(info->cs, accel_state->vb_bo[accel_state->vb_bo_index], RADEON_GEM_DOMAIN_GTT, 0); radeon_cs_space_check(info->cs); accel_state->ib_reset_op = info->cs->cdw; + accel_state->vb_start_op = accel_state->vb_offset; } else #endif { @@ -1232,13 +1251,70 @@ r600_cp_start(ScrnInfoPtr pScrn) return 0; } -void r600_finish_op(ScrnInfoPtr pScrn) +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; + 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[accel_state->vb_bo_index], + 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[accel_state->vb_bo_index], + 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[accel_state->vb_bo_index]; + 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); + accel_state->vb_start_op = 0; accel_state->ib_reset_op = 0; - R600CPFlushIndirect(pScrn, accel_state->ib); +#if KMS_MULTI_OP + if (!info->cs) +#endif + R600CPFlushIndirect(pScrn, accel_state->ib); } + diff --git a/src/radeon.h b/src/radeon.h index 71357b3b..5eec147a 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -708,7 +708,8 @@ struct radeon_accel_state { int vb_total; void *vb_ptr; uint32_t vb_size; - struct radeon_bo *vb_bo; + struct radeon_bo *vb_bo[2]; + int vb_bo_index; uint32_t vb_start_op; /* where to discard IB from if we cancel operation */ uint32_t ib_reset_op; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 9ee08f3f..f6c41d9b 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -80,7 +80,7 @@ void radeon_cs_flush_indirect(ScrnInfoPtr pScrn) return; if (info->accel_state->vb_ptr) { - radeon_bo_unmap(info->accel_state->vb_bo); + radeon_bo_unmap(info->accel_state->vb_bo[info->accel_state->vb_bo_index]); info->accel_state->vb_ptr = NULL; info->accel_state->vb_start_op = 0; info->accel_state->vb_offset = 0; |