static INLINE boolean nouveau_buffer_allocate(struct nouveau_screen *screen, struct nv04_resource *buf, unsigned domain) { uint32_t size = buf->base.width0; if (buf->base.bind & PIPE_BIND_CONSTANT_BUFFER) size = align(size, 0x100); if (domain == NOUVEAU_BO_VRAM) { buf->mm = nouveau_mm_allocate(screen->mm_VRAM, size, &buf->bo, &buf->offset); if (!buf->bo) return nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_GART); } else if (domain == NOUVEAU_BO_GART) { buf->mm = nouveau_mm_allocate(screen->mm_GART, size, &buf->bo, &buf->offset); if (!buf->bo) return FALSE; } else { assert(domain == 0); if (!nouveau_buffer_malloc(buf)) return FALSE; } buf->domain = domain; if (buf->bo) buf->address = buf->bo->offset + buf->offset; return TRUE; }
static boolean nouveau_buffer_cache(struct nouveau_context *nv, struct nv04_resource *buf) { struct nouveau_transfer tx; boolean ret; tx.base.resource = &buf->base; tx.base.box.x = 0; tx.base.box.width = buf->base.width0; tx.bo = NULL; if (!buf->data) if (!nouveau_buffer_malloc(buf)) return FALSE; if (!(buf->status & NOUVEAU_BUFFER_STATUS_DIRTY)) return TRUE; nv->stats.buf_cache_count++; if (!nouveau_transfer_staging(nv, &tx, FALSE)) return FALSE; ret = nouveau_transfer_read(nv, &tx); if (ret) { buf->status &= ~NOUVEAU_BUFFER_STATUS_DIRTY; memcpy(buf->data, tx.map, buf->base.width0); } nouveau_buffer_transfer_del(nv, &tx); return ret; }
static inline bool nouveau_buffer_allocate(struct nouveau_screen *screen, struct nv04_resource *buf, unsigned domain) { uint32_t size = align(buf->base.width0, 0x100); if (domain == NOUVEAU_BO_VRAM) { buf->mm = nouveau_mm_allocate(screen->mm_VRAM, size, &buf->bo, &buf->offset); if (!buf->bo) return nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_GART); NOUVEAU_DRV_STAT(screen, buf_obj_current_bytes_vid, buf->base.width0); } else if (domain == NOUVEAU_BO_GART) { buf->mm = nouveau_mm_allocate(screen->mm_GART, size, &buf->bo, &buf->offset); if (!buf->bo) return false; NOUVEAU_DRV_STAT(screen, buf_obj_current_bytes_sys, buf->base.width0); } else { assert(domain == 0); if (!nouveau_buffer_malloc(buf)) return false; } buf->domain = domain; if (buf->bo) buf->address = buf->bo->offset + buf->offset; util_range_set_empty(&buf->valid_buffer_range); return true; }
static INLINE boolean nouveau_buffer_data_fetch(struct nouveau_context *nv, struct nv04_resource *buf, struct nouveau_bo *bo, unsigned offset, unsigned size) { if (!nouveau_buffer_malloc(buf)) return FALSE; if (nouveau_bo_map(bo, NOUVEAU_BO_RD, nv->client)) return FALSE; memcpy(buf->data, (uint8_t *)bo->map + offset, size); return TRUE; }
static inline bool nouveau_buffer_data_fetch(struct nouveau_context *nv, struct nv04_resource *buf, struct nouveau_bo *bo, unsigned offset, unsigned size) { if (!nouveau_buffer_malloc(buf)) return false; if (nouveau_bo_map(bo, NOUVEAU_BO_RD, nv->client)) return false; memcpy(buf->data, (uint8_t *)bo->map + offset, size); return true; }
static INLINE boolean nouveau_buffer_allocate(struct nouveau_screen *screen, struct nv04_resource *buf, unsigned domain) { uint32_t size = buf->base.width0; if (buf->base.bind & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_COMPUTE_RESOURCE | PIPE_BIND_SHADER_RESOURCE)) size = align(size, 0x100); if (domain == NOUVEAU_BO_VRAM) { buf->mm = nouveau_mm_allocate(screen->mm_VRAM, size, &buf->bo, &buf->offset); if (!buf->bo) return nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_GART); NOUVEAU_DRV_STAT(screen, buf_obj_current_bytes_vid, buf->base.width0); } else if (domain == NOUVEAU_BO_GART) { buf->mm = nouveau_mm_allocate(screen->mm_GART, size, &buf->bo, &buf->offset); if (!buf->bo) return FALSE; NOUVEAU_DRV_STAT(screen, buf_obj_current_bytes_sys, buf->base.width0); } else { assert(domain == 0); if (!nouveau_buffer_malloc(buf)) return FALSE; } buf->domain = domain; if (buf->bo) buf->address = buf->bo->offset + buf->offset; util_range_set_empty(&buf->valid_buffer_range); return TRUE; }