/* * Make sure previous submission of this cs are completed */ void radeon_drm_cs_sync_flush(struct radeon_cmdbuf *rcs) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); /* Wait for any pending ioctl of this CS to complete. */ if (util_queue_is_initialized(&cs->ws->cs_queue)) util_queue_fence_wait(&cs->flush_completed); }
void fd_context_destroy(struct pipe_context *pctx) { struct fd_context *ctx = fd_context(pctx); unsigned i; DBG(""); fd_fence_ref(pctx->screen, &ctx->last_fence, NULL); if (ctx->screen->reorder && util_queue_is_initialized(&ctx->flush_queue)) util_queue_destroy(&ctx->flush_queue); util_copy_framebuffer_state(&ctx->framebuffer, NULL); fd_batch_reference(&ctx->batch, NULL); /* unref current batch */ fd_bc_invalidate_context(ctx); fd_prog_fini(pctx); if (ctx->blitter) util_blitter_destroy(ctx->blitter); if (pctx->stream_uploader) u_upload_destroy(pctx->stream_uploader); if (ctx->clear_rs_state) pctx->delete_rasterizer_state(pctx, ctx->clear_rs_state); if (ctx->primconvert) util_primconvert_destroy(ctx->primconvert); slab_destroy_child(&ctx->transfer_pool); for (i = 0; i < ARRAY_SIZE(ctx->vsc_pipe); i++) { struct fd_vsc_pipe *pipe = &ctx->vsc_pipe[i]; if (!pipe->bo) break; fd_bo_del(pipe->bo); } fd_device_del(ctx->dev); fd_pipe_del(ctx->pipe); if (fd_mesa_debug & (FD_DBG_BSTAT | FD_DBG_MSGS)) { printf("batch_total=%u, batch_sysmem=%u, batch_gmem=%u, batch_nondraw=%u, batch_restore=%u\n", (uint32_t)ctx->stats.batch_total, (uint32_t)ctx->stats.batch_sysmem, (uint32_t)ctx->stats.batch_gmem, (uint32_t)ctx->stats.batch_nondraw, (uint32_t)ctx->stats.batch_restore); } }
static void si_destroy_screen(struct pipe_screen* pscreen) { struct si_screen *sscreen = (struct si_screen *)pscreen; struct si_shader_part *parts[] = { sscreen->vs_prologs, sscreen->vs_epilogs, sscreen->tcs_epilogs, sscreen->gs_prologs, sscreen->ps_prologs, sscreen->ps_epilogs }; unsigned i; if (!sscreen) return; if (!sscreen->b.ws->unref(sscreen->b.ws)) return; if (util_queue_is_initialized(&sscreen->shader_compiler_queue)) util_queue_destroy(&sscreen->shader_compiler_queue); for (i = 0; i < ARRAY_SIZE(sscreen->tm); i++) if (sscreen->tm[i]) LLVMDisposeTargetMachine(sscreen->tm[i]); /* Free shader parts. */ for (i = 0; i < ARRAY_SIZE(parts); i++) { while (parts[i]) { struct si_shader_part *part = parts[i]; parts[i] = part->next; radeon_shader_binary_clean(&part->binary); FREE(part); } } pipe_mutex_destroy(sscreen->shader_parts_mutex); si_destroy_shader_cache(sscreen); r600_destroy_common_screen(&sscreen->b); }
static int radeon_drm_cs_flush(struct radeon_cmdbuf *rcs, unsigned flags, struct pipe_fence_handle **pfence) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); struct radeon_cs_context *tmp; switch (cs->ring_type) { case RING_DMA: /* pad DMA ring to 8 DWs */ if (cs->ws->info.chip_class <= GFX6) { while (rcs->current.cdw & 7) radeon_emit(&cs->base, 0xf0000000); /* NOP packet */ } else { while (rcs->current.cdw & 7) radeon_emit(&cs->base, 0x00000000); /* NOP packet */ } break; case RING_GFX: /* pad GFX ring to 8 DWs to meet CP fetch alignment requirements * r6xx, requires at least 4 dw alignment to avoid a hw bug. */ if (cs->ws->info.gfx_ib_pad_with_type2) { while (rcs->current.cdw & 7) radeon_emit(&cs->base, 0x80000000); /* type2 nop packet */ } else { while (rcs->current.cdw & 7) radeon_emit(&cs->base, 0xffff1000); /* type3 nop packet */ } break; case RING_UVD: while (rcs->current.cdw & 15) radeon_emit(&cs->base, 0x80000000); /* type2 nop packet */ break; default: break; } if (rcs->current.cdw > rcs->current.max_dw) { fprintf(stderr, "radeon: command stream overflowed\n"); } if (pfence || cs->csc->num_slab_buffers) { struct pipe_fence_handle *fence; if (cs->next_fence) { fence = cs->next_fence; cs->next_fence = NULL; } else { fence = radeon_cs_create_fence(rcs); } if (fence) { if (pfence) radeon_fence_reference(pfence, fence); mtx_lock(&cs->ws->bo_fence_lock); for (unsigned i = 0; i < cs->csc->num_slab_buffers; ++i) { struct radeon_bo *bo = cs->csc->slab_buffers[i].bo; p_atomic_inc(&bo->num_active_ioctls); radeon_bo_slab_fence(bo, (struct radeon_bo *)fence); } mtx_unlock(&cs->ws->bo_fence_lock); radeon_fence_reference(&fence, NULL); } } else { radeon_fence_reference(&cs->next_fence, NULL); } radeon_drm_cs_sync_flush(rcs); /* Swap command streams. */ tmp = cs->csc; cs->csc = cs->cst; cs->cst = tmp; /* If the CS is not empty or overflowed, emit it in a separate thread. */ if (cs->base.current.cdw && cs->base.current.cdw <= cs->base.current.max_dw && !debug_get_option_noop()) { unsigned i, num_relocs; num_relocs = cs->cst->num_relocs; cs->cst->chunks[0].length_dw = cs->base.current.cdw; for (i = 0; i < num_relocs; i++) { /* Update the number of active asynchronous CS ioctls for the buffer. */ p_atomic_inc(&cs->cst->relocs_bo[i].bo->num_active_ioctls); } switch (cs->ring_type) { case RING_DMA: cs->cst->flags[0] = 0; cs->cst->flags[1] = RADEON_CS_RING_DMA; cs->cst->cs.num_chunks = 3; if (cs->ws->info.r600_has_virtual_memory) { cs->cst->flags[0] |= RADEON_CS_USE_VM; } break; case RING_UVD: cs->cst->flags[0] = 0; cs->cst->flags[1] = RADEON_CS_RING_UVD; cs->cst->cs.num_chunks = 3; break; case RING_VCE: cs->cst->flags[0] = 0; cs->cst->flags[1] = RADEON_CS_RING_VCE; cs->cst->cs.num_chunks = 3; break; default: case RING_GFX: case RING_COMPUTE: cs->cst->flags[0] = RADEON_CS_KEEP_TILING_FLAGS; cs->cst->flags[1] = RADEON_CS_RING_GFX; cs->cst->cs.num_chunks = 3; if (cs->ws->info.r600_has_virtual_memory) { cs->cst->flags[0] |= RADEON_CS_USE_VM; cs->cst->cs.num_chunks = 3; } if (flags & PIPE_FLUSH_END_OF_FRAME) { cs->cst->flags[0] |= RADEON_CS_END_OF_FRAME; cs->cst->cs.num_chunks = 3; } if (cs->ring_type == RING_COMPUTE) { cs->cst->flags[1] = RADEON_CS_RING_COMPUTE; cs->cst->cs.num_chunks = 3; } break; } if (util_queue_is_initialized(&cs->ws->cs_queue)) { util_queue_add_job(&cs->ws->cs_queue, cs, &cs->flush_completed, radeon_drm_cs_emit_ioctl_oneshot, NULL); if (!(flags & PIPE_FLUSH_ASYNC)) radeon_drm_cs_sync_flush(rcs); } else { radeon_drm_cs_emit_ioctl_oneshot(cs, 0); } } else { radeon_cs_context_cleanup(cs->cst); } /* Prepare a new CS. */ cs->base.current.buf = cs->csc->buf; cs->base.current.cdw = 0; cs->base.used_vram = 0; cs->base.used_gart = 0; if (cs->ring_type == RING_GFX) cs->ws->num_gfx_IBs++; else if (cs->ring_type == RING_DMA) cs->ws->num_sdma_IBs++; return 0; }