📄 dri_bufmgr_fake.c
字号:
*/ bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; DBG("drm_bo_validate: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, bo_fake->bo.size / 1024); /* Sanity check: Buffers should be unmapped before being validated. * This is not so much of a problem for bufmgr_fake, but TTM refuses, * and the problem is harder to debug there. */ assert(bo_fake->map_count == 0); if (bo_fake->is_static) { /* Add it to the needs-fence list */ bufmgr_fake->need_fence = 1; return 0; } /* reset size accounted */ bo_fake->size_accounted = 0; /* Allocate the card memory */ if (!bo_fake->block && !evict_and_alloc_block(bo)) { bufmgr_fake->fail = 1; DBG("Failed to validate buf %d:%s\n", bo_fake->id, bo_fake->name); return -1; } assert(bo_fake->block); assert(bo_fake->block->bo == &bo_fake->bo); bo->offset = bo_fake->block->mem->ofs; /* Upload the buffer contents if necessary */ if (bo_fake->dirty) { DBG("Upload dirty buf %d:%s, sz %d offset 0x%x\n", bo_fake->id, bo_fake->name, bo->size, bo_fake->block->mem->ofs); assert(!(bo_fake->flags & (BM_NO_BACKING_STORE|BM_PINNED))); /* Actually, should be able to just wait for a fence on the memory, * which we would be tracking when we free it. Waiting for idle is * a sufficiently large hammer for now. */ dri_bufmgr_fake_wait_idle(bufmgr_fake); /* we may never have mapped this BO so it might not have any backing * store if this happens it should be rare, but 0 the card memory * in any case */ if (bo_fake->backing_store) memcpy(bo_fake->block->virtual, bo_fake->backing_store, bo->size); else memset(bo_fake->block->virtual, 0, bo->size); bo_fake->dirty = 0; } bo_fake->block->fenced = 0; bo_fake->block->on_hardware = 1; move_to_tail(&bufmgr_fake->on_hardware, bo_fake->block); bo_fake->validated = GL_TRUE; bufmgr_fake->need_fence = 1; return 0;}static dri_fence *dri_fake_fence_validated(dri_bufmgr *bufmgr, const char *name, GLboolean flushed){ dri_fence_fake *fence_fake; dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr; unsigned int cookie; fence_fake = malloc(sizeof(*fence_fake)); if (!fence_fake) return NULL; fence_fake->refcount = 1; fence_fake->name = name; fence_fake->flushed = flushed; fence_fake->fence.bufmgr = bufmgr; cookie = _fence_emit_internal(bufmgr_fake); fence_fake->fence_cookie = cookie; fence_blocks(bufmgr_fake, cookie); DBG("drm_fence_validated: 0x%08x cookie\n", fence_fake->fence_cookie); return &fence_fake->fence;}static voiddri_fake_fence_reference(dri_fence *fence){ dri_fence_fake *fence_fake = (dri_fence_fake *)fence; ++fence_fake->refcount;}static voiddri_fake_fence_unreference(dri_fence *fence){ dri_fence_fake *fence_fake = (dri_fence_fake *)fence; if (!fence) return; if (--fence_fake->refcount == 0) { free(fence); return; }}static voiddri_fake_fence_wait(dri_fence *fence){ dri_fence_fake *fence_fake = (dri_fence_fake *)fence; dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr; DBG("drm_fence_wait: 0x%08x cookie\n", fence_fake->fence_cookie); _fence_wait_internal(bufmgr_fake, fence_fake->fence_cookie);}static voiddri_fake_destroy(dri_bufmgr *bufmgr){ dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr; mmDestroy(bufmgr_fake->heap); free(bufmgr);}static intdri_fake_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta, GLuint offset, dri_bo *target_buf){ dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)reloc_buf->bufmgr; struct fake_buffer_reloc *r; dri_bo_fake *reloc_fake = (dri_bo_fake *)reloc_buf; dri_bo_fake *target_fake = (dri_bo_fake *)target_buf; int i; assert(reloc_buf); assert(target_buf); assert(target_fake->is_static || target_fake->size_accounted); if (reloc_fake->relocs == NULL) { reloc_fake->relocs = malloc(sizeof(struct fake_buffer_reloc) * MAX_RELOCS); } r = &reloc_fake->relocs[reloc_fake->nr_relocs++]; assert(reloc_fake->nr_relocs <= MAX_RELOCS); dri_bo_reference(target_buf); r->target_buf = target_buf; r->offset = offset; r->last_target_offset = target_buf->offset; r->delta = delta; r->validate_flags = flags; if (bufmgr_fake->debug) { /* Check that a conflicting relocation hasn't already been emitted. */ for (i = 0; i < reloc_fake->nr_relocs - 1; i++) { struct fake_buffer_reloc *r2 = &reloc_fake->relocs[i]; assert(r->offset != r2->offset); } } return 0;}/** * Incorporates the validation flags associated with each relocation into * the combined validation flags for the buffer on this batchbuffer submission. */static voiddri_fake_calculate_validate_flags(dri_bo *bo){ dri_bo_fake *bo_fake = (dri_bo_fake *)bo; int i; for (i = 0; i < bo_fake->nr_relocs; i++) { struct fake_buffer_reloc *r = &bo_fake->relocs[i]; dri_bo_fake *target_fake = (dri_bo_fake *)r->target_buf; /* Do the same for the tree of buffers we depend on */ dri_fake_calculate_validate_flags(r->target_buf); if (target_fake->validate_flags == 0) { target_fake->validate_flags = r->validate_flags; } else { /* Mask the memory location to the intersection of all the memory * locations the buffer is being validated to. */ target_fake->validate_flags = (target_fake->validate_flags & ~DRM_BO_MASK_MEM) | (r->validate_flags & target_fake->validate_flags & DRM_BO_MASK_MEM); /* All the other flags just accumulate. */ target_fake->validate_flags |= r->validate_flags & ~DRM_BO_MASK_MEM; } }}static intdri_fake_reloc_and_validate_buffer(dri_bo *bo){ dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; dri_bo_fake *bo_fake = (dri_bo_fake *)bo; int i, ret; assert(bo_fake->map_count == 0); for (i = 0; i < bo_fake->nr_relocs; i++) { struct fake_buffer_reloc *r = &bo_fake->relocs[i]; dri_bo_fake *target_fake = (dri_bo_fake *)r->target_buf; uint32_t reloc_data; /* Validate the target buffer if that hasn't been done. */ if (!target_fake->validated) { ret = dri_fake_reloc_and_validate_buffer(r->target_buf); if (ret != 0) { if (bo->virtual != NULL) dri_bo_unmap(bo); return ret; } } /* Calculate the value of the relocation entry. */ if (r->target_buf->offset != r->last_target_offset) { reloc_data = r->target_buf->offset + r->delta; if (bo->virtual == NULL) dri_bo_map(bo, GL_TRUE); *(uint32_t *)(bo->virtual + r->offset) = reloc_data; r->last_target_offset = r->target_buf->offset; } } if (bo->virtual != NULL) dri_bo_unmap(bo); if (bo_fake->validate_flags & DRM_BO_FLAG_WRITE) { if (!(bo_fake->flags & (BM_NO_BACKING_STORE|BM_PINNED))) { if (bo_fake->backing_store == 0) alloc_backing_store(bo); bo_fake->card_dirty = 1; } bufmgr_fake->performed_rendering = GL_TRUE; } return dri_fake_bo_validate(bo, bo_fake->validate_flags);}static void *dri_fake_process_relocs(dri_bo *batch_buf, GLuint *count_p){ dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)batch_buf->bufmgr; dri_bo_fake *batch_fake = (dri_bo_fake *)batch_buf; int ret; int retry_count = 0; bufmgr_fake->performed_rendering = GL_FALSE; dri_fake_calculate_validate_flags(batch_buf); batch_fake->validate_flags = DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ; /* we've ran out of RAM so blow the whole lot away and retry */ restart: ret = dri_fake_reloc_and_validate_buffer(batch_buf); if (bufmgr_fake->fail == 1) { if (retry_count == 0) { retry_count++; dri_fake_kick_all(bufmgr_fake); bufmgr_fake->fail = 0; goto restart; } else /* dump out the memory here */ mmDumpMemInfo(bufmgr_fake->heap); } assert(ret == 0); *count_p = 0; /* junk */ bufmgr_fake->current_total_size = 0; return NULL;}static voiddri_bo_fake_post_submit(dri_bo *bo){ dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; dri_bo_fake *bo_fake = (dri_bo_fake *)bo; int i; for (i = 0; i < bo_fake->nr_relocs; i++) { struct fake_buffer_reloc *r = &bo_fake->relocs[i]; dri_bo_fake *target_fake = (dri_bo_fake *)r->target_buf; if (target_fake->validated) dri_bo_fake_post_submit(r->target_buf); DBG("%s@0x%08x + 0x%08x -> %s@0x%08x + 0x%08x\n", bo_fake->name, (uint32_t)bo->offset, r->offset, target_fake->name, (uint32_t)r->target_buf->offset, r->delta); } assert(bo_fake->map_count == 0); bo_fake->validated = GL_FALSE; bo_fake->validate_flags = 0;}static voiddri_fake_post_submit(dri_bo *batch_buf, dri_fence **last_fence){ dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)batch_buf->bufmgr; dri_fence *fo; fo = dri_fake_fence_validated(batch_buf->bufmgr, "Batch fence", GL_TRUE); if (bufmgr_fake->performed_rendering) { dri_fence_unreference(*last_fence); *last_fence = fo; } else { dri_fence_unreference(fo); } dri_bo_fake_post_submit(batch_buf);}static intdri_fake_check_aperture_space(dri_bo *bo){ dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; dri_bo_fake *bo_fake = (dri_bo_fake *)bo; GLuint sz; sz = (bo->size + bo_fake->alignment - 1) & ~(bo_fake->alignment - 1); if (bo_fake->size_accounted || bo_fake->is_static) return 0; if (bufmgr_fake->current_total_size + sz > bufmgr_fake->size) { DBG("check_space: %s bo %d %d overflowed bufmgr size %d\n", bo_fake->name, bo_fake->id, sz, bufmgr_fake->size); return -1; } bufmgr_fake->current_total_size += sz; bo_fake->size_accounted = 1; DBG("drm_check_space: buf %d, %s %d %d\n", bo_fake->id, bo_fake->name, bo->size, bufmgr_fake->current_total_size); return 0;}dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, unsigned long size, unsigned int (*fence_emit)(void *private), int (*fence_wait)(void *private, unsigned int cookie), void *driver_priv){ dri_bufmgr_fake *bufmgr_fake; bufmgr_fake = calloc(1, sizeof(*bufmgr_fake)); /* Initialize allocator */ make_empty_list(&bufmgr_fake->fenced); make_empty_list(&bufmgr_fake->on_hardware); make_empty_list(&bufmgr_fake->lru); bufmgr_fake->low_offset = low_offset; bufmgr_fake->virtual = low_virtual; bufmgr_fake->size = size; bufmgr_fake->heap = mmInit(low_offset, size); /* Hook in methods */ bufmgr_fake->bufmgr.bo_alloc = dri_fake_bo_alloc; bufmgr_fake->bufmgr.bo_alloc_static = dri_fake_bo_alloc_static; bufmgr_fake->bufmgr.bo_reference = dri_fake_bo_reference; bufmgr_fake->bufmgr.bo_unreference = dri_fake_bo_unreference; bufmgr_fake->bufmgr.bo_map = dri_fake_bo_map; bufmgr_fake->bufmgr.bo_unmap = dri_fake_bo_unmap; bufmgr_fake->bufmgr.fence_wait = dri_fake_fence_wait; bufmgr_fake->bufmgr.fence_reference = dri_fake_fence_reference; bufmgr_fake->bufmgr.fence_unreference = dri_fake_fence_unreference; bufmgr_fake->bufmgr.destroy = dri_fake_destroy; bufmgr_fake->bufmgr.emit_reloc = dri_fake_emit_reloc; bufmgr_fake->bufmgr.process_relocs = dri_fake_process_relocs; bufmgr_fake->bufmgr.post_submit = dri_fake_post_submit; bufmgr_fake->bufmgr.check_aperture_space = dri_fake_check_aperture_space; bufmgr_fake->bufmgr.debug = GL_FALSE; bufmgr_fake->fence_emit = fence_emit; bufmgr_fake->fence_wait = fence_wait; bufmgr_fake->driver_priv = driver_priv; return &bufmgr_fake->bufmgr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -