19f464c52Smaya/* 29f464c52Smaya * Copyright (c) 2017-2019 Lima Project 39f464c52Smaya * 49f464c52Smaya * Permission is hereby granted, free of charge, to any person obtaining a 59f464c52Smaya * copy of this software and associated documentation files (the "Software"), 69f464c52Smaya * to deal in the Software without restriction, including without limitation 79f464c52Smaya * the rights to use, copy, modify, merge, publish, distribute, sub license, 89f464c52Smaya * and/or sell copies of the Software, and to permit persons to whom the 99f464c52Smaya * Software is furnished to do so, subject to the following conditions: 109f464c52Smaya * 119f464c52Smaya * The above copyright notice and this permission notice (including the 129f464c52Smaya * next paragraph) shall be included in all copies or substantial portions 139f464c52Smaya * of the Software. 149f464c52Smaya * 159f464c52Smaya * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 169f464c52Smaya * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 179f464c52Smaya * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 189f464c52Smaya * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 199f464c52Smaya * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 209f464c52Smaya * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 219f464c52Smaya * DEALINGS IN THE SOFTWARE. 229f464c52Smaya * 239f464c52Smaya */ 249f464c52Smaya 259f464c52Smaya#include "util/u_memory.h" 269f464c52Smaya#include "util/u_blitter.h" 279f464c52Smaya#include "util/u_upload_mgr.h" 289f464c52Smaya#include "util/u_math.h" 299f464c52Smaya#include "util/u_debug.h" 309f464c52Smaya#include "util/ralloc.h" 319f464c52Smaya#include "util/u_inlines.h" 329f464c52Smaya#include "util/hash_table.h" 339f464c52Smaya 349f464c52Smaya#include "lima_screen.h" 359f464c52Smaya#include "lima_context.h" 369f464c52Smaya#include "lima_resource.h" 379f464c52Smaya#include "lima_bo.h" 387ec681f3Smrg#include "lima_job.h" 399f464c52Smaya#include "lima_util.h" 409f464c52Smaya#include "lima_fence.h" 419f464c52Smaya 429f464c52Smaya#include <drm-uapi/lima_drm.h> 439f464c52Smaya#include <xf86drm.h> 449f464c52Smaya 459f464c52Smayaint lima_ctx_num_plb = LIMA_CTX_PLB_DEF_NUM; 469f464c52Smaya 479f464c52Smayauint32_t 487ec681f3Smrglima_ctx_buff_va(struct lima_context *ctx, enum lima_ctx_buff buff) 499f464c52Smaya{ 507ec681f3Smrg struct lima_job *job = lima_job_get(ctx); 519f464c52Smaya struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff; 529f464c52Smaya struct lima_resource *res = lima_resource(cbs->res); 537ec681f3Smrg int pipe = buff < lima_ctx_buff_num_gp ? LIMA_PIPE_GP : LIMA_PIPE_PP; 549f464c52Smaya 557ec681f3Smrg lima_job_add_bo(job, pipe, res->bo, LIMA_SUBMIT_BO_READ); 569f464c52Smaya 579f464c52Smaya return res->bo->va + cbs->offset; 589f464c52Smaya} 599f464c52Smaya 609f464c52Smayavoid * 619f464c52Smayalima_ctx_buff_map(struct lima_context *ctx, enum lima_ctx_buff buff) 629f464c52Smaya{ 639f464c52Smaya struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff; 649f464c52Smaya struct lima_resource *res = lima_resource(cbs->res); 659f464c52Smaya 669f464c52Smaya return lima_bo_map(res->bo) + cbs->offset; 679f464c52Smaya} 689f464c52Smaya 699f464c52Smayavoid * 709f464c52Smayalima_ctx_buff_alloc(struct lima_context *ctx, enum lima_ctx_buff buff, 717ec681f3Smrg unsigned size) 729f464c52Smaya{ 739f464c52Smaya struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff; 749f464c52Smaya void *ret = NULL; 759f464c52Smaya 769f464c52Smaya cbs->size = align(size, 0x40); 779f464c52Smaya 787ec681f3Smrg u_upload_alloc(ctx->uploader, 0, cbs->size, 0x40, &cbs->offset, 797ec681f3Smrg &cbs->res, &ret); 809f464c52Smaya 819f464c52Smaya return ret; 829f464c52Smaya} 839f464c52Smaya 849f464c52Smayastatic int 859f464c52Smayalima_context_create_drm_ctx(struct lima_screen *screen) 869f464c52Smaya{ 879f464c52Smaya struct drm_lima_ctx_create req = {0}; 889f464c52Smaya 899f464c52Smaya int ret = drmIoctl(screen->fd, DRM_IOCTL_LIMA_CTX_CREATE, &req); 909f464c52Smaya if (ret) 919f464c52Smaya return errno; 929f464c52Smaya 939f464c52Smaya return req.id; 949f464c52Smaya} 959f464c52Smaya 969f464c52Smayastatic void 979f464c52Smayalima_context_free_drm_ctx(struct lima_screen *screen, int id) 989f464c52Smaya{ 999f464c52Smaya struct drm_lima_ctx_free req = { 1009f464c52Smaya .id = id, 1019f464c52Smaya }; 1029f464c52Smaya 1039f464c52Smaya drmIoctl(screen->fd, DRM_IOCTL_LIMA_CTX_FREE, &req); 1049f464c52Smaya} 1059f464c52Smaya 1067ec681f3Smrgstatic void 1077ec681f3Smrglima_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc) 1087ec681f3Smrg{ 1097ec681f3Smrg struct lima_context *ctx = lima_context(pctx); 1107ec681f3Smrg 1117ec681f3Smrg struct hash_entry *entry = _mesa_hash_table_search(ctx->write_jobs, prsc); 1127ec681f3Smrg if (!entry) 1137ec681f3Smrg return; 1147ec681f3Smrg 1157ec681f3Smrg struct lima_job *job = entry->data; 1167ec681f3Smrg if (job->key.zsbuf && (job->key.zsbuf->texture == prsc)) 1177ec681f3Smrg job->resolve &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL); 1187ec681f3Smrg 1197ec681f3Smrg if (job->key.cbuf && (job->key.cbuf->texture == prsc)) 1207ec681f3Smrg job->resolve &= ~PIPE_CLEAR_COLOR0; 1217ec681f3Smrg 1227ec681f3Smrg _mesa_hash_table_remove_key(ctx->write_jobs, prsc); 1237ec681f3Smrg} 1247ec681f3Smrg 1257ec681f3Smrgstatic void 1267ec681f3Smrgplb_pp_stream_delete_fn(struct hash_entry *entry) 1277ec681f3Smrg{ 1287ec681f3Smrg struct lima_ctx_plb_pp_stream *s = entry->data; 1297ec681f3Smrg 1307ec681f3Smrg lima_bo_unreference(s->bo); 1317ec681f3Smrg list_del(&s->lru_list); 1327ec681f3Smrg ralloc_free(s); 1337ec681f3Smrg} 1347ec681f3Smrg 1359f464c52Smayastatic void 1369f464c52Smayalima_context_destroy(struct pipe_context *pctx) 1379f464c52Smaya{ 1389f464c52Smaya struct lima_context *ctx = lima_context(pctx); 1399f464c52Smaya struct lima_screen *screen = lima_screen(pctx->screen); 1409f464c52Smaya 1417ec681f3Smrg lima_job_fini(ctx); 1429f464c52Smaya 1439f464c52Smaya for (int i = 0; i < lima_ctx_buff_num; i++) 1449f464c52Smaya pipe_resource_reference(&ctx->buffer_state[i].res, NULL); 1459f464c52Smaya 1467ec681f3Smrg lima_program_fini(ctx); 1479f464c52Smaya lima_state_fini(ctx); 1489f464c52Smaya 1499f464c52Smaya if (ctx->blitter) 1509f464c52Smaya util_blitter_destroy(ctx->blitter); 1519f464c52Smaya 1529f464c52Smaya if (ctx->uploader) 1539f464c52Smaya u_upload_destroy(ctx->uploader); 1549f464c52Smaya 1559f464c52Smaya slab_destroy_child(&ctx->transfer_pool); 1569f464c52Smaya 1579f464c52Smaya for (int i = 0; i < LIMA_CTX_PLB_MAX_NUM; i++) { 1589f464c52Smaya if (ctx->plb[i]) 1597ec681f3Smrg lima_bo_unreference(ctx->plb[i]); 1609f464c52Smaya if (ctx->gp_tile_heap[i]) 1617ec681f3Smrg lima_bo_unreference(ctx->gp_tile_heap[i]); 1629f464c52Smaya } 1639f464c52Smaya 1649f464c52Smaya if (ctx->plb_gp_stream) 1657ec681f3Smrg lima_bo_unreference(ctx->plb_gp_stream); 1667ec681f3Smrg 1677ec681f3Smrg if (ctx->gp_output) 1687ec681f3Smrg lima_bo_unreference(ctx->gp_output); 1699f464c52Smaya 1707ec681f3Smrg _mesa_hash_table_destroy(ctx->plb_pp_stream, 1717ec681f3Smrg plb_pp_stream_delete_fn); 1729f464c52Smaya 1739f464c52Smaya lima_context_free_drm_ctx(screen, ctx->id); 1749f464c52Smaya 1759f464c52Smaya ralloc_free(ctx); 1769f464c52Smaya} 1779f464c52Smaya 1789f464c52Smayastatic uint32_t 1799f464c52Smayaplb_pp_stream_hash(const void *key) 1809f464c52Smaya{ 1819f464c52Smaya return _mesa_hash_data(key, sizeof(struct lima_ctx_plb_pp_stream_key)); 1829f464c52Smaya} 1839f464c52Smaya 1849f464c52Smayastatic bool 1859f464c52Smayaplb_pp_stream_compare(const void *key1, const void *key2) 1869f464c52Smaya{ 1879f464c52Smaya return memcmp(key1, key2, sizeof(struct lima_ctx_plb_pp_stream_key)) == 0; 1889f464c52Smaya} 1899f464c52Smaya 1907ec681f3Smrgstatic void 1917ec681f3Smrglima_set_debug_callback(struct pipe_context *pctx, 1927ec681f3Smrg const struct pipe_debug_callback *cb) 1937ec681f3Smrg{ 1947ec681f3Smrg struct lima_context *ctx = lima_context(pctx); 1957ec681f3Smrg 1967ec681f3Smrg if (cb) 1977ec681f3Smrg ctx->debug = *cb; 1987ec681f3Smrg else 1997ec681f3Smrg memset(&ctx->debug, 0, sizeof(ctx->debug)); 2007ec681f3Smrg} 2017ec681f3Smrg 2029f464c52Smayastruct pipe_context * 2039f464c52Smayalima_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) 2049f464c52Smaya{ 2059f464c52Smaya struct lima_screen *screen = lima_screen(pscreen); 2069f464c52Smaya struct lima_context *ctx; 2079f464c52Smaya 2089f464c52Smaya ctx = rzalloc(screen, struct lima_context); 2099f464c52Smaya if (!ctx) 2109f464c52Smaya return NULL; 2119f464c52Smaya 2129f464c52Smaya ctx->id = lima_context_create_drm_ctx(screen); 2139f464c52Smaya if (ctx->id < 0) { 2149f464c52Smaya ralloc_free(ctx); 2159f464c52Smaya return NULL; 2169f464c52Smaya } 2179f464c52Smaya 2189f464c52Smaya ctx->base.screen = pscreen; 2199f464c52Smaya ctx->base.destroy = lima_context_destroy; 2207ec681f3Smrg ctx->base.set_debug_callback = lima_set_debug_callback; 2217ec681f3Smrg ctx->base.invalidate_resource = lima_invalidate_resource; 2229f464c52Smaya 2239f464c52Smaya lima_resource_context_init(ctx); 2249f464c52Smaya lima_fence_context_init(ctx); 2259f464c52Smaya lima_state_init(ctx); 2269f464c52Smaya lima_draw_init(ctx); 2279f464c52Smaya lima_program_init(ctx); 2289f464c52Smaya lima_query_init(ctx); 2299f464c52Smaya 2309f464c52Smaya slab_create_child(&ctx->transfer_pool, &screen->transfer_pool); 2319f464c52Smaya 2329f464c52Smaya ctx->blitter = util_blitter_create(&ctx->base); 2339f464c52Smaya if (!ctx->blitter) 2349f464c52Smaya goto err_out; 2359f464c52Smaya 2369f464c52Smaya ctx->uploader = u_upload_create_default(&ctx->base); 2379f464c52Smaya if (!ctx->uploader) 2389f464c52Smaya goto err_out; 2399f464c52Smaya ctx->base.stream_uploader = ctx->uploader; 2409f464c52Smaya ctx->base.const_uploader = ctx->uploader; 2419f464c52Smaya 2427ec681f3Smrg ctx->plb_size = screen->plb_max_blk * LIMA_CTX_PLB_BLK_SIZE; 2437ec681f3Smrg ctx->plb_gp_size = screen->plb_max_blk * 4; 2447ec681f3Smrg 2457ec681f3Smrg uint32_t heap_flags; 2467ec681f3Smrg if (screen->has_growable_heap_buffer) { 2477ec681f3Smrg /* growable size buffer, initially will allocate 32K (by default) 2487ec681f3Smrg * backup memory in kernel driver, and will allocate more when GP 2497ec681f3Smrg * get out of memory interrupt. Max to 16M set here. 2507ec681f3Smrg */ 2517ec681f3Smrg ctx->gp_tile_heap_size = 0x1000000; 2527ec681f3Smrg heap_flags = LIMA_BO_FLAG_HEAP; 2537ec681f3Smrg } else { 2547ec681f3Smrg /* fix size buffer */ 2557ec681f3Smrg ctx->gp_tile_heap_size = 0x100000; 2567ec681f3Smrg heap_flags = 0; 2577ec681f3Smrg } 2589f464c52Smaya 2599f464c52Smaya for (int i = 0; i < lima_ctx_num_plb; i++) { 2609f464c52Smaya ctx->plb[i] = lima_bo_create(screen, ctx->plb_size, 0); 2619f464c52Smaya if (!ctx->plb[i]) 2629f464c52Smaya goto err_out; 2637ec681f3Smrg ctx->gp_tile_heap[i] = lima_bo_create(screen, ctx->gp_tile_heap_size, heap_flags); 2649f464c52Smaya if (!ctx->gp_tile_heap[i]) 2659f464c52Smaya goto err_out; 2669f464c52Smaya } 2679f464c52Smaya 2689f464c52Smaya unsigned plb_gp_stream_size = 2699f464c52Smaya align(ctx->plb_gp_size * lima_ctx_num_plb, LIMA_PAGE_SIZE); 2709f464c52Smaya ctx->plb_gp_stream = 2719f464c52Smaya lima_bo_create(screen, plb_gp_stream_size, 0); 2729f464c52Smaya if (!ctx->plb_gp_stream) 2739f464c52Smaya goto err_out; 2749f464c52Smaya lima_bo_map(ctx->plb_gp_stream); 2759f464c52Smaya 2769f464c52Smaya /* plb gp stream is static for any framebuffer */ 2779f464c52Smaya for (int i = 0; i < lima_ctx_num_plb; i++) { 2789f464c52Smaya uint32_t *plb_gp_stream = ctx->plb_gp_stream->map + i * ctx->plb_gp_size; 2797ec681f3Smrg for (int j = 0; j < screen->plb_max_blk; j++) 2809f464c52Smaya plb_gp_stream[j] = ctx->plb[i]->va + LIMA_CTX_PLB_BLK_SIZE * j; 2819f464c52Smaya } 2829f464c52Smaya 2837ec681f3Smrg list_inithead(&ctx->plb_pp_stream_lru_list); 2847ec681f3Smrg ctx->plb_pp_stream = _mesa_hash_table_create( 2857ec681f3Smrg ctx, plb_pp_stream_hash, plb_pp_stream_compare); 2867ec681f3Smrg if (!ctx->plb_pp_stream) 2879f464c52Smaya goto err_out; 2889f464c52Smaya 2897ec681f3Smrg if (!lima_job_init(ctx)) 2909f464c52Smaya goto err_out; 2919f464c52Smaya 2929f464c52Smaya return &ctx->base; 2939f464c52Smaya 2949f464c52Smayaerr_out: 2959f464c52Smaya lima_context_destroy(&ctx->base); 2969f464c52Smaya return NULL; 2979f464c52Smaya} 298