"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/lima/lima_context.c" (16 Sep 2020, 8367 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "lima_context.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (c) 2017-2019 Lima Project
    3  *
    4  * Permission is hereby granted, free of charge, to any person obtaining a
    5  * copy of this software and associated documentation files (the "Software"),
    6  * to deal in the Software without restriction, including without limitation
    7  * the rights to use, copy, modify, merge, publish, distribute, sub license,
    8  * and/or sell copies of the Software, and to permit persons to whom the
    9  * Software is furnished to do so, subject to the following conditions:
   10  *
   11  * The above copyright notice and this permission notice (including the
   12  * next paragraph) shall be included in all copies or substantial portions
   13  * of the Software.
   14  *
   15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
   18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   21  * DEALINGS IN THE SOFTWARE.
   22  *
   23  */
   24 
   25 #include "util/u_memory.h"
   26 #include "util/u_blitter.h"
   27 #include "util/u_upload_mgr.h"
   28 #include "util/u_math.h"
   29 #include "util/u_debug.h"
   30 #include "util/ralloc.h"
   31 #include "util/u_inlines.h"
   32 #include "util/hash_table.h"
   33 
   34 #include "lima_screen.h"
   35 #include "lima_context.h"
   36 #include "lima_resource.h"
   37 #include "lima_bo.h"
   38 #include "lima_job.h"
   39 #include "lima_util.h"
   40 #include "lima_fence.h"
   41 
   42 #include <drm-uapi/lima_drm.h>
   43 #include <xf86drm.h>
   44 
   45 int lima_ctx_num_plb = LIMA_CTX_PLB_DEF_NUM;
   46 
   47 uint32_t
   48 lima_ctx_buff_va(struct lima_context *ctx, enum lima_ctx_buff buff)
   49 {
   50    struct lima_job *job = lima_job_get(ctx);
   51    struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;
   52    struct lima_resource *res = lima_resource(cbs->res);
   53    int pipe = buff < lima_ctx_buff_num_gp ? LIMA_PIPE_GP : LIMA_PIPE_PP;
   54 
   55    lima_job_add_bo(job, pipe, res->bo, LIMA_SUBMIT_BO_READ);
   56 
   57    return res->bo->va + cbs->offset;
   58 }
   59 
   60 void *
   61 lima_ctx_buff_map(struct lima_context *ctx, enum lima_ctx_buff buff)
   62 {
   63    struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;
   64    struct lima_resource *res = lima_resource(cbs->res);
   65 
   66    return lima_bo_map(res->bo) + cbs->offset;
   67 }
   68 
   69 void *
   70 lima_ctx_buff_alloc(struct lima_context *ctx, enum lima_ctx_buff buff,
   71                     unsigned size)
   72 {
   73    struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;
   74    void *ret = NULL;
   75 
   76    cbs->size = align(size, 0x40);
   77 
   78    u_upload_alloc(ctx->uploader, 0, cbs->size, 0x40, &cbs->offset,
   79                   &cbs->res, &ret);
   80 
   81    return ret;
   82 }
   83 
   84 static int
   85 lima_context_create_drm_ctx(struct lima_screen *screen)
   86 {
   87    struct drm_lima_ctx_create req = {0};
   88 
   89    int ret = drmIoctl(screen->fd, DRM_IOCTL_LIMA_CTX_CREATE, &req);
   90    if (ret)
   91       return errno;
   92 
   93    return req.id;
   94 }
   95 
   96 static void
   97 lima_context_free_drm_ctx(struct lima_screen *screen, int id)
   98 {
   99    struct drm_lima_ctx_free req = {
  100       .id = id,
  101    };
  102 
  103    drmIoctl(screen->fd, DRM_IOCTL_LIMA_CTX_FREE, &req);
  104 }
  105 
  106 static void
  107 lima_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
  108 {
  109    struct lima_context *ctx = lima_context(pctx);
  110 
  111    struct hash_entry *entry = _mesa_hash_table_search(ctx->write_jobs, prsc);
  112    if (!entry)
  113       return;
  114 
  115    struct lima_job *job = entry->data;
  116    if (job->key.zsbuf && (job->key.zsbuf->texture == prsc))
  117       job->resolve &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL);
  118 
  119    if (job->key.cbuf && (job->key.cbuf->texture == prsc))
  120       job->resolve &= ~PIPE_CLEAR_COLOR0;
  121 
  122    _mesa_hash_table_remove_key(ctx->write_jobs, prsc);
  123 }
  124 
  125 static void
  126 plb_pp_stream_delete_fn(struct hash_entry *entry)
  127 {
  128    struct lima_ctx_plb_pp_stream *s = entry->data;
  129 
  130    lima_bo_unreference(s->bo);
  131    list_del(&s->lru_list);
  132    ralloc_free(s);
  133 }
  134 
  135 static void
  136 lima_context_destroy(struct pipe_context *pctx)
  137 {
  138    struct lima_context *ctx = lima_context(pctx);
  139    struct lima_screen *screen = lima_screen(pctx->screen);
  140 
  141    lima_job_fini(ctx);
  142 
  143    for (int i = 0; i < lima_ctx_buff_num; i++)
  144       pipe_resource_reference(&ctx->buffer_state[i].res, NULL);
  145 
  146    lima_state_fini(ctx);
  147 
  148    if (ctx->blitter)
  149       util_blitter_destroy(ctx->blitter);
  150 
  151    if (ctx->uploader)
  152       u_upload_destroy(ctx->uploader);
  153 
  154    slab_destroy_child(&ctx->transfer_pool);
  155 
  156    for (int i = 0; i < LIMA_CTX_PLB_MAX_NUM; i++) {
  157       if (ctx->plb[i])
  158          lima_bo_unreference(ctx->plb[i]);
  159       if (ctx->gp_tile_heap[i])
  160          lima_bo_unreference(ctx->gp_tile_heap[i]);
  161    }
  162 
  163    if (ctx->plb_gp_stream)
  164       lima_bo_unreference(ctx->plb_gp_stream);
  165 
  166    if (ctx->gp_output)
  167       lima_bo_unreference(ctx->gp_output);
  168 
  169    _mesa_hash_table_destroy(ctx->plb_pp_stream,
  170                             plb_pp_stream_delete_fn);
  171 
  172    lima_context_free_drm_ctx(screen, ctx->id);
  173 
  174    ralloc_free(ctx);
  175 }
  176 
  177 static uint32_t
  178 plb_pp_stream_hash(const void *key)
  179 {
  180    return _mesa_hash_data(key, sizeof(struct lima_ctx_plb_pp_stream_key));
  181 }
  182 
  183 static bool
  184 plb_pp_stream_compare(const void *key1, const void *key2)
  185 {
  186    return memcmp(key1, key2, sizeof(struct lima_ctx_plb_pp_stream_key)) == 0;
  187 }
  188 
  189 static void
  190 lima_set_debug_callback(struct pipe_context *pctx,
  191                         const struct pipe_debug_callback *cb)
  192 {
  193    struct lima_context *ctx = lima_context(pctx);
  194 
  195    if (cb)
  196       ctx->debug = *cb;
  197    else
  198       memset(&ctx->debug, 0, sizeof(ctx->debug));
  199 }
  200 
  201 struct pipe_context *
  202 lima_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
  203 {
  204    struct lima_screen *screen = lima_screen(pscreen);
  205    struct lima_context *ctx;
  206 
  207    ctx = rzalloc(screen, struct lima_context);
  208    if (!ctx)
  209       return NULL;
  210 
  211    ctx->id = lima_context_create_drm_ctx(screen);
  212    if (ctx->id < 0) {
  213       ralloc_free(ctx);
  214       return NULL;
  215    }
  216 
  217    ctx->base.screen = pscreen;
  218    ctx->base.destroy = lima_context_destroy;
  219    ctx->base.set_debug_callback = lima_set_debug_callback;
  220    ctx->base.invalidate_resource = lima_invalidate_resource;
  221 
  222    lima_resource_context_init(ctx);
  223    lima_fence_context_init(ctx);
  224    lima_state_init(ctx);
  225    lima_draw_init(ctx);
  226    lima_program_init(ctx);
  227    lima_query_init(ctx);
  228 
  229    slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);
  230 
  231    ctx->blitter = util_blitter_create(&ctx->base);
  232    if (!ctx->blitter)
  233       goto err_out;
  234 
  235    ctx->uploader = u_upload_create_default(&ctx->base);
  236    if (!ctx->uploader)
  237       goto err_out;
  238    ctx->base.stream_uploader = ctx->uploader;
  239    ctx->base.const_uploader = ctx->uploader;
  240 
  241    ctx->plb_size = screen->plb_max_blk * LIMA_CTX_PLB_BLK_SIZE;
  242    ctx->plb_gp_size = screen->plb_max_blk * 4;
  243 
  244    uint32_t heap_flags;
  245    if (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 GP
  248        * get out of memory interrupt. Max to 16M set here.
  249        */
  250       ctx->gp_tile_heap_size = 0x1000000;
  251       heap_flags = LIMA_BO_FLAG_HEAP;
  252    } else {
  253       /* fix size buffer */
  254       ctx->gp_tile_heap_size = 0x100000;
  255       heap_flags = 0;
  256    }
  257 
  258    for (int i = 0; i < lima_ctx_num_plb; i++) {
  259       ctx->plb[i] = lima_bo_create(screen, ctx->plb_size, 0);
  260       if (!ctx->plb[i])
  261          goto err_out;
  262       ctx->gp_tile_heap[i] = lima_bo_create(screen, ctx->gp_tile_heap_size, heap_flags);
  263       if (!ctx->gp_tile_heap[i])
  264          goto err_out;
  265    }
  266 
  267    unsigned plb_gp_stream_size =
  268       align(ctx->plb_gp_size * lima_ctx_num_plb, LIMA_PAGE_SIZE);
  269    ctx->plb_gp_stream =
  270       lima_bo_create(screen, plb_gp_stream_size, 0);
  271    if (!ctx->plb_gp_stream)
  272       goto err_out;
  273    lima_bo_map(ctx->plb_gp_stream);
  274 
  275    /* plb gp stream is static for any framebuffer */
  276    for (int i = 0; i < lima_ctx_num_plb; i++) {
  277       uint32_t *plb_gp_stream = ctx->plb_gp_stream->map + i * ctx->plb_gp_size;
  278       for (int j = 0; j < screen->plb_max_blk; j++)
  279          plb_gp_stream[j] = ctx->plb[i]->va + LIMA_CTX_PLB_BLK_SIZE * j;
  280    }
  281 
  282    list_inithead(&ctx->plb_pp_stream_lru_list);
  283    ctx->plb_pp_stream = _mesa_hash_table_create(
  284       ctx, plb_pp_stream_hash, plb_pp_stream_compare);
  285    if (!ctx->plb_pp_stream)
  286       goto err_out;
  287 
  288    if (!lima_job_init(ctx))
  289       goto err_out;
  290 
  291    return &ctx->base;
  292 
  293 err_out:
  294    lima_context_destroy(&ctx->base);
  295    return NULL;
  296 }