Path: blob/21.2-virgl/src/gallium/drivers/lima/lima_context.c
4565 views
/*1* Copyright (c) 2017-2019 Lima Project2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sub license,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the11* next paragraph) shall be included in all copies or substantial portions12* of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER20* DEALINGS IN THE SOFTWARE.21*22*/2324#include "util/u_memory.h"25#include "util/u_blitter.h"26#include "util/u_upload_mgr.h"27#include "util/u_math.h"28#include "util/u_debug.h"29#include "util/ralloc.h"30#include "util/u_inlines.h"31#include "util/hash_table.h"3233#include "lima_screen.h"34#include "lima_context.h"35#include "lima_resource.h"36#include "lima_bo.h"37#include "lima_job.h"38#include "lima_util.h"39#include "lima_fence.h"4041#include <drm-uapi/lima_drm.h>42#include <xf86drm.h>4344int lima_ctx_num_plb = LIMA_CTX_PLB_DEF_NUM;4546uint32_t47lima_ctx_buff_va(struct lima_context *ctx, enum lima_ctx_buff buff)48{49struct lima_job *job = lima_job_get(ctx);50struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;51struct lima_resource *res = lima_resource(cbs->res);52int pipe = buff < lima_ctx_buff_num_gp ? LIMA_PIPE_GP : LIMA_PIPE_PP;5354lima_job_add_bo(job, pipe, res->bo, LIMA_SUBMIT_BO_READ);5556return res->bo->va + cbs->offset;57}5859void *60lima_ctx_buff_map(struct lima_context *ctx, enum lima_ctx_buff buff)61{62struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;63struct lima_resource *res = lima_resource(cbs->res);6465return lima_bo_map(res->bo) + cbs->offset;66}6768void *69lima_ctx_buff_alloc(struct lima_context *ctx, enum lima_ctx_buff buff,70unsigned size)71{72struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;73void *ret = NULL;7475cbs->size = align(size, 0x40);7677u_upload_alloc(ctx->uploader, 0, cbs->size, 0x40, &cbs->offset,78&cbs->res, &ret);7980return ret;81}8283static int84lima_context_create_drm_ctx(struct lima_screen *screen)85{86struct drm_lima_ctx_create req = {0};8788int ret = drmIoctl(screen->fd, DRM_IOCTL_LIMA_CTX_CREATE, &req);89if (ret)90return errno;9192return req.id;93}9495static void96lima_context_free_drm_ctx(struct lima_screen *screen, int id)97{98struct drm_lima_ctx_free req = {99.id = id,100};101102drmIoctl(screen->fd, DRM_IOCTL_LIMA_CTX_FREE, &req);103}104105static void106lima_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc)107{108struct lima_context *ctx = lima_context(pctx);109110struct hash_entry *entry = _mesa_hash_table_search(ctx->write_jobs, prsc);111if (!entry)112return;113114struct lima_job *job = entry->data;115if (job->key.zsbuf && (job->key.zsbuf->texture == prsc))116job->resolve &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL);117118if (job->key.cbuf && (job->key.cbuf->texture == prsc))119job->resolve &= ~PIPE_CLEAR_COLOR0;120121_mesa_hash_table_remove_key(ctx->write_jobs, prsc);122}123124static void125plb_pp_stream_delete_fn(struct hash_entry *entry)126{127struct lima_ctx_plb_pp_stream *s = entry->data;128129lima_bo_unreference(s->bo);130list_del(&s->lru_list);131ralloc_free(s);132}133134static void135lima_context_destroy(struct pipe_context *pctx)136{137struct lima_context *ctx = lima_context(pctx);138struct lima_screen *screen = lima_screen(pctx->screen);139140lima_job_fini(ctx);141142for (int i = 0; i < lima_ctx_buff_num; i++)143pipe_resource_reference(&ctx->buffer_state[i].res, NULL);144145lima_program_fini(ctx);146lima_state_fini(ctx);147148if (ctx->blitter)149util_blitter_destroy(ctx->blitter);150151if (ctx->uploader)152u_upload_destroy(ctx->uploader);153154slab_destroy_child(&ctx->transfer_pool);155156for (int i = 0; i < LIMA_CTX_PLB_MAX_NUM; i++) {157if (ctx->plb[i])158lima_bo_unreference(ctx->plb[i]);159if (ctx->gp_tile_heap[i])160lima_bo_unreference(ctx->gp_tile_heap[i]);161}162163if (ctx->plb_gp_stream)164lima_bo_unreference(ctx->plb_gp_stream);165166if (ctx->gp_output)167lima_bo_unreference(ctx->gp_output);168169_mesa_hash_table_destroy(ctx->plb_pp_stream,170plb_pp_stream_delete_fn);171172lima_context_free_drm_ctx(screen, ctx->id);173174ralloc_free(ctx);175}176177static uint32_t178plb_pp_stream_hash(const void *key)179{180return _mesa_hash_data(key, sizeof(struct lima_ctx_plb_pp_stream_key));181}182183static bool184plb_pp_stream_compare(const void *key1, const void *key2)185{186return memcmp(key1, key2, sizeof(struct lima_ctx_plb_pp_stream_key)) == 0;187}188189static void190lima_set_debug_callback(struct pipe_context *pctx,191const struct pipe_debug_callback *cb)192{193struct lima_context *ctx = lima_context(pctx);194195if (cb)196ctx->debug = *cb;197else198memset(&ctx->debug, 0, sizeof(ctx->debug));199}200201struct pipe_context *202lima_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)203{204struct lima_screen *screen = lima_screen(pscreen);205struct lima_context *ctx;206207ctx = rzalloc(screen, struct lima_context);208if (!ctx)209return NULL;210211ctx->id = lima_context_create_drm_ctx(screen);212if (ctx->id < 0) {213ralloc_free(ctx);214return NULL;215}216217ctx->base.screen = pscreen;218ctx->base.destroy = lima_context_destroy;219ctx->base.set_debug_callback = lima_set_debug_callback;220ctx->base.invalidate_resource = lima_invalidate_resource;221222lima_resource_context_init(ctx);223lima_fence_context_init(ctx);224lima_state_init(ctx);225lima_draw_init(ctx);226lima_program_init(ctx);227lima_query_init(ctx);228229slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);230231ctx->blitter = util_blitter_create(&ctx->base);232if (!ctx->blitter)233goto err_out;234235ctx->uploader = u_upload_create_default(&ctx->base);236if (!ctx->uploader)237goto err_out;238ctx->base.stream_uploader = ctx->uploader;239ctx->base.const_uploader = ctx->uploader;240241ctx->plb_size = screen->plb_max_blk * LIMA_CTX_PLB_BLK_SIZE;242ctx->plb_gp_size = screen->plb_max_blk * 4;243244uint32_t heap_flags;245if (screen->has_growable_heap_buffer) {246/* growable size buffer, initially will allocate 32K (by default)247* backup memory in kernel driver, and will allocate more when GP248* get out of memory interrupt. Max to 16M set here.249*/250ctx->gp_tile_heap_size = 0x1000000;251heap_flags = LIMA_BO_FLAG_HEAP;252} else {253/* fix size buffer */254ctx->gp_tile_heap_size = 0x100000;255heap_flags = 0;256}257258for (int i = 0; i < lima_ctx_num_plb; i++) {259ctx->plb[i] = lima_bo_create(screen, ctx->plb_size, 0);260if (!ctx->plb[i])261goto err_out;262ctx->gp_tile_heap[i] = lima_bo_create(screen, ctx->gp_tile_heap_size, heap_flags);263if (!ctx->gp_tile_heap[i])264goto err_out;265}266267unsigned plb_gp_stream_size =268align(ctx->plb_gp_size * lima_ctx_num_plb, LIMA_PAGE_SIZE);269ctx->plb_gp_stream =270lima_bo_create(screen, plb_gp_stream_size, 0);271if (!ctx->plb_gp_stream)272goto err_out;273lima_bo_map(ctx->plb_gp_stream);274275/* plb gp stream is static for any framebuffer */276for (int i = 0; i < lima_ctx_num_plb; i++) {277uint32_t *plb_gp_stream = ctx->plb_gp_stream->map + i * ctx->plb_gp_size;278for (int j = 0; j < screen->plb_max_blk; j++)279plb_gp_stream[j] = ctx->plb[i]->va + LIMA_CTX_PLB_BLK_SIZE * j;280}281282list_inithead(&ctx->plb_pp_stream_lru_list);283ctx->plb_pp_stream = _mesa_hash_table_create(284ctx, plb_pp_stream_hash, plb_pp_stream_compare);285if (!ctx->plb_pp_stream)286goto err_out;287288if (!lima_job_init(ctx))289goto err_out;290291return &ctx->base;292293err_out:294lima_context_destroy(&ctx->base);295return NULL;296}297298299