aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/lima/lima_context.c
diff options
context:
space:
mode:
authorQiang Yu <[email protected]>2019-03-12 13:49:26 -0600
committerQiang Yu <[email protected]>2019-04-11 09:57:53 +0800
commit92d7ca4b1cdfe1ffc80748fa7eedf927f3c664f0 (patch)
treed96651839bae0342e65b9cd414e56759a9a25cea /src/gallium/drivers/lima/lima_context.c
parent64eaf60ca739704f71bd312c0f4039d287258216 (diff)
gallium: add lima driver
v2: - use renamed util_dynarray_grow_cap - use DEBUG_GET_ONCE_FLAGS_OPTION for debug flags - remove DRM_FORMAT_MOD_ARM_AGTB_MODE0 usage - compute min/max index in driver v3: - fix plbu framebuffer state calculation - fix color_16pc assemble - use nir_lower_all_source_mods for lowering neg/abs/sat - use float arrary for static GPU data - add disassemble comment for static shader code - use drm_find_modifier v4: - use lima_nir_lower_uniform_to_scalar v5: - remove nir_opt_global_to_local when rebase Cc: Rob Clark <[email protected]> Cc: Alyssa Rosenzweig <[email protected]> Acked-by: Eric Anholt <[email protected]> Signed-off-by: Andreas Baierl <[email protected]> Signed-off-by: Arno Messiaen <[email protected]> Signed-off-by: Connor Abbott <[email protected]> Signed-off-by: Erico Nunes <[email protected]> Signed-off-by: Heiko Stuebner <[email protected]> Signed-off-by: Koen Kooi <[email protected]> Signed-off-by: Marek Vasut <[email protected]> Signed-off-by: marmeladema <[email protected]> Signed-off-by: PaweÅ‚ Chmiel <[email protected]> Signed-off-by: Rob Herring <[email protected]> Signed-off-by: Rohan Garg <[email protected]> Signed-off-by: Vasily Khoruzhick <[email protected]> Signed-off-by: Qiang Yu <[email protected]>
Diffstat (limited to 'src/gallium/drivers/lima/lima_context.c')
-rw-r--r--src/gallium/drivers/lima/lima_context.c262
1 files changed, 262 insertions, 0 deletions
diff --git a/src/gallium/drivers/lima/lima_context.c b/src/gallium/drivers/lima/lima_context.c
new file mode 100644
index 00000000000..35bf8c89a9c
--- /dev/null
+++ b/src/gallium/drivers/lima/lima_context.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2017-2019 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "util/u_memory.h"
+#include "util/u_upload_mgr.h"
+#include "util/u_math.h"
+#include "util/u_debug.h"
+#include "util/ralloc.h"
+#include "util/u_inlines.h"
+#include "util/u_suballoc.h"
+#include "util/hash_table.h"
+
+#include "lima_screen.h"
+#include "lima_context.h"
+#include "lima_resource.h"
+#include "lima_bo.h"
+#include "lima_submit.h"
+#include "lima_util.h"
+#include "lima_fence.h"
+
+#include <drm-uapi/lima_drm.h>
+#include <xf86drm.h>
+
+int lima_ctx_num_plb = LIMA_CTX_PLB_DEF_NUM;
+
+uint32_t
+lima_ctx_buff_va(struct lima_context *ctx, enum lima_ctx_buff buff, unsigned submit)
+{
+ struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;
+ struct lima_resource *res = lima_resource(cbs->res);
+
+ if (submit & LIMA_CTX_BUFF_SUBMIT_GP)
+ lima_submit_add_bo(ctx->gp_submit, res->bo, LIMA_SUBMIT_BO_READ);
+ if (submit & LIMA_CTX_BUFF_SUBMIT_PP)
+ lima_submit_add_bo(ctx->pp_submit, res->bo, LIMA_SUBMIT_BO_READ);
+
+ return res->bo->va + cbs->offset;
+}
+
+void *
+lima_ctx_buff_map(struct lima_context *ctx, enum lima_ctx_buff buff)
+{
+ struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;
+ struct lima_resource *res = lima_resource(cbs->res);
+
+ return lima_bo_map(res->bo) + cbs->offset;
+}
+
+void *
+lima_ctx_buff_alloc(struct lima_context *ctx, enum lima_ctx_buff buff,
+ unsigned size, bool uploader)
+{
+ struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;
+ void *ret = NULL;
+
+ cbs->size = align(size, 0x40);
+
+ if (uploader)
+ u_upload_alloc(ctx->uploader, 0, cbs->size, 0x40, &cbs->offset,
+ &cbs->res, &ret);
+ else
+ u_suballocator_alloc(ctx->suballocator, cbs->size, 0x10,
+ &cbs->offset, &cbs->res);
+
+ return ret;
+}
+
+static int
+lima_context_create_drm_ctx(struct lima_screen *screen)
+{
+ struct drm_lima_ctx_create req = {0};
+
+ int ret = drmIoctl(screen->fd, DRM_IOCTL_LIMA_CTX_CREATE, &req);
+ if (ret)
+ return errno;
+
+ return req.id;
+}
+
+static void
+lima_context_free_drm_ctx(struct lima_screen *screen, int id)
+{
+ struct drm_lima_ctx_free req = {
+ .id = id,
+ };
+
+ drmIoctl(screen->fd, DRM_IOCTL_LIMA_CTX_FREE, &req);
+}
+
+static void
+lima_context_destroy(struct pipe_context *pctx)
+{
+ struct lima_context *ctx = lima_context(pctx);
+ struct lima_screen *screen = lima_screen(pctx->screen);
+
+ if (ctx->pp_submit)
+ lima_submit_free(ctx->pp_submit);
+ if (ctx->gp_submit)
+ lima_submit_free(ctx->gp_submit);
+
+ for (int i = 0; i < lima_ctx_buff_num; i++)
+ pipe_resource_reference(&ctx->buffer_state[i].res, NULL);
+
+ lima_state_fini(ctx);
+
+ if (ctx->suballocator)
+ u_suballocator_destroy(ctx->suballocator);
+
+ if (ctx->uploader)
+ u_upload_destroy(ctx->uploader);
+
+ slab_destroy_child(&ctx->transfer_pool);
+
+ for (int i = 0; i < LIMA_CTX_PLB_MAX_NUM; i++) {
+ if (ctx->plb[i])
+ lima_bo_free(ctx->plb[i]);
+ }
+
+ if (ctx->plb_gp_stream)
+ lima_bo_free(ctx->plb_gp_stream);
+
+ if (ctx->plb_pp_stream)
+ assert(!_mesa_hash_table_num_entries(ctx->plb_pp_stream));
+
+ lima_context_free_drm_ctx(screen, ctx->id);
+
+ ralloc_free(ctx);
+}
+
+static uint32_t
+plb_pp_stream_hash(const void *key)
+{
+ return _mesa_hash_data(key, sizeof(struct lima_ctx_plb_pp_stream_key));
+}
+
+static bool
+plb_pp_stream_compare(const void *key1, const void *key2)
+{
+ return memcmp(key1, key2, sizeof(struct lima_ctx_plb_pp_stream_key)) == 0;
+}
+
+struct pipe_context *
+lima_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
+{
+ struct lima_screen *screen = lima_screen(pscreen);
+ struct lima_context *ctx;
+
+ ctx = rzalloc(screen, struct lima_context);
+ if (!ctx)
+ return NULL;
+
+ ctx->id = lima_context_create_drm_ctx(screen);
+ if (ctx->id < 0) {
+ ralloc_free(ctx);
+ return NULL;
+ }
+
+ ctx->base.screen = pscreen;
+ ctx->base.destroy = lima_context_destroy;
+
+ lima_resource_context_init(ctx);
+ lima_fence_context_init(ctx);
+ lima_state_init(ctx);
+ lima_draw_init(ctx);
+ lima_program_init(ctx);
+ lima_query_init(ctx);
+
+ slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);
+
+ ctx->uploader = u_upload_create_default(&ctx->base);
+ if (!ctx->uploader)
+ goto err_out;
+ ctx->base.stream_uploader = ctx->uploader;
+ ctx->base.const_uploader = ctx->uploader;
+
+ /* for varying output which need not mmap */
+ ctx->suballocator =
+ u_suballocator_create(&ctx->base, 1024 * 1024, 0,
+ PIPE_USAGE_STREAM, 0, false);
+ if (!ctx->suballocator)
+ goto err_out;
+
+ util_dynarray_init(&ctx->vs_cmd_array, ctx);
+ util_dynarray_init(&ctx->plbu_cmd_array, ctx);
+
+ if (screen->gpu_type == DRM_LIMA_PARAM_GPU_ID_MALI450)
+ ctx->plb_max_blk = 4096;
+ else
+ ctx->plb_max_blk = 512;
+ ctx->plb_size = ctx->plb_max_blk * LIMA_CTX_PLB_BLK_SIZE;
+ ctx->plb_gp_size = ctx->plb_max_blk * 4;
+
+ for (int i = 0; i < lima_ctx_num_plb; i++) {
+ ctx->plb[i] = lima_bo_create(screen, ctx->plb_size, 0);
+ if (!ctx->plb[i])
+ goto err_out;
+ }
+
+ unsigned plb_gp_stream_size =
+ align(ctx->plb_gp_size * lima_ctx_num_plb, LIMA_PAGE_SIZE);
+ ctx->plb_gp_stream =
+ lima_bo_create(screen, plb_gp_stream_size, 0);
+ if (!ctx->plb_gp_stream)
+ goto err_out;
+ lima_bo_map(ctx->plb_gp_stream);
+
+ /* plb gp stream is static for any framebuffer */
+ for (int i = 0; i < lima_ctx_num_plb; i++) {
+ uint32_t *plb_gp_stream = ctx->plb_gp_stream->map + i * ctx->plb_gp_size;
+ for (int j = 0; j < ctx->plb_max_blk; j++)
+ plb_gp_stream[j] = ctx->plb[i]->va + LIMA_CTX_PLB_BLK_SIZE * j;
+ }
+
+ if (screen->gpu_type == DRM_LIMA_PARAM_GPU_ID_MALI400) {
+ ctx->plb_pp_stream = _mesa_hash_table_create(
+ ctx, plb_pp_stream_hash, plb_pp_stream_compare);
+ if (!ctx->plb_pp_stream)
+ goto err_out;
+ }
+
+ ctx->gp_submit = lima_submit_create(ctx, LIMA_PIPE_GP);
+ if (!ctx->gp_submit)
+ goto err_out;
+
+ ctx->pp_submit = lima_submit_create(ctx, LIMA_PIPE_PP);
+ if (!ctx->pp_submit)
+ goto err_out;
+
+ return &ctx->base;
+
+err_out:
+ lima_context_destroy(&ctx->base);
+ return NULL;
+}
+
+bool
+lima_need_flush(struct lima_context *ctx, struct lima_bo *bo, bool write)
+{
+ return lima_submit_has_bo(ctx->gp_submit, bo, write) ||
+ lima_submit_has_bo(ctx->pp_submit, bo, write);
+}